dsda: set gammma after core seal but before first frame advance

This commit is contained in:
feos 2025-06-01 16:23:40 +03:00
parent 2d23183569
commit f0564300c7
7 changed files with 76 additions and 31 deletions

Binary file not shown.

View File

@ -323,7 +323,7 @@ namespace BizHawk.Emulation.Cores.Computers.Doom
public MultiplayerMode MultiplayerMode { get; set; }
[DisplayName("Initial Episode")]
[Description("Selects the initial episode. Ignored for non-episodic IWADs (e.g., DOOM2)")]
[Description("Selects the initial episode. Ignored for non-episodic IWADs (e.g., DOOM2) and Shareware.")]
[DefaultValue(1)]
public int InitialEpisode { get; set; }

View File

@ -17,20 +17,17 @@ namespace BizHawk.Emulation.Cores.Computers.Doom
public int VsyncDenominator { get; }
public int[] GetVideoBuffer() => _vidBuff;
private unsafe void UpdateVideo()
private unsafe void UpdateVideo(int gamma = -1)
{
using (_elf.EnterExit())
{
var videoBufferSrc = IntPtr.Zero;
var palletteBufferSrc = IntPtr.Zero;
_core.dsda_get_video(gamma, out LibDSDA.VideoInfo vi);
_core.dsda_get_video(out var width, out var height, out var pitch, ref videoBufferSrc, out var paletteSize, ref palletteBufferSrc);
var videoBuffer = (byte*) videoBufferSrc.ToPointer();
var paletteBuffer = (int*) palletteBufferSrc.ToPointer();
PaletteSize = paletteSize;
BufferWidth = width;
BufferHeight = height;
var videoBuffer = (byte*)vi.VideoBuffer.ToPointer();
var paletteBuffer = (int*)vi.PaletteBuffer.ToPointer();
PaletteSize = vi.PaletteSize;
BufferWidth = vi.Width;
BufferHeight = vi.Height;
// Handling pallette buffer
if (_palBuffer.Length < PaletteSize)

View File

@ -39,9 +39,11 @@ namespace BizHawk.Emulation.Cores.Computers.Doom
_pwadFiles = new();
bool foundIWAD = false;
string IWADName = "";
foreach (var wadFile in _wadFiles)
{
bool recognized = false;
if (wadFile.RomData is [ (byte) 'I', (byte) 'W', (byte) 'A', (byte) 'D', .. ])
{
// Check not more than one IWAD is provided
@ -56,18 +58,28 @@ namespace BizHawk.Emulation.Cores.Computers.Doom
_pwadFiles.Add(wadFile);
recognized = true;
}
if (!recognized) throw new Exception($"Unrecognized WAD provided: '{wadFile.RomPath}' has non-standard header.");
if (!recognized)
{
throw new Exception($"Unrecognized WAD provided: '{wadFile.RomPath}' has non-standard header.");
}
}
// Check at least one IWAD was provided
if (!foundIWAD) throw new Exception($"No IWAD was provided");
if (!foundIWAD)
{
throw new Exception($"No IWAD was provided");
}
// Getting dsda-doom.wad -- required by DSDA
_dsdaWadFileData = Zstd.DecompressZstdStream(new MemoryStream(Resources.DSDA_DOOM_WAD.Value)).ToArray();
// Getting sum of wad sizes for the accurate calculation of the invisible heap
uint totalWadSize = (uint)_dsdaWadFileData.Length;
foreach (var wadFile in _wadFiles) totalWadSize += (uint) wadFile.FileData.Length;
foreach (var wadFile in _wadFiles)
{
totalWadSize += (uint) wadFile.FileData.Length;
}
uint totalWadSizeKb = (totalWadSize / 1024) + 1;
Console.WriteLine($"Reserving {totalWadSizeKb}kb for WAD file memory");
@ -135,16 +147,20 @@ namespace BizHawk.Emulation.Cores.Computers.Doom
_core.dsda_add_wad_file(_dsdaWadFileName, _dsdaWadFileData.Length, _loadCallback);
// Adding IWAD file
var loadWadResult = _core.dsda_add_wad_file(_iwadFile.RomPath, _iwadFile.RomData.Length, _loadCallback);
if (loadWadResult is 0) throw new Exception($"Could not load WAD file: '{_iwadFile.RomPath}'");
_gameMode = (LibDSDA.GameMode)loadWadResult;
_gameMode = _core.dsda_add_wad_file(_iwadFile.RomPath, _iwadFile.RomData.Length, _loadCallback);
if (_gameMode is LibDSDA.GameMode.Fail)
{
throw new Exception($"Could not load WAD file: '{_iwadFile.RomPath}'");
}
// Adding PWAD file(s)
foreach (var wadFile in _pwadFiles)
{
loadWadResult = _core.dsda_add_wad_file(wadFile.RomPath, wadFile.RomData.Length, _loadCallback);
if (loadWadResult is 0) throw new Exception($"Could not load WAD file: '{wadFile.RomPath}'");
_gameMode = (LibDSDA.GameMode)loadWadResult;
_gameMode = _core.dsda_add_wad_file(wadFile.RomPath, wadFile.RomData.Length, _loadCallback);
if (_gameMode is LibDSDA.GameMode.Fail)
{
throw new Exception($"Could not load WAD file: '{wadFile.RomPath}'");
}
}
_elf.AddReadonlyFile(_configFile, "dsda-doom.cfg");
@ -152,7 +168,10 @@ namespace BizHawk.Emulation.Cores.Computers.Doom
var initSettings = _syncSettings.GetNativeSettings(lp.Game);
CreateArguments(initSettings);
var initResult = _core.dsda_init(ref initSettings, _args.Count, _args.ToArray());
if (!initResult) throw new Exception($"{nameof(_core.dsda_init)}() failed");
if (!initResult)
{
throw new Exception($"{nameof(_core.dsda_init)}() failed");
}
VsyncNumerator = 35;
VsyncDenominator = 1;
@ -182,7 +201,10 @@ namespace BizHawk.Emulation.Cores.Computers.Doom
_elf.Seal();
}
UpdateVideo();
// we have to set gamma after the core is sealed to ensure states don't depend on its initial value
// but if we set it during frame advance, first frame won't have it set
// so we set gamma here and force a video update, and other UpdateVideo() calls are blank
UpdateVideo(_settings.Gamma);
// Registering memory domains
SetupMemoryDomains();

View File

@ -78,6 +78,17 @@ namespace BizHawk.Emulation.Cores.Computers.Doom
public int MapOverlay;
public int PlayerPointOfView;
}
[StructLayout(LayoutKind.Sequential)]
public struct VideoInfo
{
public int Width;
public int Height;
public int Pitch;
public int PaletteSize;
public IntPtr PaletteBuffer;
public IntPtr VideoBuffer;
};
[BizImport(CallingConvention.Cdecl)]
public abstract void dsda_get_audio(ref int n, ref IntPtr buffer);
@ -86,12 +97,12 @@ namespace BizHawk.Emulation.Cores.Computers.Doom
public abstract bool dsda_init(ref InitSettings settings, int argc, string[] argv);
[BizImport(CallingConvention.Cdecl)]
public abstract void dsda_get_video(out int w, out int h, out int pitch, ref IntPtr buffer, out int palSize, ref IntPtr palBuffer);
public abstract void dsda_get_video(int gamma, out VideoInfo info);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int load_archive_cb(string filename, IntPtr buffer, int maxsize);
[BizImport(CallingConvention.Cdecl)]
public abstract int dsda_add_wad_file(string fileName, int fileSize, load_archive_cb feload_archive_cb);
public abstract GameMode dsda_add_wad_file(string fileName, int fileSize, load_archive_cb feload_archive_cb);
[BizImport(CallingConvention.Cdecl)]
public abstract byte dsda_read_memory_array(MemoryArrayType type, uint addr);

