From 79ed3a5fb330830114e61ea0db8ed299584d9704 Mon Sep 17 00:00:00 2001 From: kub Date: Thu, 23 Nov 2023 21:00:56 +0100 Subject: [PATCH] psp, fix GU hardware rendering --- platform/psp/emu.c | 145 +++++++++++++++++++++++++------------------- platform/psp/emu.h | 2 + platform/psp/plat.c | 13 +++- platform/psp/psp.c | 4 +- 4 files changed, 100 insertions(+), 64 deletions(-) diff --git a/platform/psp/emu.c b/platform/psp/emu.c index 18eb388b7..e696041e3 100644 --- a/platform/psp/emu.c +++ b/platform/psp/emu.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "psp.h" #include "emu.h" @@ -48,7 +49,9 @@ static struct Vertex __attribute__((aligned(4))) g_vertices[2]; static u16 __attribute__((aligned(16))) localPal[0x100]; static int need_pal_upload = 0; -static u16 __attribute__((aligned(16))) osd_buf[512*8]; // buffer for osd text +u16 __attribute__((aligned(16))) osd_buf[512*8]; // buffer for osd text +int osd_buf_x[4], osd_buf_l[4]; // store for x and length for blitting +int osd_buf_cnt, osd_cdleds; static int out_x, out_y; static int out_w, out_h; @@ -105,6 +108,7 @@ static void change_renderer(int diff) static void apply_renderer(void) { PicoIn.opt &= ~(POPT_ALT_RENDERER|POPT_EN_SOFTSCALE); + PicoIn.opt |= POPT_DIS_32C_BORDER; switch (get_renderer()) { case RT_16BIT: @@ -120,32 +124,6 @@ static void apply_renderer(void) } } -static void osd_text(int x, const char *text) -{ - struct Vertex* vx; - int len = strlen(text) * 8 / 2; - int *p, h; - void *tmp = g_screen_ptr; - - g_screen_ptr = osd_buf; - for (h = 0; h < 8; h++) { - p = (int *) (osd_buf+x+512*h); - p = (int *) ((int)p & ~3); // align - memset32_uncached(p, 0, len); - } - emu_text_out16(x, 0, text); - g_screen_ptr = tmp; - - vx = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); - vx[0].u = x, vx[0].v = 0; - vx[1].u = x + len*2, vx[1].v = 8; - vx[0].x = x, vx[0].y = 264; - vx[1].x = x + len*2, vx[1].y = 272; - sceGuTexMode(GU_PSM_5650,0,0,0); - sceGuTexImage(0,512,8,512,osd_buf); - sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vx); -} - static void set_scaling_params(void) { @@ -276,7 +254,79 @@ static void do_pal_update(void) need_pal_upload = 1; } -static void blitscreen_clut(void) +static void osd_text(int x, const char *text) +{ + int len = strlen(text) * 8; + int *p, h; + void *tmp = g_screen_ptr; + + g_screen_ptr = osd_buf; + for (h = 0; h < 8; h++) { + p = (int *) (osd_buf+x+512*h); + p = (int *) ((int)p & ~3); // align + memset32_uncached(p, 0, len/2); + } + emu_text_out16(x, 0, text); + g_screen_ptr = tmp; + + osd_buf_x[osd_buf_cnt] = x; + osd_buf_l[osd_buf_cnt] = len; + osd_buf_cnt ++; +} + +static void blit_osd(void) +{ + struct Vertex* vx; + int x, len; + + while (osd_buf_cnt > 0) { + osd_buf_cnt --; + x = osd_buf_x[osd_buf_cnt]; + len = osd_buf_l[osd_buf_cnt]; + vx = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); + vx[0].u = x, vx[0].v = 0; + vx[1].u = x + len, vx[1].v = 8; + vx[0].x = x, vx[0].y = 264; + vx[1].x = x + len, vx[1].y = 272; + sceGuTexMode(GU_PSM_5650,0,0,0); + sceGuTexImage(0,512,8,512,osd_buf); + sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vx); + } +} + +static void cd_leds(void) +{ + unsigned int reg, col_g, col_r, *p; + + reg = Pico_mcd->s68k_regs[0]; + + p = (unsigned int *)((short *)osd_buf + 512*2+498); + col_g = (reg & 2) ? 0x06000600 : 0; + col_r = (reg & 1) ? 0x00180018 : 0; + *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; p += 512/2 - 12/2; + *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; p += 512/2 - 12/2; + *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; + + osd_cdleds = 1; +} + +static void blit_cdleds(void) +{ + struct Vertex* vx; + + if (!osd_cdleds) return; + + vx = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); + vx[0].u = 497, vx[0].v = 1; + vx[1].u = 497+14, vx[1].v = 6; + vx[0].x = 4, vx[0].y = 1; + vx[1].x = 4+14, vx[1].y = 6; + sceGuTexMode(GU_PSM_5650,0,0,0); + sceGuTexImage(0,512,8,512,osd_buf); + sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vx); +} + +void blitscreen_clut(void) { sceGuTexMode(is_16bit_mode() ? GU_PSM_5650:GU_PSM_T8,0,0,0); sceGuTexImage(0,512,512,512,g_screen_ptr); @@ -314,33 +364,12 @@ static void blitscreen_clut(void) else #endif sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,g_vertices); -} - -static void cd_leds(void) -{ - struct Vertex* vx; - unsigned int reg, col_g, col_r, *p; - - reg = Pico_mcd->s68k_regs[0]; - - p = (unsigned int *)((short *)osd_buf + 512*2+498); - col_g = (reg & 2) ? 0x06000600 : 0; - col_r = (reg & 1) ? 0x00180018 : 0; - *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; p += 512/2 - 12/2; - *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; p += 512/2 - 12/2; - *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; - - vx = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); - vx[0].u = 497, vx[0].v = 1; - vx[1].u = 497+14, vx[1].v = 6; - vx[0].x = 4, vx[0].y = 1; - vx[1].x = 4+14, vx[1].y = 6; - sceGuTexMode(GU_PSM_5650,0,0,0); - sceGuTexImage(0,512,8,512,osd_buf); - sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vx); + blit_osd(); + blit_cdleds(); } + static void draw_pico_ptr(void) { unsigned char *p = (unsigned char *)g_screen_ptr + 8; @@ -614,25 +643,19 @@ void pemu_validate_config(void) void pemu_finalize_frame(const char *fps, const char *notice) { int emu_opt = currentConfig.EmuOpt; - int offs = (psp_screen == VRAM_FB0) ? VRAMOFFS_FB0 : VRAMOFFS_FB1; if (PicoIn.AHW & PAHW_PICO) draw_pico_ptr(); - sceGuSync(0,0); // sync with prev - sceGuStart(GU_DIRECT, guCmdList); - sceGuDrawBuffer(GU_PSM_5650, (void *)offs, 512); // point to back buffer - - blitscreen_clut(); - + osd_buf_cnt = 0; if (notice) osd_text(4, notice); if (emu_opt & 2) osd_text(OSD_FPS_X, fps); + osd_cdleds = 0; if ((emu_opt & 0x400) && (PicoIn.AHW & PAHW_MCD)) cd_leds(); sceKernelDcacheWritebackAll(); - sceGuFinish(); } /* FIXME: move plat_* to plat? */ @@ -690,7 +713,7 @@ void emu_video_mode_change(int start_line, int line_count, int start_col, int co out_y = start_line; out_x = start_col; out_h = line_count; out_w = col_count; - if (col_count == 248) // mind aspect ration when blanking 1st column + if (col_count == 248) // mind aspect ratio when blanking 1st column col_count = 256; switch (currentConfig.vscaling) { diff --git a/platform/psp/emu.h b/platform/psp/emu.h index e9202745a..7eed9f9cc 100644 --- a/platform/psp/emu.h +++ b/platform/psp/emu.h @@ -3,6 +3,8 @@ extern int engineStateSuspend; void emu_handle_resume(void); +void blitscreen_clut(void); + // actually comes from Pico/Misc_amips.s void memset32_uncached(int *dest, int c, int count); diff --git a/platform/psp/plat.c b/platform/psp/plat.c index 0232b1d0d..e486f69a9 100644 --- a/platform/psp/plat.c +++ b/platform/psp/plat.c @@ -70,8 +70,19 @@ void plat_target_finish(void) /* display a completed frame buffer and prepare a new render buffer */ void plat_video_flip(void) { + int offs = (psp_screen == VRAM_FB0) ? VRAMOFFS_FB0 : VRAMOFFS_FB1; + g_menubg_src_ptr = psp_screen; - psp_video_flip(currentConfig.EmuOpt & EOPT_VSYNC, 1); + + sceGuSync(0, 0); // sync with prev + psp_video_flip(currentConfig.EmuOpt & EOPT_VSYNC, 0); + sceGuStart(GU_DIRECT, guCmdList); + sceGuDrawBuffer(GU_PSM_5650, (void *)offs, 512); // point to back buffer + + blitscreen_clut(); + + sceGuFinish(); + g_screen_ptr = VRAM_CACHED_STUFF + (psp_screen - VRAM_FB0); plat_video_set_buffer(g_screen_ptr); } diff --git a/platform/psp/psp.c b/platform/psp/psp.c index e719e4695..5f389f8ee 100644 --- a/platform/psp/psp.c +++ b/platform/psp/psp.c @@ -195,9 +195,9 @@ void psp_video_flip(int wait_vsync, int other) { unsigned long fb = (unsigned long)psp_screen & ~0x40000000; if (other) fb ^= 0x44000; - //if (wait_vsync) sceDisplayWaitVblankStart(); + if (wait_vsync) sceDisplayWaitVblankStart(); sceDisplaySetFrameBuf((void *)fb, 512, PSP_DISPLAY_PIXEL_FORMAT_565, - wait_vsync ? PSP_DISPLAY_SETBUF_NEXTFRAME : PSP_DISPLAY_SETBUF_IMMEDIATE); + PSP_DISPLAY_SETBUF_IMMEDIATE); current_screen ^= 1; psp_screen = current_screen ? VRAM_FB0 : VRAM_FB1; }