diff --git a/BizHawk.Emulation.Cores/Consoles/NEC/PCFX/LibTst.cs b/BizHawk.Emulation.Cores/Consoles/NEC/PCFX/LibTst.cs index c6fdf48c55..a108e501d7 100644 --- a/BizHawk.Emulation.Cores/Consoles/NEC/PCFX/LibTst.cs +++ b/BizHawk.Emulation.Cores/Consoles/NEC/PCFX/LibTst.cs @@ -49,6 +49,7 @@ namespace BizHawk.Emulation.Cores.Consoles.NEC.PCFX public int CpuEmulation; public int Port1; public int Port2; + public int PixelPro; } [BizImport(CC)] diff --git a/BizHawk.Emulation.Cores/Consoles/NEC/PCFX/Tst.cs b/BizHawk.Emulation.Cores/Consoles/NEC/PCFX/Tst.cs index b89760ba34..e0ee26e575 100644 --- a/BizHawk.Emulation.Cores/Consoles/NEC/PCFX/Tst.cs +++ b/BizHawk.Emulation.Cores/Consoles/NEC/PCFX/Tst.cs @@ -222,6 +222,10 @@ namespace BizHawk.Emulation.Cores.Consoles.NEC.PCFX [DeepEqualsIgnore] private bool _showLayerRAINBOW; + [Description("Pixel Pro. Overrides HiResEmulation if set")] + [DefaultValue(false)] + public bool PixelPro { get; set; } + public Settings Clone() { return (Settings)MemberwiseClone(); @@ -321,7 +325,8 @@ namespace BizHawk.Emulation.Cores.Consoles.NEC.PCFX CdSpeed = _syncSettings.CdSpeed, CpuEmulation = (int)_syncSettings.CpuEmulation, Port1 = (int)_syncSettings.Port1, - Port2 = (int)_syncSettings.Port2 + Port2 = (int)_syncSettings.Port2, + PixelPro = _settings.PixelPro ? 1 : 0 }; _core.PutSettingsBeforeInit(s); } diff --git a/output/dll/pcfx.wbx.gz b/output/dll/pcfx.wbx.gz index a8d7576f4a..855f4fea14 100644 Binary files a/output/dll/pcfx.wbx.gz and b/output/dll/pcfx.wbx.gz differ diff --git a/waterbox/pcfx/.vscode/settings.json b/waterbox/pcfx/.vscode/settings.json index ed2aea06d3..63ffa1793c 100644 --- a/waterbox/pcfx/.vscode/settings.json +++ b/waterbox/pcfx/.vscode/settings.json @@ -10,6 +10,7 @@ "xiosbase": "cpp", "iosfwd": "cpp", "xlocale": "cpp", - "xstring": "cpp" + "xstring": "cpp", + "queue": "cpp" } } \ No newline at end of file diff --git a/waterbox/pcfx/defs.h b/waterbox/pcfx/defs.h index d6ec6a9f47..1c1245fa95 100644 --- a/waterbox/pcfx/defs.h +++ b/waterbox/pcfx/defs.h @@ -80,7 +80,7 @@ typedef struct // Set by the system emulation code every frame, to denote the horizontal and vertical offsets of the image, and the size // of the image. If the emulated system sets the elements of LineWidths, then the width(w) of this structure // is ignored while drawing the image. - int32 x, y, w, h; + int32 y, w, h; // Set(optionally) by emulation code. If InterlaceOn is true, then assume field height is 1/2 DisplayRect.h, and // only every other line in surface (with the start line defined by InterlacedField) has valid data @@ -118,3 +118,5 @@ extern bool Setting_AdpcmNoClicks; extern bool Setting_ChromaInterpolate; extern int Setting_PortDevice[2]; + +extern bool Setting_PixelPro; diff --git a/waterbox/pcfx/king.cpp b/waterbox/pcfx/king.cpp index 6a691a83ff..c2b67e446e 100644 --- a/waterbox/pcfx/king.cpp +++ b/waterbox/pcfx/king.cpp @@ -2628,7 +2628,6 @@ void KING_StartFrame(VDC **arg_vdc_chips, EmulateSpecStruct *espec) LineWidths[0] = 0; // These 2 should be overwritten in the big loop below. - espec->x = 0; espec->w = 256; espec->y = Setting_SlStart; @@ -3104,7 +3103,6 @@ static void MixLayers(void) #undef YUV888_TO_xxx } Ess->w = fx_vce.dot_clock ? HighDotClockWidth : 256; - Ess->x = 0; // FIXME if (fx_vce.frame_interlaced) diff --git a/waterbox/pcfx/pcfx.cpp b/waterbox/pcfx/pcfx.cpp index 96623ed54f..f201921d48 100644 --- a/waterbox/pcfx/pcfx.cpp +++ b/waterbox/pcfx/pcfx.cpp @@ -706,6 +706,90 @@ EXPORT bool Init(int numDisks, const uint8_t *bios) static int ActiveDisk; static uint32_t PrevConsoleButtons; +static void Blit(MyFrameInfo &f) +{ + // two widths to deal with: 256 and "341" (which can be 256, 341, or 1024 wide depending on settings) + // two heights: 240 and 480, but watch out for scanlinestart / scanline end + + // in pixel pro mode, 341 width is forced to 1024. we upsize 256 to 1024 as well, and double 240 tall + + const uint32_t *src = FrameBuffer; + uint32_t *dst = f.VideoBuffer; + const int srcp = 1024; + src += Ess.y * srcp; + + if (Setting_PixelPro) + { + f.Width = 1024; + f.Height = Ess.h; + + const int dstp = 1024; + + if (Ess.h > 240) // interlace + { + if (Ess.w == 256) + { + for (int j = 0; j < Ess.h; j++, src += srcp, dst += dstp) + { + for (int i = 0; i < 256; i++) + { + auto c = src[i]; + dst[i * 4 + 0] = c; + dst[i * 4 + 1] = c; + dst[i * 4 + 2] = c; + dst[i * 4 + 3] = c; + } + } + } + else + { + for (int j = 0; j < Ess.h; j++, src += srcp, dst += dstp) + { + memcpy(dst, src, LineWidths[j + Ess.y] * sizeof(uint32_t)); + } + } + } + else // progressive: line double + { + f.Height *= 2; + if (Ess.w == 256) + { + for (int j = 0; j < Ess.h; j++, src += srcp, dst += dstp * 2) + { + for (int i = 0; i < 256; i++) + { + auto c = src[i]; + dst[i * 4 + 0] = c; + dst[i * 4 + 1] = c; + dst[i * 4 + 2] = c; + dst[i * 4 + 3] = c; + } + memcpy(dst + dstp, dst, 4096); + } + } + else + { + for (int j = 0; j < Ess.h; j++, src += srcp, dst += dstp * 2) + { + memcpy(dst, src, 4096); + memcpy(dst + dstp, src, 4096); + } + } + } + } + else + { + f.Width = Ess.w; + f.Height = Ess.h; + + const int dstp = Ess.w; + for (int j = 0; j < Ess.h; j++, src += srcp, dst += dstp) + { + memcpy(dst, src, LineWidths[j + Ess.y] * sizeof(uint32_t)); + } + } +} + EXPORT void FrameAdvance(MyFrameInfo &f) { for (int i = 0; i < 2; i++) @@ -733,20 +817,10 @@ EXPORT void FrameAdvance(MyFrameInfo &f) Ess.SoundBuf = f.SoundBuffer; Emulate(&Ess); f.Cycles = Ess.MasterCycles; - f.Width = Ess.w; - f.Height = Ess.h; f.Samples = Ess.SoundBufSize; f.Lagged = Lagged; - const uint32_t *src = FrameBuffer; - uint32_t *dst = f.VideoBuffer; - const int srcp = 1024; - const int dstp = Ess.w; - src += Ess.y * srcp + Ess.x; - for (int j = 0; j < Ess.h; j++, src += srcp, dst += dstp) - { - memcpy(dst, src, LineWidths[j + Ess.y] * sizeof(uint32_t)); - } + Blit(f); } EXPORT void GetMemoryAreas(MemoryArea *m) @@ -821,6 +895,8 @@ ECL_SEALED bool Setting_ChromaInterpolate = false; ECL_SEALED int Setting_PortDevice[2]; +ECL_SEALED bool Setting_PixelPro; + struct FrontendSettings { int32_t AdpcmEmulateBuggyCodec; @@ -834,13 +910,14 @@ struct FrontendSettings int32_t CpuEmulation; int32_t Port1; int32_t Port2; + int32_t PixelPro; }; EXPORT void PutSettingsBeforeInit(const FrontendSettings &s) { Setting_AdpcmBuggy = s.AdpcmEmulateBuggyCodec; Setting_AdpcmNoClicks = s.AdpcmSuppressChannelResetClicks; - Setting_HighDotclockWidth = s.HiResEmulation; + Setting_HighDotclockWidth = s.PixelPro ? 1024 : s.HiResEmulation; Setting_NoSpriteLimit = s.DisableSpriteLimit; Setting_ChromaInterpolate = s.ChromaInterpolation; Setting_SlStart = s.ScanlineStart; @@ -849,6 +926,7 @@ EXPORT void PutSettingsBeforeInit(const FrontendSettings &s) Setting_CpuEmulation = s.CpuEmulation; Setting_PortDevice[0] = s.Port1; Setting_PortDevice[1] = s.Port2; + Setting_PixelPro = s.PixelPro; } /*MDFNGI EmulatedPCFX =