diff --git a/output/dll/faust.wbx b/output/dll/faust.wbx deleted file mode 100644 index 0251dc18a6..0000000000 Binary files a/output/dll/faust.wbx and /dev/null differ diff --git a/output/dll/faust.wbx.gz b/output/dll/faust.wbx.gz new file mode 100644 index 0000000000..1cbfd5b46c Binary files /dev/null and b/output/dll/faust.wbx.gz differ diff --git a/output/dll/ngp.wbx.gz b/output/dll/ngp.wbx.gz index 5616cf19ea..e844a763a5 100644 Binary files a/output/dll/ngp.wbx.gz and b/output/dll/ngp.wbx.gz differ diff --git a/output/dll/pce-fast.wbx.gz b/output/dll/pce-fast.wbx.gz index ef33760ae6..69de895163 100644 Binary files a/output/dll/pce-fast.wbx.gz and b/output/dll/pce-fast.wbx.gz differ diff --git a/output/dll/pce.wbx.gz b/output/dll/pce.wbx.gz index f81b5999d0..d74db38efa 100644 Binary files a/output/dll/pce.wbx.gz and b/output/dll/pce.wbx.gz differ diff --git a/src/BizHawk.Emulation.Cores/Consoles/NEC/PCE/HyperNyma.cs b/src/BizHawk.Emulation.Cores/Consoles/NEC/PCE/HyperNyma.cs index 8ef1f362c0..0d3d56dfca 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/NEC/PCE/HyperNyma.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/NEC/PCE/HyperNyma.cs @@ -38,7 +38,6 @@ namespace BizHawk.Emulation.Cores.Consoles.NEC.PCE protected override IDictionary SettingsOverrides { get; } = new Dictionary { - { "pce_fast.correct_aspect", null }, { "pce_fast.mouse_sensitivity", null }, { "pce_fast.disable_softreset", null }, { "pce_fast.cdbios", null }, diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Faust/Faust.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Faust/Faust.cs index 1ac9e1af15..d1b89af382 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Faust/Faust.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Faust/Faust.cs @@ -27,7 +27,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Faust { "snes_faust.affinity.msu1.data", null }, { "snes_faust.frame_begin_vblank", null }, { "snes_faust.msu1.resamp_quality", null }, - { "snes_faust.correct_aspect", null }, { "snes_faust.spex", null }, { "snes_faust.spex.sound", null }, { "nyma.rtcinitialtime", null }, diff --git a/src/BizHawk.Emulation.Cores/Consoles/SNK/NeoGeoPort.cs b/src/BizHawk.Emulation.Cores/Consoles/SNK/NeoGeoPort.cs index cbcb82a7dd..517c3fcf00 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/SNK/NeoGeoPort.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/SNK/NeoGeoPort.cs @@ -51,5 +51,10 @@ namespace BizHawk.Emulation.Cores.Consoles.SNK throw new InvalidOperationException("Core rejected the saveram"); _exe.RemoveTransientFile("SAV:flash"); } + + protected override IDictionary SettingsOverrides { get; } = new Dictionary + { + { "nyma.constantfb", null }, // TODO: Couldn't we just autodetect this whenever lcm == max == nominal? + }; } } diff --git a/src/BizHawk.Emulation.Cores/Waterbox/LibNymaCore.cs b/src/BizHawk.Emulation.Cores/Waterbox/LibNymaCore.cs index 1d6774aedb..ba14511cf2 100644 --- a/src/BizHawk.Emulation.Cores/Waterbox/LibNymaCore.cs +++ b/src/BizHawk.Emulation.Cores/Waterbox/LibNymaCore.cs @@ -43,7 +43,7 @@ namespace BizHawk.Emulation.Cores.Waterbox [BizImport(CC)] public abstract bool InitCd(int numdisks); - public enum CommandType : int + public enum CommandType : short { NONE = 0x00, RESET = 0x01, @@ -85,6 +85,10 @@ namespace BizHawk.Emulation.Cores.Waterbox /// public CommandType Command; /// + /// True to render to a single framebuffer size (LCM * LCM) + /// + public short RenderConstantSize; + /// /// raw data for each input port, assumed to be MAX_PORTS * MAX_PORT_DATA long /// public byte* InputPortData; @@ -135,6 +139,8 @@ namespace BizHawk.Emulation.Cores.Waterbox public int NominalHeight; public VideoSystem VideoSystem; public int FpsFixed; + public int LcmWidth; + public int LcmHeight; } [BizImport(CC, Compatibility = true)] diff --git a/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Settings.cs b/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Settings.cs index f60c6caffa..6cc6197a52 100644 --- a/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Settings.cs +++ b/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Settings.cs @@ -119,7 +119,7 @@ namespace BizHawk.Emulation.Cores.Waterbox else { // try to get actual value from settings - if (NonSyncSettingNames.Contains(name)) + if (/* TODO: unhack */name == "nyma.constantfb" || NonSyncSettingNames.Contains(name)) _settings.MednafenValues.TryGetValue(name, out val); else _syncSettings.MednafenValues.TryGetValue(name, out val); @@ -208,7 +208,7 @@ namespace BizHawk.Emulation.Cores.Waterbox s.AllSettingsByKey.Add(setting.SettingsKey, setting); if (!SettingsOverrides.ContainsKey(setting.SettingsKey)) { - if (NonSyncSettingNames.Contains(setting.SettingsKey)) + if (/* TODO: unhack */setting.SettingsKey == "nyma.constantfb" || NonSyncSettingNames.Contains(setting.SettingsKey)) { s.Settings.Add(setting); } @@ -223,6 +223,15 @@ namespace BizHawk.Emulation.Cores.Waterbox private static IReadOnlyCollection ExtraSettings = new List { + new SettingT + { + Name = "Constant Framebuffer Size", + Description = "Output a constant framebuffer size regardless of internal resolution.", + SettingsKey = "nyma.constantfb", + DefaultValue = "0", + Flags = 0, + Type = SettingType.Bool + }, new SettingT { Name = "Initial Time", diff --git a/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.cs b/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.cs index 6844db6568..1299e2bc0e 100644 --- a/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.cs +++ b/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.cs @@ -98,7 +98,7 @@ namespace BizHawk.Emulation.Cores.Waterbox } var info = *_nyma.GetSystemInfo(); - _videoBuffer = new int[info.MaxWidth * info.MaxHeight]; + _videoBuffer = new int[Math.Max(info.MaxWidth * info.MaxHeight, info.LcmWidth * info.LcmHeight)]; BufferWidth = info.NominalWidth; BufferHeight = info.NominalHeight; switch (info.VideoSystem) @@ -182,12 +182,13 @@ namespace BizHawk.Emulation.Cores.Waterbox var ret = new LibNymaCore.FrameInfo { SkipRendering = (short)(render ? 0 : 1), - SkipSoundening =(short)(rendersound ? 0 : 1), + SkipSoundening = (short)(rendersound ? 0 : 1), Command = controller.IsPressed("Power") ? LibNymaCore.CommandType.POWER : controller.IsPressed("Reset") ? LibNymaCore.CommandType.RESET : LibNymaCore.CommandType.NONE, + RenderConstantSize = (short)(SettingsQuery("nyma.constantfb") != "0" ? 1 : 0), InputPortData = (byte*)_frameAdvanceInputLock.AddrOfPinnedObject(), FrontendTime = GetRtcTime(SettingsQuery("nyma.rtcrealtime") != "0"), }; diff --git a/waterbox/nyma/NymaCore.cpp b/waterbox/nyma/NymaCore.cpp index f4b271ab67..68377ebc62 100644 --- a/waterbox/nyma/NymaCore.cpp +++ b/waterbox/nyma/NymaCore.cpp @@ -104,7 +104,9 @@ struct MyFrameInfo: public FrameInfo int16_t SkipRendering; int16_t SkipSoundening; // a single MDFN_MSC_* command to run at the start of this frame; 0 if none - int32_t Command; + int16_t Command; + // true to render LCM * LCM instead of raw + int16_t RenderConstantSize; // raw data for each input port, assumed to be MAX_PORTS * MAX_PORT_DATA long uint8_t* InputPortData; int64_t FrontendTime; @@ -139,31 +141,80 @@ ECL_EXPORT void FrameAdvance(MyFrameInfo& frame) int h = EES->DisplayRect.h; int lineStart = EES->DisplayRect.y; int lineEnd = lineStart + h; - auto multiWidth = EES->LineWidths[0] != -1; - int w; - if (multiWidth) + + int srcp = Game->fb_width; + uint32_t* src = pixels + EES->DisplayRect.x + EES->DisplayRect.y * srcp; + uint32_t* dst = frame.VideoBuffer; + + if (!frame.RenderConstantSize || !multiWidth && Game->lcm_width == EES->DisplayRect.w && Game->lcm_height == h) { - w = 0; + // simple non-resizing blitter + // TODO: What does this do with true multiwidth? Probably not anything good + + int w; + if (multiWidth) + { + w = 0; + for (int line = lineStart; line < lineEnd; line++) + w = std::max(w, EES->LineWidths[line]); + } + else + { + w = EES->DisplayRect.w; + } + + frame.Width = w; + frame.Height = h; + int dstp = w; + for (int line = lineStart; line < lineEnd; line++) - w = std::max(w, EES->LineWidths[line]); + { + memcpy(dst, src, (multiWidth ? EES->LineWidths[line] : w) * sizeof(uint32_t)); + src += srcp; + dst += dstp; + } } else { - w = EES->DisplayRect.w; - } + // resize to lcm_width * lcm_height - frame.Width = w; - frame.Height = h; - int srcp = Game->fb_width; - int dstp = w; - uint32_t* src = pixels + EES->DisplayRect.x + EES->DisplayRect.y * srcp; - uint32_t* dst = frame.VideoBuffer; - for (int line = lineStart; line < lineEnd; line++) - { - memcpy(dst, src, (multiWidth ? EES->LineWidths[line] : w) * sizeof(uint32_t)); - src += srcp; - dst += dstp; + frame.Width = Game->lcm_width; + frame.Height = Game->lcm_height; + int dstp = frame.Width; + + int hf = Game->lcm_height / h; + for (int line = lineStart; line < lineEnd; line++) + { + int w = multiWidth ? EES->LineWidths[line] : EES->DisplayRect.w; + auto srcNext = src + srcp; + if (frame.Width == w) + { + memcpy(dst, src, w * sizeof(uint32_t)); + dst += dstp; + } + else + { + // stretch horizontal + int wf = Game->lcm_width / w; + auto dstNext = dst + dstp; + for (int x = 0; x < w; x++) + { + for (int n = 0; n < wf; n++) + *dst++ = *src; + src++; + } + while (dst < dstNext) // 1024 % 3 == 1, not quite "lcm" + *dst++ = src[-1]; + } + src = srcNext; + for (int y = 1; y < hf; y++) + { + // stretch vertical + memcpy(dst, dst - dstp, dstp * sizeof(uint32_t)); + dst += dstp; + } + } } } } @@ -176,6 +227,8 @@ struct SystemInfo int32_t NominalHeight; int32_t VideoSystem; int32_t FpsFixed; + int32_t LcmWidth; + int32_t LcmHeight; }; SystemInfo SI; @@ -187,6 +240,8 @@ ECL_EXPORT SystemInfo* GetSystemInfo() SI.NominalHeight = Game->nominal_height; SI.VideoSystem = Game->VideoSystem; SI.FpsFixed = Game->fps; + SI.LcmWidth = Game->lcm_width; + SI.LcmHeight = Game->lcm_height; return &SI; }