From 4660cc6be888c17ee0b31890307d023f6d058d9b Mon Sep 17 00:00:00 2001 From: Stefan Koelle Date: Tue, 11 Aug 2026 14:51:40 +0200 Subject: [PATCH 1/2] release v0.9.5\n\nThis release updates the Marcer GameDVD Launcher with the following changes:\n\n#### Bug Fixes\n- Fix bundled config path resolution using Directory.GetCurrentDirectory() for better cross-platform compatibility\n\n#### Features\n- Add bundled Hatari configuration file for automatic fallback\n- Make Hatari.ConfigFile optional with automatic fallback to bundled config\n\n#### Code Improvements\n- Centralize configuration handling for better maintainability\n- Improve documentation and comments throughout\n\nThe launcher now provides improved configuration handling and bundled support for Hatari. From 7b40cbc331d2c0eb3e5d053aea809d396ff04d24 Mon Sep 17 00:00:00 2001 From: Stefan Koelle Date: Tue, 11 Aug 2026 19:22:53 +0200 Subject: [PATCH 2/2] launcher fixes - hatari config fixes --- src/MarcerGameDvdLauncher/HatariLauncher.cs | 8 +-- src/MarcerGameDvdLauncher/LauncherApp.cs | 12 +--- .../MarcerGameDvd-Hatari.cfg | 59 +++++++++++-------- 3 files changed, 41 insertions(+), 38 deletions(-) diff --git a/src/MarcerGameDvdLauncher/HatariLauncher.cs b/src/MarcerGameDvdLauncher/HatariLauncher.cs index fc5ee6a..60898fa 100644 --- a/src/MarcerGameDvdLauncher/HatariLauncher.cs +++ b/src/MarcerGameDvdLauncher/HatariLauncher.cs @@ -8,7 +8,7 @@ namespace MarcerGameDvdLauncher // The Hatari configuration file that is shipped with the launcher. // When Hatari.ConfigFile is not set in launcher.config.json, this file // (resolved relative to the executable directory) is used automatically. - public const string DefaultConfigFile = "MarcerGameDvd-Hatari.cfg"; + private const string DEFAULT_CONFIG_FILE = "MarcerGameDvd-Hatari.cfg"; private readonly string _exePath; private readonly string _cfgPath; @@ -26,6 +26,8 @@ namespace MarcerGameDvdLauncher // Validate argsTemplate if (string.IsNullOrWhiteSpace(argsTemplate) || !argsTemplate.Contains("{zip}")) throw new ArgumentException("Hatari.ArgsTemplate must contain the {zip} placeholder.", nameof(argsTemplate)); + if (string.IsNullOrWhiteSpace(argsTemplate) || !argsTemplate.Contains("{cfg}")) + throw new ArgumentException("Hatari.ArgsTemplate must contain the {cfg} placeholder.", nameof(argsTemplate)); _exePath = exePath; _cfgPath = cfgPath; @@ -42,7 +44,6 @@ namespace MarcerGameDvdLauncher throw new ArgumentException("ZIP archive path must not be empty.", nameof(zipFilePath)); try { - // Build arguments: only include config section if cfgPath is not empty string args = _argsTemplate; if (!string.IsNullOrWhiteSpace(_cfgPath)) { @@ -50,8 +51,7 @@ namespace MarcerGameDvdLauncher } else { - // Remove {cfg} placeholder entirely if config file is empty - args = args.Replace("{cfg}", string.Empty); + args = args.Replace("{cfg}", Path.Combine(Directory.GetCurrentDirectory(),DEFAULT_CONFIG_FILE)); } args = args.Replace("{zip}", zipFilePath); diff --git a/src/MarcerGameDvdLauncher/LauncherApp.cs b/src/MarcerGameDvdLauncher/LauncherApp.cs index edc458b..48320da 100644 --- a/src/MarcerGameDvdLauncher/LauncherApp.cs +++ b/src/MarcerGameDvdLauncher/LauncherApp.cs @@ -63,17 +63,11 @@ namespace MarcerGameDvdLauncher if (!File.Exists(cfg.Hatari.Executable)) throw new InvalidOperationException($"Hatari executable not found: {cfg.Hatari.Executable}"); - // If no Hatari config file was specified, fall back to the bundled - // MarcerGameDvd-Hatari.cfg that ships with the launcher. - // Use current working directory to allow running from different locations - if (string.IsNullOrWhiteSpace(cfg.Hatari.ConfigFile)) - { - cfg.Hatari.ConfigFile = Path.Combine(Directory.GetCurrentDirectory(), HatariLauncher.DefaultConfigFile); - } - // Validate the Hatari config file (either user-specified or bundled fallback) - if (!File.Exists(cfg.Hatari.ConfigFile)) + if (!string.IsNullOrEmpty(cfg.Hatari.ConfigFile) && !File.Exists(cfg.Hatari.ConfigFile)) throw new InvalidOperationException($"Hatari configuration file not found: {cfg.Hatari.ConfigFile}"); + if (string.IsNullOrWhiteSpace(cfg.Hatari.ArgsTemplate) || !cfg.Hatari.ArgsTemplate.Contains("{cfg}")) + throw new InvalidOperationException("Hatari.ArgsTemplate must contain the {cfg} placeholder."); if (string.IsNullOrWhiteSpace(cfg.Hatari.ArgsTemplate) || !cfg.Hatari.ArgsTemplate.Contains("{zip}")) throw new InvalidOperationException("Hatari.ArgsTemplate must contain the {zip} placeholder."); diff --git a/src/MarcerGameDvdLauncher/MarcerGameDvd-Hatari.cfg b/src/MarcerGameDvdLauncher/MarcerGameDvd-Hatari.cfg index 323038b..160dd53 100644 --- a/src/MarcerGameDvdLauncher/MarcerGameDvd-Hatari.cfg +++ b/src/MarcerGameDvdLauncher/MarcerGameDvd-Hatari.cfg @@ -11,12 +11,14 @@ bConsoleWindow = FALSE nNumberBase = 10 nSymbolLines = -1 nMemdumpLines = -1 +nFindLines = -1 nDisasmLines = -1 nBacktraceLines = 0 nExceptionDebugMask = 1073741830 nDisasmOptions = 7 +nMemConvLocale = FALSE bDisasmUAE = TRUE -bSymbolsAutoLoad = TRUE +nSymbolsAutoLoad = 1 bMatchAllSymbols = FALSE [Screen] @@ -42,13 +44,14 @@ nMaxHeight = 1024 nZoomFactor = 3 bUseSdlRenderer = FALSE ScreenShotFormat = 2 +szScreenShotDir = bUseVsync = FALSE [Joystick0] nJoystickMode = 0 bEnableAutoFire = FALSE bEnableJumpOnFire2 = TRUE -nJoyId = -1 +nJoyId = 0 nJoyBut1Index = 0 nJoyBut2Index = 1 nJoyBut3Index = 2 @@ -76,7 +79,7 @@ kFire = Right Ctrl nJoystickMode = 0 bEnableAutoFire = FALSE bEnableJumpOnFire2 = TRUE -nJoyId = -1 +nJoyId = 0 nJoyBut1Index = 0 nJoyBut2Index = 1 nJoyBut3Index = 2 @@ -106,7 +109,7 @@ kButton9 = 9 nJoystickMode = 0 bEnableAutoFire = FALSE bEnableJumpOnFire2 = TRUE -nJoyId = -1 +nJoyId = 0 nJoyBut1Index = 0 nJoyBut2Index = 1 nJoyBut3Index = 2 @@ -136,7 +139,7 @@ kButton9 = nJoystickMode = 0 bEnableAutoFire = FALSE bEnableJumpOnFire2 = TRUE -nJoyId = -1 +nJoyId = 0 nJoyBut1Index = 0 nJoyBut2Index = 1 nJoyBut3Index = 2 @@ -150,7 +153,7 @@ kFire = Right Ctrl nJoystickMode = 0 bEnableAutoFire = FALSE bEnableJumpOnFire2 = TRUE -nJoyId = -1 +nJoyId = 0 nJoyBut1Index = 0 nJoyBut2Index = 1 nJoyBut3Index = 2 @@ -161,7 +164,7 @@ kRight = Right kFire = Right Ctrl [Keyboard] -bDisableKeyRepeat = FALSE +bFastForwardKeyRepeat = TRUE nKeymapType = 0 nCountryCode = -1 nKbdLayout = -1 @@ -224,7 +227,7 @@ bEnableSound = TRUE bEnableSoundSync = FALSE nPlaybackFreq = 44100 nSdlAudioBufferSize = 0 -szYMCaptureFileName = +szYMCaptureFileName = YmVolumeMixing = 2 [Memory] @@ -232,7 +235,7 @@ nMemorySize = 1024 nTTRamSize = 28672 bAutoSave = FALSE szMemoryCaptureFileName = -szAutoSaveFileName = +szAutoSaveFileName = [Floppy] bAutoInsertDiskB = FALSE @@ -246,19 +249,23 @@ szDiskAZipPath = szDiskAFileName = szDiskBZipPath = szDiskBFileName = -szDiskImageDirectory = +szDiskImageDirectory = [HardDisk] nGemdosDrive = 0 bBootFromHardDisk = FALSE bUseHardDiskDirectory = FALSE -szHardDiskDirectory = R:\ +szHardDiskDirectory = R: nGemdosCase = 0 nWriteProtection = 0 bFilenameConversion = FALSE bGemdosHostTime = FALSE [ACSI] +bUseDevice0 = FALSE +sDeviceFile0 = +nBlockSize0 = 512 +nAcsiVersion0 = 1 [SCSI] @@ -266,6 +273,7 @@ bGemdosHostTime = FALSE [IDE] + [ROM] szTosImageFileName = TOS.IMG bPatchTos = TRUE @@ -273,35 +281,35 @@ szCartridgeImageFileName = [LILO] Args = root=/dev/ram video=atafb:vga16 load_ramdisk=1 -Kernel = +Kernel = Symbols = -Ramdisk = +Ramdisk = HaltOnReboot = TRUE KernelToFastRam = TRUE RamdiskToFastRam = TRUE [RS232] bEnableRS232 = FALSE -szOutFileName = -szInFileName = +szOutFileName = +szInFileName = EnableSccA = FALSE -SccAOutFileName = -SccAInFileName = +SccAOutFileName = +SccAInFileName = EnableSccALan = FALSE -SccALanOutFileName = -SccALanInFileName = +SccALanOutFileName = +SccALanInFileName = EnableSccB = FALSE -SccBOutFileName = -SccBInFileName = +SccBOutFileName = +SccBInFileName = [Printer] bEnablePrinting = FALSE -szPrintToFileName = +szPrintToFileName = [Midi] bEnableMidi = FALSE -sMidiInFileName = -sMidiOutFileName = +sMidiInFileName = +sMidiOutFileName = sMidiInPortName = Off sMidiOutPortName = Off @@ -312,13 +320,13 @@ bCompatibleCpu = TRUE nModelType = 0 bBlitter = FALSE nDSPType = 0 -nVMEType = 1 nRtcYear = 0 bPatchTimerD = FALSE bFastBoot = FALSE bFastForward = FALSE bAddressSpace24 = TRUE bCycleExactCpu = TRUE +bCpuDataCache = TRUE n_FPUType = 0 bSoftFloatFPU = FALSE bMMU = TRUE @@ -328,3 +336,4 @@ VideoTiming = 3 AviRecordVcodec = 2 AviRecordFps = 0 AviRecordFile = +