mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00
core+gp2x+psp, fix handling mid-frame palette changes
This commit is contained in:
parent
d05e2eb3d6
commit
ace184013b
8 changed files with 82 additions and 51 deletions
|
@ -1894,10 +1894,10 @@ PICO_INTERNAL void PicoFrameStart(void)
|
||||||
|
|
||||||
if (FinalizeLine == FinalizeLine8bit) {
|
if (FinalizeLine == FinalizeLine8bit) {
|
||||||
// make a backup of the current palette in case Sonic mode is detected later
|
// make a backup of the current palette in case Sonic mode is detected later
|
||||||
Pico.est.SonicPalCount = 0;
|
Pico.m.dirtyPal = (Pico.m.dirtyPal || Pico.est.SonicPalCount ? 2 : 0);
|
||||||
Pico.m.dirtyPal = (Pico.m.dirtyPal ? 2 : 0); // mark as dirty but copied
|
|
||||||
blockcpy(Pico.est.SonicPal, PicoMem.cram, 0x40*2);
|
blockcpy(Pico.est.SonicPal, PicoMem.cram, 0x40*2);
|
||||||
}
|
}
|
||||||
|
Pico.est.SonicPalCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawBlankedLine(int line, int offs, int sh, int bgc)
|
static void DrawBlankedLine(int line, int offs, int sh, int bgc)
|
||||||
|
|
27
pico/mode4.c
27
pico/mode4.c
|
@ -656,10 +656,10 @@ void PicoFrameStartSMS(void)
|
||||||
Pico.est.DrawLineDest = (char *)DrawLineDestBase + screen_offset * DrawLineDestIncrement;
|
Pico.est.DrawLineDest = (char *)DrawLineDestBase + screen_offset * DrawLineDestIncrement;
|
||||||
|
|
||||||
if (FinalizeLineSMS == FinalizeLine8bitSMS) {
|
if (FinalizeLineSMS == FinalizeLine8bitSMS) {
|
||||||
Pico.est.SonicPalCount = 0;
|
Pico.m.dirtyPal = (Pico.m.dirtyPal || Pico.est.SonicPalCount ? 2 : 0);
|
||||||
Pico.m.dirtyPal = (Pico.m.dirtyPal ? 2 : 0);
|
memcpy(Pico.est.SonicPal, PicoMem.cram, 0x40*2);
|
||||||
memcpy(Pico.est.SonicPal, PicoMem.cram, 0x20*2);
|
|
||||||
}
|
}
|
||||||
|
Pico.est.SonicPalCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PicoParseSATSMS(int line)
|
void PicoParseSATSMS(int line)
|
||||||
|
@ -707,13 +707,12 @@ norender:
|
||||||
|
|
||||||
/* Fixed palette for TMS9918 modes */
|
/* Fixed palette for TMS9918 modes */
|
||||||
static u16 tmspal[32] = {
|
static u16 tmspal[32] = {
|
||||||
#if 1 // SMS palette
|
// SMS palette
|
||||||
0x0000, 0x0000, 0x00a0, 0x00f0, 0x0500, 0x0f00, 0x0005, 0x0ff0,
|
0x0000, 0x0000, 0x00a0, 0x00f0, 0x0500, 0x0f00, 0x0005, 0x0ff0,
|
||||||
0x000a, 0x000f, 0x0055, 0x00ff, 0x0050, 0x0f0f, 0x0555, 0x0fff,
|
0x000a, 0x000f, 0x0055, 0x00ff, 0x0050, 0x0f0f, 0x0555, 0x0fff,
|
||||||
#else // TMS palette
|
// TMS palette
|
||||||
0x0000, 0x0000, 0x04c2, 0x07d5, 0x0e55, 0x0f77, 0x045d, 0x0fe4,
|
0x0000, 0x0000, 0x04c2, 0x07d5, 0x0e55, 0x0f77, 0x045d, 0x0fe4,
|
||||||
0x055f, 0x077f, 0x05cd, 0x08ce, 0x03b2, 0x0b5c, 0x0ccc, 0x0fff,
|
0x055f, 0x077f, 0x05cd, 0x08ce, 0x03b2, 0x0b5c, 0x0ccc, 0x0fff,
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void PicoDoHighPal555SMS(void)
|
void PicoDoHighPal555SMS(void)
|
||||||
|
@ -737,18 +736,18 @@ void PicoDoHighPal555SMS(void)
|
||||||
if (!(Pico.video.reg[0] & 0x4))
|
if (!(Pico.video.reg[0] & 0x4))
|
||||||
spal = (u32 *)tmspal; // fixed palette in TMS modes
|
spal = (u32 *)tmspal; // fixed palette in TMS modes
|
||||||
for (i = 0x20/2; i > 0; i--, spal++, dpal++) {
|
for (i = 0x20/2; i > 0; i--, spal++, dpal++) {
|
||||||
t = *spal;
|
t = *spal;
|
||||||
#if defined(USE_BGR555)
|
#if defined(USE_BGR555)
|
||||||
t = ((t & 0x000f000f)<< 1) | ((t & 0x00f000f0)<<2) | ((t & 0x0f000f00)<<3);
|
t = ((t & 0x000f000f)<<1) | ((t & 0x00f000f0)<<2) | ((t & 0x0f000f00)<<3);
|
||||||
t |= (t >> 4) & 0x04210421;
|
t |= (t >> 4) & 0x04210421;
|
||||||
#elif defined(USE_BGR565)
|
#elif defined(USE_BGR565)
|
||||||
t = ((t & 0x000f000f)<< 1) | ((t & 0x00f000f0)<<3) | ((t & 0x0f000f00)<<4);
|
t = ((t & 0x000f000f)<<1) | ((t & 0x00f000f0)<<3) | ((t & 0x0f000f00)<<4);
|
||||||
t |= (t >> 4) & 0x08610861;
|
t |= (t >> 4) & 0x08610861;
|
||||||
#else
|
#else
|
||||||
t = ((t & 0x000f000f)<<12) | ((t & 0x00f000f0)<<3) | ((t & 0x0f000f00)>>7);
|
t = ((t & 0x000f000f)<<12)| ((t & 0x00f000f0)<<3) | ((t & 0x0f000f00)>>7);
|
||||||
t |= (t >> 4) & 0x08610861;
|
t |= (t >> 4) & 0x08610861;
|
||||||
#endif
|
#endif
|
||||||
*dpal = t;
|
*dpal = t;
|
||||||
}
|
}
|
||||||
memcpy(dpal, dpal-0x20/2, 0x20*2); // for prio bit
|
memcpy(dpal, dpal-0x20/2, 0x20*2); // for prio bit
|
||||||
spal += 0x20/2, dpal += 0x20/2;
|
spal += 0x20/2, dpal += 0x20/2;
|
||||||
|
|
|
@ -56,18 +56,19 @@ static void vdp_data_write(unsigned char d)
|
||||||
struct PicoVideo *pv = &Pico.video;
|
struct PicoVideo *pv = &Pico.video;
|
||||||
|
|
||||||
if (pv->type == 3) {
|
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
|
if (Pico.m.hardware & 0x1) { // GG, same layout as MD
|
||||||
unsigned a = pv->addr & 0x3f;
|
unsigned a = pv->addr & 0x3f;
|
||||||
if (a & 0x1) { // write complete color on high byte write
|
if (a & 0x1) { // write complete color on high byte write
|
||||||
u16 c = ((d&0x0f) << 8) | Pico.ms.vdp_buffer;
|
u16 c = ((d&0x0f) << 8) | Pico.ms.vdp_buffer;
|
||||||
if (PicoMem.cram[a >> 1] != c) Pico.m.dirtyPal = 1;
|
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)
|
} else { // SMS, convert to MD layout (00BbGgRr to 0000BbBbGgGgRrRr)
|
||||||
unsigned a = pv->addr & 0x1f;
|
unsigned a = pv->addr & 0x1f;
|
||||||
u16 c = ((d&0x30)<<6) + ((d&0x0c)<<4) + ((d&0x03)<<2);
|
u16 c = ((d&0x30)<<6) + ((d&0x0c)<<4) + ((d&0x03)<<2);
|
||||||
if (PicoMem.cram[a] != (c | (c>>2))) Pico.m.dirtyPal = 1;
|
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 {
|
} else {
|
||||||
PicoMem.vramb[MEM_LE2(pv->addr)] = d;
|
PicoMem.vramb[MEM_LE2(pv->addr)] = d;
|
||||||
|
|
|
@ -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 bgr444_to_rgb32_sh(void *to, void *from);
|
||||||
|
|
||||||
void vidcpy_m2(void *dest, void *src, int m32col, int with_32c_border);
|
void vidcpy_m2(void *dest, void *src, int m32col, int with_32c_border);
|
||||||
|
|
|
@ -62,12 +62,12 @@
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
|
||||||
.global bgr444_to_rgb32 @ void *to, void *from
|
.global bgr444_to_rgb32 @ void *to, void *from, unsigned entries
|
||||||
|
|
||||||
bgr444_to_rgb32:
|
bgr444_to_rgb32:
|
||||||
stmfd sp!, {r4-r7,lr}
|
stmfd sp!, {r4-r7,lr}
|
||||||
|
|
||||||
mov r12, #0x40>>3 @ repeats
|
mov r12, r2, lsr #3 @ repeats
|
||||||
mov lr, #0x00f00000
|
mov lr, #0x00f00000
|
||||||
orr lr, lr, #0x00f0
|
orr lr, lr, #0x00f0
|
||||||
|
|
||||||
|
|
|
@ -301,26 +301,26 @@ static int make_local_pal_md(int fast_mode)
|
||||||
int pallen = 0x100;
|
int pallen = 0x100;
|
||||||
|
|
||||||
if (fast_mode) {
|
if (fast_mode) {
|
||||||
bgr444_to_rgb32(localPal, PicoMem.cram);
|
bgr444_to_rgb32(localPal, PicoMem.cram, 64);
|
||||||
pallen = 0x40;
|
pallen = 0x40;
|
||||||
Pico.m.dirtyPal = 0;
|
Pico.m.dirtyPal = 0;
|
||||||
}
|
}
|
||||||
else if (Pico.est.rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes
|
else if (Pico.est.rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes
|
||||||
switch (Pico.est.SonicPalCount) {
|
switch (Pico.est.SonicPalCount) {
|
||||||
case 3: bgr444_to_rgb32(localPal+0xc0, Pico.est.SonicPal+0xc0);
|
case 3: bgr444_to_rgb32(localPal+0xc0, Pico.est.SonicPal+0xc0, 64);
|
||||||
case 2: bgr444_to_rgb32(localPal+0x80, Pico.est.SonicPal+0x80);
|
case 2: bgr444_to_rgb32(localPal+0x80, Pico.est.SonicPal+0x80, 64);
|
||||||
case 1: bgr444_to_rgb32(localPal+0x40, Pico.est.SonicPal+0x40);
|
case 1: bgr444_to_rgb32(localPal+0x40, Pico.est.SonicPal+0x40, 64);
|
||||||
default:bgr444_to_rgb32(localPal, Pico.est.SonicPal);
|
default:bgr444_to_rgb32(localPal, Pico.est.SonicPal, 64);
|
||||||
}
|
}
|
||||||
pallen = (Pico.est.SonicPalCount+1)*0x40;
|
pallen = (Pico.est.SonicPalCount+1)*0x40;
|
||||||
}
|
}
|
||||||
else if (Pico.video.reg[0xC] & 8) { // shadow/hilight mode
|
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);
|
bgr444_to_rgb32_sh(localPal, Pico.est.SonicPal);
|
||||||
memcpy(localPal+0xc0, localPal, 0x40*4); // for spr prio mess
|
memcpy(localPal+0xc0, localPal, 0x40*4); // for spr prio mess
|
||||||
}
|
}
|
||||||
else {
|
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+0x40, localPal, 0x40*4); // for spr prio mess
|
||||||
memcpy(localPal+0x80, localPal, 0x80*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)
|
static int make_local_pal_sms(int fast_mode)
|
||||||
{
|
{
|
||||||
bgr444_to_rgb32(localPal, PicoMem.cram);
|
static u16 tmspal[32] = {
|
||||||
Pico.m.dirtyPal = 0;
|
// SMS palette for TMS modes
|
||||||
return 0x40;
|
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)
|
void pemu_finalize_frame(const char *fps, const char *notice)
|
||||||
|
|
|
@ -10,13 +10,13 @@
|
||||||
// to 00000000 rrr00000 ggg00000 bbb00000 ...
|
// to 00000000 rrr00000 ggg00000 bbb00000 ...
|
||||||
// TODO: rm when gp2x/emu.c is no longer used
|
// 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 short *ps = from;
|
||||||
unsigned int *pd = to;
|
unsigned int *pd = to;
|
||||||
int pixels;
|
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 = ((*ps<<20)&0xe00000) | ((*ps<<8)&0xe000) | ((*ps>>4)&0xe0);
|
||||||
*pd |= *pd >> 3;
|
*pd |= *pd >> 3;
|
||||||
|
|
|
@ -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)
|
static void do_pal_update(void)
|
||||||
{
|
{
|
||||||
u32 *dpal=(void *)localPal;
|
u32 *dpal=(void *)localPal;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
//for (i = 0x3f/2; i >= 0; i--)
|
if (PicoIn.opt & POPT_ALT_RENDERER) {
|
||||||
// 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) {
|
|
||||||
do_pal_convert(localPal, PicoMem.cram, currentConfig.gamma, currentConfig.gamma2);
|
do_pal_convert(localPal, PicoMem.cram, currentConfig.gamma, currentConfig.gamma2);
|
||||||
Pico.m.dirtyPal = 0;
|
Pico.m.dirtyPal = 0;
|
||||||
}
|
}
|
||||||
else if (Pico.est.rendstatus & PDRAW_SONIC_MODE)
|
else if (Pico.est.rendstatus & PDRAW_SONIC_MODE)
|
||||||
{
|
{
|
||||||
switch (Pico.est.SonicPalCount) {
|
switch (Pico.est.SonicPalCount) {
|
||||||
case 3: do_pal_convert(localPal+0xc0/2, Pico.est.SonicPal+0xc0, 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/2, Pico.est.SonicPal+0x80, 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/2, Pico.est.SonicPal+0x40, 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);
|
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);
|
sceGuTexMode(is_16bit_mode() ? GU_PSM_5650:GU_PSM_T8,0,0,0);
|
||||||
sceGuTexImage(0,512,512,512,g_screen_ptr);
|
sceGuTexImage(0,512,512,512,g_screen_ptr);
|
||||||
|
|
||||||
if (!is_16bit_mode() && Pico.m.dirtyPal)
|
if (!is_16bit_mode() && Pico.m.dirtyPal) {
|
||||||
do_pal_update();
|
if (PicoIn.AHW & PAHW_SMS)
|
||||||
|
do_pal_update_sms();
|
||||||
|
else
|
||||||
|
do_pal_update();
|
||||||
|
}
|
||||||
|
|
||||||
if (need_pal_upload) {
|
if (need_pal_upload) {
|
||||||
need_pal_upload = 0;
|
need_pal_upload = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue