diff --git a/BizHawk.Client.Common/PathManager.cs b/BizHawk.Client.Common/PathManager.cs index c908157956..465dacb381 100644 --- a/BizHawk.Client.Common/PathManager.cs +++ b/BizHawk.Client.Common/PathManager.cs @@ -13,6 +13,11 @@ namespace BizHawk.Client.Common { public static class PathManager { + static PathManager() + { + SetDefaultIniPath(MakeProgramRelativePath("config.ini")); + } + public static string GetExeDirectoryAbsolute() { var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); @@ -40,7 +45,12 @@ namespace BizHawk.Client.Common /// /// The location of the default INI file /// - public static string DefaultIniPath => MakeProgramRelativePath("config.ini"); + public static string DefaultIniPath { get; private set; } + + public static void SetDefaultIniPath(string newDefaultIniPath) + { + DefaultIniPath = newDefaultIniPath; + } /// /// Gets absolute base as derived from EXE diff --git a/BizHawk.Client.EmuHawk/ArgParser.cs b/BizHawk.Client.EmuHawk/ArgParser.cs index 0912c68ba9..6c4823af50 100644 --- a/BizHawk.Client.EmuHawk/ArgParser.cs +++ b/BizHawk.Client.EmuHawk/ArgParser.cs @@ -14,6 +14,8 @@ namespace BizHawk.Client.EmuHawk public string cmdRom = null; public string cmdLoadSlot = null; public string cmdLoadState = null; + public string cmdConfigPath = null; + public string cmdConfigFile = null; public string cmdMovie = null; public string cmdDumpType = null; public string cmdDumpName = null; @@ -55,6 +57,10 @@ namespace BizHawk.Client.EmuHawk { cmdLoadState = args[i].Substring(args[i].IndexOf('=') + 1); } + if (arg.StartsWith("--config=")) + { + cmdConfigFile = args[i].Substring(args[i].IndexOf('=') + 1); + } else if (arg.StartsWith("--movie=")) { cmdMovie = args[i].Substring(args[i].IndexOf('=') + 1); diff --git a/BizHawk.Client.EmuHawk/MainForm.Events.cs b/BizHawk.Client.EmuHawk/MainForm.Events.cs index 314c2adaaa..e47ce7a138 100644 --- a/BizHawk.Client.EmuHawk/MainForm.Events.cs +++ b/BizHawk.Client.EmuHawk/MainForm.Events.cs @@ -2782,7 +2782,7 @@ namespace BizHawk.Client.EmuHawk showMenuVisible = true; // need to always be able to restore this as an emergency measure } - if (argParse._chromeless) + if (argParser._chromeless) { showMenuVisible = true; // I decided this was always possible in chromeless mode, we'll see what they think } diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index 2cc7539c80..626e98fe2b 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -154,7 +154,7 @@ namespace BizHawk.Client.EmuHawk } }; - argParse.ParseArguments(args); + argParser.ParseArguments(args); Database.LoadDatabase(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "gamedb.txt")); @@ -270,14 +270,14 @@ namespace BizHawk.Client.EmuHawk Location = new Point(Global.Config.MainWndx, Global.Config.MainWndy); } - if (argParse.cmdRom != null) + if (argParser.cmdRom != null) { // Commandline should always override auto-load - var ioa = OpenAdvancedSerializer.ParseWithLegacy(argParse.cmdRom); - LoadRom(argParse.cmdRom, new LoadRomArgs { OpenAdvanced = ioa }); + var ioa = OpenAdvancedSerializer.ParseWithLegacy(argParser.cmdRom); + LoadRom(argParser.cmdRom, new LoadRomArgs { OpenAdvanced = ioa }); if (Global.Game == null) { - MessageBox.Show("Failed to load " + argParse.cmdRom + " specified on commandline"); + MessageBox.Show("Failed to load " + argParser.cmdRom + " specified on commandline"); } } else if (Global.Config.RecentRoms.AutoLoad && !Global.Config.RecentRoms.Empty) @@ -285,7 +285,7 @@ namespace BizHawk.Client.EmuHawk LoadRomFromRecent(Global.Config.RecentRoms.MostRecent); } - if (argParse.cmdMovie != null) + if (argParser.cmdMovie != null) { _supressSyncSettingsWarning = true; // We dont' want to be nagged if we are attempting to automate if (Global.Game == null) @@ -296,21 +296,21 @@ namespace BizHawk.Client.EmuHawk // If user picked a game, then do the commandline logic if (!Global.Game.IsNullInstance) { - var movie = MovieService.Get(argParse.cmdMovie); + var movie = MovieService.Get(argParser.cmdMovie); Global.MovieSession.ReadOnly = true; // if user is dumping and didnt supply dump length, make it as long as the loaded movie - if (argParse._autoDumpLength == 0) + if (argParser._autoDumpLength == 0) { - argParse._autoDumpLength = movie.InputLogLength; + argParser._autoDumpLength = movie.InputLogLength; } // Copy pasta from drag & drop - if (MovieImport.IsValidMovieExtension(Path.GetExtension(argParse.cmdMovie))) + if (MovieImport.IsValidMovieExtension(Path.GetExtension(argParser.cmdMovie))) { string errorMsg; string warningMsg; - var imported = MovieImport.ImportFile(argParse.cmdMovie, out errorMsg, out warningMsg); + var imported = MovieImport.ImportFile(argParser.cmdMovie, out errorMsg, out warningMsg); if (!string.IsNullOrEmpty(errorMsg)) { MessageBox.Show(errorMsg, "Conversion error", MessageBoxButtons.OK, MessageBoxIcon.Error); @@ -328,7 +328,7 @@ namespace BizHawk.Client.EmuHawk else { StartNewMovie(movie, false); - Global.Config.RecentMovies.Add(argParse.cmdMovie); + Global.Config.RecentMovies.Add(argParser.cmdMovie); } _supressSyncSettingsWarning = false; @@ -355,20 +355,20 @@ namespace BizHawk.Client.EmuHawk } } - if (argParse.startFullscreen || Global.Config.StartFullscreen) + if (argParser.startFullscreen || Global.Config.StartFullscreen) { _needsFullscreenOnLoad = true; } if (!Global.Game.IsNullInstance) { - if (argParse.cmdLoadState != null) + if (argParser.cmdLoadState != null) { - LoadState(argParse.cmdLoadState, Path.GetFileName(argParse.cmdLoadState)); + LoadState(argParser.cmdLoadState, Path.GetFileName(argParser.cmdLoadState)); } - else if (argParse.cmdLoadSlot != null) + else if (argParser.cmdLoadSlot != null) { - LoadQuickSave("QuickSave" + argParse.cmdLoadSlot); + LoadQuickSave("QuickSave" + argParser.cmdLoadSlot); } else if (Global.Config.AutoLoadLastSaveSlot) { @@ -377,14 +377,14 @@ namespace BizHawk.Client.EmuHawk } //start Lua Console if requested in the command line arguments - if (argParse.luaConsole) + if (argParser.luaConsole) { GlobalWin.Tools.Load(); } //load Lua Script if requested in the command line arguments - if (argParse.luaScript != null) + if (argParser.luaScript != null) { - GlobalWin.Tools.LuaConsole.LoadLuaFile(argParse.luaScript); + GlobalWin.Tools.LuaConsole.LoadLuaFile(argParser.luaScript); } GlobalWin.Tools.AutoLoad(); @@ -407,9 +407,9 @@ namespace BizHawk.Client.EmuHawk } // start dumping, if appropriate - if (argParse.cmdDumpType != null && argParse.cmdDumpName != null) + if (argParser.cmdDumpType != null && argParser.cmdDumpName != null) { - RecordAv(argParse.cmdDumpType, argParse.cmdDumpName); + RecordAv(argParser.cmdDumpType, argParser.cmdDumpName); } SetMainformMovieInfo(); @@ -1023,15 +1023,15 @@ namespace BizHawk.Client.EmuHawk { // TODO - maybe apply a hack tracked during fullscreen here to override it FormBorderStyle = FormBorderStyle.None; - MainMenuStrip.Visible = Global.Config.DispChrome_MenuFullscreen && !argParse._chromeless; - MainStatusBar.Visible = Global.Config.DispChrome_StatusBarFullscreen && !argParse._chromeless; + MainMenuStrip.Visible = Global.Config.DispChrome_MenuFullscreen && !argParser._chromeless; + MainStatusBar.Visible = Global.Config.DispChrome_StatusBarFullscreen && !argParser._chromeless; } else { - MainStatusBar.Visible = Global.Config.DispChrome_StatusBarWindowed && !argParse._chromeless; - MainMenuStrip.Visible = Global.Config.DispChrome_MenuWindowed && !argParse._chromeless; - MaximizeBox = MinimizeBox = Global.Config.DispChrome_CaptionWindowed && !argParse._chromeless; - if (Global.Config.DispChrome_FrameWindowed == 0 || argParse._chromeless) + MainStatusBar.Visible = Global.Config.DispChrome_StatusBarWindowed && !argParser._chromeless; + MainMenuStrip.Visible = Global.Config.DispChrome_MenuWindowed && !argParser._chromeless; + MaximizeBox = MinimizeBox = Global.Config.DispChrome_CaptionWindowed && !argParser._chromeless; + if (Global.Config.DispChrome_FrameWindowed == 0 || argParser._chromeless) { FormBorderStyle = FormBorderStyle.None; } @@ -1401,7 +1401,7 @@ namespace BizHawk.Client.EmuHawk private int _lastOpenRomFilter; - private ArgParser argParse = new ArgParser(); + private ArgParser argParser = new ArgParser(); // Resources private Bitmap _statusBarDiskLightOnImage; private Bitmap _statusBarDiskLightOffImage; @@ -1470,7 +1470,7 @@ namespace BizHawk.Client.EmuHawk } } - if (!Global.Config.DispChrome_CaptionWindowed || argParse._chromeless) + if (!Global.Config.DispChrome_CaptionWindowed || argParser._chromeless) { str = ""; } @@ -3368,9 +3368,9 @@ namespace BizHawk.Client.EmuHawk try { // is this the best time to handle this? or deeper inside? - if (argParse._currAviWriterFrameList != null) + if (argParser._currAviWriterFrameList != null) { - if (!argParse._currAviWriterFrameList.Contains(Emulator.Frame)) + if (!argParser._currAviWriterFrameList.Contains(Emulator.Frame)) { goto HANDLE_AUTODUMP; } @@ -3453,13 +3453,13 @@ namespace BizHawk.Client.EmuHawk } HANDLE_AUTODUMP: - if (argParse._autoDumpLength > 0) + if (argParser._autoDumpLength > 0) { - argParse._autoDumpLength--; - if (argParse._autoDumpLength == 0) // finish + argParser._autoDumpLength--; + if (argParser._autoDumpLength == 0) // finish { StopAv(); - if (argParse._autoCloseOnDump) + if (argParser._autoCloseOnDump) { _exitRequestPending = true; } diff --git a/BizHawk.Client.EmuHawk/Program.cs b/BizHawk.Client.EmuHawk/Program.cs index 051f48faeb..8321603006 100644 --- a/BizHawk.Client.EmuHawk/Program.cs +++ b/BizHawk.Client.EmuHawk/Program.cs @@ -284,19 +284,20 @@ namespace BizHawk.Client.EmuHawk BizHawk.Common.TempFileManager.Start(); - HawkFile.ArchiveHandlerFactory = new SevenZipSharpArchiveHandler(); - string iniPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "config.ini"); + ArgParser argParser = new ArgParser(); + argParser.ParseArguments(args); + if (argParser.cmdConfigFile != null) PathManager.SetDefaultIniPath(argParser.cmdConfigFile); try { - Global.Config = ConfigService.Load(iniPath); + Global.Config = ConfigService.Load(PathManager.DefaultIniPath); } catch (Exception e) { new ExceptionBox(e).ShowDialog(); new ExceptionBox("Since your config file is corrupted, we're going to recreate it. Back it up before proceeding if you want to investigate further.").ShowDialog(); - File.Delete(iniPath); - Global.Config = ConfigService.Load(iniPath); + File.Delete(PathManager.DefaultIniPath); + Global.Config = ConfigService.Load(PathManager.DefaultIniPath); } Global.Config.ResolveDefaults(); diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs index 2532554bc7..a809042862 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs @@ -480,6 +480,31 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk mapper.RTC_Get((byte)(remaining & 0xFF), 0); } + + if (mppr == "HuC3") + { + Use_MT = true; + + int years = (int)Math.Floor(_syncSettings.RTCInitialTime / 31536000.0); + + mapper.RTC_Get((byte)years, 24); + + int remaining = _syncSettings.RTCInitialTime - (years * 31536000); + + int days = (int)Math.Floor(remaining / 86400.0); + int days_upper = (days >> 8) & 0xF; + + mapper.RTC_Get((byte)days_upper, 20); + mapper.RTC_Get((byte)(days & 0xFF), 12); + + remaining = remaining - (days * 86400); + + int minutes = (int)Math.Floor(remaining / 60.0); + int minutes_upper = (minutes >> 8) & 0xF; + + mapper.RTC_Get((byte)(minutes_upper), 8); + mapper.RTC_Get((byte)(remaining & 0xFF), 0); + } } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_HuC3.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_HuC3.cs index dab71a0b4b..88029763c2 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_HuC3.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_HuC3.cs @@ -1,55 +1,140 @@ -using BizHawk.Common; -using BizHawk.Common.NumberExtensions; -using System; +using System; +using BizHawk.Common; using BizHawk.Emulation.Common.Components.LR35902; namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { - // Default mapper with no bank switching + // Hudson HuC3 used with Robopon and others public class MapperHuC3 : MapperBase { + public int ROM_bank; + public int RAM_bank; + public bool RAM_enable; + public int ROM_mask; + public int RAM_mask; + public bool IR_signal; + public byte control; + public byte chip_read; + public bool timer_read; + public int time_val_shift; + public uint time; + public int RTC_timer; + public int RTC_low_clock; + public int RTC_seconds; + public override void Initialize() { - // nothing to initialize + ROM_bank = 0; + RAM_bank = 0; + RAM_enable = false; + ROM_mask = Core._rom.Length / 0x4000 - 1; + control = 0; + chip_read = 1; + timer_read = false; + time_val_shift = 0; + + // some games have sizes that result in a degenerate ROM, account for it here + if (ROM_mask > 4) { ROM_mask |= 3; } + + RAM_mask = 0; + if (Core.cart_RAM != null) + { + RAM_mask = Core.cart_RAM.Length / 0x2000 - 1; + if (Core.cart_RAM.Length == 0x800) { RAM_mask = 0; } + } } public override byte ReadMemory(ushort addr) { - if (addr < 0x8000) + if (addr < 0x4000) { return Core._rom[addr]; } - else + else if (addr < 0x8000) { - if (Core.cart_RAM != null) + return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000]; + } + else if ((addr >= 0xA000) && (addr < 0xC000)) + { + if ((control >= 0xB) && (control < 0xE)) { - return Core.cart_RAM[addr - 0xA000]; + if (control == 0xD) + { + return 1; + } + return chip_read; + } + + if (RAM_enable) + { + if (Core.cart_RAM != null) + { + if (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length) + { + return Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000]; + } + else + { + return 0xFF; + } + } + else + { + return 0xFF; + } } else { - return 0; + // what to return if RAM not enabled and controller not selected? + return 0xFF; } } + else + { + return 0xFF; + } } public override void MapCDL(ushort addr, LR35902.eCDLogMemFlags flags) { - if (addr < 0x8000) + if (addr < 0x4000) { SetCDLROM(flags, addr); } - else + else if (addr < 0x8000) { - if (Core.cart_RAM != null) + SetCDLROM(flags, (addr - 0x4000) + ROM_bank * 0x4000); + } + else if ((addr >= 0xA000) && (addr < 0xC000)) + { + if (RAM_enable) { - SetCDLRAM(flags, addr - 0xA000); + if (Core.cart_RAM != null) + { + if (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length) + { + SetCDLRAM(flags, (addr - 0xA000) + RAM_bank * 0x2000); + } + else + { + return; + } + } + else + { + return; + } } else { return; } } + else + { + return; + } } public override byte PeekMemory(ushort addr) @@ -61,20 +146,158 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { if (addr < 0x8000) { - // no mapping hardware available + if (addr < 0x2000) + { + RAM_enable = (value & 0xA) == 0xA; + control = value; + } + else if (addr < 0x4000) + { + if (value == 0) { value = 1; } + + ROM_bank = value; + ROM_bank &= ROM_mask; + } + else if (addr < 0x6000) + { + RAM_bank = value; + RAM_bank &= 0xF; + RAM_bank &= RAM_mask; + } } else { - if (Core.cart_RAM != null) + if (RAM_enable && ((control < 0xB) || (control > 0xE))) { - Core.cart_RAM[addr - 0xA000] = value; + if (Core.cart_RAM != null) + { + if (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length) + { + Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000] = value; + } + } + } + + if (control == 0xB) + { + switch (value & 0xF0) + { + case 0x10: + if (timer_read) + { + // return timer value + chip_read = (byte)((time >> time_val_shift) & 0xF); + time_val_shift += 4; + if (time_val_shift == 28) { time_val_shift = 0; } + } + break; + case 0x20: + break; + case 0x30: + if (!timer_read) + { + // write to timer + if (time_val_shift == 0) { time = 0; } + if (time_val_shift < 28) + { + time |= (uint)((value & 0x0F) << time_val_shift); + time_val_shift += 4; + if (time_val_shift == 28) { timer_read = true; } + } + } + break; + case 0x40: + // other commands + switch (value & 0xF) + { + case 0x0: + time_val_shift = 0; + break; + case 0x3: + timer_read = false; + time_val_shift = 0; + break; + case 0x7: + timer_read = true; + time_val_shift = 0; + break; + case 0xF: + break; + } + break; + case 0x50: + break; + case 0x60: + timer_read = true; + break; + } + } + else if (control == 0xC) + { + // maybe IR + } + else if (control == 0xD) + { + // maybe IR } } } - public override void PokeMemory(ushort addr, byte value) + public override void RTC_Get(byte value, int index) { - WriteMemory(addr, value); + time |= (uint)((value & 0xFF) << index); + } + + public override void Mapper_Tick() + { + RTC_timer++; + + if (RTC_timer == 128) + { + RTC_timer = 0; + + RTC_low_clock++; + + if (RTC_low_clock == 32768) + { + RTC_low_clock = 0; + + RTC_seconds++; + if (RTC_seconds > 59) + { + RTC_seconds = 0; + time++; + if ((time & 0xFFF) > 1439) + { + time -= 1440; + time += (1 << 12); + if ((time >> 12) > 365) + { + time -= (365 << 12); + time += (1 << 24); + } + } + } + } + } + } + + public override void SyncState(Serializer ser) + { + ser.Sync("ROM_Bank", ref ROM_bank); + ser.Sync("ROM_Mask", ref ROM_mask); + ser.Sync("RAM_Bank", ref RAM_bank); + ser.Sync("RAM_Mask", ref RAM_mask); + ser.Sync("RAM_enable", ref RAM_enable); + ser.Sync("IR_signal", ref IR_signal); + ser.Sync("control", ref control); + ser.Sync("chip_read", ref chip_read); + ser.Sync("timer_read", ref timer_read); + ser.Sync("time_val_shift", ref time_val_shift); + ser.Sync("time", ref time); + ser.Sync("RTC_timer", ref RTC_timer); + ser.Sync("RTC_low_clock", ref RTC_low_clock); + ser.Sync("RTC_seconds", ref RTC_seconds); } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ITraceable.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ITraceable.cs index dfddf14bc7..377a6ab7be 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ITraceable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ITraceable.cs @@ -23,12 +23,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx { var regs = DebuggableCore.GetCpuFlagsAndRegisters(); uint pc = (uint)regs["M68K PC"].Value; - var length = 0; - var disasm = Disassembler.Disassemble(MemoryDomains.SystemBus, pc & 0xFFFFFF, out length); + var disasm = Disassembler.Disassemble(MemoryDomains.SystemBus, pc & 0xFFFFFF, out int length); var traceInfo = new TraceInfo { - Disassembly = string.Format("{0:X6}: {1}", pc, disasm) + Disassembly = string.Format("{0:X6}: {1}", pc, disasm).PadRight(50) }; var sb = new StringBuilder(); diff --git a/output/dll/mupen64plus-video-GLideN64.dll b/output/dll/mupen64plus-video-GLideN64.dll index 054dc854c1..c8eb531227 100644 Binary files a/output/dll/mupen64plus-video-GLideN64.dll and b/output/dll/mupen64plus-video-GLideN64.dll differ