diff --git a/cpu.cpp b/cpu.cpp index bcc4adf9..2c8d07d6 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -75,7 +75,6 @@ static void S9xSoftResetCPU (void) SetFlags(MemoryFlag | IndexFlag | IRQ | Emulation); ClearFlags(Decimal); - Timings.InterlaceField = FALSE; Timings.H_Max = Timings.H_Max_Master; Timings.V_Max = Timings.V_Max_Master; Timings.NMITriggerPos = 0xffff; diff --git a/cpuexec.cpp b/cpuexec.cpp index cd2b1ba1..d8769f28 100644 --- a/cpuexec.cpp +++ b/cpuexec.cpp @@ -276,7 +276,6 @@ void S9xDoHEventProcessing (void) if (CPU.V_Counter >= Timings.V_Max) // V ranges from 0 to Timings.V_Max - 1 { CPU.V_Counter = 0; - Timings.InterlaceField ^= 1; // From byuu: // [NTSC] @@ -285,7 +284,7 @@ void S9xDoHEventProcessing (void) // [PAL] // interlace mode has 625 scanlines: 313 on the even frame, and 312 on the odd. // non-interlace mode has 624 scanlines: 312 scanlines on both even and odd frames. - if (IPPU.Interlace && !Timings.InterlaceField) + if (IPPU.Interlace && S9xInterlaceField) Timings.V_Max = Timings.V_Max_Master + 1; // 263 (NTSC), 313?(PAL) else Timings.V_Max = Timings.V_Max_Master; // 262 (NTSC), 312?(PAL) @@ -306,14 +305,14 @@ void S9xDoHEventProcessing (void) // In interlace mode, there are always 341 dots per scanline. Even frames have 263 scanlines, // and odd frames have 262 scanlines. // Interlace mode scanline 240 on odd frames is not missing a dot. - if (CPU.V_Counter == 240 && !IPPU.Interlace && Timings.InterlaceField) // V=240 + if (CPU.V_Counter == 240 && !IPPU.Interlace && S9xInterlaceField) // V=240 Timings.H_Max = Timings.H_Max_Master - ONE_DOT_CYCLE; // HC=1360 else Timings.H_Max = Timings.H_Max_Master; // HC=1364 if (Model->_5A22 == 2) { - if (CPU.V_Counter != 240 || IPPU.Interlace || !Timings.InterlaceField) // V=240 + if (CPU.V_Counter != 240 || IPPU.Interlace || !S9xInterlaceField) // V=240 { if (Timings.WRAMRefreshPos == SNES_WRAM_REFRESH_HC_v2 - ONE_DOT_CYCLE) // HC=534 Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2; // HC=538 diff --git a/gfx.cpp b/gfx.cpp index 1e26db44..2abad594 100644 --- a/gfx.cpp +++ b/gfx.cpp @@ -122,7 +122,7 @@ void S9xGraphicsScreenResize (void) IPPU.Interlace = Memory.FillRAM[0x2133] & 1; IPPU.InterlaceOBJ = Memory.FillRAM[0x2133] & 2; IPPU.PseudoHires = Memory.FillRAM[0x2133] & 8; - + if (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.PseudoHires) { IPPU.DoubleWidthPixels = TRUE; @@ -146,7 +146,7 @@ void S9xGraphicsScreenResize (void) GFX.PPL = GFX.RealPPL; IPPU.DoubleHeightPixels = FALSE; IPPU.RenderedScreenHeight = PPU.ScreenHeight; - } + } } void S9xBuildDirectColourMaps (void) @@ -160,13 +160,12 @@ void S9xBuildDirectColourMaps (void) void S9xStartScreenRefresh (void) { - GFX.InterlaceFrame = !GFX.InterlaceFrame; if (GFX.DoInterlace) GFX.DoInterlace--; if (IPPU.RenderThisFrame) { - if (!GFX.DoInterlace || !GFX.InterlaceFrame) + if (!GFX.DoInterlace || !S9xInterlaceField) { if (!S9xInitUpdate()) { @@ -206,7 +205,7 @@ void S9xEndScreenRefresh (void) { FLUSH_REDRAW(); - if (GFX.DoInterlace && GFX.InterlaceFrame == 0) + if (GFX.DoInterlace && S9xInterlaceField == 0) { S9xControlEOF(); S9xContinueUpdate(IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight); @@ -329,7 +328,7 @@ static inline void RenderScreen (bool8 sub) if (!sub) { GFX.S = GFX.Screen; - if (GFX.DoInterlace && GFX.InterlaceFrame) + if (GFX.DoInterlace && S9xInterlaceField) GFX.S += GFX.RealPPL; GFX.DB = GFX.ZBuffer; GFX.Clip = IPPU.Clip[0]; @@ -515,7 +514,7 @@ void S9xUpdateScreen (void) const uint16 black = BUILD_PIXEL(0, 0, 0); GFX.S = GFX.Screen + GFX.StartY * GFX.PPL; - if (GFX.DoInterlace && GFX.InterlaceFrame) + if (GFX.DoInterlace && S9xInterlaceField) GFX.S += GFX.RealPPL; for (uint32 l = GFX.StartY; l <= GFX.EndY; l++, GFX.S += GFX.PPL) @@ -576,7 +575,7 @@ static void SetupOBJ (void) int inc = IPPU.InterlaceOBJ ? 2 : 1; - int startline = (IPPU.InterlaceOBJ && GFX.InterlaceFrame) ? 1 : 0; + int startline = (IPPU.InterlaceOBJ && S9xInterlaceField) ? 1 : 0; // OK, we have three cases here. Either there's no priority, priority is // normal FirstSprite, or priority is FirstSprite+Y. The first two are @@ -771,10 +770,10 @@ static void DrawOBJS (int D) void (*DrawClippedTile) (uint32, uint32, uint32, uint32, uint32, uint32) = NULL; int PixWidth = IPPU.DoubleWidthPixels ? 2 : 1; - BG.InterlaceLine = GFX.InterlaceFrame ? 8 : 0; + BG.InterlaceLine = S9xInterlaceField ? 8 : 0; GFX.Z1 = 2; int sprite_limit = (Settings.MaxSpriteTilesPerLine == 128) ? 128 : 32; - + for (uint32 Y = GFX.StartY, Offset = Y * GFX.PPL; Y <= GFX.EndY; Y++, Offset += GFX.PPL) { int I = 0; @@ -906,7 +905,7 @@ static void DrawBackground (int bg, uint8 Zh, uint8 Zl) for (uint32 Y = GFX.StartY; Y <= GFX.EndY; Y += Lines) { - uint32 Y2 = HiresInterlace ? Y * 2 + GFX.InterlaceFrame : Y; + uint32 Y2 = HiresInterlace ? Y * 2 + S9xInterlaceField : Y; uint32 VOffset = LineData[Y].BG[bg].VOffset + (HiresInterlace ? 1 : 0); uint32 HOffset = LineData[Y].BG[bg].HOffset; int VirtAlign = ((Y2 + VOffset) & 7) >> (HiresInterlace ? 1 : 0); @@ -1300,7 +1299,7 @@ static void DrawBackgroundOffset (int bg, uint8 Zh, uint8 Zl, int VOffOff) for (uint32 Y = GFX.StartY; Y <= GFX.EndY; Y++) { - uint32 Y2 = HiresInterlace ? Y * 2 + GFX.InterlaceFrame : Y; + uint32 Y2 = HiresInterlace ? Y * 2 + S9xInterlaceField : Y; uint32 VOff = LineData[Y].BG[2].VOffset - 1; uint32 HOff = LineData[Y].BG[2].HOffset; uint32 HOffsetRow = VOff >> Offset2Shift; @@ -1822,7 +1821,7 @@ static void S9xDisplayStringType (const char *string, int linesFromBottom, int p static void DisplayTime (void) { char string[10]; - + time_t rawtime; struct tm *timeinfo; @@ -2026,7 +2025,7 @@ void S9xDisplayMessages (uint16 *screen, int ppl, int width, int height, int sca { if (Settings.DisplayTime) DisplayTime(); - + if (Settings.DisplayFrameRate) DisplayFrameRate(); diff --git a/gfx.h b/gfx.h index a1f4e1a2..9cd649bf 100644 --- a/gfx.h +++ b/gfx.h @@ -32,7 +32,6 @@ struct SGFX uint8 Z2; // depth to save uint32 FixedColour; uint8 DoInterlace; - uint8 InterlaceFrame; uint32 StartY; uint32 EndY; bool8 ClipColors; diff --git a/ppu.cpp b/ppu.cpp index 50446f3f..26510802 100644 --- a/ppu.cpp +++ b/ppu.cpp @@ -94,7 +94,7 @@ static int CyclesUntilNext (int hc, int vc) // Add number of lines total += (vc - vpos) * Timings.H_Max_Master; // If line 240 is in there and we're odd, subtract a dot - if (vpos <= 240 && vc > 240 && Timings.InterlaceField & !IPPU.Interlace) + if (vpos <= 240 && vc > 240 && S9xInterlaceField & !IPPU.Interlace) total -= ONE_DOT_CYCLE; } else @@ -105,11 +105,11 @@ static int CyclesUntilNext (int hc, int vc) } total += (Timings.V_Max - vpos) * Timings.H_Max_Master; - if (vpos <= 240 && Timings.InterlaceField && !IPPU.Interlace) + if (vpos <= 240 && S9xInterlaceField && !IPPU.Interlace) total -= ONE_DOT_CYCLE; total += (vc) * Timings.H_Max_Master; - if (vc > 240 && !Timings.InterlaceField && !IPPU.Interlace) + if (vc > 240 && !S9xInterlaceField && !IPPU.Interlace) total -= ONE_DOT_CYCLE; } @@ -146,7 +146,7 @@ void S9xUpdateIRQPositions (bool initial) } // Check for short dot scanline - if (v_pos == 240 && Timings.InterlaceField && !IPPU.Interlace) + if (v_pos == 240 && S9xInterlaceField && !IPPU.Interlace) { Timings.NextIRQTimer -= PPU.IRQHBeamPos <= 322 ? ONE_DOT_CYCLE / 2 : 0; Timings.NextIRQTimer -= PPU.IRQHBeamPos <= 326 ? ONE_DOT_CYCLE / 2 : 0; @@ -164,7 +164,7 @@ void S9xUpdateIRQPositions (bool initial) Timings.NextIRQTimer = CyclesUntilNext (PPU.HTimerPosition, PPU.VTimerPosition); // Check for short dot scanline - int field = Timings.InterlaceField; + int field = S9xInterlaceField; if (PPU.VTimerPosition < CPU.V_Counter || (PPU.VTimerPosition == CPU.V_Counter && Timings.NextIRQTimer > Timings.H_Max)) @@ -1894,7 +1894,6 @@ void S9xSoftResetPPU (void) memset(IPPU.TileCached[TILE_4BIT_EVEN], 0, MAX_4BIT_TILES); memset(IPPU.TileCached[TILE_4BIT_ODD], 0, MAX_4BIT_TILES); PPU.VRAMReadBuffer = 0; // XXX: FIXME: anything better? - GFX.InterlaceFrame = 0; GFX.DoInterlace = 0; IPPU.Interlace = FALSE; IPPU.InterlaceOBJ = FALSE; diff --git a/snapshot.cpp b/snapshot.cpp index 834c1365..4e65469e 100644 --- a/snapshot.cpp +++ b/snapshot.cpp @@ -410,7 +410,7 @@ static FreezeData SnapTimings[] = INT_ENTRY(6, NMITriggerPos), INT_ENTRY(6, WRAMRefreshPos), INT_ENTRY(6, RenderPos), - INT_ENTRY(6, InterlaceField), + DELETED_INT_ENTRY(6, 12, InterlaceField, 1), INT_ENTRY(6, DMACPUSync), INT_ENTRY(6, NMIDMADelay), INT_ENTRY(6, IRQFlagChanging), @@ -1689,12 +1689,11 @@ int S9xUnfreezeFromStream (STREAM stream) IPPU.ColorsChanged = TRUE; IPPU.OBJChanged = TRUE; IPPU.RenderThisFrame = TRUE; - - GFX.InterlaceFrame = Timings.InterlaceField; + GFX.DoInterlace = 0; S9xGraphicsScreenResize(); - + if (Settings.FastSavestates == 0) memset(GFX.Screen,0,GFX.Pitch * MAX_SNES_HEIGHT); diff --git a/snapshot.h b/snapshot.h index 03e59856..fe5fc519 100644 --- a/snapshot.h +++ b/snapshot.h @@ -13,7 +13,7 @@ #define SNAPSHOT_VERSION_IRQ 7 #define SNAPSHOT_VERSION_BAPU 8 #define SNAPSHOT_VERSION_IRQ_2018 11 // irq changes were introduced earlier, since this we store NextIRQTimer directly -#define SNAPSHOT_VERSION 11 +#define SNAPSHOT_VERSION 12 #define SUCCESS 1 #define WRONG_FORMAT (-1) diff --git a/snes9x.h b/snes9x.h index c4fe5e15..f1a5d66c 100644 --- a/snes9x.h +++ b/snes9x.h @@ -180,7 +180,6 @@ struct STimings int32 IRQTriggerCycles; int32 WRAMRefreshPos; int32 RenderPos; - bool8 InterlaceField; int32 DMACPUSync; // The cycles to synchronize DMA and CPU. Snes9x cannot emulate correctly. int32 NMIDMADelay; // The delay of NMI trigger after DMA transfers. Snes9x cannot emulate correctly. int32 IRQFlagChanging; // This value is just a hack. @@ -188,6 +187,8 @@ struct STimings bool8 APUAllowTimeOverflow; }; +#define S9xInterlaceField ((Memory.FillRAM[0x213F] & 0x80) >> 7) + struct SSettings { bool8 TraceDMA; @@ -217,7 +218,7 @@ struct SSettings bool8 JustifierMaster; bool8 MultiPlayer5Master; bool8 MacsRifleMaster; - + bool8 ForceLoROM; bool8 ForceHiROM; bool8 ForceHeader;