#include <stdlib.h>
#include <string.h>
#include "gpu.h"
+#include "../../libpcsxcore/gpu.h" // meh
+#include "../../frontend/plugin_lib.h"
+#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
#ifdef __GNUC__
#define unlikely(x) __builtin_expect((x), 0)
#define preload __builtin_prefetch
int hres = hres_all[(gpu.status >> 16) & 7];
int pal = gpu.status & PSX_GPU_STATUS_PAL;
int sw = gpu.screen.x2 - gpu.screen.x1;
+ int type = gpu.state.screen_centering_type;
int x = 0, x_auto;
+ if (type == C_AUTO)
+ type = gpu.state.screen_centering_type_default;
if (sw <= 0)
/* nothing displayed? */;
else {
x = (x + 1) & ~1; // blitter limitation
sw /= hdiv;
sw = (sw + 2) & ~3; // according to nocash
- switch (gpu.state.screen_centering_type) {
- case 1:
+ switch (type) {
+ case C_INGAME:
break;
- case 2:
+ case C_MANUAL:
x = gpu.state.screen_centering_x;
break;
default:
/* nothing displayed? */;
else {
switch (gpu.state.screen_centering_type) {
- case 1:
+ case C_INGAME:
break;
- case 2:
+ case C_BORDERLESS:
+ y = 0;
+ break;
+ case C_MANUAL:
y = gpu.state.screen_centering_y;
break;
default:
void GPUwriteStatus(uint32_t data)
{
uint32_t cmd = data >> 24;
+ int src_x, src_y;
if (cmd < ARRAY_SIZE(gpu.regs)) {
if (cmd > 1 && cmd != 5 && gpu.regs[cmd] == data)
gpu.status |= PSX_GPU_STATUS_DMA(data & 3);
break;
case 0x05:
- gpu.screen.src_x = data & 0x3ff;
- gpu.screen.src_y = (data >> 10) & 0x1ff;
- renderer_notify_scanout_x_change(gpu.screen.src_x, gpu.screen.hres);
- if (gpu.frameskip.set) {
- decide_frameskip_allow(gpu.ex_regs[3]);
- if (gpu.frameskip.last_flip_frame != *gpu.state.frame_count) {
- decide_frameskip();
- gpu.frameskip.last_flip_frame = *gpu.state.frame_count;
+ src_x = data & 0x3ff; src_y = (data >> 10) & 0x1ff;
+ if (src_x != gpu.screen.src_x || src_y != gpu.screen.src_y) {
+ gpu.screen.src_x = src_x;
+ gpu.screen.src_y = src_y;
+ renderer_notify_scanout_change(src_x, src_y);
+ if (gpu.frameskip.set) {
+ decide_frameskip_allow(gpu.ex_regs[3]);
+ if (gpu.frameskip.last_flip_frame != *gpu.state.frame_count) {
+ decide_frameskip();
+ gpu.frameskip.last_flip_frame = *gpu.state.frame_count;
+ }
}
}
break;
log_io("start_vram_transfer %c (%d, %d) %dx%d\n", is_read ? 'r' : 'w',
gpu.dma.x, gpu.dma.y, gpu.dma.w, gpu.dma.h);
+ if (gpu.gpu_state_change)
+ gpu.gpu_state_change(PGS_VRAM_TRANSFER_START);
}
static void finish_vram_transfer(int is_read)
{
if (is_read)
gpu.status &= ~PSX_GPU_STATUS_IMG;
- else
+ else {
+ gpu.state.fb_dirty = 1;
renderer_update_caches(gpu.dma_start.x, gpu.dma_start.y,
gpu.dma_start.w, gpu.dma_start.h, 0);
+ }
+ if (gpu.gpu_state_change)
+ gpu.gpu_state_change(PGS_VRAM_TRANSFER_END);
}
static void do_vram_copy(const uint32_t *params)
break;
}
do_vram_copy(data + pos + 1);
+ vram_dirty = 1;
pos += 4;
continue;
}
return count - pos;
}
-static void flush_cmd_buffer(void)
+static noinline void flush_cmd_buffer(void)
{
int left = do_cmd_buffer(gpu.cmd_buffer, gpu.cmd_len);
if (left > 0)
memmove(gpu.cmd_buffer, gpu.cmd_buffer + gpu.cmd_len - left, left * 4);
- gpu.cmd_len = left;
+ if (left != gpu.cmd_len) {
+ if (!gpu.dma.h && gpu.gpu_state_change)
+ gpu.gpu_state_change(PGS_PRIMITIVE_START);
+ gpu.cmd_len = left;
+ }
}
void GPUwriteDataMem(uint32_t *mem, int count)
GPUwriteStatus((i << 24) | (gpu.regs[i] ^ 1));
}
renderer_sync_ecmds(gpu.ex_regs);
- renderer_update_caches(0, 0, 1024, 512, 1);
+ renderer_update_caches(0, 0, 1024, 512, 0);
break;
}
}
}
-#include "../../frontend/plugin_lib.h"
+void GPUgetScreenInfo(int *y, int *base_hres)
+{
+ *y = gpu.screen.y;
+ *base_hres = gpu.screen.vres;
+ if (gpu.status & PSX_GPU_STATUS_DHEIGHT)
+ *base_hres >>= 1;
+}
void GPUrearmedCallbacks(const struct rearmed_cbs *cbs)
{
gpu.state.frame_count = cbs->gpu_frame_count;
gpu.state.allow_interlace = cbs->gpu_neon.allow_interlace;
gpu.state.enhancement_enable = cbs->gpu_neon.enhancement_enable;
+ gpu.state.screen_centering_type_default = cbs->screen_centering_type_default;
if (gpu.state.screen_centering_type != cbs->screen_centering_type
|| gpu.state.screen_centering_x != cbs->screen_centering_x
|| gpu.state.screen_centering_y != cbs->screen_centering_y) {
gpu.mmap = cbs->mmap;
gpu.munmap = cbs->munmap;
+ gpu.gpu_state_change = cbs->gpu_state_change;
// delayed vram mmap
if (gpu.vram == NULL)