diff --git a/Assets/dll/dsda.wbx.zst b/Assets/dll/dsda.wbx.zst index 443598d45d..905091c7af 100644 Binary files a/Assets/dll/dsda.wbx.zst and b/Assets/dll/dsda.wbx.zst differ diff --git a/src/BizHawk.Emulation.Cores/Computers/Doom/DSDA.ISettable.cs b/src/BizHawk.Emulation.Cores/Computers/Doom/DSDA.ISettable.cs index 90ee4e0dee..356f32ebe3 100644 --- a/src/BizHawk.Emulation.Cores/Computers/Doom/DSDA.ISettable.cs +++ b/src/BizHawk.Emulation.Cores/Computers/Doom/DSDA.ISettable.cs @@ -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; } diff --git a/src/BizHawk.Emulation.Cores/Computers/Doom/DSDA.IVideoProvider.cs b/src/BizHawk.Emulation.Cores/Computers/Doom/DSDA.IVideoProvider.cs index 3ff875043c..e7f5a7fdc5 100644 --- a/src/BizHawk.Emulation.Cores/Computers/Doom/DSDA.IVideoProvider.cs +++ b/src/BizHawk.Emulation.Cores/Computers/Doom/DSDA.IVideoProvider.cs @@ -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) diff --git a/src/BizHawk.Emulation.Cores/Computers/Doom/DSDA.cs b/src/BizHawk.Emulation.Cores/Computers/Doom/DSDA.cs index ef0246a1de..316c4d6dfe 100644 --- a/src/BizHawk.Emulation.Cores/Computers/Doom/DSDA.cs +++ b/src/BizHawk.Emulation.Cores/Computers/Doom/DSDA.cs @@ -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(); diff --git a/src/BizHawk.Emulation.Cores/Computers/Doom/LibDSDA.cs b/src/BizHawk.Emulation.Cores/Computers/Doom/LibDSDA.cs index 1972478afb..05bcc44a16 100644 --- a/src/BizHawk.Emulation.Cores/Computers/Doom/LibDSDA.cs +++ b/src/BizHawk.Emulation.Cores/Computers/Doom/LibDSDA.cs @@ -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); diff --git a/waterbox/dsda/BizhawkInterface.c b/waterbox/dsda/BizhawkInterface.c index cb542b6e74..f5935a746e 100644 --- a/waterbox/dsda/BizhawkInterface.c +++ b/waterbox/dsda/BizhawkInterface.c @@ -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) diff --git a/waterbox/dsda/BizhawkInterface.h b/waterbox/dsda/BizhawkInterface.h index 332f028e59..a4e73891f1 100644 --- a/waterbox/dsda/BizhawkInterface.h +++ b/waterbox/dsda/BizhawkInterface.h @@ -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 \ No newline at end of file