Remove extra variables for interlace field.

Keeping unsynchronized copies around is just asking for trouble.
Instead, use a macro to check the actual memory address.
This commit is contained in:
BearOso 2023-03-04 11:31:18 -06:00
parent 7a7e5226cc
commit daf8fba09c
8 changed files with 28 additions and 33 deletions

View File

@ -75,7 +75,6 @@ static void S9xSoftResetCPU (void)
SetFlags(MemoryFlag | IndexFlag | IRQ | Emulation); SetFlags(MemoryFlag | IndexFlag | IRQ | Emulation);
ClearFlags(Decimal); ClearFlags(Decimal);
Timings.InterlaceField = FALSE;
Timings.H_Max = Timings.H_Max_Master; Timings.H_Max = Timings.H_Max_Master;
Timings.V_Max = Timings.V_Max_Master; Timings.V_Max = Timings.V_Max_Master;
Timings.NMITriggerPos = 0xffff; Timings.NMITriggerPos = 0xffff;

View File

@ -276,7 +276,6 @@ void S9xDoHEventProcessing (void)
if (CPU.V_Counter >= Timings.V_Max) // V ranges from 0 to Timings.V_Max - 1 if (CPU.V_Counter >= Timings.V_Max) // V ranges from 0 to Timings.V_Max - 1
{ {
CPU.V_Counter = 0; CPU.V_Counter = 0;
Timings.InterlaceField ^= 1;
// From byuu: // From byuu:
// [NTSC] // [NTSC]
@ -285,7 +284,7 @@ void S9xDoHEventProcessing (void)
// [PAL] <PAL info is unverified on hardware> // [PAL] <PAL info is unverified on hardware>
// interlace mode has 625 scanlines: 313 on the even frame, and 312 on the odd. // 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. // 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) Timings.V_Max = Timings.V_Max_Master + 1; // 263 (NTSC), 313?(PAL)
else else
Timings.V_Max = Timings.V_Max_Master; // 262 (NTSC), 312?(PAL) 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, // In interlace mode, there are always 341 dots per scanline. Even frames have 263 scanlines,
// and odd frames have 262 scanlines. // and odd frames have 262 scanlines.
// Interlace mode scanline 240 on odd frames is not missing a dot. // 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 Timings.H_Max = Timings.H_Max_Master - ONE_DOT_CYCLE; // HC=1360
else else
Timings.H_Max = Timings.H_Max_Master; // HC=1364 Timings.H_Max = Timings.H_Max_Master; // HC=1364
if (Model->_5A22 == 2) 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 if (Timings.WRAMRefreshPos == SNES_WRAM_REFRESH_HC_v2 - ONE_DOT_CYCLE) // HC=534
Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2; // HC=538 Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2; // HC=538

27
gfx.cpp
View File

@ -122,7 +122,7 @@ void S9xGraphicsScreenResize (void)
IPPU.Interlace = Memory.FillRAM[0x2133] & 1; IPPU.Interlace = Memory.FillRAM[0x2133] & 1;
IPPU.InterlaceOBJ = Memory.FillRAM[0x2133] & 2; IPPU.InterlaceOBJ = Memory.FillRAM[0x2133] & 2;
IPPU.PseudoHires = Memory.FillRAM[0x2133] & 8; IPPU.PseudoHires = Memory.FillRAM[0x2133] & 8;
if (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.PseudoHires) if (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.PseudoHires)
{ {
IPPU.DoubleWidthPixels = TRUE; IPPU.DoubleWidthPixels = TRUE;
@ -146,7 +146,7 @@ void S9xGraphicsScreenResize (void)
GFX.PPL = GFX.RealPPL; GFX.PPL = GFX.RealPPL;
IPPU.DoubleHeightPixels = FALSE; IPPU.DoubleHeightPixels = FALSE;
IPPU.RenderedScreenHeight = PPU.ScreenHeight; IPPU.RenderedScreenHeight = PPU.ScreenHeight;
} }
} }
void S9xBuildDirectColourMaps (void) void S9xBuildDirectColourMaps (void)
@ -160,13 +160,12 @@ void S9xBuildDirectColourMaps (void)
void S9xStartScreenRefresh (void) void S9xStartScreenRefresh (void)
{ {
GFX.InterlaceFrame = !GFX.InterlaceFrame;
if (GFX.DoInterlace) if (GFX.DoInterlace)
GFX.DoInterlace--; GFX.DoInterlace--;
if (IPPU.RenderThisFrame) if (IPPU.RenderThisFrame)
{ {
if (!GFX.DoInterlace || !GFX.InterlaceFrame) if (!GFX.DoInterlace || !S9xInterlaceField)
{ {
if (!S9xInitUpdate()) if (!S9xInitUpdate())
{ {
@ -206,7 +205,7 @@ void S9xEndScreenRefresh (void)
{ {
FLUSH_REDRAW(); FLUSH_REDRAW();
if (GFX.DoInterlace && GFX.InterlaceFrame == 0) if (GFX.DoInterlace && S9xInterlaceField == 0)
{ {
S9xControlEOF(); S9xControlEOF();
S9xContinueUpdate(IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight); S9xContinueUpdate(IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight);
@ -329,7 +328,7 @@ static inline void RenderScreen (bool8 sub)
if (!sub) if (!sub)
{ {
GFX.S = GFX.Screen; GFX.S = GFX.Screen;
if (GFX.DoInterlace && GFX.InterlaceFrame) if (GFX.DoInterlace && S9xInterlaceField)
GFX.S += GFX.RealPPL; GFX.S += GFX.RealPPL;
GFX.DB = GFX.ZBuffer; GFX.DB = GFX.ZBuffer;
GFX.Clip = IPPU.Clip[0]; GFX.Clip = IPPU.Clip[0];
@ -515,7 +514,7 @@ void S9xUpdateScreen (void)
const uint16 black = BUILD_PIXEL(0, 0, 0); const uint16 black = BUILD_PIXEL(0, 0, 0);
GFX.S = GFX.Screen + GFX.StartY * GFX.PPL; GFX.S = GFX.Screen + GFX.StartY * GFX.PPL;
if (GFX.DoInterlace && GFX.InterlaceFrame) if (GFX.DoInterlace && S9xInterlaceField)
GFX.S += GFX.RealPPL; GFX.S += GFX.RealPPL;
for (uint32 l = GFX.StartY; l <= GFX.EndY; l++, GFX.S += GFX.PPL) 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 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 // OK, we have three cases here. Either there's no priority, priority is
// normal FirstSprite, or priority is FirstSprite+Y. The first two are // 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; void (*DrawClippedTile) (uint32, uint32, uint32, uint32, uint32, uint32) = NULL;
int PixWidth = IPPU.DoubleWidthPixels ? 2 : 1; int PixWidth = IPPU.DoubleWidthPixels ? 2 : 1;
BG.InterlaceLine = GFX.InterlaceFrame ? 8 : 0; BG.InterlaceLine = S9xInterlaceField ? 8 : 0;
GFX.Z1 = 2; GFX.Z1 = 2;
int sprite_limit = (Settings.MaxSpriteTilesPerLine == 128) ? 128 : 32; int sprite_limit = (Settings.MaxSpriteTilesPerLine == 128) ? 128 : 32;
for (uint32 Y = GFX.StartY, Offset = Y * GFX.PPL; Y <= GFX.EndY; Y++, Offset += GFX.PPL) for (uint32 Y = GFX.StartY, Offset = Y * GFX.PPL; Y <= GFX.EndY; Y++, Offset += GFX.PPL)
{ {
int I = 0; 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) 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 VOffset = LineData[Y].BG[bg].VOffset + (HiresInterlace ? 1 : 0);
uint32 HOffset = LineData[Y].BG[bg].HOffset; uint32 HOffset = LineData[Y].BG[bg].HOffset;
int VirtAlign = ((Y2 + VOffset) & 7) >> (HiresInterlace ? 1 : 0); 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++) 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 VOff = LineData[Y].BG[2].VOffset - 1;
uint32 HOff = LineData[Y].BG[2].HOffset; uint32 HOff = LineData[Y].BG[2].HOffset;
uint32 HOffsetRow = VOff >> Offset2Shift; uint32 HOffsetRow = VOff >> Offset2Shift;
@ -1822,7 +1821,7 @@ static void S9xDisplayStringType (const char *string, int linesFromBottom, int p
static void DisplayTime (void) static void DisplayTime (void)
{ {
char string[10]; char string[10];
time_t rawtime; time_t rawtime;
struct tm *timeinfo; struct tm *timeinfo;
@ -2026,7 +2025,7 @@ void S9xDisplayMessages (uint16 *screen, int ppl, int width, int height, int sca
{ {
if (Settings.DisplayTime) if (Settings.DisplayTime)
DisplayTime(); DisplayTime();
if (Settings.DisplayFrameRate) if (Settings.DisplayFrameRate)
DisplayFrameRate(); DisplayFrameRate();

1
gfx.h
View File

@ -32,7 +32,6 @@ struct SGFX
uint8 Z2; // depth to save uint8 Z2; // depth to save
uint32 FixedColour; uint32 FixedColour;
uint8 DoInterlace; uint8 DoInterlace;
uint8 InterlaceFrame;
uint32 StartY; uint32 StartY;
uint32 EndY; uint32 EndY;
bool8 ClipColors; bool8 ClipColors;

11
ppu.cpp
View File

@ -94,7 +94,7 @@ static int CyclesUntilNext (int hc, int vc)
// Add number of lines // Add number of lines
total += (vc - vpos) * Timings.H_Max_Master; total += (vc - vpos) * Timings.H_Max_Master;
// If line 240 is in there and we're odd, subtract a dot // 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; total -= ONE_DOT_CYCLE;
} }
else else
@ -105,11 +105,11 @@ static int CyclesUntilNext (int hc, int vc)
} }
total += (Timings.V_Max - vpos) * Timings.H_Max_Master; 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 -= ONE_DOT_CYCLE;
total += (vc) * Timings.H_Max_Master; total += (vc) * Timings.H_Max_Master;
if (vc > 240 && !Timings.InterlaceField && !IPPU.Interlace) if (vc > 240 && !S9xInterlaceField && !IPPU.Interlace)
total -= ONE_DOT_CYCLE; total -= ONE_DOT_CYCLE;
} }
@ -146,7 +146,7 @@ void S9xUpdateIRQPositions (bool initial)
} }
// Check for short dot scanline // 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 <= 322 ? ONE_DOT_CYCLE / 2 : 0;
Timings.NextIRQTimer -= PPU.IRQHBeamPos <= 326 ? 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); Timings.NextIRQTimer = CyclesUntilNext (PPU.HTimerPosition, PPU.VTimerPosition);
// Check for short dot scanline // Check for short dot scanline
int field = Timings.InterlaceField; int field = S9xInterlaceField;
if (PPU.VTimerPosition < CPU.V_Counter || if (PPU.VTimerPosition < CPU.V_Counter ||
(PPU.VTimerPosition == CPU.V_Counter && Timings.NextIRQTimer > Timings.H_Max)) (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_EVEN], 0, MAX_4BIT_TILES);
memset(IPPU.TileCached[TILE_4BIT_ODD], 0, MAX_4BIT_TILES); memset(IPPU.TileCached[TILE_4BIT_ODD], 0, MAX_4BIT_TILES);
PPU.VRAMReadBuffer = 0; // XXX: FIXME: anything better? PPU.VRAMReadBuffer = 0; // XXX: FIXME: anything better?
GFX.InterlaceFrame = 0;
GFX.DoInterlace = 0; GFX.DoInterlace = 0;
IPPU.Interlace = FALSE; IPPU.Interlace = FALSE;
IPPU.InterlaceOBJ = FALSE; IPPU.InterlaceOBJ = FALSE;

View File

@ -410,7 +410,7 @@ static FreezeData SnapTimings[] =
INT_ENTRY(6, NMITriggerPos), INT_ENTRY(6, NMITriggerPos),
INT_ENTRY(6, WRAMRefreshPos), INT_ENTRY(6, WRAMRefreshPos),
INT_ENTRY(6, RenderPos), INT_ENTRY(6, RenderPos),
INT_ENTRY(6, InterlaceField), DELETED_INT_ENTRY(6, 12, InterlaceField, 1),
INT_ENTRY(6, DMACPUSync), INT_ENTRY(6, DMACPUSync),
INT_ENTRY(6, NMIDMADelay), INT_ENTRY(6, NMIDMADelay),
INT_ENTRY(6, IRQFlagChanging), INT_ENTRY(6, IRQFlagChanging),
@ -1689,12 +1689,11 @@ int S9xUnfreezeFromStream (STREAM stream)
IPPU.ColorsChanged = TRUE; IPPU.ColorsChanged = TRUE;
IPPU.OBJChanged = TRUE; IPPU.OBJChanged = TRUE;
IPPU.RenderThisFrame = TRUE; IPPU.RenderThisFrame = TRUE;
GFX.InterlaceFrame = Timings.InterlaceField;
GFX.DoInterlace = 0; GFX.DoInterlace = 0;
S9xGraphicsScreenResize(); S9xGraphicsScreenResize();
if (Settings.FastSavestates == 0) if (Settings.FastSavestates == 0)
memset(GFX.Screen,0,GFX.Pitch * MAX_SNES_HEIGHT); memset(GFX.Screen,0,GFX.Pitch * MAX_SNES_HEIGHT);

View File

@ -13,7 +13,7 @@
#define SNAPSHOT_VERSION_IRQ 7 #define SNAPSHOT_VERSION_IRQ 7
#define SNAPSHOT_VERSION_BAPU 8 #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_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 SUCCESS 1
#define WRONG_FORMAT (-1) #define WRONG_FORMAT (-1)

View File

@ -180,7 +180,6 @@ struct STimings
int32 IRQTriggerCycles; int32 IRQTriggerCycles;
int32 WRAMRefreshPos; int32 WRAMRefreshPos;
int32 RenderPos; int32 RenderPos;
bool8 InterlaceField;
int32 DMACPUSync; // The cycles to synchronize DMA and CPU. Snes9x cannot emulate correctly. 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 NMIDMADelay; // The delay of NMI trigger after DMA transfers. Snes9x cannot emulate correctly.
int32 IRQFlagChanging; // This value is just a hack. int32 IRQFlagChanging; // This value is just a hack.
@ -188,6 +187,8 @@ struct STimings
bool8 APUAllowTimeOverflow; bool8 APUAllowTimeOverflow;
}; };
#define S9xInterlaceField ((Memory.FillRAM[0x213F] & 0x80) >> 7)
struct SSettings struct SSettings
{ {
bool8 TraceDMA; bool8 TraceDMA;
@ -217,7 +218,7 @@ struct SSettings
bool8 JustifierMaster; bool8 JustifierMaster;
bool8 MultiPlayer5Master; bool8 MultiPlayer5Master;
bool8 MacsRifleMaster; bool8 MacsRifleMaster;
bool8 ForceLoROM; bool8 ForceLoROM;
bool8 ForceHiROM; bool8 ForceHiROM;
bool8 ForceHeader; bool8 ForceHeader;