From: kub Date: Wed, 10 Nov 2021 22:06:08 +0000 (+0100) Subject: core+gp2x+psp, fix handling mid-frame palette changes X-Git-Tag: v2.00~424 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ace184013b0a0b152be3c901028f82d0105f0a85;p=picodrive.git core+gp2x+psp, fix handling mid-frame palette changes --- diff --git a/pico/draw.c b/pico/draw.c index 38b920d6..6dce27c9 100644 --- a/pico/draw.c +++ b/pico/draw.c @@ -1894,10 +1894,10 @@ PICO_INTERNAL void PicoFrameStart(void) if (FinalizeLine == FinalizeLine8bit) { // make a backup of the current palette in case Sonic mode is detected later - Pico.est.SonicPalCount = 0; - Pico.m.dirtyPal = (Pico.m.dirtyPal ? 2 : 0); // mark as dirty but copied + Pico.m.dirtyPal = (Pico.m.dirtyPal || Pico.est.SonicPalCount ? 2 : 0); blockcpy(Pico.est.SonicPal, PicoMem.cram, 0x40*2); } + Pico.est.SonicPalCount = 0; } static void DrawBlankedLine(int line, int offs, int sh, int bgc) diff --git a/pico/mode4.c b/pico/mode4.c index 54440e38..55127e36 100644 --- a/pico/mode4.c +++ b/pico/mode4.c @@ -656,10 +656,10 @@ void PicoFrameStartSMS(void) Pico.est.DrawLineDest = (char *)DrawLineDestBase + screen_offset * DrawLineDestIncrement; if (FinalizeLineSMS == FinalizeLine8bitSMS) { - Pico.est.SonicPalCount = 0; - Pico.m.dirtyPal = (Pico.m.dirtyPal ? 2 : 0); - memcpy(Pico.est.SonicPal, PicoMem.cram, 0x20*2); + Pico.m.dirtyPal = (Pico.m.dirtyPal || Pico.est.SonicPalCount ? 2 : 0); + memcpy(Pico.est.SonicPal, PicoMem.cram, 0x40*2); } + Pico.est.SonicPalCount = 0; } void PicoParseSATSMS(int line) @@ -707,13 +707,12 @@ norender: /* Fixed palette for TMS9918 modes */ static u16 tmspal[32] = { -#if 1 // SMS palette + // SMS palette 0x0000, 0x0000, 0x00a0, 0x00f0, 0x0500, 0x0f00, 0x0005, 0x0ff0, 0x000a, 0x000f, 0x0055, 0x00ff, 0x0050, 0x0f0f, 0x0555, 0x0fff, -#else // TMS palette + // TMS palette 0x0000, 0x0000, 0x04c2, 0x07d5, 0x0e55, 0x0f77, 0x045d, 0x0fe4, 0x055f, 0x077f, 0x05cd, 0x08ce, 0x03b2, 0x0b5c, 0x0ccc, 0x0fff, -#endif }; void PicoDoHighPal555SMS(void) @@ -737,18 +736,18 @@ void PicoDoHighPal555SMS(void) if (!(Pico.video.reg[0] & 0x4)) spal = (u32 *)tmspal; // fixed palette in TMS modes for (i = 0x20/2; i > 0; i--, spal++, dpal++) { - t = *spal; + t = *spal; #if defined(USE_BGR555) - t = ((t & 0x000f000f)<< 1) | ((t & 0x00f000f0)<<2) | ((t & 0x0f000f00)<<3); - t |= (t >> 4) & 0x04210421; + t = ((t & 0x000f000f)<<1) | ((t & 0x00f000f0)<<2) | ((t & 0x0f000f00)<<3); + t |= (t >> 4) & 0x04210421; #elif defined(USE_BGR565) - t = ((t & 0x000f000f)<< 1) | ((t & 0x00f000f0)<<3) | ((t & 0x0f000f00)<<4); - t |= (t >> 4) & 0x08610861; + t = ((t & 0x000f000f)<<1) | ((t & 0x00f000f0)<<3) | ((t & 0x0f000f00)<<4); + t |= (t >> 4) & 0x08610861; #else - t = ((t & 0x000f000f)<<12) | ((t & 0x00f000f0)<<3) | ((t & 0x0f000f00)>>7); - t |= (t >> 4) & 0x08610861; + t = ((t & 0x000f000f)<<12)| ((t & 0x00f000f0)<<3) | ((t & 0x0f000f00)>>7); + t |= (t >> 4) & 0x08610861; #endif - *dpal = t; + *dpal = t; } memcpy(dpal, dpal-0x20/2, 0x20*2); // for prio bit spal += 0x20/2, dpal += 0x20/2; diff --git a/pico/sms.c b/pico/sms.c index a62f4077..ab8a6f03 100644 --- a/pico/sms.c +++ b/pico/sms.c @@ -56,18 +56,19 @@ static void vdp_data_write(unsigned char d) struct PicoVideo *pv = &Pico.video; if (pv->type == 3) { + // cram. 32 on SMS, but 64 on MD. Fill 2nd half of cram for prio bit mirror if (Pico.m.hardware & 0x1) { // GG, same layout as MD unsigned a = pv->addr & 0x3f; if (a & 0x1) { // write complete color on high byte write u16 c = ((d&0x0f) << 8) | Pico.ms.vdp_buffer; if (PicoMem.cram[a >> 1] != c) Pico.m.dirtyPal = 1; - PicoMem.cram[a >> 1] = c; + PicoMem.cram[a >> 1] = PicoMem.cram[(a >> 1)+0x20] = c; } } else { // SMS, convert to MD layout (00BbGgRr to 0000BbBbGgGgRrRr) unsigned a = pv->addr & 0x1f; u16 c = ((d&0x30)<<6) + ((d&0x0c)<<4) + ((d&0x03)<<2); if (PicoMem.cram[a] != (c | (c>>2))) Pico.m.dirtyPal = 1; - PicoMem.cram[a] = c | (c>>2); + PicoMem.cram[a] = PicoMem.cram[a+0x20] = c | (c>>2); } } else { PicoMem.vramb[MEM_LE2(pv->addr)] = d; diff --git a/platform/common/arm_utils.h b/platform/common/arm_utils.h index 21204c92..628daf65 100644 --- a/platform/common/arm_utils.h +++ b/platform/common/arm_utils.h @@ -1,5 +1,5 @@ -void bgr444_to_rgb32(void *to, void *from); +void bgr444_to_rgb32(void *to, void *from, unsigned entries); void bgr444_to_rgb32_sh(void *to, void *from); void vidcpy_m2(void *dest, void *src, int m32col, int with_32c_border); diff --git a/platform/common/arm_utils.s b/platform/common/arm_utils.s index 7dbed97d..b4f739d9 100644 --- a/platform/common/arm_utils.s +++ b/platform/common/arm_utils.s @@ -62,12 +62,12 @@ .endm -.global bgr444_to_rgb32 @ void *to, void *from +.global bgr444_to_rgb32 @ void *to, void *from, unsigned entries bgr444_to_rgb32: stmfd sp!, {r4-r7,lr} - mov r12, #0x40>>3 @ repeats + mov r12, r2, lsr #3 @ repeats mov lr, #0x00f00000 orr lr, lr, #0x00f0 diff --git a/platform/gp2x/emu.c b/platform/gp2x/emu.c index 7c94c45e..70c6d3dc 100644 --- a/platform/gp2x/emu.c +++ b/platform/gp2x/emu.c @@ -301,26 +301,26 @@ static int make_local_pal_md(int fast_mode) int pallen = 0x100; if (fast_mode) { - bgr444_to_rgb32(localPal, PicoMem.cram); + bgr444_to_rgb32(localPal, PicoMem.cram, 64); pallen = 0x40; Pico.m.dirtyPal = 0; } else if (Pico.est.rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes switch (Pico.est.SonicPalCount) { - case 3: bgr444_to_rgb32(localPal+0xc0, Pico.est.SonicPal+0xc0); - case 2: bgr444_to_rgb32(localPal+0x80, Pico.est.SonicPal+0x80); - case 1: bgr444_to_rgb32(localPal+0x40, Pico.est.SonicPal+0x40); - default:bgr444_to_rgb32(localPal, Pico.est.SonicPal); + case 3: bgr444_to_rgb32(localPal+0xc0, Pico.est.SonicPal+0xc0, 64); + case 2: bgr444_to_rgb32(localPal+0x80, Pico.est.SonicPal+0x80, 64); + case 1: bgr444_to_rgb32(localPal+0x40, Pico.est.SonicPal+0x40, 64); + default:bgr444_to_rgb32(localPal, Pico.est.SonicPal, 64); } pallen = (Pico.est.SonicPalCount+1)*0x40; } else if (Pico.video.reg[0xC] & 8) { // shadow/hilight mode - bgr444_to_rgb32(localPal, Pico.est.SonicPal); + bgr444_to_rgb32(localPal, Pico.est.SonicPal, 64); bgr444_to_rgb32_sh(localPal, Pico.est.SonicPal); memcpy(localPal+0xc0, localPal, 0x40*4); // for spr prio mess } else { - bgr444_to_rgb32(localPal, Pico.est.SonicPal); + bgr444_to_rgb32(localPal, Pico.est.SonicPal, 64); memcpy(localPal+0x40, localPal, 0x40*4); // for spr prio mess memcpy(localPal+0x80, localPal, 0x80*4); // for spr prio mess } @@ -336,9 +336,27 @@ static int make_local_pal_md(int fast_mode) static int make_local_pal_sms(int fast_mode) { - bgr444_to_rgb32(localPal, PicoMem.cram); - Pico.m.dirtyPal = 0; - return 0x40; + static u16 tmspal[32] = { + // SMS palette for TMS modes + 0x0000, 0x0000, 0x00a0, 0x00f0, 0x0500, 0x0f00, 0x0005, 0x0ff0, + 0x000a, 0x000f, 0x0055, 0x00ff, 0x0050, 0x0f0f, 0x0555, 0x0fff, + }; + int i; + + if (!(Pico.video.reg[0] & 0x4)) { + for (i = Pico.est.SonicPalCount; i >= 0; i--) { + bgr444_to_rgb32(localPal+i*0x40, tmspal, 32); + memcpy(localPal+i*0x40+0x20, localPal+i*0x40, 0x20*4); + } + } else { + for (i = Pico.est.SonicPalCount; i >= 0; i--) { + bgr444_to_rgb32(localPal+i*0x40, Pico.est.SonicPal+i*0x40, 32); + memcpy(localPal+i*0x40+0x20, localPal+i*0x40, 0x20*4); + } + } + if (Pico.m.dirtyPal == 2) + Pico.m.dirtyPal = 0; + return (Pico.est.SonicPalCount+1)*0x40; } void pemu_finalize_frame(const char *fps, const char *notice) diff --git a/platform/linux/blit.c b/platform/linux/blit.c index 82bc4ba5..b70262eb 100644 --- a/platform/linux/blit.c +++ b/platform/linux/blit.c @@ -10,13 +10,13 @@ // to 00000000 rrr00000 ggg00000 bbb00000 ... // TODO: rm when gp2x/emu.c is no longer used -void bgr444_to_rgb32(void *to, void *from) +void bgr444_to_rgb32(void *to, void *from, unsigned entries) { unsigned short *ps = from; unsigned int *pd = to; int pixels; - for (pixels = 0x40; pixels; pixels--, ps++, pd++) + for (pixels = entries; pixels; pixels--, ps++, pd++) { *pd = ((*ps<<20)&0xe00000) | ((*ps<<8)&0xe000) | ((*ps>>4)&0xe0); *pd |= *pd >> 3; diff --git a/platform/psp/emu.c b/platform/psp/emu.c index 89b2c26c..59ccab56 100644 --- a/platform/psp/emu.c +++ b/platform/psp/emu.c @@ -204,32 +204,42 @@ static void set_scaling_params(void) */ } +static void do_pal_update_sms(void) +{ + static u16 tmspal[32] = { + // SMS palette + 0x0000, 0x0000, 0x00a0, 0x00f0, 0x0500, 0x0f00, 0x0005, 0x0ff0, + 0x000a, 0x000f, 0x0055, 0x00ff, 0x0050, 0x0f0f, 0x0555, 0x0fff, + }; + int i; + + if (!(Pico.video.reg[0] & 0x4)) { + for (i = Pico.est.SonicPalCount; i >= 0; i--) + do_pal_convert(localPal+i*0x40, tmspal, currentConfig.gamma, currentConfig.gamma2); + } else { + for (i = Pico.est.SonicPalCount; i >= 0; i--) + do_pal_convert(localPal+i*0x40, Pico.est.SonicPal+i*0x40, currentConfig.gamma, currentConfig.gamma2); + } + if (Pico.m.dirtyPal == 2) + Pico.m.dirtyPal = 0; + need_pal_upload = 1; +} + static void do_pal_update(void) { u32 *dpal=(void *)localPal; int i; - //for (i = 0x3f/2; i >= 0; i--) - // dpal[i] = ((spal[i]&0x000f000f)<< 1)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)<<4); - if (PicoIn.AHW & PAHW_SMS) { - u32 *spal = (void *)PicoMem.cram; - for (i = 0; i < 0x20 / 2; i++) { - u32 t = spal[i]; - t = ((t & 0x00030003)<< 3) | ((t & 0x000c000c)<<7) | ((t & 0x00300030)<<10); - t |= (t >> 2) | ((t >> 4) & 0x08610861); - dpal[i] = t; - } - Pico.m.dirtyPal = 0; - } else if (PicoIn.opt & POPT_ALT_RENDERER) { + if (PicoIn.opt & POPT_ALT_RENDERER) { do_pal_convert(localPal, PicoMem.cram, currentConfig.gamma, currentConfig.gamma2); Pico.m.dirtyPal = 0; } else if (Pico.est.rendstatus & PDRAW_SONIC_MODE) { switch (Pico.est.SonicPalCount) { - case 3: do_pal_convert(localPal+0xc0/2, Pico.est.SonicPal+0xc0, currentConfig.gamma, currentConfig.gamma2); - case 2: do_pal_convert(localPal+0x80/2, Pico.est.SonicPal+0x80, currentConfig.gamma, currentConfig.gamma2); - case 1: do_pal_convert(localPal+0x40/2, Pico.est.SonicPal+0x40, currentConfig.gamma, currentConfig.gamma2); + case 3: do_pal_convert(localPal+0xc0, Pico.est.SonicPal+0xc0, currentConfig.gamma, currentConfig.gamma2); + case 2: do_pal_convert(localPal+0x80, Pico.est.SonicPal+0x80, currentConfig.gamma, currentConfig.gamma2); + case 1: do_pal_convert(localPal+0x40, Pico.est.SonicPal+0x40, currentConfig.gamma, currentConfig.gamma2); default:do_pal_convert(localPal, Pico.est.SonicPal, currentConfig.gamma, currentConfig.gamma2); } } @@ -267,9 +277,12 @@ static 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); - if (!is_16bit_mode() && Pico.m.dirtyPal) - do_pal_update(); - + if (!is_16bit_mode() && Pico.m.dirtyPal) { + if (PicoIn.AHW & PAHW_SMS) + do_pal_update_sms(); + else + do_pal_update(); + } if (need_pal_upload) { need_pal_upload = 0;