all nyma cores: support constant size framebuffer
this will do lossless integer scaling using mednafen provided screen geometry data
This commit is contained in:
parent
ddfd6fd49a
commit
b11b50a950
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -38,7 +38,6 @@ namespace BizHawk.Emulation.Cores.Consoles.NEC.PCE
|
|||
|
||||
protected override IDictionary<string, string> SettingsOverrides { get; } = new Dictionary<string, string>
|
||||
{
|
||||
{ "pce_fast.correct_aspect", null },
|
||||
{ "pce_fast.mouse_sensitivity", null },
|
||||
{ "pce_fast.disable_softreset", null },
|
||||
{ "pce_fast.cdbios", null },
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -51,5 +51,10 @@ namespace BizHawk.Emulation.Cores.Consoles.SNK
|
|||
throw new InvalidOperationException("Core rejected the saveram");
|
||||
_exe.RemoveTransientFile("SAV:flash");
|
||||
}
|
||||
|
||||
protected override IDictionary<string, string> SettingsOverrides { get; } = new Dictionary<string, string>
|
||||
{
|
||||
{ "nyma.constantfb", null }, // TODO: Couldn't we just autodetect this whenever lcm == max == nominal?
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
|||
/// </summary>
|
||||
public CommandType Command;
|
||||
/// <summary>
|
||||
/// True to render to a single framebuffer size (LCM * LCM)
|
||||
/// </summary>
|
||||
public short RenderConstantSize;
|
||||
/// <summary>
|
||||
/// raw data for each input port, assumed to be MAX_PORTS * MAX_PORT_DATA long
|
||||
/// </summary>
|
||||
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)]
|
||||
|
|
|
@ -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<SettingT> ExtraSettings = new List<SettingT>
|
||||
{
|
||||
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",
|
||||
|
|
|
@ -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"),
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue