From 0c8c5f81c6acb48bdbb551d97c9d4932b66d612a Mon Sep 17 00:00:00 2001 From: hegyak Date: Sun, 15 Nov 2015 06:25:55 -0800 Subject: [PATCH 01/20] Added N64 GameShark Support. --- BizHawk.Client.EmuHawk/tools/GameShark.cs | 160 +++++++++++++++++----- 1 file changed, 124 insertions(+), 36 deletions(-) diff --git a/BizHawk.Client.EmuHawk/tools/GameShark.cs b/BizHawk.Client.EmuHawk/tools/GameShark.cs index 3ac98d6e56..48bf36e68c 100644 --- a/BizHawk.Client.EmuHawk/tools/GameShark.cs +++ b/BizHawk.Client.EmuHawk/tools/GameShark.cs @@ -6,12 +6,14 @@ using System.Globalization; namespace BizHawk.Client.EmuHawk { - [ToolAttributes(released: true, supportedSystems: new[] { "GB" })] + [ToolAttributes(released: true, supportedSystems: new[] { "GB", "N64" })] public partial class GameShark : Form, IToolForm, IToolFormAutoConfig { //We are using Memory Domains, so we NEED this. [RequiredService] private IMemoryDomains MemoryDomains { get; set; } + [RequiredService] + private IEmulator Emulator { get; set; } public GameShark() { InitializeComponent(); @@ -47,44 +49,128 @@ namespace BizHawk.Client.EmuHawk private void btnGo_Click(object sender, EventArgs e) { - //This line ONLY applies to GB/GBC codes. - if (txtCheat.Text.Length != 8) - { - MessageBox.Show("All GameShark and CodeBreaker cheats need to be Eight characters in Length", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - //Sample Input for GB/GBC: - //010FF6C1 - //Becomes: - //Address C1F6 - //Value 0F string parseString = null; string RAMAddress = null; string RAMValue = null; - parseString = txtCheat.Text.Remove(0, 2); - //Now we need to break it down a little more. - RAMValue = parseString.Remove(2, 4); - parseString = parseString.Remove(0, 2); - //The issue is Endian... Time to get ultra clever. And Regret it. - //First Half - RAMAddress = parseString.Remove(0, 2); - RAMAddress = RAMAddress + parseString.Remove(2, 2); - //We now have our values. - //This part, is annoying... - try + //What System are we running? + switch (Emulator.SystemId) { - //A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works. - //System Bus Domain, The Address to Watch, Byte size (Byte), Hex Display, Description. Not Big Endian. - var watch = Watch.GenerateWatch(MemoryDomains["System Bus"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, false); - //Take Watch, Add our Value we want, and it should be active when addded? - Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); - //Clear old Inputs - txtCheat.Clear(); - txtDescription.Clear(); - } - catch (Exception ex) - { - MessageBox.Show("An Error occured:" + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + case "GB": + //This Check ONLY applies to GB/GBC codes. + if (txtCheat.Text.Length != 8) + { + MessageBox.Show("All GameShark cheats need to be Eight characters in Length", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + //Sample Input for GB/GBC: + //010FF6C1 + //Becomes: + //Address C1F6 + //Value 0F + + parseString = txtCheat.Text.Remove(0, 2); + //Now we need to break it down a little more. + RAMValue = parseString.Remove(2, 4); + parseString = parseString.Remove(0, 2); + //The issue is Endian... Time to get ultra clever. And Regret it. + //First Half + RAMAddress = parseString.Remove(0, 2); + RAMAddress = RAMAddress + parseString.Remove(2, 2); + //We now have our values. + //This part, is annoying... + try + { + //A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works. + //System Bus Domain, The Address to Watch, Byte size (Byte), Hex Display, Description. Not Big Endian. + var watch = Watch.GenerateWatch(MemoryDomains["System Bus"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, false); + //Take Watch, Add our Value we want, and it should be active when addded? + Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); + //Clear old Inputs + txtCheat.Clear(); + txtDescription.Clear(); + } + //Someone broke the world? + catch (Exception ex) + { + MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + break; + case "N64": + //N64 Cheats are going be more, limited/restricted. I am NOT going to support the non-8XXXXXXX YYYY style of codes. That's too much work/hassle. + //TODO: Find someone to impliment the Non-8XXXXXXX YYYY style of codes Or Ignore them all together? + //I think they can in theory work with straight conversion as written? + if (txtCheat.Text.Contains(" ") == false) + { + MessageBox.Show("All N64 GameShark Cheats need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + //Big Endian is USED constantly here. The question is, how do we determine if it's one or two bytes? + if (txtCheat.Text.StartsWith("8") == false) + { + MessageBox.Show("All N64 GameShark Cheats need to start with the number 8.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (txtCheat.Text.Length != 13) + { + MessageBox.Show("All N64 GameShark Cheats need to be 13 characters in length.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + //Now to get clever. + //Sample Input for N64: + //8133B21E 08FF + //Becomes: + //Address 33B21E + //Value 08FF + + //Note, 8XXXXXXX 00YY + //Is Byte, not Word + //Remove the 8X Octect + parseString = txtCheat.Text.Remove(0, 2); + //Get RAM Address + RAMAddress = parseString.Remove(6, 5); + //Get RAM Value + RAMValue = parseString.Remove(0, 7); + //I need to determine if this is a Byte or Word. + //TODO: Make this suck less? I feel it's sloppy as is and it may be false-postive. + Boolean isByte = false; + string firstTwo = null; + firstTwo = RAMValue.Remove(2, 2); + //MessageBox.Show(firstTwo); + if (firstTwo == "00") + { + isByte = true; + } + try + { + //A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works. + //System Bus Domain, The Address to Watch, Byte size (Word), Hex Display, Description. Big Endian. + if (isByte == false) + { + //We have a Word (Double Byte) sized Value + var watch = Watch.GenerateWatch(MemoryDomains["RDRAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Word, Watch.DisplayType.Hex, txtDescription.Text, true); + //Take Watch, Add our Value we want, and it should be active when addded? + Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); + } + if (isByte == true) + { + //We have a Byte sized value + var watch = Watch.GenerateWatch(MemoryDomains["RDRAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, true); + //Take Watch, Add our Value we want, and it should be active when addded? + Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); + } + //Clear old Inputs + txtCheat.Clear(); + txtDescription.Clear(); + } + //Someone broke the world? + catch (Exception ex) + { + MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + break; + default: + //This should NEVER happen + break; } } @@ -97,7 +183,9 @@ namespace BizHawk.Client.EmuHawk private void GameShark_Load(object sender, EventArgs e) { - + //Welp, let's determine what System we got. + //NOTE: This is a sloppy Debugger/testing code. For Bad Development usage. DO NOT release with that line uncommented + //MessageBox.Show(Emulator.SystemId); } } } From afa4ec30b677e1fc055d78fa6511f88cf7fbc43b Mon Sep 17 00:00:00 2001 From: hegyak Date: Sun, 15 Nov 2015 11:09:55 -0800 Subject: [PATCH 02/20] Clean up GB/GBC GameShark Handling. Improve N64 Code Recognition. --- BizHawk.Client.EmuHawk/tools/GameShark.cs | 76 ++++++++++++++++++++--- 1 file changed, 69 insertions(+), 7 deletions(-) diff --git a/BizHawk.Client.EmuHawk/tools/GameShark.cs b/BizHawk.Client.EmuHawk/tools/GameShark.cs index 48bf36e68c..55060f7f1c 100644 --- a/BizHawk.Client.EmuHawk/tools/GameShark.cs +++ b/BizHawk.Client.EmuHawk/tools/GameShark.cs @@ -53,6 +53,8 @@ namespace BizHawk.Client.EmuHawk string RAMAddress = null; string RAMValue = null; //What System are we running? + //We want Upper Case. + txtCheat.Text = txtCheat.Text.ToUpper(); switch (Emulator.SystemId) { case "GB": @@ -62,6 +64,12 @@ namespace BizHawk.Client.EmuHawk MessageBox.Show("All GameShark cheats need to be Eight characters in Length", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } + //Let's make sure we start with zero. We have a good length, and a good starting zero, we should be good. Hopefully. + if (txtCheat.Text.StartsWith("0") == false) + { + MessageBox.Show("All GameShark cheats for GameBoy need to start with the number 0", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } //Sample Input for GB/GBC: //010FF6C1 //Becomes: @@ -97,24 +105,75 @@ namespace BizHawk.Client.EmuHawk break; case "N64": //N64 Cheats are going be more, limited/restricted. I am NOT going to support the non-8XXXXXXX YYYY style of codes. That's too much work/hassle. - //TODO: Find someone to impliment the Non-8XXXXXXX YYYY style of codes Or Ignore them all together? //I think they can in theory work with straight conversion as written? if (txtCheat.Text.Contains(" ") == false) { MessageBox.Show("All N64 GameShark Cheats need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } - //Big Endian is USED constantly here. The question is, how do we determine if it's one or two bytes? - if (txtCheat.Text.StartsWith("8") == false) - { - MessageBox.Show("All N64 GameShark Cheats need to start with the number 8.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } if (txtCheat.Text.Length != 13) { MessageBox.Show("All N64 GameShark Cheats need to be 13 characters in length.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } + //We need to determine what kind of cheat this is. + string testo = txtCheat.Text.Remove(2, 11); + //MessageBox.Show(testo); + switch (testo) + { + //80 and 81 are the most common, so let's not get all worried. + case "80": + break; + case "81": + break; + //Case A0 and A1 means "Write to Uncached address. + case "A0": + break; + case "A1": + break; + //Do we support the GameShark Button? No. But these cheats, can be toggled. Which "Counts" + // Consequences be damned! + case "88": + break; + case "89": + break; + //These are compare Address X to Value Y, then apply Value B to Address A + //This is not supported, yet + //TODO: When BizHawk supports a compare RAM Address's value is true then apply a value to another address, make it a thing. + case "D0": + case "D1": + case "D2": + case "D3": + MessageBox.Show("The code you entered is not supported by BizHawk.", "Emulator Error", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + //These codes are for Disabling the Expansion Pak. that's a bad thing? Assuming bad codes, until told otherwise. + case "EE": + case "DD": + case "CC": + MessageBox.Show("The code you entered is for Disabling the Expansion Pak. This is not allowed.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + //Enable Code + //Not Necessary? Think so? + case "DE": + //Single Write ON-Boot code. + //Not Necessary? Think so? + case "F0": + case "F1": + case "2A": + MessageBox.Show("The code you entered is not needed by Bizhawk.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + //TODO: Make Patch Code (5000XXYY) work. + case "50": + MessageBox.Show("The code you entered is not supported by this tool. Please Submit the Game's Name, Cheat/Code and Purpose to the BizHawk forums.", "Tool Error", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + //I hope this isn't a thing. + default: + MessageBox.Show("The GameShark code entered is not a recognized format.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + //Leave this Method, before someone gets hurt. + return; + //break; + } + //Big Endian is USED constantly here. The question is, how do we determine if it's one or two bytes? //Now to get clever. //Sample Input for N64: //8133B21E 08FF @@ -168,6 +227,9 @@ namespace BizHawk.Client.EmuHawk MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } break; + case "PSX": + //Not yet. + break; default: //This should NEVER happen break; From 3596407791e58c2d3f983d3a1a15a2701d4adf52 Mon Sep 17 00:00:00 2001 From: hegyak Date: Sun, 15 Nov 2015 11:37:30 -0800 Subject: [PATCH 03/20] Changed the Byte Detection method for N46 Cheats. --- BizHawk.Client.EmuHawk/tools/GameShark.cs | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/BizHawk.Client.EmuHawk/tools/GameShark.cs b/BizHawk.Client.EmuHawk/tools/GameShark.cs index 55060f7f1c..afb695879c 100644 --- a/BizHawk.Client.EmuHawk/tools/GameShark.cs +++ b/BizHawk.Client.EmuHawk/tools/GameShark.cs @@ -117,19 +117,28 @@ namespace BizHawk.Client.EmuHawk return; } //We need to determine what kind of cheat this is. + //I need to determine if this is a Byte or Word. + Boolean isByte = false; string testo = txtCheat.Text.Remove(2, 11); - //MessageBox.Show(testo); switch (testo) { //80 and 81 are the most common, so let's not get all worried. case "80": - break; + //Byte + isByte = true; + break; case "81": + //Word + isByte = false; break; //Case A0 and A1 means "Write to Uncached address. case "A0": + //Byte + isByte = true; break; case "A1": + //Word + isByte = false; break; //Do we support the GameShark Button? No. But these cheats, can be toggled. Which "Counts" // Consequences be damned! @@ -189,16 +198,7 @@ namespace BizHawk.Client.EmuHawk RAMAddress = parseString.Remove(6, 5); //Get RAM Value RAMValue = parseString.Remove(0, 7); - //I need to determine if this is a Byte or Word. - //TODO: Make this suck less? I feel it's sloppy as is and it may be false-postive. - Boolean isByte = false; - string firstTwo = null; - firstTwo = RAMValue.Remove(2, 2); - //MessageBox.Show(firstTwo); - if (firstTwo == "00") - { - isByte = true; - } + try { //A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works. From 59766d07c08ab479d32c3c13d14d935b11b27c40 Mon Sep 17 00:00:00 2001 From: hegyak Date: Sun, 15 Nov 2015 12:25:32 -0800 Subject: [PATCH 04/20] Further Cleaned up the GameShark N64 Code Behaviors. Byte and Word Recognized. --- BizHawk.Client.EmuHawk/tools/GameShark.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/BizHawk.Client.EmuHawk/tools/GameShark.cs b/BizHawk.Client.EmuHawk/tools/GameShark.cs index afb695879c..36aaa961c3 100644 --- a/BizHawk.Client.EmuHawk/tools/GameShark.cs +++ b/BizHawk.Client.EmuHawk/tools/GameShark.cs @@ -104,8 +104,7 @@ namespace BizHawk.Client.EmuHawk } break; case "N64": - //N64 Cheats are going be more, limited/restricted. I am NOT going to support the non-8XXXXXXX YYYY style of codes. That's too much work/hassle. - //I think they can in theory work with straight conversion as written? + //These codes, more or less work without Needing much work. if (txtCheat.Text.Contains(" ") == false) { MessageBox.Show("All N64 GameShark Cheats need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); @@ -143,23 +142,31 @@ namespace BizHawk.Client.EmuHawk //Do we support the GameShark Button? No. But these cheats, can be toggled. Which "Counts" // Consequences be damned! case "88": + //Byte + isByte = true; break; case "89": + //Word + isByte = false; break; //These are compare Address X to Value Y, then apply Value B to Address A //This is not supported, yet //TODO: When BizHawk supports a compare RAM Address's value is true then apply a value to another address, make it a thing. case "D0": - case "D1": + //Byte + case "D1": + //Word case "D2": + //Byte case "D3": + //Word MessageBox.Show("The code you entered is not supported by BizHawk.", "Emulator Error", MessageBoxButtons.OK, MessageBoxIcon.Information); return; //These codes are for Disabling the Expansion Pak. that's a bad thing? Assuming bad codes, until told otherwise. case "EE": case "DD": case "CC": - MessageBox.Show("The code you entered is for Disabling the Expansion Pak. This is not allowed.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Information); + MessageBox.Show("The code you entered is for Disabling the Expansion Pak. This is not allowed by this tool.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Information); return; //Enable Code //Not Necessary? Think so? @@ -173,6 +180,7 @@ namespace BizHawk.Client.EmuHawk return; //TODO: Make Patch Code (5000XXYY) work. case "50": + //Word? MessageBox.Show("The code you entered is not supported by this tool. Please Submit the Game's Name, Cheat/Code and Purpose to the BizHawk forums.", "Tool Error", MessageBoxButtons.OK, MessageBoxIcon.Information); return; //I hope this isn't a thing. From 0ff2a2eb4918b1df104271459781b4c67e16bab9 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 15 Nov 2015 18:02:20 -0600 Subject: [PATCH 05/20] fix crashy bugs in snes gfx debugger --- BizHawk.Client.EmuHawk/tools/SNES/SNESGraphicsDebugger.cs | 4 ++++ .../Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/BizHawk.Client.EmuHawk/tools/SNES/SNESGraphicsDebugger.cs b/BizHawk.Client.EmuHawk/tools/SNES/SNESGraphicsDebugger.cs index dc76e411a8..9754c7cb3d 100644 --- a/BizHawk.Client.EmuHawk/tools/SNES/SNESGraphicsDebugger.cs +++ b/BizHawk.Client.EmuHawk/tools/SNES/SNESGraphicsDebugger.cs @@ -1160,6 +1160,10 @@ namespace BizHawk.Client.EmuHawk { var bg = si.BG[(int)CurrDisplaySelection]; + //unavailable BG for this mode + if (bg.Bpp == 0) + break; + if (bg.TileSize == 16) { tx /= 2; ty /= 2; } //worry about this later. need to pass a different flag into `currViewingTile` int tloc = ty * bg.ScreenSizeInTiles.Width + tx; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs index 1f3ac22c98..362c524900 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs @@ -6,8 +6,7 @@ //http://wiki.superfamicom.org/snes/show/Registers //TODO -//SF2 title art doesnt seem to show up.. -//scanline control doesnt work? +//when a BG is not available, the last rendered BG still shows up. should clear it using System; @@ -645,6 +644,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES /// public void DecodeBG(int* screen, int stride, TileEntry[] map, int tiledataBaseAddr, ScreenSize size, int bpp, int tilesize, int paletteStart) { + //emergency backstop. this can only happen if we're displaying an unavailable BG or other similar such value + if (bpp == 0) return; + int ncolors = 1 << bpp; int[] tileBuf = new int[16*16]; From 8d955a870372afc24da1a3b26c32dafd84ee2627 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 15 Nov 2015 18:04:42 -0600 Subject: [PATCH 06/20] fix snes gfx debugger scanline CB --- .../Consoles/Nintendo/SNES/LibsnesApi_BRK.cs | 10 +++++++ .../Nintendo/SNES/LibsnesApi_Enums.cs | 2 +- .../Consoles/Nintendo/SNES/LibsnesApi_SIG.cs | 11 -------- .../bsnes/target-libsnes/libsnes_pwrap.cpp | 26 +++++++++++------- output/dll/libsneshawk-32-compatibility.dll | Bin 1055744 -> 1056256 bytes output/dll/libsneshawk-32-performance.dll | Bin 1064448 -> 1064448 bytes 6 files changed, 27 insertions(+), 22 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_BRK.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_BRK.cs index c0f9c1271e..e312640397 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_BRK.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_BRK.cs @@ -32,10 +32,20 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES WriteHook((uint)addr, value); break; } + + //not supported yet case eMessage.eMessage_BRK_hook_nmi: break; case eMessage.eMessage_BRK_hook_irq: break; + + case eMessage.eMessage_BRK_scanlineStart: + int line = brPipe.ReadInt32(); + if (scanlineStart != null) + scanlineStart(line); + SPECIAL_Resume(); + break; + } //switch(msg) return true; } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_Enums.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_Enums.cs index affb989217..02acdcd22c 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_Enums.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_Enums.cs @@ -61,7 +61,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES eMessage_SIG_input_state, eMessage_SIG_input_notify, eMessage_SIG_audio_flush, - eMessage_SIG_scanlineStart, eMessage_SIG_path_request, eMessage_SIG_trace_callback, eMessage_SIG_allocSharedMemory, //? @@ -73,6 +72,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES eMessage_BRK_hook_write, eMessage_BRK_hook_nmi, eMessage_BRK_hook_irq, + eMessage_BRK_scanlineStart, }; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_SIG.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_SIG.cs index ffae4c7275..15f3a602dc 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_SIG.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_SIG.cs @@ -70,17 +70,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES brPipe.ReadInt32(); //dummy synchronization break; } - case eMessage.eMessage_SIG_scanlineStart: - { - int line = brPipe.ReadInt32(); - if (scanlineStart != null) - scanlineStart(line); - - //we have to notify the unmanaged process that we're done peeking thruogh its memory and whatnot so it can proceed with emulation - //HUM??????????? BRK_COMPLETE???? SCANLINE CB NEEDS RE-EVALUATING - WritePipeMessage(eMessage.eMessage_BRK_Complete); - break; - } case eMessage.eMessage_SIG_path_request: { int slot = brPipe.ReadInt32(); diff --git a/libsnes/bsnes/target-libsnes/libsnes_pwrap.cpp b/libsnes/bsnes/target-libsnes/libsnes_pwrap.cpp index 9ff8c34e27..ddb22c5d0b 100644 --- a/libsnes/bsnes/target-libsnes/libsnes_pwrap.cpp +++ b/libsnes/bsnes/target-libsnes/libsnes_pwrap.cpp @@ -95,7 +95,6 @@ enum eMessage : int32 eMessage_SIG_input_state, eMessage_SIG_input_notify, eMessage_SIG_audio_flush, - eMessage_SIG_scanlineStart, eMessage_SIG_path_request, eMessage_SIG_trace_callback, eMessage_SIG_allocSharedMemory, //? @@ -107,6 +106,7 @@ enum eMessage : int32 eMessage_BRK_hook_write, eMessage_BRK_hook_nmi, eMessage_BRK_hook_irq, + eMessage_BRK_scanlineStart, //implemented as a BRK because that's really what it is, its just a graphical event and not a CPU event }; @@ -122,6 +122,7 @@ enum eEmulationCallback { eEmulationCallback_snes_video_refresh, eEmulationCallback_snes_audio_flush, + eEmulationCallback_snes_scanline, eEmulationCallback_snes_input_poll, eEmulationCallback_snes_input_state, eEmulationCallback_snes_input_notify, @@ -162,6 +163,10 @@ struct EmulationControl unsigned height; } cb_video_refresh_params; struct + { + int32_t scanline; + } cb_scanline_params; + struct { unsigned port, device, index, id; int16_t result; @@ -552,14 +557,10 @@ const char* snes_path_request(int slot, const char* hint) void RunControlMessageLoop(); void snes_scanlineStart(int line) { - //TODO - //WritePipe(eMessage_snes_cb_scanlineStart); - //WritePipe(line); - - ////we've got to wait for the frontend to finish processing. - ////in theory we could let emulation proceed after snagging the vram and registers, and do decoding and stuff on another thread... - ////but its too hard for now. - //RunMessageLoop(); + s_EmulationControl.exitReason = eEmulationExitReason_BRK; + s_EmulationControl.hookExitType = eMessage_BRK_scanlineStart; + s_EmulationControl.cb_scanline_params.scanline = line; + SETCONTROL; } class SharedMemoryBlock @@ -979,9 +980,10 @@ TOP: char* buf = (char*)hMapFilePtr + destOfs; int bufsize = 512 * 480 * 4; memcpy(buf,s_EmulationControl.cb_video_refresh_params.data,bufsize); - WritePipe((char)0); //dummy synchronization + WritePipe((char)0); //dummy synchronization (alert frontend we're done with buffer) break; } + case eEmulationCallback_snes_audio_flush: Handle_SIG_audio_flush(); break; @@ -1029,6 +1031,10 @@ TOP: s_EmulationControl.exitReason = eEmulationExitReason_NotSet; switch(s_EmulationControl.hookExitType) { + case eMessage_BRK_scanlineStart: + WritePipe(eMessage_BRK_scanlineStart); + WritePipe((uint32)s_EmulationControl.hookAddr); + break; case eMessage_BRK_hook_exec: WritePipe(eMessage_BRK_hook_exec); WritePipe((uint32)s_EmulationControl.hookAddr); diff --git a/output/dll/libsneshawk-32-compatibility.dll b/output/dll/libsneshawk-32-compatibility.dll index b8e06af9bda2f1f3251483c95080fb95e781e718..fea764ec23a927d841a6a84144409befb74b2d9f 100644 GIT binary patch delta 89157 zcmZ^M34Bb~`}f>)XU-jjj7TCOB8XUGiG7PmNGugKDPkwoGE_AxL2U_15D`m9J(Mb? zq^cT%u{UZ-?AoeQdu=z?*eNyd_uM;4w7>uB)90S^Eay4TdCtB}n!F=Cc~5w@MXF}1 z+$GlF`ghg9s+Ez-84PR77!08njk?F)NSY$$+JBJxmrnc!bU|Kg_h7+NmOYHslIGe+ z;M>zaAKzH}c6A1=YO z1-`umH!KCdt^^Md_>vMlUf{E~mr5$~cCH{yC=swM13sbzj}v%o37#$RjwQI^OW@5* zaI3(BN^paL8PwCLJ=-d9*7WRD(V{9M|CEDfQQx*~k>L5ZB1hN^%Yol2!L0&6TY|?6 z{BQ}LEAZ_lxMc%@UOrcQ_Rup#Fi_lvBgxI zWhL;AC3u{`o0s6(0uL(2cV>SB{T*A$2Akn)aNIOblB>dn2Lc57`PO0�&gZ37!i) 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 diff --git a/output/dll/libsneshawk-32-performance.dll b/output/dll/libsneshawk-32-performance.dll index 559da54ce0f2aebee8c330efa653451ada4e22c5..1d1e77fbf56dbef27cbb7fd922eb8fb979602fa9 100644 GIT binary patch delta 47747 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 C@E#NZ delta 47366 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 From 6f71956faa1ffd37aadef29405033d1625881855 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 15 Nov 2015 18:22:12 -0600 Subject: [PATCH 07/20] add lousy logic to fix cheat compares --- BizHawk.Client.Common/tools/Cheat.cs | 2 +- BizHawk.Client.Common/tools/Watch.cs | 38 +++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/BizHawk.Client.Common/tools/Cheat.cs b/BizHawk.Client.Common/tools/Cheat.cs index 8ef405f03a..159e19f027 100644 --- a/BizHawk.Client.Common/tools/Cheat.cs +++ b/BizHawk.Client.Common/tools/Cheat.cs @@ -214,7 +214,7 @@ namespace BizHawk.Client.Common { if (_compare.HasValue) { - if (_compare.Value == _watch.Value) + if (_compare.Value == _watch.ValueNoFreeze) { _watch.Poke(GetStringForPulse(_val)); } diff --git a/BizHawk.Client.Common/tools/Watch.cs b/BizHawk.Client.Common/tools/Watch.cs index 9dd553fd6a..87786391d9 100644 --- a/BizHawk.Client.Common/tools/Watch.cs +++ b/BizHawk.Client.Common/tools/Watch.cs @@ -113,6 +113,9 @@ namespace BizHawk.Client.Common public abstract string ValueString { get; } public abstract WatchSize Size { get; } + //zero 15-nov-2015 - bypass LIAR LOGIC, see fdc9ea2aa922876d20ba897fb76909bf75fa6c92 https://github.com/TASVideos/BizHawk/issues/326 + public abstract int? ValueNoFreeze { get; } + public abstract uint MaxValue { get; } public abstract int? Previous { get; } @@ -237,10 +240,11 @@ namespace BizHawk.Client.Common } } - protected byte GetByte() + protected byte GetByte(bool bypassFreeze = false) { - if (Global.CheatList.IsActive(_domain, _address)) + if (!bypassFreeze && Global.CheatList.IsActive(_domain, _address)) { + //LIAR logic return Global.CheatList.GetByteValue(_domain, _address).Value; } else @@ -256,10 +260,11 @@ namespace BizHawk.Client.Common } } - protected ushort GetWord() + protected ushort GetWord(bool bypassFreeze = false) { - if (Global.CheatList.IsActive(_domain, _address)) + if (!bypassFreeze && Global.CheatList.IsActive(_domain, _address)) { + //LIAR logic return (ushort)Global.CheatList.GetCheatValue(_domain, _address, WatchSize.Word).Value; } else @@ -275,10 +280,11 @@ namespace BizHawk.Client.Common } } - protected uint GetDWord() + protected uint GetDWord(bool bypassFreeze = false) { - if (Global.CheatList.IsActive(_domain, _address)) + if (!bypassFreeze && Global.CheatList.IsActive(_domain, _address)) { + //LIAR logic return (uint)Global.CheatList.GetCheatValue(_domain, _address, WatchSize.DWord).Value; } else @@ -458,6 +464,11 @@ namespace BizHawk.Client.Common get { return null; } } + public override int? ValueNoFreeze + { + get { return null; } + } + public override int? Previous { get { return null; } @@ -562,6 +573,11 @@ namespace BizHawk.Client.Common get { return GetByte(); } } + public override int? ValueNoFreeze + { + get { return GetByte(true); } + } + public override string ValueString { get { return FormatValue(GetByte()); } @@ -792,6 +808,11 @@ namespace BizHawk.Client.Common get { return GetWord(); } } + public override int? ValueNoFreeze + { + get { return GetWord(true); } + } + public override int? Previous { get { return _previous; } @@ -1008,6 +1029,11 @@ namespace BizHawk.Client.Common get { return (int)GetDWord(); } } + public override int? ValueNoFreeze + { + get { return (int)GetDWord(true); } + } + public override int? Previous { get { return (int)_previous; } From ca2a98c029c001ab5c04d5ef52c46ba488f6632d Mon Sep 17 00:00:00 2001 From: hegyak Date: Sun, 15 Nov 2015 19:35:05 -0800 Subject: [PATCH 08/20] Improve GB/GBC GameShark Parsing. Make N64 Parsing robust. Start on PSX handling. --- BizHawk.Client.EmuHawk/tools/GameShark.cs | 76 ++++++++++++++++++----- 1 file changed, 60 insertions(+), 16 deletions(-) diff --git a/BizHawk.Client.EmuHawk/tools/GameShark.cs b/BizHawk.Client.EmuHawk/tools/GameShark.cs index 36aaa961c3..044ca687a6 100644 --- a/BizHawk.Client.EmuHawk/tools/GameShark.cs +++ b/BizHawk.Client.EmuHawk/tools/GameShark.cs @@ -54,21 +54,30 @@ namespace BizHawk.Client.EmuHawk string RAMValue = null; //What System are we running? //We want Upper Case. + int byteSize = 0; txtCheat.Text = txtCheat.Text.ToUpper(); + string testo = txtCheat.Text.Remove(2, 11); switch (Emulator.SystemId) { case "GB": //This Check ONLY applies to GB/GBC codes. if (txtCheat.Text.Length != 8) { - MessageBox.Show("All GameShark cheats need to be Eight characters in Length", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + MessageBox.Show("All GameShark Codes need to be Eight characters in Length", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } //Let's make sure we start with zero. We have a good length, and a good starting zero, we should be good. Hopefully. - if (txtCheat.Text.StartsWith("0") == false) + switch (testo) { - MessageBox.Show("All GameShark cheats for GameBoy need to start with the number 0", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; + //Is this 00 or 01? + case "00": + case "01": + //Good. + break; + default: + //No. + MessageBox.Show("All GameShark Codes for GameBoy need to start with 00 or 01", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; } //Sample Input for GB/GBC: //010FF6C1 @@ -107,47 +116,45 @@ namespace BizHawk.Client.EmuHawk //These codes, more or less work without Needing much work. if (txtCheat.Text.Contains(" ") == false) { - MessageBox.Show("All N64 GameShark Cheats need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + MessageBox.Show("All N64 GameShark Codes need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (txtCheat.Text.Length != 13) { - MessageBox.Show("All N64 GameShark Cheats need to be 13 characters in length.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + MessageBox.Show("All N64 GameShark Codes need to be 13 characters in length.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } //We need to determine what kind of cheat this is. //I need to determine if this is a Byte or Word. - Boolean isByte = false; - string testo = txtCheat.Text.Remove(2, 11); switch (testo) { //80 and 81 are the most common, so let's not get all worried. case "80": //Byte - isByte = true; + byteSize = 8; break; case "81": //Word - isByte = false; + byteSize = 16; break; //Case A0 and A1 means "Write to Uncached address. case "A0": //Byte - isByte = true; + byteSize = 8; break; case "A1": //Word - isByte = false; + byteSize = 16; break; //Do we support the GameShark Button? No. But these cheats, can be toggled. Which "Counts" // Consequences be damned! case "88": //Byte - isByte = true; + byteSize = 8; break; case "89": //Word - isByte = false; + byteSize = 16; break; //These are compare Address X to Value Y, then apply Value B to Address A //This is not supported, yet @@ -211,14 +218,14 @@ namespace BizHawk.Client.EmuHawk { //A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works. //System Bus Domain, The Address to Watch, Byte size (Word), Hex Display, Description. Big Endian. - if (isByte == false) + if (byteSize == 8) { //We have a Word (Double Byte) sized Value var watch = Watch.GenerateWatch(MemoryDomains["RDRAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Word, Watch.DisplayType.Hex, txtDescription.Text, true); //Take Watch, Add our Value we want, and it should be active when addded? Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); } - if (isByte == true) + if (byteSize == 16) { //We have a Byte sized value var watch = Watch.GenerateWatch(MemoryDomains["RDRAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, true); @@ -237,6 +244,43 @@ namespace BizHawk.Client.EmuHawk break; case "PSX": //Not yet. + //These codes, more or less work without Needing much work. + if (txtCheat.Text.Contains(" ") == false) + { + MessageBox.Show("All PSX GameShark Cheats need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (txtCheat.Text.Length != 13) + { + MessageBox.Show("All PSX GameShark Cheats need to be 13 characters in length.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + //We need to determine what kind of cheat this is. + //I need to determine if this is a Byte or Word. + switch (testo) + { + //30 80 Cheats mean, "Write, don't care otherwise." + case "30": + byteSize = 8; + break; + case "80": + byteSize = 16; + break; + //When value hits YYYY, make the next cheat go off + case "E0": + //E0 byteSize = 8; + case "D0": + //D0 byteSize = 16; + MessageBox.Show("The code you entered is not supported by BizHawk.", "Emulator Error", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + //Something wrong with their input. + default: + MessageBox.Show("The GameShark code entered is not a recognized format.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + //Leave this Method, before someone gets hurt. + return; + } + + //MainRAM break; default: //This should NEVER happen From b3166094ca2470da4a427f64ed6d4ef3c6def269 Mon Sep 17 00:00:00 2001 From: hegyak Date: Mon, 16 Nov 2015 06:49:00 -0800 Subject: [PATCH 09/20] Added PSX and Saturn GameShark Code Support. --- BizHawk.Client.EmuHawk/tools/GameShark.cs | 625 ++++++++++++++-------- 1 file changed, 400 insertions(+), 225 deletions(-) diff --git a/BizHawk.Client.EmuHawk/tools/GameShark.cs b/BizHawk.Client.EmuHawk/tools/GameShark.cs index 044ca687a6..9a051cb7df 100644 --- a/BizHawk.Client.EmuHawk/tools/GameShark.cs +++ b/BizHawk.Client.EmuHawk/tools/GameShark.cs @@ -6,7 +6,7 @@ using System.Globalization; namespace BizHawk.Client.EmuHawk { - [ToolAttributes(released: true, supportedSystems: new[] { "GB", "N64" })] + [ToolAttributes(released: true, supportedSystems: new[] { "GB", "N64", "PSX", "SAT" })] public partial class GameShark : Form, IToolForm, IToolFormAutoConfig { //We are using Memory Domains, so we NEED this. @@ -47,247 +47,422 @@ namespace BizHawk.Client.EmuHawk } + //My Variables + string parseString = null; + string RAMAddress = null; + string RAMValue = null; + int byteSize = 0; + string testo = null; private void btnGo_Click(object sender, EventArgs e) { - string parseString = null; - string RAMAddress = null; - string RAMValue = null; - //What System are we running? + //Reset Variables + parseString = null; + RAMAddress = null; + RAMValue = null; + byteSize = 0; //We want Upper Case. - int byteSize = 0; txtCheat.Text = txtCheat.Text.ToUpper(); - string testo = txtCheat.Text.Remove(2, 11); + //This determies what kind of Code we have + testo = txtCheat.Text.Remove(2, 11); + //What System are we running? switch (Emulator.SystemId) { case "GB": - //This Check ONLY applies to GB/GBC codes. - if (txtCheat.Text.Length != 8) - { - MessageBox.Show("All GameShark Codes need to be Eight characters in Length", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - //Let's make sure we start with zero. We have a good length, and a good starting zero, we should be good. Hopefully. - switch (testo) - { - //Is this 00 or 01? - case "00": - case "01": - //Good. - break; - default: - //No. - MessageBox.Show("All GameShark Codes for GameBoy need to start with 00 or 01", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - //Sample Input for GB/GBC: - //010FF6C1 - //Becomes: - //Address C1F6 - //Value 0F - - parseString = txtCheat.Text.Remove(0, 2); - //Now we need to break it down a little more. - RAMValue = parseString.Remove(2, 4); - parseString = parseString.Remove(0, 2); - //The issue is Endian... Time to get ultra clever. And Regret it. - //First Half - RAMAddress = parseString.Remove(0, 2); - RAMAddress = RAMAddress + parseString.Remove(2, 2); - //We now have our values. - //This part, is annoying... - try - { - //A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works. - //System Bus Domain, The Address to Watch, Byte size (Byte), Hex Display, Description. Not Big Endian. - var watch = Watch.GenerateWatch(MemoryDomains["System Bus"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, false); - //Take Watch, Add our Value we want, and it should be active when addded? - Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); - //Clear old Inputs - txtCheat.Clear(); - txtDescription.Clear(); - } - //Someone broke the world? - catch (Exception ex) - { - MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - break; + GB(); + break; case "N64": - //These codes, more or less work without Needing much work. - if (txtCheat.Text.Contains(" ") == false) - { - MessageBox.Show("All N64 GameShark Codes need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - if (txtCheat.Text.Length != 13) - { - MessageBox.Show("All N64 GameShark Codes need to be 13 characters in length.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - //We need to determine what kind of cheat this is. - //I need to determine if this is a Byte or Word. - switch (testo) - { - //80 and 81 are the most common, so let's not get all worried. - case "80": - //Byte - byteSize = 8; - break; - case "81": - //Word - byteSize = 16; - break; - //Case A0 and A1 means "Write to Uncached address. - case "A0": - //Byte - byteSize = 8; - break; - case "A1": - //Word - byteSize = 16; - break; - //Do we support the GameShark Button? No. But these cheats, can be toggled. Which "Counts" - // Consequences be damned! - case "88": - //Byte - byteSize = 8; - break; - case "89": - //Word - byteSize = 16; - break; - //These are compare Address X to Value Y, then apply Value B to Address A - //This is not supported, yet - //TODO: When BizHawk supports a compare RAM Address's value is true then apply a value to another address, make it a thing. - case "D0": - //Byte - case "D1": - //Word - case "D2": - //Byte - case "D3": - //Word - MessageBox.Show("The code you entered is not supported by BizHawk.", "Emulator Error", MessageBoxButtons.OK, MessageBoxIcon.Information); - return; - //These codes are for Disabling the Expansion Pak. that's a bad thing? Assuming bad codes, until told otherwise. - case "EE": - case "DD": - case "CC": - MessageBox.Show("The code you entered is for Disabling the Expansion Pak. This is not allowed by this tool.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Information); - return; - //Enable Code - //Not Necessary? Think so? - case "DE": - //Single Write ON-Boot code. - //Not Necessary? Think so? - case "F0": - case "F1": - case "2A": - MessageBox.Show("The code you entered is not needed by Bizhawk.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Information); - return; - //TODO: Make Patch Code (5000XXYY) work. - case "50": - //Word? - MessageBox.Show("The code you entered is not supported by this tool. Please Submit the Game's Name, Cheat/Code and Purpose to the BizHawk forums.", "Tool Error", MessageBoxButtons.OK, MessageBoxIcon.Information); - return; - //I hope this isn't a thing. - default: - MessageBox.Show("The GameShark code entered is not a recognized format.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - //Leave this Method, before someone gets hurt. - return; - //break; - } - //Big Endian is USED constantly here. The question is, how do we determine if it's one or two bytes? - //Now to get clever. - //Sample Input for N64: - //8133B21E 08FF - //Becomes: - //Address 33B21E - //Value 08FF - - //Note, 8XXXXXXX 00YY - //Is Byte, not Word - //Remove the 8X Octect - parseString = txtCheat.Text.Remove(0, 2); - //Get RAM Address - RAMAddress = parseString.Remove(6, 5); - //Get RAM Value - RAMValue = parseString.Remove(0, 7); - - try - { - //A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works. - //System Bus Domain, The Address to Watch, Byte size (Word), Hex Display, Description. Big Endian. - if (byteSize == 8) - { - //We have a Word (Double Byte) sized Value - var watch = Watch.GenerateWatch(MemoryDomains["RDRAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Word, Watch.DisplayType.Hex, txtDescription.Text, true); - //Take Watch, Add our Value we want, and it should be active when addded? - Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); - } - if (byteSize == 16) - { - //We have a Byte sized value - var watch = Watch.GenerateWatch(MemoryDomains["RDRAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, true); - //Take Watch, Add our Value we want, and it should be active when addded? - Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); - } - //Clear old Inputs - txtCheat.Clear(); - txtDescription.Clear(); - } - //Someone broke the world? - catch (Exception ex) - { - MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } + N64(); break; case "PSX": - //Not yet. - //These codes, more or less work without Needing much work. - if (txtCheat.Text.Contains(" ") == false) - { - MessageBox.Show("All PSX GameShark Cheats need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - if (txtCheat.Text.Length != 13) - { - MessageBox.Show("All PSX GameShark Cheats need to be 13 characters in length.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - //We need to determine what kind of cheat this is. - //I need to determine if this is a Byte or Word. - switch (testo) - { - //30 80 Cheats mean, "Write, don't care otherwise." - case "30": - byteSize = 8; - break; - case "80": - byteSize = 16; - break; - //When value hits YYYY, make the next cheat go off - case "E0": - //E0 byteSize = 8; - case "D0": - //D0 byteSize = 16; - MessageBox.Show("The code you entered is not supported by BizHawk.", "Emulator Error", MessageBoxButtons.OK, MessageBoxIcon.Information); - return; - //Something wrong with their input. - default: - MessageBox.Show("The GameShark code entered is not a recognized format.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - //Leave this Method, before someone gets hurt. - return; - } - - //MainRAM + PSX(); break; + case "SAT": + SAT(); + break; default: //This should NEVER happen break; } } + private void GB() + { + //This Check ONLY applies to GB/GBC codes. + if (txtCheat.Text.Length != 8) + { + MessageBox.Show("All GameShark Codes need to be Eight characters in Length", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + //Let's make sure we start with zero. We have a good length, and a good starting zero, we should be good. Hopefully. + switch (testo) + { + //Is this 00 or 01? + case "00": + case "01": + //Good. + break; + default: + //No. + MessageBox.Show("All GameShark Codes for GameBoy need to start with 00 or 01", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + //Sample Input for GB/GBC: + //010FF6C1 + //Becomes: + //Address C1F6 + //Value 0F + parseString = txtCheat.Text.Remove(0, 2); + //Now we need to break it down a little more. + RAMValue = parseString.Remove(2, 4); + parseString = parseString.Remove(0, 2); + //The issue is Endian... Time to get ultra clever. And Regret it. + //First Half + RAMAddress = parseString.Remove(0, 2); + RAMAddress = RAMAddress + parseString.Remove(2, 2); + //We now have our values. + //This part, is annoying... + try + { + //A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works. + //System Bus Domain, The Address to Watch, Byte size (Byte), Hex Display, Description. Not Big Endian. + var watch = Watch.GenerateWatch(MemoryDomains["System Bus"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, false); + //Take Watch, Add our Value we want, and it should be active when addded? + Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); + //Clear old Inputs + txtCheat.Clear(); + txtDescription.Clear(); + } + //Someone broke the world? + catch (Exception ex) + { + MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + private void N64() + { //These codes, more or less work without Needing much work. + if (txtCheat.Text.Contains(" ") == false) + { + MessageBox.Show("All N64 GameShark Codes need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (txtCheat.Text.Length != 13) + { + MessageBox.Show("All N64 GameShark Codes need to be 13 characters in length.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + //We need to determine what kind of cheat this is. + //I need to determine if this is a Byte or Word. + switch (testo) + { + //80 and 81 are the most common, so let's not get all worried. + case "80": + //Byte + byteSize = 8; + break; + case "81": + //Word + byteSize = 16; + break; + //Case A0 and A1 means "Write to Uncached address. + case "A0": + //Byte + byteSize = 8; + break; + case "A1": + //Word + byteSize = 16; + break; + //Do we support the GameShark Button? No. But these cheats, can be toggled. Which "Counts" + // Consequences be damned! + case "88": + //Byte + byteSize = 8; + break; + case "89": + //Word + byteSize = 16; + break; + //These are compare Address X to Value Y, then apply Value B to Address A + //This is not supported, yet + //TODO: When BizHawk supports a compare RAM Address's value is true then apply a value to another address, make it a thing. + case "D0": + //Byte + case "D1": + //Word + case "D2": + //Byte + case "D3": + //Word + MessageBox.Show("The code you entered is not supported by BizHawk.", "Emulator Error", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + //These codes are for Disabling the Expansion Pak. that's a bad thing? Assuming bad codes, until told otherwise. + case "EE": + case "DD": + case "CC": + MessageBox.Show("The code you entered is for Disabling the Expansion Pak. This is not allowed by this tool.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + //Enable Code + //Not Necessary? Think so? + case "DE": + //Single Write ON-Boot code. + //Not Necessary? Think so? + case "F0": + case "F1": + case "2A": + case "3C": + case "FF": + MessageBox.Show("The code you entered is not needed by Bizhawk.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + //TODO: Make Patch Code (5000XXYY) work. + case "50": + //Word? + MessageBox.Show("The code you entered is not supported by this tool. Please Submit the Game's Name, Cheat/Code and Purpose to the BizHawk forums.", "Tool Error", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + //I hope this isn't a thing. + default: + MessageBox.Show("The GameShark code entered is not a recognized format.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + //Leave this Method, before someone gets hurt. + return; + //break; + } + //Big Endian is USED constantly here. The question is, how do we determine if it's one or two bytes? + //Now to get clever. + //Sample Input for N64: + //8133B21E 08FF + //Becomes: + //Address 33B21E + //Value 08FF + + //Note, 80XXXXXX 00YY + //Is Byte, not Word + //Remove the 80 Octect + parseString = txtCheat.Text.Remove(0, 2); + //Get RAM Address + RAMAddress = parseString.Remove(6, 5); + //Get RAM Value + RAMValue = parseString.Remove(0, 7); + + try + { + //A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works. + //System Bus Domain, The Address to Watch, Byte size (Word), Hex Display, Description. Big Endian. + if (byteSize == 8) + { + //We have a Byte sized value + var watch = Watch.GenerateWatch(MemoryDomains["RDRAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Word, Watch.DisplayType.Hex, txtDescription.Text, true); + //Take Watch, Add our Value we want, and it should be active when addded? + Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); + } + if (byteSize == 16) + { + //We have a Word (Double Byte) sized Value + var watch = Watch.GenerateWatch(MemoryDomains["RDRAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, true); + //Take Watch, Add our Value we want, and it should be active when addded? + Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); + } + //Clear old Inputs + txtCheat.Clear(); + txtDescription.Clear(); + } + //Someone broke the world? + catch (Exception ex) + { + MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + private void PSX() + { + //These codes, more or less work without Needing much work. + if (txtCheat.Text.Contains(" ") == false) + { + MessageBox.Show("All PSX GameShark Cheats need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (txtCheat.Text.Length != 13) + { + MessageBox.Show("All PSX GameShark Cheats need to be 13 characters in length.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + //We need to determine what kind of cheat this is. + //I need to determine if this is a Byte or Word. + switch (testo) + { + //30 80 Cheats mean, "Write, don't care otherwise." + case "30": + byteSize = 8; + break; + case "80": + byteSize = 16; + break; + //When value hits YYYY, make the next cheat go off + case "E0": + //E0 byteSize = 8; + case "E1": + //E1 byteSize = 8; + case "E2": + //E2 byteSize = 8; + case "D0": + //D0 byteSize = 16; + case "D1": + //D1 byteSize = 16; + case "D2": + //D2 byteSize = 16; + case "D3": + //D3 byteSize = 16; + case "D4": + //D4 byteSize = 16; + case "D5": + //D5 byteSize = 16; + case "D6": + //D6 byteSize = 16; + + //Increment/Decrement Codes + case "10": + //10 byteSize = 16; + case "11": + //11 byteSize = 16; + case "20": + //20 byteSize = 8 + case "21": + //21 byteSize = 8 + MessageBox.Show("The code you entered is not supported by BizHawk.", "Emulator Error", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + case "C0": + case "C1": + //Slow-Mo + case "40": + MessageBox.Show("The code you entered is not needed by Bizhawk.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + case "C2": + case "50": + //Word? + MessageBox.Show("The code you entered is not supported by this tool. Please Submit the Game's Name, Cheat/Code and Purpose to the BizHawk forums.", "Tool Error", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + //Something wrong with their input. + default: + MessageBox.Show("The GameShark code entered is not a recognized format.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + //Leave this Method, before someone gets hurt. + return; + } + //Sample Input for PSX: + //800D10BA 0009 + //Address: 0D10BA + //Value: 0009 + //Remove first two octets + parseString = txtCheat.Text.Remove(0, 2); + //Get RAM Address + RAMAddress = parseString.Remove(6, 5); + //Get RAM Value + RAMValue = parseString.Remove(0, 7); + try + { + //A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works. + //System Bus Domain, The Address to Watch, Byte size (Word), Hex Display, Description. Big Endian. + + //My Consern is that Work RAM High may be incorrect? + if (byteSize == 8) + { + //We have a Byte sized value + var watch = Watch.GenerateWatch(MemoryDomains["MainRAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Word, Watch.DisplayType.Hex, txtDescription.Text, false); + //Take Watch, Add our Value we want, and it should be active when addded? + Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); + } + if (byteSize == 16) + { + //We have a Word (Double Byte) sized Value + var watch = Watch.GenerateWatch(MemoryDomains["MainRAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, false); + //Take Watch, Add our Value we want, and it should be active when addded? + Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); + } + //Clear old Inputs + txtCheat.Clear(); + txtDescription.Clear(); + } + //Someone broke the world? + catch (Exception ex) + { + MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + } + private void SAT() + { + //Not yet. + if (txtCheat.Text.Contains(" ") == false) + { + MessageBox.Show("All Saturn GameShark Cheats need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (txtCheat.Text.Length != 13) + { + MessageBox.Show("All Saturn GameShark Cheats need to be 13 characters in length.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + //This is a special test. Only the first character really matters? 16 or 36? + testo = testo.Remove(1, 1); + switch (testo) + { + case "1": + byteSize = 16; + break; + case "3": + byteSize = 8; + break; + //0 writes once. + case "0": + //D is RAM Equal To Activator, do Next Value + case "D": + MessageBox.Show("The code you entered is not supported by BizHawk.", "Emulator Error", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + case "F": + MessageBox.Show("The code you entered is not needed by Bizhawk.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + default: + MessageBox.Show("The GameShark code entered is not a recognized format.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + //Leave this Method, before someone gets hurt. + return; + } + //Sample Input for Saturn: + //160949FC 0090 + //Address: 0949FC + //Value: 90 + //Note, 3XXXXXXX are Big Endian + //Remove first two octets + parseString = txtCheat.Text.Remove(0, 2); + //Get RAM Address + RAMAddress = parseString.Remove(6, 5); + //Get RAM Value + RAMValue = parseString.Remove(0, 7); + try + { + //A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works. + //System Bus Domain, The Address to Watch, Byte size (Word), Hex Display, Description. Big Endian. + + //My Consern is that Work RAM High may be incorrect? + if (byteSize == 8) + { + //We have a Byte sized value + var watch = Watch.GenerateWatch(MemoryDomains["Work Ram High"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Word, Watch.DisplayType.Hex, txtDescription.Text, true); + //Take Watch, Add our Value we want, and it should be active when addded? + Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); + } + if (byteSize == 16) + { + //We have a Word (Double Byte) sized Value + var watch = Watch.GenerateWatch(MemoryDomains["Work Ram High"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, true); + //Take Watch, Add our Value we want, and it should be active when addded? + Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); + } + //Clear old Inputs + txtCheat.Clear(); + txtDescription.Clear(); + } + //Someone broke the world? + catch (Exception ex) + { + MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } private void btnClear_Click(object sender, EventArgs e) { //Clear old Inputs From 1e878f700c9e085785a9373ccbe9dc10ee55958f Mon Sep 17 00:00:00 2001 From: hegyak Date: Mon, 16 Nov 2015 09:22:58 -0800 Subject: [PATCH 10/20] Corrected GB/GBC Code Handling. Added SNES Action Replay code handling. --- BizHawk.Client.EmuHawk/tools/GameShark.cs | 63 +++++++++++++++++++++-- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/BizHawk.Client.EmuHawk/tools/GameShark.cs b/BizHawk.Client.EmuHawk/tools/GameShark.cs index 9a051cb7df..3c9a23dc64 100644 --- a/BizHawk.Client.EmuHawk/tools/GameShark.cs +++ b/BizHawk.Client.EmuHawk/tools/GameShark.cs @@ -6,7 +6,22 @@ using System.Globalization; namespace BizHawk.Client.EmuHawk { - [ToolAttributes(released: true, supportedSystems: new[] { "GB", "N64", "PSX", "SAT" })] + + //TODO: + //Add Support/Handling for The Following Systems and Devices: + //NES: Game Genie, Pro Action Replay + //GB/GBC: Pro Action Replay + //GBA: GameShark, Action Replay (Same?), Code Breaker + //GameGear: Game Genie, Pro Action Replay + //Genesis: Game Genie, Pro Action Replay + //N64: Action Replay + //PSX: Code Breaker, Action Replay, Game Busters (What is that?!) + //Saturn: Pro Action Replay (Is it the same as GameShark? Appears to be so?) + //SMS: Pro Action Replay + //SNES: Game Genie, Pro Action Replay + + + [ToolAttributes(released: true, supportedSystems: new[] { "GB", "N64", "PSX", "SAT", "SNES" })] public partial class GameShark : Form, IToolForm, IToolFormAutoConfig { //We are using Memory Domains, so we NEED this. @@ -62,8 +77,6 @@ namespace BizHawk.Client.EmuHawk byteSize = 0; //We want Upper Case. txtCheat.Text = txtCheat.Text.ToUpper(); - //This determies what kind of Code we have - testo = txtCheat.Text.Remove(2, 11); //What System are we running? switch (Emulator.SystemId) { @@ -71,14 +84,24 @@ namespace BizHawk.Client.EmuHawk GB(); break; case "N64": + //This determies what kind of Code we have + testo = txtCheat.Text.Remove(2, 11); N64(); break; case "PSX": + //This determies what kind of Code we have + testo = txtCheat.Text.Remove(2, 11); PSX(); break; case "SAT": + //This determies what kind of Code we have + testo = txtCheat.Text.Remove(2, 11); SAT(); break; + case "SNES": + //Currently only does Action Replay + SNES(); + break; default: //This should NEVER happen break; @@ -92,6 +115,7 @@ namespace BizHawk.Client.EmuHawk MessageBox.Show("All GameShark Codes need to be Eight characters in Length", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } + testo = txtCheat.Text.Remove(2, 6); //Let's make sure we start with zero. We have a good length, and a good starting zero, we should be good. Hopefully. switch (testo) { @@ -463,7 +487,38 @@ namespace BizHawk.Client.EmuHawk MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } - private void btnClear_Click(object sender, EventArgs e) + private void SNES() + { + //This ONLY applies to Action Replay. + if (txtCheat.Text.Length != 8) + { + MessageBox.Show("All Action Replay Codes need to be Eight characters in Length", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + //The Action Replay, is odd. + //Checking won't be done. + //Remove first two octets + RAMAddress = txtCheat.Text.Remove(6, 2); + //Get RAM Value + RAMValue = txtCheat.Text.Remove(0, 6); + try + { + //A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works. + //System Bus Domain, The Address to Watch, Byte size (Byte), Hex Display, Description. Not Big Endian. + var watch = Watch.GenerateWatch(MemoryDomains["System Bus"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, false); + //Take Watch, Add our Value we want, and it should be active when addded? + Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); + //Clear old Inputs + txtCheat.Clear(); + txtDescription.Clear(); + } + //Someone broke the world? + catch (Exception ex) + { + MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + private void btnClear_Click(object sender, EventArgs e) { //Clear old Inputs txtCheat.Clear(); From 59048264cd70202484f021b742b4428bbed52970 Mon Sep 17 00:00:00 2001 From: zeromus Date: Tue, 17 Nov 2015 01:50:38 -0600 Subject: [PATCH 11/20] fix regression in libretro core loading and streamline open advanced libretro ui --- BizHawk.Client.EmuHawk/MainForm.Events.cs | 6 ++++-- BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs | 4 ++-- BizHawk.Common/InstanceDll.cs | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/BizHawk.Client.EmuHawk/MainForm.Events.cs b/BizHawk.Client.EmuHawk/MainForm.Events.cs index 42ef3a00a7..72c9d8adb1 100644 --- a/BizHawk.Client.EmuHawk/MainForm.Events.cs +++ b/BizHawk.Client.EmuHawk/MainForm.Events.cs @@ -1185,7 +1185,7 @@ namespace BizHawk.Client.EmuHawk ThrottleMessage(); } - public void RunLibretroCoreChooser() + public bool RunLibretroCoreChooser() { var ofd = new OpenFileDialog(); @@ -1203,9 +1203,11 @@ namespace BizHawk.Client.EmuHawk ofd.Filter = "Libretro Cores (*.dll)|*.dll"; if (ofd.ShowDialog() == DialogResult.Cancel) - return; + return false; Global.Config.LibretroCore = ofd.FileName; + + return true; } private void setLibretroCoreToolStripMenuItem_Click(object sender, EventArgs e) diff --git a/BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs b/BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs index a1e6ee192e..c75d82be1a 100644 --- a/BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs +++ b/BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs @@ -51,8 +51,8 @@ namespace BizHawk.Client.EmuHawk private void btnSetLibretroCore_Click(object sender, EventArgs e) { - mainForm.RunLibretroCoreChooser(); - RefreshLibretroCore(false); + if(mainForm.RunLibretroCoreChooser()) + RefreshLibretroCore(false); } LibRetroEmulator.RetroDescription CurrentDescription; diff --git a/BizHawk.Common/InstanceDll.cs b/BizHawk.Common/InstanceDll.cs index e3be750a65..aa02cd3230 100644 --- a/BizHawk.Common/InstanceDll.cs +++ b/BizHawk.Common/InstanceDll.cs @@ -21,7 +21,7 @@ namespace BizHawk.Common var envpath = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process); try { - string envpath_new = Path.GetDirectoryName(path) + ";" + envpath; + string envpath_new = Path.GetDirectoryName(dllPath) + ";" + envpath; Environment.SetEnvironmentVariable("PATH", envpath_new, EnvironmentVariableTarget.Process); _hModule = LoadLibrary(path); //consider using LoadLibraryEx instead of shenanigans? var newfname = TempFileCleaner.RenameTempFilenameForDelete(path); From 5196fc6b70fb026a56e484ed255afac9196fe769 Mon Sep 17 00:00:00 2001 From: zeromus Date: Tue, 17 Nov 2015 17:10:27 -0600 Subject: [PATCH 12/20] Revert "common logic for tempfiles" This reverts commit 5afa44bbece22c105e250f3510a4852d0625e65a. and also "fix regression in libretro core loading and streamline open advanced libretro ui" 59048264cd70202484f021b742b4428bbed52970 but tortoisegit didn't put that in the commit message. --- .../BizHawk.Client.Common.csproj | 1 + .../TempFileCleaner.cs | 21 ++----------------- BizHawk.Client.Common/movie/bk2/StringLogs.cs | 4 +--- .../rewind/StreamBlobDatabase.cs | 4 +--- BizHawk.Client.EmuHawk/MainForm.Events.cs | 6 ++---- BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs | 4 ++-- BizHawk.Client.EmuHawk/Program.cs | 2 +- BizHawk.Common/BizHawk.Common.csproj | 1 - BizHawk.Common/InstanceDll.cs | 10 +++++---- 9 files changed, 16 insertions(+), 37 deletions(-) rename BizHawk.Common/TempFileManager.cs => BizHawk.Client.Common/TempFileCleaner.cs (60%) diff --git a/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/BizHawk.Client.Common/BizHawk.Client.Common.csproj index c35c7ad9d1..821672cd53 100644 --- a/BizHawk.Client.Common/BizHawk.Client.Common.csproj +++ b/BizHawk.Client.Common/BizHawk.Client.Common.csproj @@ -230,6 +230,7 @@ + diff --git a/BizHawk.Common/TempFileManager.cs b/BizHawk.Client.Common/TempFileCleaner.cs similarity index 60% rename from BizHawk.Common/TempFileManager.cs rename to BizHawk.Client.Common/TempFileCleaner.cs index 2c927f6ab5..b6a7f0eda6 100644 --- a/BizHawk.Common/TempFileManager.cs +++ b/BizHawk.Client.Common/TempFileCleaner.cs @@ -1,7 +1,7 @@ using System; using System.IO; -namespace BizHawk.Common +namespace BizHawk.Client.Common { ///

/// Starts a thread which cleans any filenames in %temp% beginning with bizhawk.bizdelete. @@ -12,23 +12,6 @@ namespace BizHawk.Common { //todo - manage paths other than %temp%, make not static, or allow adding multiple paths to static instance - public static string GetTempFilename(string friendlyname, string extension = null, bool delete = true) - { - string guidPart = Guid.NewGuid().ToString(); - var fname = string.Format("biz-{0}-{1}-{2}{3}", System.Diagnostics.Process.GetCurrentProcess().Id, friendlyname, guidPart, extension ?? ""); - if (delete) fname = RenameTempFilenameForDelete(fname); - return Path.Combine(Path.GetTempPath(), fname); - } - - public static string RenameTempFilenameForDelete(string path) - { - string filename = Path.GetFileName(path); - string dir = Path.GetDirectoryName(path); - if (!filename.StartsWith("biz-")) throw new InvalidOperationException(); - filename = "bizdelete-" + filename.Remove(0, 4); - return Path.Combine(dir, filename); - } - public static void Start() { lock (typeof(TempFileCleaner)) @@ -48,7 +31,7 @@ namespace BizHawk.Common var di = new DirectoryInfo(Path.GetTempPath()); for (; ; ) { - var fis = di.GetFiles("bizdelete-*"); + var fis = di.GetFiles("bizhawk.bizdelete*"); foreach (var fi in fis) { try diff --git a/BizHawk.Client.Common/movie/bk2/StringLogs.cs b/BizHawk.Client.Common/movie/bk2/StringLogs.cs index 355efdc9ef..b11db3a210 100644 --- a/BizHawk.Client.Common/movie/bk2/StringLogs.cs +++ b/BizHawk.Client.Common/movie/bk2/StringLogs.cs @@ -5,8 +5,6 @@ using System.IO; using System.Linq; using System.Text; -using BizHawk.Common; - namespace BizHawk.Client.Common { public static class StringLogUtil @@ -64,7 +62,7 @@ namespace BizHawk.Client.Common FileStream stream; public DiskStringLog() { - var path = TempFileCleaner.GetTempFilename("movieOnDisk"); + var path = Path.Combine(Path.GetTempPath(), "bizhawk.disklist-pid" + System.Diagnostics.Process.GetCurrentProcess().Id + "-" + Guid.NewGuid()); stream = new FileStream(path, FileMode.Create, System.Security.AccessControl.FileSystemRights.FullControl, FileShare.None, 4 * 1024, FileOptions.DeleteOnClose); bw = new BinaryWriter(stream); br = new BinaryReader(stream); diff --git a/BizHawk.Client.Common/rewind/StreamBlobDatabase.cs b/BizHawk.Client.Common/rewind/StreamBlobDatabase.cs index 50dbc74333..1ec2f9e157 100644 --- a/BizHawk.Client.Common/rewind/StreamBlobDatabase.cs +++ b/BizHawk.Client.Common/rewind/StreamBlobDatabase.cs @@ -2,8 +2,6 @@ using System.Collections.Generic; using System.IO; -using BizHawk.Common; - namespace BizHawk.Client.Common { /// @@ -25,7 +23,7 @@ namespace BizHawk.Client.Common _mCapacity = capacity; if (onDisk) { - var path = TempFileCleaner.GetTempFilename("rewindbuf"); + var path = Path.Combine(Path.GetTempPath(), "bizhawk.rewindbuf-pid" + System.Diagnostics.Process.GetCurrentProcess().Id + "-" + Guid.NewGuid()); // I checked the DeleteOnClose operation to make sure it cleans up when the process is aborted, and it seems to. // Otherwise we would have a more complex tempfile management problem here. diff --git a/BizHawk.Client.EmuHawk/MainForm.Events.cs b/BizHawk.Client.EmuHawk/MainForm.Events.cs index 72c9d8adb1..42ef3a00a7 100644 --- a/BizHawk.Client.EmuHawk/MainForm.Events.cs +++ b/BizHawk.Client.EmuHawk/MainForm.Events.cs @@ -1185,7 +1185,7 @@ namespace BizHawk.Client.EmuHawk ThrottleMessage(); } - public bool RunLibretroCoreChooser() + public void RunLibretroCoreChooser() { var ofd = new OpenFileDialog(); @@ -1203,11 +1203,9 @@ namespace BizHawk.Client.EmuHawk ofd.Filter = "Libretro Cores (*.dll)|*.dll"; if (ofd.ShowDialog() == DialogResult.Cancel) - return false; + return; Global.Config.LibretroCore = ofd.FileName; - - return true; } private void setLibretroCoreToolStripMenuItem_Click(object sender, EventArgs e) diff --git a/BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs b/BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs index c75d82be1a..a1e6ee192e 100644 --- a/BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs +++ b/BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs @@ -51,8 +51,8 @@ namespace BizHawk.Client.EmuHawk private void btnSetLibretroCore_Click(object sender, EventArgs e) { - if(mainForm.RunLibretroCoreChooser()) - RefreshLibretroCore(false); + mainForm.RunLibretroCoreChooser(); + RefreshLibretroCore(false); } LibRetroEmulator.RetroDescription CurrentDescription; diff --git a/BizHawk.Client.EmuHawk/Program.cs b/BizHawk.Client.EmuHawk/Program.cs index 96c37c97c6..09a44a0c86 100644 --- a/BizHawk.Client.EmuHawk/Program.cs +++ b/BizHawk.Client.EmuHawk/Program.cs @@ -59,7 +59,7 @@ namespace BizHawk.Client.EmuHawk } } - BizHawk.Common.TempFileCleaner.Start(); + BizHawk.Client.Common.TempFileCleaner.Start(); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); diff --git a/BizHawk.Common/BizHawk.Common.csproj b/BizHawk.Common/BizHawk.Common.csproj index eaeabf9830..825675481d 100644 --- a/BizHawk.Common/BizHawk.Common.csproj +++ b/BizHawk.Common/BizHawk.Common.csproj @@ -76,7 +76,6 @@ - diff --git a/BizHawk.Common/InstanceDll.cs b/BizHawk.Common/InstanceDll.cs index aa02cd3230..5f4ae2b744 100644 --- a/BizHawk.Common/InstanceDll.cs +++ b/BizHawk.Common/InstanceDll.cs @@ -9,7 +9,7 @@ namespace BizHawk.Common public InstanceDll(string dllPath) { //copy the dll to a temp directory - var path = TempFileCleaner.GetTempFilename(string.Format("{0}", Path.GetFileNameWithoutExtension(dllPath)),".dll",false); + var path = Path.Combine(Path.GetTempPath(), "instancedll-pid" + System.Diagnostics.Process.GetCurrentProcess().Id + "-" + Guid.NewGuid()) + "-" + Path.GetFileName(dllPath); using (var stream = new FileStream(path, FileMode.Create, System.Security.AccessControl.FileSystemRights.FullControl, FileShare.ReadWrite | FileShare.Delete, 4 * 1024, FileOptions.None)) using (var sdll = File.OpenRead(dllPath)) sdll.CopyTo(stream); @@ -21,11 +21,13 @@ namespace BizHawk.Common var envpath = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process); try { - string envpath_new = Path.GetDirectoryName(dllPath) + ";" + envpath; + string envpath_new = Path.GetDirectoryName(path) + ";" + envpath; Environment.SetEnvironmentVariable("PATH", envpath_new, EnvironmentVariableTarget.Process); _hModule = LoadLibrary(path); //consider using LoadLibraryEx instead of shenanigans? - var newfname = TempFileCleaner.RenameTempFilenameForDelete(path); - File.Move(path, newfname); + var newfname = Path.GetFileName(path); + newfname = "bizhawk.bizdelete-" + newfname; + var newpath = Path.Combine(Path.GetDirectoryName(path), newfname); + File.Move(path, newpath); } finally { From 28eae0dcb14da89d12b02eb53f5f55d897dc7da9 Mon Sep 17 00:00:00 2001 From: zeromus Date: Tue, 17 Nov 2015 17:26:03 -0600 Subject: [PATCH 13/20] Revert "Revert "common logic for tempfiles"" This reverts commit 5196fc6b70fb026a56e484ed255afac9196fe769. --- .../BizHawk.Client.Common.csproj | 1 - BizHawk.Client.Common/movie/bk2/StringLogs.cs | 4 +++- .../rewind/StreamBlobDatabase.cs | 4 +++- BizHawk.Client.EmuHawk/MainForm.Events.cs | 6 ++++-- BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs | 4 ++-- BizHawk.Client.EmuHawk/Program.cs | 2 +- BizHawk.Common/BizHawk.Common.csproj | 1 + BizHawk.Common/InstanceDll.cs | 10 ++++----- .../TempFileManager.cs | 21 +++++++++++++++++-- 9 files changed, 37 insertions(+), 16 deletions(-) rename BizHawk.Client.Common/TempFileCleaner.cs => BizHawk.Common/TempFileManager.cs (60%) diff --git a/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/BizHawk.Client.Common/BizHawk.Client.Common.csproj index 821672cd53..c35c7ad9d1 100644 --- a/BizHawk.Client.Common/BizHawk.Client.Common.csproj +++ b/BizHawk.Client.Common/BizHawk.Client.Common.csproj @@ -230,7 +230,6 @@ - diff --git a/BizHawk.Client.Common/movie/bk2/StringLogs.cs b/BizHawk.Client.Common/movie/bk2/StringLogs.cs index b11db3a210..355efdc9ef 100644 --- a/BizHawk.Client.Common/movie/bk2/StringLogs.cs +++ b/BizHawk.Client.Common/movie/bk2/StringLogs.cs @@ -5,6 +5,8 @@ using System.IO; using System.Linq; using System.Text; +using BizHawk.Common; + namespace BizHawk.Client.Common { public static class StringLogUtil @@ -62,7 +64,7 @@ namespace BizHawk.Client.Common FileStream stream; public DiskStringLog() { - var path = Path.Combine(Path.GetTempPath(), "bizhawk.disklist-pid" + System.Diagnostics.Process.GetCurrentProcess().Id + "-" + Guid.NewGuid()); + var path = TempFileCleaner.GetTempFilename("movieOnDisk"); stream = new FileStream(path, FileMode.Create, System.Security.AccessControl.FileSystemRights.FullControl, FileShare.None, 4 * 1024, FileOptions.DeleteOnClose); bw = new BinaryWriter(stream); br = new BinaryReader(stream); diff --git a/BizHawk.Client.Common/rewind/StreamBlobDatabase.cs b/BizHawk.Client.Common/rewind/StreamBlobDatabase.cs index 1ec2f9e157..50dbc74333 100644 --- a/BizHawk.Client.Common/rewind/StreamBlobDatabase.cs +++ b/BizHawk.Client.Common/rewind/StreamBlobDatabase.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.IO; +using BizHawk.Common; + namespace BizHawk.Client.Common { /// @@ -23,7 +25,7 @@ namespace BizHawk.Client.Common _mCapacity = capacity; if (onDisk) { - var path = Path.Combine(Path.GetTempPath(), "bizhawk.rewindbuf-pid" + System.Diagnostics.Process.GetCurrentProcess().Id + "-" + Guid.NewGuid()); + var path = TempFileCleaner.GetTempFilename("rewindbuf"); // I checked the DeleteOnClose operation to make sure it cleans up when the process is aborted, and it seems to. // Otherwise we would have a more complex tempfile management problem here. diff --git a/BizHawk.Client.EmuHawk/MainForm.Events.cs b/BizHawk.Client.EmuHawk/MainForm.Events.cs index 42ef3a00a7..72c9d8adb1 100644 --- a/BizHawk.Client.EmuHawk/MainForm.Events.cs +++ b/BizHawk.Client.EmuHawk/MainForm.Events.cs @@ -1185,7 +1185,7 @@ namespace BizHawk.Client.EmuHawk ThrottleMessage(); } - public void RunLibretroCoreChooser() + public bool RunLibretroCoreChooser() { var ofd = new OpenFileDialog(); @@ -1203,9 +1203,11 @@ namespace BizHawk.Client.EmuHawk ofd.Filter = "Libretro Cores (*.dll)|*.dll"; if (ofd.ShowDialog() == DialogResult.Cancel) - return; + return false; Global.Config.LibretroCore = ofd.FileName; + + return true; } private void setLibretroCoreToolStripMenuItem_Click(object sender, EventArgs e) diff --git a/BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs b/BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs index a1e6ee192e..c75d82be1a 100644 --- a/BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs +++ b/BizHawk.Client.EmuHawk/OpenAdvancedChooser.cs @@ -51,8 +51,8 @@ namespace BizHawk.Client.EmuHawk private void btnSetLibretroCore_Click(object sender, EventArgs e) { - mainForm.RunLibretroCoreChooser(); - RefreshLibretroCore(false); + if(mainForm.RunLibretroCoreChooser()) + RefreshLibretroCore(false); } LibRetroEmulator.RetroDescription CurrentDescription; diff --git a/BizHawk.Client.EmuHawk/Program.cs b/BizHawk.Client.EmuHawk/Program.cs index 09a44a0c86..96c37c97c6 100644 --- a/BizHawk.Client.EmuHawk/Program.cs +++ b/BizHawk.Client.EmuHawk/Program.cs @@ -59,7 +59,7 @@ namespace BizHawk.Client.EmuHawk } } - BizHawk.Client.Common.TempFileCleaner.Start(); + BizHawk.Common.TempFileCleaner.Start(); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); diff --git a/BizHawk.Common/BizHawk.Common.csproj b/BizHawk.Common/BizHawk.Common.csproj index 825675481d..eaeabf9830 100644 --- a/BizHawk.Common/BizHawk.Common.csproj +++ b/BizHawk.Common/BizHawk.Common.csproj @@ -76,6 +76,7 @@ + diff --git a/BizHawk.Common/InstanceDll.cs b/BizHawk.Common/InstanceDll.cs index 5f4ae2b744..aa02cd3230 100644 --- a/BizHawk.Common/InstanceDll.cs +++ b/BizHawk.Common/InstanceDll.cs @@ -9,7 +9,7 @@ namespace BizHawk.Common public InstanceDll(string dllPath) { //copy the dll to a temp directory - var path = Path.Combine(Path.GetTempPath(), "instancedll-pid" + System.Diagnostics.Process.GetCurrentProcess().Id + "-" + Guid.NewGuid()) + "-" + Path.GetFileName(dllPath); + var path = TempFileCleaner.GetTempFilename(string.Format("{0}", Path.GetFileNameWithoutExtension(dllPath)),".dll",false); using (var stream = new FileStream(path, FileMode.Create, System.Security.AccessControl.FileSystemRights.FullControl, FileShare.ReadWrite | FileShare.Delete, 4 * 1024, FileOptions.None)) using (var sdll = File.OpenRead(dllPath)) sdll.CopyTo(stream); @@ -21,13 +21,11 @@ namespace BizHawk.Common var envpath = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process); try { - string envpath_new = Path.GetDirectoryName(path) + ";" + envpath; + string envpath_new = Path.GetDirectoryName(dllPath) + ";" + envpath; Environment.SetEnvironmentVariable("PATH", envpath_new, EnvironmentVariableTarget.Process); _hModule = LoadLibrary(path); //consider using LoadLibraryEx instead of shenanigans? - var newfname = Path.GetFileName(path); - newfname = "bizhawk.bizdelete-" + newfname; - var newpath = Path.Combine(Path.GetDirectoryName(path), newfname); - File.Move(path, newpath); + var newfname = TempFileCleaner.RenameTempFilenameForDelete(path); + File.Move(path, newfname); } finally { diff --git a/BizHawk.Client.Common/TempFileCleaner.cs b/BizHawk.Common/TempFileManager.cs similarity index 60% rename from BizHawk.Client.Common/TempFileCleaner.cs rename to BizHawk.Common/TempFileManager.cs index b6a7f0eda6..2c927f6ab5 100644 --- a/BizHawk.Client.Common/TempFileCleaner.cs +++ b/BizHawk.Common/TempFileManager.cs @@ -1,7 +1,7 @@ using System; using System.IO; -namespace BizHawk.Client.Common +namespace BizHawk.Common { /// /// Starts a thread which cleans any filenames in %temp% beginning with bizhawk.bizdelete. @@ -12,6 +12,23 @@ namespace BizHawk.Client.Common { //todo - manage paths other than %temp%, make not static, or allow adding multiple paths to static instance + public static string GetTempFilename(string friendlyname, string extension = null, bool delete = true) + { + string guidPart = Guid.NewGuid().ToString(); + var fname = string.Format("biz-{0}-{1}-{2}{3}", System.Diagnostics.Process.GetCurrentProcess().Id, friendlyname, guidPart, extension ?? ""); + if (delete) fname = RenameTempFilenameForDelete(fname); + return Path.Combine(Path.GetTempPath(), fname); + } + + public static string RenameTempFilenameForDelete(string path) + { + string filename = Path.GetFileName(path); + string dir = Path.GetDirectoryName(path); + if (!filename.StartsWith("biz-")) throw new InvalidOperationException(); + filename = "bizdelete-" + filename.Remove(0, 4); + return Path.Combine(dir, filename); + } + public static void Start() { lock (typeof(TempFileCleaner)) @@ -31,7 +48,7 @@ namespace BizHawk.Client.Common var di = new DirectoryInfo(Path.GetTempPath()); for (; ; ) { - var fis = di.GetFiles("bizhawk.bizdelete*"); + var fis = di.GetFiles("bizdelete-*"); foreach (var fi in fis) { try From 5086ea62c2254a3db36feb383ef2e0e66e172843 Mon Sep 17 00:00:00 2001 From: zeromus Date: Tue, 17 Nov 2015 17:40:51 -0600 Subject: [PATCH 14/20] fix libretro sprintf of %f and %e throwing exceptions --- BizHawk.Common/Sprintf.cs | 45 +++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/BizHawk.Common/Sprintf.cs b/BizHawk.Common/Sprintf.cs index 010e3635fe..45bfafbe14 100644 --- a/BizHawk.Common/Sprintf.cs +++ b/BizHawk.Common/Sprintf.cs @@ -240,6 +240,19 @@ namespace BizHawk.Common } } #endregion + + static double GetDouble(IntPtr first, IntPtr second) + { + var ms = new MemoryStream(8); + var bw = new BinaryWriter(ms); + bw.Write(second.ToInt32()); + bw.Write(first.ToInt32()); + bw.Flush(); + ms.Position = 0; + var br = new BinaryReader(ms); + return br.ReadDouble(); + } + #region sprintf public static string sprintf( string Format, Func fetcher ) { @@ -457,24 +470,24 @@ namespace BizHawk.Common break; #endregion #region f - double number - case 'f': // double - throw new InvalidOperationException("cataleptic kangaroo orchestra"); - //w = FormatNumber( ( flagGroupThousands ? "n" : "f" ), flagAlternate, - // fieldLength, fieldPrecision, flagLeft2Right, - // flagPositiveSign, flagPositiveSpace, - // paddingCharacter, o ); - //defaultParamIx++; - //break; + case 'f': // double + o = GetDouble(n, fetcher()); + w = FormatNumber( ( flagGroupThousands ? "n" : "f" ), flagAlternate, + fieldLength, fieldPrecision, flagLeft2Right, + flagPositiveSign, flagPositiveSpace, + paddingCharacter, o ); + defaultParamIx++; + break; #endregion #region e - exponent number - case 'e': // double / exponent - throw new InvalidOperationException("cataleptic kangaroo orchestra"); - //w = FormatNumber( "e", flagAlternate, - // fieldLength, fieldPrecision, flagLeft2Right, - // flagPositiveSign, flagPositiveSpace, - // paddingCharacter, o ); - //defaultParamIx++; - //break; + case 'e': // double / exponent + o = GetDouble(n, fetcher()); + w = FormatNumber( "e", flagAlternate, + fieldLength, fieldPrecision, flagLeft2Right, + flagPositiveSign, flagPositiveSpace, + paddingCharacter, o ); + defaultParamIx++; + break; #endregion #region E - exponent number case 'E': // double / exponent From 4b46bc60bb1453271c7a089d0f4675b314342cf3 Mon Sep 17 00:00:00 2001 From: zeromus Date: Tue, 17 Nov 2015 17:41:01 -0600 Subject: [PATCH 15/20] TempFileManager throws less exceptions --- BizHawk.Common/TempFileManager.cs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/BizHawk.Common/TempFileManager.cs b/BizHawk.Common/TempFileManager.cs index 2c927f6ab5..39b8b67af5 100644 --- a/BizHawk.Common/TempFileManager.cs +++ b/BizHawk.Common/TempFileManager.cs @@ -48,19 +48,22 @@ namespace BizHawk.Common var di = new DirectoryInfo(Path.GetTempPath()); for (; ; ) { - var fis = di.GetFiles("bizdelete-*"); - foreach (var fi in fis) + if (!System.Diagnostics.Debugger.IsAttached) //exceptions due to can't-delete are annoying. see this for another approach: http://www.codeproject.com/Articles/14402/Testing-File-Access-Rights-in-NET { - try + var fis = di.GetFiles("bizdelete-*"); + foreach (var fi in fis) { - fi.Delete(); - } - catch - { - } + try + { + fi.Delete(); + } + catch + { + } - //try not to do more than one thing per frame - System.Threading.Thread.Sleep(100); + //try not to do more than one thing per frame + System.Threading.Thread.Sleep(100); + } } //try not to slam the filesystem too hard, we dont want this to cause any hiccups From 4de1d244ce7584bfb570fbdf29830d9d10a5ee17 Mon Sep 17 00:00:00 2001 From: zeromus Date: Wed, 18 Nov 2015 18:12:05 -0600 Subject: [PATCH 16/20] fix endianness of sprintf floats. i thought i checked this, but i guess not --- BizHawk.Common/Sprintf.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BizHawk.Common/Sprintf.cs b/BizHawk.Common/Sprintf.cs index 45bfafbe14..9d940625f9 100644 --- a/BizHawk.Common/Sprintf.cs +++ b/BizHawk.Common/Sprintf.cs @@ -244,9 +244,9 @@ namespace BizHawk.Common static double GetDouble(IntPtr first, IntPtr second) { var ms = new MemoryStream(8); - var bw = new BinaryWriter(ms); + var bw = new BinaryWriter(ms); + bw.Write(first.ToInt32()); bw.Write(second.ToInt32()); - bw.Write(first.ToInt32()); bw.Flush(); ms.Position = 0; var br = new BinaryReader(ms); From bc2e8c773d274af755824b7b2a02a2b18b5de164 Mon Sep 17 00:00:00 2001 From: zeromus Date: Wed, 18 Nov 2015 21:17:34 -0600 Subject: [PATCH 17/20] fix crash in loading hex editor (openadvanced regression) --- BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs b/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs index 4cbe83357a..427f0f4345 100644 --- a/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs +++ b/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs @@ -367,8 +367,8 @@ namespace BizHawk.Client.EmuHawk private static byte[] GetRomBytes() { - var path = GlobalWin.MainForm.CurrentlyOpenRom; - if (path == null) + var path = GlobalWin.MainForm.CurrentlyOpenRomArgs.OpenAdvanced.SimplePath; + if (string.IsNullOrEmpty(path)) { return new byte[] { 0xFF }; } From 10fcf662a16270fa70095bbe734de2d52ef7dbd9 Mon Sep 17 00:00:00 2001 From: zeromus Date: Wed, 18 Nov 2015 21:18:00 -0600 Subject: [PATCH 18/20] oops, i didnt commit enough --- BizHawk.Client.EmuHawk/MainForm.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index d8ff6ff961..8e8dbdcc9f 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -595,7 +595,7 @@ namespace BizHawk.Client.EmuHawk #region Properties public string CurrentlyOpenRom; //todo - delete me and use only args instead - LoadRomArgs CurrentlyOpenRomArgs; + public LoadRomArgs CurrentlyOpenRomArgs; public bool PauseAVI = false; public bool PressFrameAdvance = false; public bool PressRewind = false; From a3b7770333b2e25593d4256707b6b73bc4e9a368 Mon Sep 17 00:00:00 2001 From: hegyak Date: Thu, 19 Nov 2015 09:34:09 -0800 Subject: [PATCH 19/20] GameShark for N64 Corrected. Genesis Game Genie and Action Replay Added. Made Code detection smarter for several systems. --- BizHawk.Client.EmuHawk/tools/GameShark.cs | 224 ++++++++++++++++++++-- 1 file changed, 206 insertions(+), 18 deletions(-) diff --git a/BizHawk.Client.EmuHawk/tools/GameShark.cs b/BizHawk.Client.EmuHawk/tools/GameShark.cs index 3c9a23dc64..3c6c803b7a 100644 --- a/BizHawk.Client.EmuHawk/tools/GameShark.cs +++ b/BizHawk.Client.EmuHawk/tools/GameShark.cs @@ -3,25 +3,25 @@ using System.Windows.Forms; using BizHawk.Emulation.Common; using BizHawk.Client.Common; using System.Globalization; +using System.Collections.Generic; namespace BizHawk.Client.EmuHawk { //TODO: //Add Support/Handling for The Following Systems and Devices: - //NES: Game Genie, Pro Action Replay //GB/GBC: Pro Action Replay //GBA: GameShark, Action Replay (Same?), Code Breaker //GameGear: Game Genie, Pro Action Replay - //Genesis: Game Genie, Pro Action Replay - //N64: Action Replay + //NES: Game Genie, Pro Action Replay //PSX: Code Breaker, Action Replay, Game Busters (What is that?!) - //Saturn: Pro Action Replay (Is it the same as GameShark? Appears to be so?) //SMS: Pro Action Replay //SNES: Game Genie, Pro Action Replay + //Saturn: Pro Action Replay (Is it the same as GameShark? Appears to be so?) - [ToolAttributes(released: true, supportedSystems: new[] { "GB", "N64", "PSX", "SAT", "SNES" })] + + [ToolAttributes(released: true, supportedSystems: new[] { "GB", "GBA", "GEN", "N64", "PSX", "SAT", "SNES" })] public partial class GameShark : Form, IToolForm, IToolFormAutoConfig { //We are using Memory Domains, so we NEED this. @@ -83,6 +83,12 @@ namespace BizHawk.Client.EmuHawk case "GB": GB(); break; + case "GBA": + GBA(); + break; + case "GEN": + GEN(); + break; case "N64": //This determies what kind of Code we have testo = txtCheat.Text.Remove(2, 11); @@ -162,9 +168,193 @@ namespace BizHawk.Client.EmuHawk MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } + private void GBA() + { + //Nothing, yet + //Sample of Decryption Code from mGBA + /* void GBACheatDecryptGameShark(uint32_t* op1, uint32_t* op2, const uint32_t* seeds) { + uint32_t sum = 0xC6EF3720; + int i; + for (i = 0; i < 32; ++i) + { + *op2 -= ((*op1 << 4) + seeds[2]) ^ (*op1 + sum) ^ ((*op1 >> 5) + seeds[3]); + *op1 -= ((*op2 << 4) + seeds[0]) ^ (*op2 + sum) ^ ((*op2 >> 5) + seeds[1]); + sum -= 0x9E3779B9; + } + } + */ + + } + //This applies to the Genesis Game Genie. + private readonly Dictionary _GENgameGenieTable = new Dictionary + { + { 'A', 0 }, + { 'B', 1 }, + { 'C', 2 }, + { 'D', 3 }, + { 'E', 4 }, + { 'F', 5 }, + { 'G', 6 }, + { 'H', 7 }, + { 'J', 8 }, + { 'K', 9 }, + { 'L', 10 }, + { 'M', 11 }, + { 'N', 12 }, + { 'P', 13 }, + { 'R', 14 }, + { 'S', 15 }, + { 'T', 16 }, + { 'V', 17 }, + { 'W', 18 }, + { 'X', 19 }, + { 'Y', 20 }, + { 'Z', 21 }, + { '0', 22 }, + { '1', 23 }, + { '2', 24 }, + { '3', 25 }, + { '4', 26 }, + { '5', 27 }, + { '6', 28 }, + { '7', 29 }, + { '8', 30 }, + { '9', 31 } + }; + private void GEN() + { + //Game Genie only, for now. + //This applies to the Game Genie + if (txtCheat.Text.Length == 9 && txtCheat.Text.Contains("-")) + { + if (txtCheat.Text.IndexOf("-") != 5) + { + MessageBox.Show("All Genesis Game Genie Codes need to contain a dash after the fourth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (txtCheat.Text.Contains("I") == true | txtCheat.Text.Contains("O") == true | txtCheat.Text.Contains("Q") == true | txtCheat.Text.Contains("U") == true) + { + MessageBox.Show("All Genesis Game Genie Codes do not use I, O, Q or U.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + //This is taken from the GenGameGenie.CS file. + string code = txtCheat.Text; + int val = 0; + int add = 0; + string address = null; + string value = null; + //Remove the - + code = code.Remove(4, 1); + long hexcode = 0; + + // convert code to a long binary string + foreach (var t in code) + { + hexcode <<= 5; + int y; + _GENgameGenieTable.TryGetValue(t, out y); + hexcode |= y; + } + long decoded = (hexcode & 0xFF00000000) >> 32; + decoded |= hexcode & 0x00FF000000; + decoded |= (hexcode & 0x0000FF0000) << 16; + decoded |= (hexcode & 0x00000000700) << 5; + decoded |= (hexcode & 0x000000F800) >> 3; + decoded |= (hexcode & 0x00000000FF) << 16; + + val = (int)(decoded & 0x000000FFFF); + add = (int)((decoded & 0xFFFFFF0000) >> 16); + //Make our Strings get the Hex Values. + address = add.ToString("X6"); + value = val.ToString("X4"); + //Game Geneie, modifies the "ROM" which is why it says, "MD CART" + var watch = Watch.GenerateWatch(MemoryDomains["MD CART"], long.Parse(address, NumberStyles.HexNumber), Watch.WatchSize.Word, Watch.DisplayType.Hex, txtDescription.Text, true); + //Add Cheat + Global.CheatList.Add(new Cheat(watch, val)); + } + //Action Replay? + if (txtCheat.Text.Contains(":")) + { + //We start from Zero. + if (txtCheat.Text.IndexOf(":") != 6) + { + MessageBox.Show("All Genesis Action Replay/Pro Action Replay Codes need to contain a colon after the sixth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + //Problem: I don't know what the Non-FF Style codes are. + //TODO: Fix that. + if (txtCheat.Text.StartsWith("FF") == false) + { + MessageBox.Show("This Action Replay Code, is not understood by this tool.", "Tool Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + return; + } + //Now to do some work. + //Determine Length, to Determine Byte Size + + parseString = txtCheat.Text.Remove(0, 2); + switch (txtCheat.Text.Length) + { + case 9: + //Sample Code of 1-Byte: + //FFF761:64 + //Becomes: + //Address: F761 + //Value: 64 + RAMAddress = parseString.Remove(4, 3); + RAMValue = parseString.Remove(0, 5); + byteSize = 1; + break; + case 11: + //Sample Code of 2-Byte: + //FFF761:6411 + //Becomes: + //Address: F761 + //Value: 6411 + RAMAddress = parseString.Remove(4, 5); + RAMValue = parseString.Remove(0, 5); + byteSize = 2; + break; + default: + //We could have checked above but here is fine, since it's a quick check due to one of three possibilities. + MessageBox.Show("All Genesis Action Replay/Pro Action Replay Codes need to be either 9 or 11 characters in length", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + //Try and add. + try + { + //A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works. + //System Bus Domain, The Address to Watch, Byte size (Byte), Hex Display, Description, Big Endian. + if (byteSize == 1) + { + var watch = Watch.GenerateWatch(MemoryDomains["68K RAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, false); + //Take Watch, Add our Value we want, and it should be active when addded? + Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); + //Clear old Inputs + txtCheat.Clear(); + txtDescription.Clear(); + } + if (byteSize == 2) + { + var watch = Watch.GenerateWatch(MemoryDomains["68K RAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Word, Watch.DisplayType.Hex, txtDescription.Text, true); + //Take Watch, Add our Value we want, and it should be active when addded? + Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); + //Clear old Inputs + txtCheat.Clear(); + txtDescription.Clear(); + } + + } + //Someone broke the world? + catch (Exception ex) + { + MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } private void N64() - { //These codes, more or less work without Needing much work. - if (txtCheat.Text.Contains(" ") == false) + { + //These codes, more or less work without Needing much work. + if (txtCheat.Text.IndexOf(" ") != 8) { MessageBox.Show("All N64 GameShark Codes need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; @@ -247,9 +437,7 @@ namespace BizHawk.Client.EmuHawk MessageBox.Show("The GameShark code entered is not a recognized format.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); //Leave this Method, before someone gets hurt. return; - //break; - } - //Big Endian is USED constantly here. The question is, how do we determine if it's one or two bytes? + } //Now to get clever. //Sample Input for N64: //8133B21E 08FF @@ -265,22 +453,21 @@ namespace BizHawk.Client.EmuHawk RAMAddress = parseString.Remove(6, 5); //Get RAM Value RAMValue = parseString.Remove(0, 7); - try { //A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works. - //System Bus Domain, The Address to Watch, Byte size (Word), Hex Display, Description. Big Endian. + //System Bus Domain, The Address to Watch, Byte size (Word), Hex Display, Description, Big Endian. if (byteSize == 8) { //We have a Byte sized value - var watch = Watch.GenerateWatch(MemoryDomains["RDRAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Word, Watch.DisplayType.Hex, txtDescription.Text, true); + var watch = Watch.GenerateWatch(MemoryDomains["RDRAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, true); //Take Watch, Add our Value we want, and it should be active when addded? Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); } if (byteSize == 16) { //We have a Word (Double Byte) sized Value - var watch = Watch.GenerateWatch(MemoryDomains["RDRAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, true); + var watch = Watch.GenerateWatch(MemoryDomains["RDRAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Word, Watch.DisplayType.Hex, txtDescription.Text, true); //Take Watch, Add our Value we want, and it should be active when addded? Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); } @@ -297,9 +484,9 @@ namespace BizHawk.Client.EmuHawk private void PSX() { //These codes, more or less work without Needing much work. - if (txtCheat.Text.Contains(" ") == false) + if (txtCheat.Text.IndexOf(" ") != 8) { - MessageBox.Show("All PSX GameShark Cheats need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + MessageBox.Show("All PSX GameShark Codes need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (txtCheat.Text.Length != 13) @@ -412,9 +599,9 @@ namespace BizHawk.Client.EmuHawk private void SAT() { //Not yet. - if (txtCheat.Text.Contains(" ") == false) + if (txtCheat.Text.IndexOf(" ") != 8) { - MessageBox.Show("All Saturn GameShark Cheats need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + MessageBox.Show("All Saturn GameShark Codes need to contain a space after the eighth character", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (txtCheat.Text.Length != 13) @@ -489,6 +676,7 @@ namespace BizHawk.Client.EmuHawk } private void SNES() { + //TODO: Sample Code and Get Smarter? //This ONLY applies to Action Replay. if (txtCheat.Text.Length != 8) { From c4016affeef1871e8a58ba35600547ffac337e47 Mon Sep 17 00:00:00 2001 From: hegyak Date: Thu, 19 Nov 2015 11:07:52 -0800 Subject: [PATCH 20/20] Add SMS Action Replay handling. --- BizHawk.Client.EmuHawk/tools/GameShark.cs | 45 ++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/BizHawk.Client.EmuHawk/tools/GameShark.cs b/BizHawk.Client.EmuHawk/tools/GameShark.cs index 3c6c803b7a..3a70e2d1e5 100644 --- a/BizHawk.Client.EmuHawk/tools/GameShark.cs +++ b/BizHawk.Client.EmuHawk/tools/GameShark.cs @@ -21,7 +21,7 @@ namespace BizHawk.Client.EmuHawk - [ToolAttributes(released: true, supportedSystems: new[] { "GB", "GBA", "GEN", "N64", "PSX", "SAT", "SNES" })] + [ToolAttributes(released: true, supportedSystems: new[] { "GB", "GBA", "GEN", "N64", "PSX", "SAT", "SMS", "SNES" })] public partial class GameShark : Form, IToolForm, IToolFormAutoConfig { //We are using Memory Domains, so we NEED this. @@ -104,6 +104,9 @@ namespace BizHawk.Client.EmuHawk testo = txtCheat.Text.Remove(2, 11); SAT(); break; + case "SMS": + SMS(); + break; case "SNES": //Currently only does Action Replay SNES(); @@ -172,6 +175,7 @@ namespace BizHawk.Client.EmuHawk { //Nothing, yet //Sample of Decryption Code from mGBA + //const uint32_t GBACheatGameSharkSeeds[4] = { 0x09F4FBBD, 0x9681884A, 0x352027E9, 0xF3DEE5A7 }; /* void GBACheatDecryptGameShark(uint32_t* op1, uint32_t* op2, const uint32_t* seeds) { uint32_t sum = 0xC6EF3720; int i; @@ -674,6 +678,45 @@ namespace BizHawk.Client.EmuHawk MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } + private void SMS() + { + //This is FUN! + if (txtCheat.Text.IndexOf("-") != 4) + { + MessageBox.Show("All Master System Action Replay Codes need to contain a dash after the fourth character.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (txtCheat.Text.Length != 9) + { + MessageBox.Show("All Master System Action Replay Codes need to nine charaters in length.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + parseString = txtCheat.Text; + parseString = parseString.Remove(0, 2); + //MessageBox.Show(parseString); + RAMAddress = parseString.Remove(4, 2); + //MessageBox.Show(RAMAddress); + RAMAddress = RAMAddress.Replace("-", ""); + MessageBox.Show(RAMAddress); + RAMValue = parseString.Remove(0, 5); + MessageBox.Show(RAMValue); + try + { + //A Watch needs to be generated so we can make a cheat out of that. This is due to how the Cheat engine works. + //System Bus Domain, The Address to Watch, Byte size (Byte), Hex Display, Description. Not Big Endian. + var watch = Watch.GenerateWatch(MemoryDomains["Main RAM"], long.Parse(RAMAddress, NumberStyles.HexNumber), Watch.WatchSize.Byte, Watch.DisplayType.Hex, txtDescription.Text, false); + //Take Watch, Add our Value we want, and it should be active when addded? + Global.CheatList.Add(new Cheat(watch, int.Parse(RAMValue, NumberStyles.HexNumber))); + //Clear old Inputs + txtCheat.Clear(); + txtDescription.Clear(); + } + //Someone broke the world? + catch (Exception ex) + { + MessageBox.Show("An Error occured: " + ex.GetType().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } private void SNES() { //TODO: Sample Code and Get Smarter?