View File

@ -143,13 +143,19 @@ ECL_EXPORT void dsda_get_audio(int *n, void **buffer)
*buffer = audioBuffer;
}
ECL_EXPORT void dsda_get_video(int *w, int *h, int *pitch, uint8_t **buffer, int *paletteSize, uint32_t **paletteBuffer)
ECL_EXPORT void dsda_get_video(int gamma, struct VideoInfo* vi)
{
*buffer = (uint8_t *)headlessGetVideoBuffer();
*w = headlessGetVideoWidth();
*h = headlessGetVideoHeight();
*pitch = headlessGetVideoPitch();
*paletteSize = PALETTE_SIZE;
if (gamma != -1)
{
dsda_UpdateIntConfig(dsda_config_usegamma, gamma, true);
headlessUpdateVideo();
}
vi->buffer = (uint8_t *)headlessGetVideoBuffer();
vi->width = headlessGetVideoWidth();
vi->height = headlessGetVideoHeight();
vi->pitch = headlessGetVideoPitch();
vi->paletteSize = PALETTE_SIZE;
uint32_t *palette = headlessGetPallette() + PALETTE_SIZE * currentPaletteIndex;
for (size_t i = 0; i < PALETTE_SIZE; i++)
@ -162,7 +168,7 @@ ECL_EXPORT void dsda_get_video(int *w, int *h, int *pitch, uint8_t **buffer, int
dstColor[3] = srcColor[3];
}
*paletteBuffer = _convertedPaletteBuffer;
vi->paletteBuffer = _convertedPaletteBuffer;
}
ECL_EXPORT bool dsda_frame_advance(AutomapButtons buttons, struct PackedPlayerInput *player1Inputs, struct PackedPlayerInput *player2Inputs, struct PackedPlayerInput *player3Inputs, struct PackedPlayerInput *player4Inputs, struct PackedRenderInfo *renderInfo)

View File

@ -179,4 +179,13 @@ struct PackedRenderInfo
int PlayerPointOfView;
} __attribute__((packed));
struct VideoInfo {
int width;
int height;
int pitch;
int paletteSize;
uint32_t* paletteBuffer;
uint8_t* buffer;
};
#endif