From 5f250a2fb00658106865528da21aee8ab2da8a73 Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Mon, 5 Feb 2018 16:58:46 -0500 Subject: [PATCH] PCE: Fix display to correctly capture changes to display offset register Fixes Devil's Crush (and by extension Final Blaster) --- .../Consoles/PC Engine/VDC.Render.cs | 27 ++++++++++--------- .../Consoles/PC Engine/VDC.cs | 17 +++++++----- .../Consoles/PC Engine/VPC.cs | 15 ++++++----- 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/PC Engine/VDC.Render.cs b/BizHawk.Emulation.Cores/Consoles/PC Engine/VDC.Render.cs index 43164ab43c..74191fd6a3 100644 --- a/BizHawk.Emulation.Cores/Consoles/PC Engine/VDC.Render.cs +++ b/BizHawk.Emulation.Cores/Consoles/PC Engine/VDC.Render.cs @@ -34,9 +34,10 @@ namespace BizHawk.Emulation.Cores.PCEngine if (MultiResHack > 0 && render) Array.Clear(FrameBuffer, 0, FrameBuffer.Length); + int ActiveDisplayStartLine = DisplayStartLine; + while (true) { - int ActiveDisplayStartLine = DisplayStartLine; int VBlankLine = ActiveDisplayStartLine + Registers[VDW] + 1; if (VBlankLine > 261) VBlankLine = 261; @@ -106,7 +107,7 @@ namespace BizHawk.Emulation.Cores.PCEngine public void RenderScanLine() { - if (ActiveLine >= FrameHeight) + if ((ActiveLine + ViewStartLine) >= 262) return; RenderBackgroundScanline(pce.Settings.ShowBG1); @@ -124,7 +125,7 @@ namespace BizHawk.Emulation.Cores.PCEngine int p = vce.Palette[256]; fixed (int* FBptr = FrameBuffer) { - int* dst = FBptr + ActiveLine * FramePitch; + int* dst = FBptr + (ActiveLine + ViewStartLine) * FramePitch; for (int i = 0; i < FrameWidth; i++) *dst++ = p; } @@ -148,7 +149,7 @@ namespace BizHawk.Emulation.Cores.PCEngine { // pointer to the BAT and the framebuffer for this line ushort* BatRow = VRAMptr + yTile * BatWidth; - int* dst = FBptr + ActiveLine * FramePitch; + int* dst = FBptr + (ActiveLine + ViewStartLine) * FramePitch; // parameters that change per tile ushort BatEnt; @@ -202,7 +203,7 @@ namespace BizHawk.Emulation.Cores.PCEngine if (BackgroundEnabled == false) { for (int i = 0; i < FrameWidth; i++) - FrameBuffer[(ActiveLine * FramePitch) + i] = vce.Palette[256]; + FrameBuffer[((ActiveLine + ViewStartLine) * FramePitch) + i] = vce.Palette[256]; return; } @@ -226,10 +227,10 @@ namespace BizHawk.Emulation.Cores.PCEngine byte c = PatternBuffer[(tileNo * 64) + (yOfs * 8) + xOfs]; if (c == 0) - FrameBuffer[(ActiveLine * FramePitch) + x] = vce.Palette[0]; + FrameBuffer[((ActiveLine + ViewStartLine) * FramePitch) + x] = vce.Palette[0]; else { - FrameBuffer[(ActiveLine * FramePitch) + x] = show ? vce.Palette[paletteBase + c] : vce.Palette[0]; + FrameBuffer[((ActiveLine + ViewStartLine) * FramePitch) + x] = show ? vce.Palette[paletteBase + c] : vce.Palette[0]; PriorityBuffer[x] = 1; } } @@ -361,7 +362,7 @@ namespace BizHawk.Emulation.Cores.PCEngine { InterSpritePriorityBuffer[xs] = 1; if ((priority || PriorityBuffer[xs] == 0) && show) - FrameBuffer[(ActiveLine * FramePitch) + xs] = vce.Palette[paletteBase + pixel]; + FrameBuffer[((ActiveLine + ViewStartLine) * FramePitch) + xs] = vce.Palette[paletteBase + pixel]; } } } @@ -378,7 +379,7 @@ namespace BizHawk.Emulation.Cores.PCEngine { InterSpritePriorityBuffer[xs] = 1; if ((priority || PriorityBuffer[xs] == 0) && show) - FrameBuffer[(ActiveLine * FramePitch) + xs] = vce.Palette[paletteBase + pixel]; + FrameBuffer[((ActiveLine + ViewStartLine) * FramePitch) + xs] = vce.Palette[paletteBase + pixel]; } } @@ -399,7 +400,7 @@ namespace BizHawk.Emulation.Cores.PCEngine { InterSpritePriorityBuffer[xs] = 1; if ((priority || PriorityBuffer[xs] == 0) && show) - FrameBuffer[(ActiveLine * FramePitch) + xs] = vce.Palette[paletteBase + pixel]; + FrameBuffer[((ActiveLine + ViewStartLine) * FramePitch) + xs] = vce.Palette[paletteBase + pixel]; } } if (width == 32) @@ -415,7 +416,7 @@ namespace BizHawk.Emulation.Cores.PCEngine { InterSpritePriorityBuffer[xs] = 1; if ((priority || PriorityBuffer[xs] == 0) && show) - FrameBuffer[(ActiveLine * FramePitch) + xs] = vce.Palette[paletteBase + pixel]; + FrameBuffer[((ActiveLine + ViewStartLine) * FramePitch) + xs] = vce.Palette[paletteBase + pixel]; } } } @@ -426,8 +427,8 @@ namespace BizHawk.Emulation.Cores.PCEngine private int FramePitch = 256; private int FrameWidth = 256; - private int FrameHeight = 240; - private int[] FrameBuffer = new int[256 * 240]; + private int FrameHeight = 262; + private int[] FrameBuffer = new int[256 * 262]; // IVideoProvider implementation public int[] GetVideoBuffer() diff --git a/BizHawk.Emulation.Cores/Consoles/PC Engine/VDC.cs b/BizHawk.Emulation.Cores/Consoles/PC Engine/VDC.cs index 7217541377..0bbcaa1934 100644 --- a/BizHawk.Emulation.Cores/Consoles/PC Engine/VDC.cs +++ b/BizHawk.Emulation.Cores/Consoles/PC Engine/VDC.cs @@ -49,6 +49,7 @@ namespace BizHawk.Emulation.Cores.PCEngine public int RequestedFrameWidth => ((Registers[HDR] & 0x3F) + 1) * 8; public int RequestedFrameHeight => (Registers[VDW] & 0x1FF) + 1; public int DisplayStartLine => (Registers[VPR] >> 8) + (Registers[VPR] & 0x1F); + public int ViewStartLine => (Registers[VPR] >> 8) + 2; private const int MAWR = 0; // Memory Address Write Register private const int MARR = 1; // Memory Address Read Register @@ -158,18 +159,20 @@ namespace BizHawk.Emulation.Cores.PCEngine case HDR: // Horizontal Display Register - update framebuffer size FrameWidth = RequestedFrameWidth; FramePitch = MultiResHack == 0 ? FrameWidth : MultiResHack; - if (FrameBuffer.Length != FramePitch * FrameHeight) - FrameBuffer = new int[FramePitch * FrameHeight]; + //if (FrameBuffer.Length != FramePitch * FrameHeight) + //FrameBuffer = new int[FramePitch * FrameHeight]; + FrameBuffer = new int[256 * 262]; break; case VDW: // Vertical Display Word? - update framebuffer size - FrameHeight = RequestedFrameHeight; + //FrameHeight = RequestedFrameHeight; FrameWidth = RequestedFrameWidth; - if (FrameHeight > 242) - FrameHeight = 242; + //if (FrameHeight > 242) + //FrameHeight = 242; if (MultiResHack != 0) FramePitch = MultiResHack; - if (FrameBuffer.Length != FramePitch * FrameHeight) - FrameBuffer = new int[FramePitch * FrameHeight]; + //if (FrameBuffer.Length != FramePitch * FrameHeight) + //FrameBuffer = new int[FramePitch * FrameHeight]; + FrameBuffer = new int[256 * 262]; break; case LENR: // Initiate DMA transfer if (!msbComplete) break; diff --git a/BizHawk.Emulation.Cores/Consoles/PC Engine/VPC.cs b/BizHawk.Emulation.Cores/Consoles/PC Engine/VPC.cs index a24910a44e..97e2e3f988 100644 --- a/BizHawk.Emulation.Cores/Consoles/PC Engine/VPC.cs +++ b/BizHawk.Emulation.Cores/Consoles/PC Engine/VPC.cs @@ -128,12 +128,13 @@ namespace BizHawk.Emulation.Cores.PCEngine FrameBuffer = VDC1.GetVideoBuffer(); int ScanLine = 0; + int ActiveDisplayStartLine = VDC1.DisplayStartLine; + while (true) { VDC1.ScanLine = ScanLine; VDC2.ScanLine = ScanLine; - - int ActiveDisplayStartLine = VDC1.DisplayStartLine; + int VBlankLine = ActiveDisplayStartLine + VDC1.Registers[VDW] + 1; if (VBlankLine > 261) VBlankLine = 261; @@ -291,7 +292,7 @@ namespace BizHawk.Emulation.Cores.PCEngine { // pointer to the BAT and the framebuffer for this line ushort* BatRow = VRAMptr + yTile * vdc.BatWidth; - int* dst = FBptr + vdc.ActiveLine * FrameWidth; + int* dst = FBptr + (vdc.ActiveLine + vdc.ViewStartLine) * FrameWidth; // parameters that change per tile ushort BatEnt; @@ -447,7 +448,7 @@ namespace BizHawk.Emulation.Cores.PCEngine byte myPriority = priority ? highPriority : lowPriority; if (PriorityBuffer[xs] < myPriority) { - if (show) FrameBuffer[(vdc.ActiveLine * FrameWidth) + xs] = VCE.Palette[paletteBase + pixel]; + if (show) FrameBuffer[((vdc.ActiveLine + vdc.ViewStartLine) * FrameWidth) + xs] = VCE.Palette[paletteBase + pixel]; PriorityBuffer[xs] = myPriority; } } @@ -466,7 +467,7 @@ namespace BizHawk.Emulation.Cores.PCEngine byte myPriority = priority ? highPriority : lowPriority; if (PriorityBuffer[xs] < myPriority) { - if (show) FrameBuffer[(vdc.ActiveLine * FrameWidth) + xs] = VCE.Palette[paletteBase + pixel]; + if (show) FrameBuffer[((vdc.ActiveLine + vdc.ViewStartLine) * FrameWidth) + xs] = VCE.Palette[paletteBase + pixel]; PriorityBuffer[xs] = myPriority; } } @@ -488,7 +489,7 @@ namespace BizHawk.Emulation.Cores.PCEngine byte myPriority = priority ? highPriority : lowPriority; if (PriorityBuffer[xs] < myPriority) { - if (show) FrameBuffer[(vdc.ActiveLine * FrameWidth) + xs] = VCE.Palette[paletteBase + pixel]; + if (show) FrameBuffer[((vdc.ActiveLine + vdc.ViewStartLine) * FrameWidth) + xs] = VCE.Palette[paletteBase + pixel]; PriorityBuffer[xs] = myPriority; } } @@ -506,7 +507,7 @@ namespace BizHawk.Emulation.Cores.PCEngine byte myPriority = priority ? highPriority : lowPriority; if (PriorityBuffer[xs] < myPriority) { - if (show) FrameBuffer[(vdc.ActiveLine * FrameWidth) + xs] = VCE.Palette[paletteBase + pixel]; + if (show) FrameBuffer[((vdc.ActiveLine + vdc.ViewStartLine) * FrameWidth) + xs] = VCE.Palette[paletteBase + pixel]; PriorityBuffer[xs] = myPriority; } }