diff --git a/pico/pico_int.h b/pico/pico_int.h index 0c71233ad..198eea4b0 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -353,6 +353,7 @@ struct PicoMisc #define PMS_HW_JAP 0x4 // japanese system #define PMS_HW_FM 0x8 // FM sound #define PMS_HW_TMS 0x10 // assume TMS9918 +#define PMS_HW_3D 0x20 // 3D glasses #define PMS_HW_FMUSED 0x80 // FM sound accessed #define PMS_MAP_AUTO 0 diff --git a/pico/sms.c b/pico/sms.c index 0c2ee6346..fe06f63fa 100644 --- a/pico/sms.c +++ b/pico/sms.c @@ -633,6 +633,13 @@ static u32 gg_smsmode[] = { // cf https://www.smspower.org/Tags/SMS-GG 0x4f813028 /* Tesserae */ }; +// TMR product codes and hardware type for known games using 3-D glasses +static u32 three_dee[] = { + 0x4f008001 /* Missile Def. */ , 0x40008007 /* Out Run 3-D */, + 0x40008006 /* Poseidon Wars */, 0x40008004 /* Space Harrier */, + 0x40008002 /* Zaxxon 3-D */ , 0x4fff8793 /* Maze Hunter */ +}; + void PicoResetMS(void) { unsigned tmr; @@ -662,7 +669,7 @@ void PicoResetMS(void) if (!memcmp(Pico.rom + tmr-16, "TMR SEGA", 8)) { hw = Pico.rom[tmr-1] >> 4; id = CPU_LE4(*(u32 *)&Pico.rom[tmr-4]); - ck = *(u16 *)&Pico.rom[tmr-6] | (id&0xf0000000) | 0xfff0000; + ck = (CPU_LE4(*(u32 *)&Pico.rom[tmr-8])>>16) | (id&0xf0000000) | 0xfff0000; if (!PicoIn.hwSelect && !PicoIn.AHW && hw && ((id+1)&0xfffe) != 0) { if (hw >= 0x5 && hw < 0x8) @@ -690,6 +697,11 @@ void PicoResetMS(void) Pico.m.hardware &= ~PMS_HW_FM; // incompatible with FM break; } + for (i = 0; i < sizeof(three_dee)/sizeof(*three_dee); i++) + if ((id == three_dee[i] || ck == three_dee[i])) { + Pico.m.hardware |= PMS_HW_3D; // uses 3-D glasses + break; + } break; } } diff --git a/platform/common/emu.c b/platform/common/emu.c index cd0c2e582..e2b540b20 100644 --- a/platform/common/emu.c +++ b/platform/common/emu.c @@ -1620,6 +1620,12 @@ void emu_loop(void) } emu_update_input(); + + // 3D glasses + skip |= (PicoIn.AHW & PAHW_SMS) && + (Pico.m.hardware & PMS_HW_3D) && + (PicoMem.zram[0x1ffb] & 1); + if (skip) { int do_audio = diff > -target_frametime * 2; PicoIn.skipFrame = do_audio ? 1 : 2;