Advertisement
AndrewHaxalot

MainForm.cs

Jan 29th, 2014
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 183.61 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Drawing.Imaging;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.IO;
  10. using System.Runtime.InteropServices;
  11.  
  12. using FTDIUSBGecko;
  13. using AMS.Profile;
  14.  
  15. namespace GeckoApp
  16. {
  17.     public partial class MainForm : Form
  18.     {
  19.         [DllImport("User32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
  20.         protected static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
  21.         [DllImport("User32.dll")]
  22.         public extern static int GetScrollInfo(IntPtr hWnd, int fnBar, ref ScrollInfo lpsi);
  23.         [DllImport("User32.dll")]
  24.         public extern static int SetScrollInfo(IntPtr hWnd, int fnBar, ref ScrollInfo lpsi, bool bRedraw);
  25.         [StructLayout(LayoutKind.Sequential)]
  26.         public struct ScrollInfo
  27.         {
  28.             public uint cbSize;
  29.             public uint fMask;
  30.             public int nMin;
  31.             public int nMax;
  32.             public uint nPage;
  33.             public int nPos;
  34.             public int nTrackPos;
  35.         };
  36.  
  37.         private USBGecko gecko;
  38.         private MemSearch search;
  39.         private MemoryViewer viewer;
  40.         private Breakpoints bpHandler;
  41.         private Disassembly disassembler;
  42.         private WatchList watcher;
  43.         private FST fst;
  44.  
  45.         private ExceptionHandler exceptionHandling;
  46.  
  47.         private WatchDialog addWatchDialog;
  48.         private ValueInput watchValueInput;
  49.  
  50.         private List<UInt32> multiPokeAddr;
  51.  
  52.         private String gamename;
  53.         private bool GameNameStored;
  54.         private Xml SettingsFile;
  55.  
  56.         private CodeController GCTCodeContents;
  57.  
  58.         private List<Control> WasAlreadyDisabled;
  59.         private List<SearchComparisonInfo> searchComparisons;
  60.  
  61.         private TabPage TabLock;
  62.         private GeckoApp.external.AddressTextBox AddressContextMenuOwner;
  63.         private GeckoApp.external.HistoryTextBox HistoryContextMenuOwner;
  64.  
  65.         private NoteSheets notes;
  66.  
  67.         private GCTWizard codeWizard;
  68.  
  69.         private TextWriter BPStepLogWriter;
  70.  
  71.         private bool Connecting;
  72.         private bool SteppingOut;
  73.         private bool SteppingUntil;
  74.         private bool SearchingDisassembly;
  75.  
  76.         #region Initialization stuff
  77.         public MainForm()
  78.         {
  79.             InitializeComponent();
  80.         }
  81.  
  82.         private void MainForm_Load(object sender, EventArgs e)
  83.         {
  84.             this.Icon = Icon.ExtractAssociatedIcon(System.Reflection.Assembly.GetEntryAssembly().Location);
  85.  
  86.             int i;
  87.             SettingsFile = new Xml("gecko.xml");
  88.             SettingsFile.RootName = "gecko";
  89.  
  90.             gamename = "";
  91.             gecko = new USBGecko();
  92.             gecko.chunkUpdate += transfer;
  93.  
  94.             exceptionHandling = new ExceptionHandler(this);
  95.  
  96.             if (!Directory.Exists("DumpHistory"))
  97.                 Directory.CreateDirectory("DumpHistory");
  98.  
  99.             search = new MemSearch(gecko, SearchResults,
  100.                 PrvPage, NxtPage, ResList, UpDownSearchResultPage, exceptionHandling);
  101.  
  102.             viewer = new MemoryViewer(gecko, ValidMemory.ValidAreas[0].low, memViewGrid,
  103.                 memViewPAddress, memViewPValue, MemViewFPValue, exceptionHandling);
  104.  
  105. #if MONO
  106.             disassembler = new Disassembly(gecko, "./vdappc", DisAssBox, DisScroll,
  107.                 DisRegion, AsAddress, AsText, exceptionHandling);
  108. #else
  109.             disassembler = new Disassembly(gecko, "vdappc.exe", DisAssBox, DisScroll,
  110.                 DisRegion, AsAddress, AsText, exceptionHandling);
  111. #endif
  112.  
  113.             bpHandler = new Breakpoints(gecko, BPList, this, disassembler, BPDiss, BPClassic, BPCondList, exceptionHandling);
  114.             //bpHandler = new Breakpoints(gecko, BPList, this, disassembler, richTextBox1, BPClassic, BPCondList, exceptionHandling);
  115.             foreach (String reg in BPList.longRegNames)
  116.                 BPConditionRegSelect.Items.Add(reg.Trim());
  117.             BPConditionRegSelect.Items.Add("VoA");
  118.  
  119.             BPConditionRegSelect.SelectedIndex = 0;
  120.             BPConditionCompare.SelectedIndex = 0;
  121.  
  122.             bpHandler.BPSkip += BPSkipped;
  123.  
  124.             watcher = new WatchList(gecko, WatchList, WatchIntervalSet, exceptionHandling);
  125.             addWatchDialog = null;
  126.             watchValueInput = null;
  127.  
  128.             fst = new FST(gecko, FSTTreeView, FSTCodeData, FSTSetAsSource, FSTSetAsTarget,
  129.                 FSTGenSwap, FSTFileSource, FSTFileTarget, FSTSwapCode, FSTSwapNow, exceptionHandling);
  130.  
  131.             GCTCodeContents = new CodeController(GCTCodeList, GCTCodeValues);
  132.             GCTCodeContents.codesModified += GCTModified;
  133.  
  134.             bpHandler.BPStop += BPStopped;
  135.  
  136.             for (i = 0; i < ValidMemory.ValidAreas.Length; i++)
  137.             {
  138.                 memRange.Items.Add(
  139.                     GlobalFunctions.toHex(ValidMemory.ValidAreas[i].id, 2));
  140.                 MemViewARange.Items.Add(
  141.                     GlobalFunctions.toHex(ValidMemory.ValidAreas[i].id, 2));
  142.                 ToolsDumpRegions.Items.Add(
  143.                     GlobalFunctions.toHex(ValidMemory.ValidAreas[i].id, 2));
  144.             }
  145.  
  146.             codeWizard = new GCTWizard(GCTCodeContents);
  147.  
  148.             memRange.SelectedIndex = 0;
  149.             MemViewARange.SelectedIndex = 0;
  150.             MemViewShowMode.SelectedIndex = 0;
  151.             MemViewSearchType.SelectedIndex = 0;
  152.             ToolsDumpRegions.SelectedIndex = 0;
  153.  
  154.             comboBoxSearchDataType.SelectedIndex = 2;
  155.  
  156.             //UpperEnable.SelectedIndex = 0;
  157.  
  158.  
  159.             //BPType.SelectedIndex = 0;
  160.             comboBoxDisplayType.SelectedIndex = 0;
  161.  
  162.             WasAlreadyDisabled = new List<Control>();
  163.             searchComparisons = new List<SearchComparisonInfo>();
  164.             searchComparisons.Add(new SearchComparisonInfo());
  165.             comboBoxComparisonType.SelectedIndex = 0;
  166.             comboBoxComparisonRHS.SelectedIndex = 0;
  167.             buttonCancelSearch.Enabled = false;
  168.             SteppingOut = false;
  169.             buttonUndoSearch.Enabled = search.CanUndo();
  170.  
  171.             TabLock = null;
  172.             BPStepLogWriter = null;
  173.  
  174.             comboBoxPokeOperation.SelectedIndex = 0;
  175.  
  176.             SetComboboxValue("Screenshots", "Format", 0, ImgFormat);
  177.             SetComboboxValue("Screenshots", "Sizing", 0, ShotSizingType);
  178.  
  179.             int value = SettingsFile.GetValue("Screenshots", "JPEGQuality", 85);
  180.             if (value < 0 || value > 100)
  181.                 value = 85;
  182.             JPGQual.Value = value;
  183.  
  184.             multiPokeAddr = new List<UInt32>();
  185.  
  186.             FormStop(false);
  187.             CUSBGecko.Enabled = true;
  188.  
  189.             codesModified = false;
  190.  
  191.             AbtText.Text = "gecko dotNET Beta 0.63 by Link and dcx2\n\n"
  192.                           + "Special thanks to:\n\n"
  193.                           + "kenobi: for original WiiRd GUI!\n"
  194.                           + "Nuke: for the USB Gecko!\n"
  195.                           + "brkirch: for continuing Gecko OS!\n"
  196.                           + "Y.S.: for the original code handler!\n"
  197.                           + "Team Twiizers for bringing homebrew to the Wii\n"
  198.                           + "DevKitPro team: No homebrew without them!\n"
  199.                           + "Frank Wille: vdappc developer!\n"
  200.                           + "various beta testers!\n"
  201.                           + "and you!";
  202.  
  203.             notes = new NoteSheets();
  204.  
  205.             //Set MEM2 upper to 93400000
  206.             MEM2UpperBoundary.SelectedIndex = 0;
  207.  
  208.             // Restore previous settings
  209.             checkBoxAlwaysOnTop.Checked = GeckoApp.Properties.Settings.Default.AlwaysOnTop;
  210.             numericUpDownFPS.Value = GeckoApp.Properties.Settings.Default.FPS;
  211.             BPAddress.Text = GeckoApp.Properties.Settings.Default.BPAddr;
  212.             memViewAValue.Text = GeckoApp.Properties.Settings.Default.MemViewAddr;
  213.             BPType.SelectedIndex = GeckoApp.Properties.Settings.Default.BPType;
  214.             checkBoxBPNext.Checked = GeckoApp.Properties.Settings.Default.BPNext;
  215.             checkBoxPauseCodes.Checked = GeckoApp.Properties.Settings.Default.PauseCodes;
  216.             Size = GeckoApp.Properties.Settings.Default.LastSize;
  217.             int oldSplitter = GeckoApp.Properties.Settings.Default.LastSplitterSize;
  218.             // The splitter gets moved when the breakpoint page is entered
  219.             // so artificially force it to move
  220.             MainControl.SelectedTab = BreakpointPage;
  221.             MainControl.SelectedTab = searchPage;
  222.             splitContainerRegASM.SplitterDistance = oldSplitter;
  223.             toolStripTextBoxMemViewFontSize.Text = GeckoApp.Properties.Settings.Default.MemViewFontSize.ToString();
  224.             toolStripTextBoxMemViewFontSize_KeyDown(null, new KeyEventArgs(Keys.Enter));
  225.             viewFloatsInHexToolStripMenuItem.Checked = GeckoApp.Properties.Settings.Default.ViewFloatsInHex;
  226.             //addressTextBox1.CopyStringToHistory(GeckoApp.Properties.Settings.Default.addressHistory);
  227.             //addressTextBox1.AutoHistory = true;
  228.  
  229.         }
  230.  
  231.         private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
  232.         {
  233.             VerifyCodesAreSaved();
  234.             watcher.StopThread();
  235.  
  236.             Connecting = false;
  237.             //GeckoApp.Properties.Settings.Default.addressHistory = addressTextBox1.GetStringFromHistory();
  238.             GeckoApp.Properties.Settings.Default.Save();
  239.         }
  240.         #endregion
  241.  
  242.         #region Core functionality
  243.         private void SetComboboxValue(String section, String entry, int defaultValue, ComboBox box)
  244.         {
  245.             int maxIndex = box.Items.Count;
  246.             int value = SettingsFile.GetValue(section, entry, defaultValue);
  247.             if (value < 0 || value >= maxIndex)
  248.                 value = defaultValue;
  249.             box.SelectedIndex = value;
  250.         }
  251.  
  252.         public void FormStop(bool enable)
  253.         {
  254.             MainControl.Enabled = true;
  255.  
  256.             EnableMainControls(enable);
  257.  
  258.             PGame.Enabled = enable;
  259.             // TODO: Make RGame into a "Cancel Search"?
  260.             RGame.Enabled = enable;
  261.             CUSBGecko.Enabled = enable;
  262.             DisconnectButton.Enabled = enable;
  263.             OpenNotePad.Enabled = enable;
  264.             if (!enable && notes != null && notes.Visible)
  265.                 notes.Close();
  266.         }
  267.  
  268.         public void CryError()
  269.         {
  270.             FormStop(false);
  271.             gecko.Disconnect();
  272.             StatusCap.Text = "An error occured. Please reconnect!";
  273.             progressBar.Value = 0;
  274.             PCent.Text = "0%";
  275.             CUSBGecko.Enabled = true;
  276.             ResetSearch();
  277.         }
  278.  
  279.         private void transfer(UInt32 currentchunk, UInt32 allchunks, UInt32 transferred, UInt32 length, bool okay, bool dump)
  280.         {
  281.             if (length <= 1024)
  282.                 return;
  283.             int percent;
  284.             if (search.blockDump)
  285.             {
  286.                 double received = (double)(search.blocksDumpedSize + transferred);
  287.                 percent = (int)Math.Round(received * 100 / (double)search.totalBlockSize);
  288.                 if (percent < 100)
  289.                 {
  290.                     StatusCap.Text = "Performing block dump (block: " +
  291.                         search.blockID.ToString() + "/" + search.blockCount.ToString() +
  292.                         "; range:" +
  293.                         GlobalFunctions.toHex(search.blockStart) + "-" +
  294.                         GlobalFunctions.toHex(search.blockEnd) + ")";
  295.                 }
  296.                 else
  297.                     StatusCap.Text = "Transfer completed!";
  298.             }
  299.             else
  300.             {
  301.                 percent = (int)Math.Round(((double)transferred) / ((double)length) * 100);
  302.                 if (dump && percent < 100)
  303.                     StatusCap.Text = "Dumping data";
  304.                 else if (percent < 100)
  305.                     StatusCap.Text = "Sending data";
  306.                 else
  307.                     StatusCap.Text = "Transfer completed!";
  308.             }
  309.             PCent.Text = percent.ToString() + "%";
  310.             progressBar.Value = percent;
  311.             Application.DoEvents();
  312.         }
  313.  
  314.         public void ResetSearch()
  315.         {
  316.             Search.Text = "Search";
  317.             comboBoxComparisonRHS.Items[1] = (String)"Unknown value";
  318.             ResSrch.Enabled = false;
  319.             search.Reset();
  320.             buttonUndoSearch.Enabled = search.CanUndo();
  321.             SearchHistoryUpdownsReset();
  322.         }
  323.  
  324.         private String fixString(String input, int length)
  325.         {
  326.             String parse = input;
  327.             if (parse.Length > length)
  328.                 parse =
  329.                     parse.Substring(parse.Length - length, length);
  330.  
  331.             while (parse.Length < length)
  332.                 parse = "0" + parse;
  333.  
  334.             return parse;
  335.         }
  336.  
  337.         private void MainForm_Shown(object sender, EventArgs e)
  338.         {
  339.             CUSBGecko_Click(sender, e);
  340.         }
  341.         #endregion
  342.  
  343.         #region Always visible buttons
  344.         public void DisconnectButton_Click(object sender, EventArgs e)
  345.         {
  346.             FormStop(false);
  347.             try { gecko.Disconnect(); }
  348.             catch { }
  349.             StatusCap.Text = "Connection has been closed!";
  350.             progressBar.Value = 0;
  351.             PCent.Text = "0%";
  352.             CUSBGecko.Enabled = true;
  353.         }
  354.  
  355.         private bool UnknownStatus()
  356.         {
  357.             try
  358.             {
  359.                 WiiStatus stat = gecko.status();
  360.                 return (stat == WiiStatus.Unknown);
  361.             }
  362.             catch
  363.             {
  364.                 return true;
  365.             }
  366.         }
  367.  
  368.         public void CUSBGecko_Click(object sender, EventArgs e)
  369.         {
  370.             if (Connecting)
  371.             {
  372.                 Connecting = false;
  373.                 CUSBGecko.Text = "Connect to Gecko";
  374.                 return;
  375.             }
  376.  
  377.             bool retry = true;
  378.             bool success = false;
  379.             int attempt = 0;
  380.  
  381.             if (gecko.connected)
  382.             {
  383.                 StatusCap.Text = "Disconnecting!";
  384.                 try { gecko.Disconnect(); }
  385.                 catch { }
  386.                 Application.DoEvents();
  387.                 System.Threading.Thread.Sleep(500);
  388.             }
  389.  
  390.             while (retry && !success)
  391.             {
  392.                 attempt++;
  393.                 StatusCap.Text = "Connection attempt: " + attempt.ToString();
  394.                 Application.DoEvents();
  395.                 try
  396.                 {
  397.                     if (!gecko.Connect())
  398.                         throw new Exception();
  399.                     int failAttempt = 0;
  400.                     Connecting = true;
  401.                     CUSBGecko.Text = "Cancel Connection";
  402.                     while (UnknownStatus())
  403.                     {
  404.                         gecko.sendfail();
  405.                         failAttempt++;
  406.                         if (failAttempt > 10 || !Connecting)
  407.                         {
  408.                             if (!Connecting)
  409.                             {
  410.                                 retry = false;
  411.                             }
  412.                             Connecting = false;
  413.                             throw new Exception();
  414.                         }
  415.                         Application.DoEvents();
  416.                     }
  417.                     Connecting = false;
  418.  
  419.                     if (gecko.status() == WiiStatus.Loader)
  420.                     {
  421.                         DialogResult dr = MessageBox.Show("No game has been loaded yet!\nGecko dotNET requires a running game!\n\nShould a game be automatically loaded!", "Gecko dotNET", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
  422.                         if (dr == DialogResult.Yes)
  423.                             gecko.Hook();
  424.                         if (dr == DialogResult.Cancel)
  425.                         {
  426.                             Close();
  427.                             return;
  428.                         }
  429.                         while (gecko.status() == WiiStatus.Loader)
  430.                         {
  431.                             StatusCap.Text = "Waiting for game!";
  432.                             Application.DoEvents();
  433.                             System.Threading.Thread.Sleep(100);
  434.                         }
  435.                     }
  436.  
  437.                     success = true;
  438.                 }
  439.                 catch
  440.                 {
  441.                     if (attempt % 3 != 0)
  442.                         continue;
  443.                     retry =
  444.                         MessageBox.Show("Connection to the USB Gecko has failed!\n" +
  445.                          "Do you want to retry?", "Connection issue",
  446.                          MessageBoxButtons.YesNo, MessageBoxIcon.Warning) ==
  447.                          DialogResult.Yes;
  448.                 }
  449.             }
  450.  
  451.             EnableMainControls(success);
  452.             ResSrch.Enabled = false;
  453.             RGame.Enabled = success;
  454.             PGame.Enabled = success;
  455.             OpenNotePad.Enabled = success;
  456.  
  457.             try
  458.             {
  459.                 if (success)
  460.                 {
  461.                     CUSBGecko.Text = "Reconnect to Gecko";
  462.                     StatusCap.Text = "Ready!";
  463.  
  464.                     // 6 bytes for Game ID + 1 for null + 1 for Version
  465.                     // Apparently, some WiiWare/VC stuff only has 4 bytes for Game ID, but still 1 null + 1 Version too
  466.                     const int bytesToRead = 8;
  467.                     MemoryStream ms = new MemoryStream();
  468.                     gecko.Dump(0x80001800, 0x80001800 + bytesToRead, ms);
  469.                     String name = "";
  470.                     Byte[] buffer = new Byte[bytesToRead];
  471.                     ms.Seek(0, SeekOrigin.Begin);
  472.                     ms.Read(buffer, 0, bytesToRead);
  473.                     name = Encoding.ASCII.GetString(buffer);
  474.                     String rname = "";
  475.                     // Don't read version digit into name
  476.                     int i;  // Declare out of for loop scope so we can test the index later
  477.                     // Go to bytesToRead - 2
  478.                     // Should end at 4 for VC games and 6 for Wii games
  479.                     for (i = 0; i < bytesToRead - 2; i++)
  480.                         if (name[i] != (char)0)
  481.                             rname += name[i];
  482.                         else
  483.                             break;
  484.  
  485.                     // first time loading a game, or game changed; reload GCT files
  486.                     bool gamenameChanged = gamename != rname;
  487.                     gamename = rname;
  488.  
  489.                     int gameVer = ((int)(name[i + 1])) + 1;
  490.  
  491.                     this.Text = "Gecko dotNET (" + gamename;
  492.                     if (gameVer != 1)
  493.                     {
  494.                         this.Text += " version " + (gameVer).ToString();
  495.                     }
  496.                     this.Text += ")";
  497.  
  498.                     if (gamenameChanged)
  499.                     {
  500.                         GCTLoadCodes();
  501.                     }
  502.  
  503.                     GameNameStored = false;
  504.                     DisconnectButton.Enabled = true;
  505.                 }
  506.                 else
  507.                 {
  508.                     DisconnectButton.Enabled = false;
  509.                     CUSBGecko.Text = "Connect to Gecko";
  510.                     StatusCap.Text = "No USB Gecko connection availible!";
  511.  
  512.                     this.Text = "Gecko dotNET";
  513.                 }
  514.             }
  515.             catch (EUSBGeckoException exc)
  516.             {
  517.                 exceptionHandling.HandleException(exc);
  518.             }
  519.         }
  520.  
  521.         private void PGame_Click(object sender, EventArgs e)
  522.         {
  523.             try
  524.             {
  525.                 WiiStatus status = gecko.status();
  526.                 //if (status == WiiStatus.Paused || status == WiiStatus.Breakpoint)
  527.                 //{
  528.                 //    // FPS clicks the breakpoint button too quickly, so fall back to the old method of next-ing
  529.                 //    if (checkBoxFPS.Checked)
  530.                 //    {
  531.                 //        if (status == WiiStatus.Breakpoint)
  532.                 //        {
  533.                 //            // If we were at a breakpoint and they hit next, cancel the breakpoint and give it some time
  534.                 //            gecko.CancelBreakpoint();
  535.                 //            System.Threading.Thread.Sleep(500);
  536.                 //        }
  537.                 //        gecko.Resume();
  538.                 //        System.Threading.Thread.Sleep(1);
  539.                 //        gecko.Pause();
  540.                 //    }
  541.                 //    else
  542.                 //    {
  543.                 //        // Set a breakpoint on the code handler
  544.                 //        if (bpHandler.SetBreakpoint(0x800018A8, BreakpointType.Execute, true))
  545.                 //        {
  546.                 //            bpHandler.BreakpointNext = true;
  547.                 //            BPMode(true);
  548.                 //            MainControl.Enabled = false;    // don't let the user do anything while a breakpoint pause is active
  549.                 //        }
  550.                 //    }
  551.                 //}
  552.                 //else
  553.                 //{
  554.                 //    gecko.Pause();
  555.                 //}
  556.  
  557.                 bpHandler.ClearLogIndent();
  558.  
  559.                 // FPS clicks the breakpoint button too quickly, so fall back to the old method of next-ing
  560.                 if (checkBoxFPS.Checked || !checkBoxBPNext.Checked)
  561.                 {
  562.                     gecko.Resume();
  563.                     System.Threading.Thread.Sleep(1);
  564.                     gecko.Pause();
  565.                     System.Threading.Thread.Sleep(100);
  566.  
  567.                     // Update memory view if we're looking at it and we pressed next
  568.                     if (MainControl.SelectedTab == MemView)
  569.                     {
  570.                         viewer.Update();
  571.                     }
  572.                 }
  573.                 else
  574.                 {
  575.                     // Set a breakpoint on the code handler
  576.                     uint BPAddress;
  577.                     if (!addressTextBoxBPNext.IsValidGet(out BPAddress))
  578.                     {
  579.                         BPAddress = 0x800018A8;
  580.                     }
  581.                     //if (bpHandler.SetBreakpoint(0x800018A8, BreakpointType.Execute, true))
  582.                     // This was a SMG2 breakpoint I was using
  583.                     //if (bpHandler.SetBreakpoint(0x80393CC0, BreakpointType.Execute, true))
  584.                     if (bpHandler.SetBreakpoint(BPAddress, BreakpointType.Execute, true))
  585.                     {
  586.                         bpHandler.BreakpointNext = true;
  587.                         BPMode(true);
  588.                         //MainControl.Enabled = false;    // don't let the user do anything while a breakpoint pause is active
  589.                     }
  590.                 }
  591.  
  592.  
  593.                 PGame.Text = "Next frame";
  594.  
  595.                 if (checkBoxBPNext.Checked)
  596.                 {
  597.                     // Use the Run button as a Cancel button for BreakpointNext
  598.                     if (bpHandler.BreakpointNext)
  599.                     {
  600.                         RGame.Text = "Cancel";
  601.                     }
  602.                 }
  603.             }
  604.             catch (EUSBGeckoException exc)
  605.             {
  606.                 exceptionHandling.HandleException(exc);
  607.             }
  608.         }
  609.  
  610.         private void RGame_Click(object sender, EventArgs e)
  611.         {
  612.             PGame.Text = "Pause game";
  613.             RGame.Text = "Run game";
  614.  
  615.             try
  616.             {
  617.                 if (bpHandler.BreakpointNext)
  618.                 {
  619.                     // We're doing a breakpoint-next and the user clicked "Cancel"
  620.                     BPCancel_Click(sender, e);
  621.                 }
  622.                 gecko.Resume();
  623.             }
  624.             catch (EUSBGeckoException exc)
  625.             {
  626.                 exceptionHandling.HandleException(exc);
  627.             }
  628.  
  629.         }
  630.  
  631.         private void OpenNotePad_Click(object sender, EventArgs e)
  632.         {
  633.             notes.Show(gamename);
  634.         }
  635.         #endregion
  636.  
  637.         #region Search tab
  638.         private void memRange_SelectedIndexChanged(object sender, EventArgs e)
  639.         {
  640.             int id = memRange.SelectedIndex;
  641.             memStart.Text =
  642.                 Convert.ToString(ValidMemory.ValidAreas[id].low, 16).ToUpper();
  643.             memEnd.Text =
  644.                 Convert.ToString(ValidMemory.ValidAreas[id].high, 16).ToUpper();
  645.         }
  646.  
  647.         private void UpperEnable_SelectedIndexChanged(object sender, EventArgs e)
  648.         {
  649.             //bool enable = UpperEnable.SelectedIndex == 1;
  650.             //upperValue.Enabled = enable;
  651.         }
  652.  
  653.         private void comboBoxComparisonRHS_SelectedIndexChanged(object sender, EventArgs e)
  654.         {
  655.             bool enable = comboBoxComparisonRHS.SelectedIndex == 0 || comboBoxComparisonRHS.SelectedIndex == 3;
  656.             textBoxComparisonValue.Enabled = enable;
  657.             //UpperEnable.Enabled = enable;
  658.             string comboBoxText = (string)comboBoxComparisonRHS.Items[1];
  659.             if (comboBoxText.Equals("Unknown Value") && comboBoxComparisonRHS.SelectedIndex == 1)
  660.             {
  661.                 // disable comparison type combo box when Unknown searching
  662.                 comboBoxComparisonType.Enabled = false;
  663.             }
  664.             else
  665.             {
  666.                 // disable comparison type combo box when Unknown searching
  667.                 comboBoxComparisonType.Enabled = true;
  668.             }
  669.  
  670.             if (!enable)
  671.             {
  672.                 //UpperEnable.SelectedIndex = 0;
  673.                 if (comboBoxComparisonType.Items.Count <= 6)
  674.                 {
  675.                     comboBoxComparisonType.Items.Add("Different by");
  676.                     comboBoxComparisonType.Items.Add("Different by less than");
  677.                     comboBoxComparisonType.Items.Add("Different by more than");
  678.                 }
  679.  
  680.  
  681.                 // Use the value field for different by searches
  682.                 if (comboBoxComparisonType.SelectedIndex >= 6 && comboBoxComparisonType.Enabled)
  683.                 {
  684.                     textBoxComparisonValue.Enabled = true;
  685.                 }
  686.  
  687.             }
  688.             if (enable)
  689.             {
  690.                 if (comboBoxComparisonType.SelectedIndex >= 6)
  691.                     comboBoxComparisonType.SelectedIndex = 0;
  692.                 while (comboBoxComparisonType.Items.Count > 6)
  693.                     comboBoxComparisonType.Items.RemoveAt(6);
  694.             }
  695.             searchComparisons[SearchGroupIndex].searchType = GetCmpRHS();
  696.         }
  697.  
  698.         private void ValueLength_SelectedIndexChanged(object sender, EventArgs e)
  699.         {
  700.             int length;
  701.             switch (comboBoxSearchDataType.SelectedIndex)
  702.             {
  703.                 case 0: length = 2; break;
  704.                 case 1: length = 4; break;
  705.                 default: length = 8; break;
  706.             }
  707.             textBoxComparisonValue.MaxLength = length;
  708.             //upperValue.MaxLength = length;
  709.  
  710.             textBoxComparisonValue.Text = fixString(textBoxComparisonValue.Text, length);
  711.             //upperValue.Text = fixString(upperValue.Text, length);
  712.             //diffOf.Text = fixString(diffOf.Text, length);
  713.         }
  714.  
  715.         private void cmpType_SelectedIndexChanged(object sender, EventArgs e)
  716.         {
  717.             bool enable = comboBoxComparisonType.SelectedIndex >= 6;
  718.             bool enable2 = comboBoxComparisonRHS.SelectedIndex == 0 || comboBoxComparisonRHS.SelectedIndex == 3;
  719.             textBoxComparisonValue.Enabled = enable || enable2;
  720.             if (enable)
  721.             {
  722.                 //UpperEnable.SelectedIndex = 0;
  723.             }
  724.             searchComparisons[SearchGroupIndex].comparisonType = GetCmpType();
  725.         }
  726.  
  727.         private void Search_Click(object sender, EventArgs e)
  728.         {
  729.             SearchSize size;
  730.             SearchType type;
  731.             ComparisonType cType;
  732.             bool enableUpper;
  733.             bool useDifference;
  734.  
  735.             switch (comboBoxSearchDataType.SelectedIndex)
  736.             {
  737.                 case 0: size = SearchSize.Bit8; break;
  738.                 case 1: size = SearchSize.Bit16; break;
  739.                 case 2: size = SearchSize.Bit32; break;
  740.                 case 3: size = SearchSize.Single; break;
  741.                 default: size = SearchSize.Bit32; break;
  742.             }
  743.  
  744.             switch (comboBoxComparisonRHS.SelectedIndex)
  745.             {
  746.                 case 3: type = SearchType.Diff; break;
  747.                 case 2: type = SearchType.Old; break;
  748.                 case 1: type = SearchType.Unknown; break;
  749.                 default: type = SearchType.Exact; break;
  750.             }
  751.  
  752.             //enableUpper = UpperEnable.SelectedIndex == 1;
  753.  
  754.             cType = GetCmpType();
  755.  
  756.             useDifference = (cType == ComparisonType.DifferentBy ||
  757.                              cType == ComparisonType.DifferentByLess ||
  758.                              cType == ComparisonType.DifferentByMore);
  759.  
  760.             UInt32 lAddress = 0;
  761.             UInt32 hAddress = 0;
  762.             UInt32 lValue = 0;
  763.             UInt32 hValue = 0;
  764.             UInt32 diffBy = 0;
  765.  
  766.             // Validate inputs
  767.             if (!GlobalFunctions.tryToHex(memStart.Text, out lAddress))
  768.             {
  769.                 MessageBox.Show("Start address invalid!");
  770.                 return;
  771.             }
  772.  
  773.             if (!GlobalFunctions.tryToHex(memEnd.Text, out hAddress))
  774.             {
  775.                 MessageBox.Show("End address invalid!");
  776.                 return;
  777.             }
  778.  
  779.             // Make sure they don't scan memory backwards, will crash the game
  780.             if (lAddress > hAddress)
  781.             {
  782.                 MessageBox.Show("Start and End addresses backwards!");
  783.                 return;
  784.             }
  785.  
  786.             if (!GlobalFunctions.tryToHex(textBoxComparisonValue.Text, out lValue) && textBoxComparisonValue.Enabled)
  787.             {
  788.                 MessageBox.Show("Search value invalid!");
  789.                 return;
  790.             }
  791.  
  792.  
  793.             //if (enableUpper)
  794.             //{
  795.             //    //if (!GlobalFunctions.tryToHex(upperValue.Text, out hValue))
  796.             //    //{
  797.             //    //    MessageBox.Show("Upper search value invalid!");
  798.             //    //    return;
  799.             //    //}
  800.  
  801.             //    if (hValue < lValue)
  802.             //    {
  803.             //        UInt32 temp = hValue;
  804.             //        hValue = lValue;
  805.             //        lValue = temp;
  806.             //    }
  807.             //}
  808.  
  809.             if (useDifference)
  810.             {
  811.                 //if (!GlobalFunctions.tryToHex(diffOf.Text, out diffBy))
  812.                 //{
  813.                 //    MessageBox.Show("Difference value invalid!");
  814.                 //    return;
  815.                 //}
  816.             }
  817.  
  818.             if (!ValidMemory.validRange(lAddress, hAddress))
  819.             {
  820.                 MessageBox.Show("Memory range invalid!");
  821.                 return;
  822.             }
  823.  
  824.             // Keep the user from doing stuff while we search
  825.             try
  826.             {
  827.                 FormStop(false);
  828.                 TabLock = searchPage;
  829.                 buttonCancelSearch.Enabled = true;
  830.                 buttonCancelSearch.BringToFront();
  831.                 // Pause Gecko - while changing blocks during block search
  832.                 // the game will sometimes move forward a few frames
  833.                 bool WasRunning = (gecko.status() == WiiStatus.Running);
  834.                 gecko.SafePause();
  835.                 //List<SearchComparisonInfo> comparisons = new List<SearchComparisonInfo>();
  836.                 //comparisons.Add(new SearchComparisonInfo(cType, lValue));
  837.                 bool success = search.SearchRefactored(lAddress, hAddress, searchComparisons, size);
  838.  
  839.  
  840.                 //bool success = search.Search(lAddress, hAddress, lValue, hValue, enableUpper, type, size, cType, diffBy);
  841.                 // If we were running, go back to running
  842.                 // If we *weren't* running, *don't* go back to running
  843.                 if (WasRunning)
  844.                 {
  845.                     gecko.SafeResume();
  846.                 }
  847.  
  848.                 FormStop(true);
  849.                 buttonCancelSearch.Enabled = false;
  850.                 buttonCancelSearch.SendToBack();
  851.                 buttonUndoSearch.Enabled = search.CanUndo();
  852.                 TabLock = null;
  853.  
  854.                 if (success)
  855.                 {
  856.                     Search.Text = "Refine";
  857.                     ResSrch.Enabled = true;
  858.                     search.SaveSearchToIndex(search.DumpNum);
  859.                     SearchHistoryUpdownsInc();
  860.                 }
  861.                 else
  862.                 {
  863.                     ResetSearch();
  864.                 }
  865.             }
  866.             catch (Exception ex)
  867.             {
  868.                 Logger.WriteException(ex);
  869.                 CryError();
  870.             }
  871.         }
  872.  
  873.         private SearchType GetCmpRHS()
  874.         {
  875.             SearchType sType;
  876.             switch (comboBoxComparisonRHS.SelectedIndex)
  877.             {
  878.                 case 1: sType = SearchType.Unknown; break;
  879.                 case 2: sType = SearchType.Old; break;
  880.                 case 3: sType = SearchType.Diff; break;
  881.                 default: sType = SearchType.Exact; break;
  882.             }
  883.  
  884.             return sType;
  885.         }
  886.  
  887.         private void SetCmpRHS(SearchType sType)
  888.         {
  889.             switch (sType)
  890.             {
  891.                 case SearchType.Unknown: comboBoxComparisonRHS.SelectedIndex = 1; break;
  892.                 case SearchType.Old: comboBoxComparisonRHS.SelectedIndex = 2; break;
  893.                 case SearchType.Diff: comboBoxComparisonRHS.SelectedIndex = 3; break;
  894.                 default: comboBoxComparisonRHS.SelectedIndex = 0; break;
  895.             }
  896.         }
  897.  
  898.         private ComparisonType GetCmpType()
  899.         {
  900.             ComparisonType cType;
  901.             switch (comboBoxComparisonType.SelectedIndex)
  902.             {
  903.                 case 1: cType = ComparisonType.NotEqual; break;
  904.                 case 2: cType = ComparisonType.Lower; break;
  905.                 case 3: cType = ComparisonType.LowerEqual; break;
  906.                 case 4: cType = ComparisonType.Greater; break;
  907.                 case 5: cType = ComparisonType.GreaterEqual; break;
  908.                 case 6: cType = ComparisonType.DifferentBy; break;
  909.                 case 7: cType = ComparisonType.DifferentByLess; break;
  910.                 case 8: cType = ComparisonType.DifferentByMore; break;
  911.                 default: cType = ComparisonType.Equal; break;
  912.             }
  913.  
  914.             return cType;
  915.         }
  916.  
  917.         private void SetCmpType(ComparisonType cType)
  918.         {
  919.             switch (cType)
  920.             {
  921.                 case ComparisonType.NotEqual: comboBoxComparisonType.SelectedIndex = 1; break;
  922.                 case ComparisonType.Lower: comboBoxComparisonType.SelectedIndex = 2; break;
  923.                 case ComparisonType.LowerEqual: comboBoxComparisonType.SelectedIndex = 3; break;
  924.                 case ComparisonType.Greater: comboBoxComparisonType.SelectedIndex = 4; break;
  925.                 case ComparisonType.GreaterEqual: comboBoxComparisonType.SelectedIndex = 5; break;
  926.                 case ComparisonType.DifferentBy: comboBoxComparisonType.SelectedIndex = 6; break;
  927.                 case ComparisonType.DifferentByLess: comboBoxComparisonType.SelectedIndex = 7; break;
  928.                 case ComparisonType.DifferentByMore: comboBoxComparisonType.SelectedIndex = 8; break;
  929.                 default: comboBoxComparisonType.SelectedIndex = 0; break;
  930.             }
  931.         }
  932.  
  933.         private void UpdateValueTypeDropDown()
  934.         {
  935.             if (numericUpDownNewSearchIndex.Value == 0)
  936.             {
  937.                 // Don't compare against anything - unknown search
  938.                 comboBoxComparisonRHS.Items[1] = (String)"Unknown value";
  939.             }
  940.             else
  941.             {
  942.                 comboBoxComparisonRHS.Items[1] = (String)"New column (" + numericUpDownNewSearchIndex.Value + ")";
  943.             }
  944.  
  945.             if (numericUpDownOldSearchIndex.Value == 0)
  946.             {
  947.                 // Clear any other items from the list if there is no old dump loaded
  948.                 while (comboBoxComparisonRHS.Items.Count > 2) comboBoxComparisonRHS.Items.RemoveAt(2);
  949.             }
  950.             else
  951.             {
  952.                 String oldCol = "Old column (" + numericUpDownOldSearchIndex.Value + ")";
  953.  
  954.                 // Create or alter the item as needed
  955.                 if (comboBoxComparisonRHS.Items.Count < 3)
  956.                 {
  957.                     comboBoxComparisonRHS.Items.Add(oldCol);
  958.                 }
  959.                 else
  960.                 {
  961.                     comboBoxComparisonRHS.Items[2] = oldCol;
  962.                 }
  963.  
  964.                 // return results that are within some distance of an existing result
  965.                 // TODO: implement this...
  966.                 //if (numericUpDownNewSearchIndex.Value != 0)
  967.                 //{
  968.                 //    String diffCol = "Distance (" + numericUpDownNewSearchIndex.Value + ")";
  969.                 //    // Create or alter the item as needed
  970.                 //    if (comboBoxComparisonRHS.Items.Count < 4)
  971.                 //    {
  972.                 //        comboBoxComparisonRHS.Items.Add(diffCol);
  973.                 //    }
  974.                 //    else
  975.                 //    {
  976.                 //        comboBoxComparisonRHS.Items[3] = diffCol;
  977.                 //    }
  978.                 //}
  979.             }
  980.         }
  981.  
  982.         private void SearchHistoryUpdownsInc()
  983.         {
  984.             numericUpDownOldSearchIndex.ValueChanged -= numericUpDownOldSearchIndex_ValueChanged;
  985.             numericUpDownNewSearchIndex.ValueChanged -= numericUpDownNewSearchIndex_ValueChanged;
  986.  
  987.             numericUpDownOldSearchIndex.Value = numericUpDownNewSearchIndex.Value;
  988.             numericUpDownNewSearchIndex.Value = Convert.ToDecimal(search.DumpNum);
  989.  
  990.             numericUpDownOldSearchIndex.ValueChanged += numericUpDownOldSearchIndex_ValueChanged;
  991.             numericUpDownNewSearchIndex.ValueChanged += numericUpDownNewSearchIndex_ValueChanged;
  992.  
  993.             UpdateValueTypeDropDown();
  994.         }
  995.  
  996.         private void SearchHistoryUpdownsReset()
  997.         {
  998.             numericUpDownOldSearchIndex.Value = 0;
  999.             numericUpDownNewSearchIndex.Value = 0;
  1000.             UpdateValueTypeDropDown();
  1001.         }
  1002.  
  1003.         private void PkAddress_Click(object sender, EventArgs e)
  1004.         {
  1005.             if (SearchResults.SelectedRows.Count == 0)
  1006.                 return;
  1007.             if (SearchResults.SelectedRows.Count == 1)
  1008.             {
  1009.                 StringResult item = search.GetResult(
  1010.                     SearchResults.SelectedRows[0].Index);
  1011.                 PAddress.Text = item.SAddress;
  1012.                 if (item.SOldValue != String.Empty)
  1013.                 {
  1014.                     PValue.Text = item.SOldValue;
  1015.                 }
  1016.                 else
  1017.                 {
  1018.                     PValue.Text = item.SValue;
  1019.                 }
  1020.             }
  1021.             else
  1022.             {
  1023.                 multiPokeAddr.Clear();
  1024.                 PAddress.ClearHistory();
  1025.                 UInt32 address;
  1026.                 StringResult item = search.GetResult(
  1027.                     SearchResults.SelectedRows[0].Index);
  1028.                 for (int i = 0; i < SearchResults.SelectedRows.Count; i++)
  1029.                 {
  1030.                     address = search.GetAddress(
  1031.                         SearchResults.SelectedRows[i].Index);
  1032.                     multiPokeAddr.Add(address);
  1033.                     PAddress.AddAddressToHistory(address);
  1034.                 }
  1035.                 PAddress.Text = "MP";
  1036.                 PValue.Text = item.SValue;
  1037.             }
  1038.         }
  1039.  
  1040.         private void makeCode_Click(object sender, EventArgs e)
  1041.         {
  1042.             if (SearchResults.SelectedRows.Count == 0)
  1043.                 return;
  1044.             List<UInt32> addresses = new List<UInt32>();
  1045.             UInt32 address;
  1046.             int i;
  1047.             for (i = 0; i < SearchResults.SelectedRows.Count; i++)
  1048.             {
  1049.                 address = search.GetAddress(SearchResults.SelectedRows[i].Index);
  1050.                 addresses.Add(address);
  1051.             }
  1052.  
  1053.             addresses.Sort();
  1054.  
  1055.             CodeContent nCode = new CodeContent();
  1056.             UInt32 cAddressR = 0x80000000;
  1057.             UInt32 rAddressR;
  1058.             UInt32 offset;
  1059.             bool firstLine = false;
  1060.             UInt32 add;
  1061.             switch (search.searchSize)
  1062.             {
  1063.                 case SearchSize.Bit8:
  1064.                     add = 0;
  1065.                     break;
  1066.                 case SearchSize.Bit16:
  1067.                     add = 0x02000000;
  1068.                     break;
  1069.                 default:
  1070.                     add = 0x04000000;
  1071.                     break;
  1072.             }
  1073.  
  1074.             int nCodeId = GCTCodeContents.Count;
  1075.             //nCode.name = "New code " + (nCodeId + 1).ToString();
  1076.             String name;
  1077.             if (!InputBox.Show("Code name", "Insert code name", "New code", out name))
  1078.             {
  1079.                 name = "New code " + (nCodeId + 1).ToString();
  1080.             }
  1081.             for (i = 0; i < addresses.Count; i++)
  1082.             {
  1083.                 rAddressR = addresses[i] & 0xFE000000;
  1084.                 if (firstLine && cAddressR != rAddressR && cAddressR != 0x80000000)
  1085.                     nCode.addLine(0xE0000000, 0x80008000);
  1086.                 if (cAddressR != rAddressR)
  1087.                     if (rAddressR != 0x80000000)
  1088.                         nCode.addLine(0x42000000, rAddressR);
  1089.                 cAddressR = rAddressR;
  1090.  
  1091.                 offset = addresses[i] + add - rAddressR;
  1092.                 nCode.addLine(offset, search.GetNewValueFromAddress(addresses[i]));
  1093.  
  1094.                 firstLine = true;
  1095.             }
  1096.             if (cAddressR != 0x80000000)
  1097.                 nCode.addLine(0xE0000000, 0x80008000);
  1098.             GCTCodeContents.AddCode(nCode, name);
  1099.  
  1100.             GCTCodeList.Items[nCodeId].Selected = true;
  1101.             MainControl.SelectedTab = GCTPage;
  1102.         }
  1103.  
  1104.         private void PButton_Click(object sender, EventArgs e)
  1105.         {
  1106.             Byte tag = Byte.Parse(((Button)sender).Tag.ToString());
  1107.  
  1108.             TextBox aBox, vBox;
  1109.             bool allowMulti;
  1110.             switch (tag)
  1111.             {
  1112.                 case 1:
  1113.                     // Don't multi-poke if we're in Memory Viewer
  1114.                     aBox = memViewPAddress;
  1115.                     vBox = memViewPValue;
  1116.                     allowMulti = false;
  1117.                     break;
  1118.                 default:
  1119.                     aBox = PAddress;
  1120.                     vBox = PValue;
  1121.                     allowMulti = true;
  1122.                     break;
  1123.             }
  1124.  
  1125.             UInt32 addr = 0;
  1126.             UInt32 value;
  1127.             UInt16 Val16;
  1128.             Byte Val8;
  1129.             UInt32 Val32;
  1130.             String AText = aBox.Text;
  1131.             String VText = vBox.Text;
  1132.             //int valLength = VText.Length;
  1133.  
  1134.  
  1135.             bool multipoke = false;
  1136.  
  1137.             if (AText != "MP")
  1138.             {
  1139.                 // Check the address text for a valid hex number, if it's not a multi-poke
  1140.                 if (!GlobalFunctions.tryToHex(AText, out addr))
  1141.                 {
  1142.                     MessageBox.Show("Invalid address");
  1143.                     return;
  1144.                 }
  1145.                 multipoke = false;
  1146.             }
  1147.             else if (allowMulti)
  1148.             {
  1149.                 // If we can multi-poke, make sure we have some to poke
  1150.                 if (PAddress.GetHistoryCount() == 0)
  1151.                 {
  1152.                     MessageBox.Show("No multipoke data availible!");
  1153.                     return;
  1154.                 }
  1155.                 multipoke = true;
  1156.             }
  1157.             else
  1158.             {
  1159.                 MessageBox.Show("Multipoke not usable in this poke box!");
  1160.                 return;
  1161.             }
  1162.  
  1163.             // Check to make sure the hex number is actually a valid address too
  1164.             // TODO: We should to something to protect multi-poke, too.  Iterate through the array with validAddress?
  1165.             if (!multipoke && !ValidMemory.validAddress(addr))
  1166.             {
  1167.                 MessageBox.Show("Address is not within valid memory!");
  1168.                 return;
  1169.             }
  1170.  
  1171.             // Okay, so far so good, the address is valid, how about the value?
  1172.             if (!GlobalFunctions.tryToHex(VText, out value))
  1173.             {
  1174.                 MessageBox.Show("Invalid address");
  1175.                 return;
  1176.             }
  1177.  
  1178.             //try
  1179.             //{
  1180.             //    value = Convert.ToUInt32(vBox.Text, 16);
  1181.             //}
  1182.             //catch
  1183.             //{
  1184.             //    MessageBox.Show("Invalid value");
  1185.             //    return;
  1186.             //}
  1187.  
  1188.             uint currentValue;
  1189.             // Currently, we only allow poke operations for
  1190.             // 32-bit single pokes in the Memory Viewer window
  1191.             // Perhaps we should include other poke types?
  1192.             if (!multipoke && VText.Length > 4 && tag == 1)
  1193.             {
  1194.                 currentValue = gecko.peek(addr);
  1195.  
  1196.                 // Modify the current value according to the Poke Operation type
  1197.                 switch (comboBoxPokeOperation.SelectedIndex)
  1198.                 {
  1199.                     case 7:     // DIV
  1200.                         value = currentValue / value;
  1201.                         break;
  1202.                     case 6:     // MUL
  1203.                         value = currentValue * value;
  1204.                         break;
  1205.                     case 5:     // SUB
  1206.                         value = currentValue - value;
  1207.                         break;
  1208.                     case 4:     // ADD
  1209.                         value = currentValue + value;
  1210.                         break;
  1211.                     case 3:     // XOR
  1212.                         value = currentValue ^ value;
  1213.                         break;
  1214.                     case 2:     // AND
  1215.                         value = currentValue & value;
  1216.                         break;
  1217.                     case 1:     // OR
  1218.                         value = currentValue | value;
  1219.                         break;
  1220.                     case 0:     // Write
  1221.                     default:     // Write
  1222.                         value = value;
  1223.                         break;
  1224.                 }
  1225.             }
  1226.  
  1227.             try
  1228.             {
  1229.                 int MultiPokeCount = PAddress.GetHistoryCount();
  1230.                 if (VText.Length > 4)
  1231.                 {
  1232.                     Val32 = value;
  1233.                     if (!multipoke)
  1234.                     {
  1235.                         // Fix the user's text box if they messed up alignment?
  1236.                         addr = addr & 0xFFFFFFFC;
  1237.                         aBox.Text = Convert.ToString(addr, 16);
  1238.                     }
  1239.                     if (!multipoke)
  1240.                         gecko.poke32(addr, Val32);
  1241.                     else
  1242.                         for (int i = 0; i < MultiPokeCount; i++)
  1243.                             gecko.poke32(PAddress.GetHistoryuint(i), Val32);
  1244.                     //gecko.poke32(multiPokeAddr[i], Val32);
  1245.                 }
  1246.                 else if (VText.Length > 2)
  1247.                 {
  1248.                     Val16 = (UInt16)value;
  1249.                     if (!multipoke)
  1250.                     {
  1251.                         // Fix the user's text box if they messed up alignment?
  1252.                         addr = addr & 0xFFFFFFFE;
  1253.                         aBox.Text = Convert.ToString(addr, 16);
  1254.                     }
  1255.                     if (!multipoke)
  1256.                         gecko.poke16(addr, Val16);
  1257.                     else
  1258.                         for (int i = 0; i < MultiPokeCount; i++)
  1259.                             gecko.poke16(PAddress.GetHistoryuint(i), Val16);
  1260.                     //gecko.poke16(multiPokeAddr[i], Val16);
  1261.                 }
  1262.                 else
  1263.                 {
  1264.                     Val8 = (Byte)value;
  1265.                     if (!multipoke)
  1266.                         gecko.poke08(addr, Val8);
  1267.                     else
  1268.                         for (int i = 0; i < MultiPokeCount; i++)
  1269.                             gecko.poke08(PAddress.GetHistoryuint(i), Val8);
  1270.                     //gecko.poke08(multiPokeAddr[i], Val8);
  1271.                 }
  1272.  
  1273.                 if (tag == 1)
  1274.                 {
  1275.                     System.Threading.Thread.Sleep(100);
  1276.                     //viewer.address = addr;
  1277.                     // Do a fast update because
  1278.                     // 1) We know they clicked on the poke button, so the selected cell isn't changing
  1279.                     // 2) We don't need to update the Poke value because
  1280.                     //   2a) on a write, it's already the value it's going to be, or
  1281.                     //   2b) on some non-write operations (like XOR), we probably want to keep the poke value
  1282.                     //       although perhaps some operations should load the new value...
  1283.                     viewer.Update(true);
  1284.                 }
  1285.             }
  1286.             catch (EUSBGeckoException exc)
  1287.             {
  1288.                 exceptionHandling.HandleException(exc);
  1289.             }
  1290.         }
  1291.  
  1292.         private void ResSrch_Click(object sender, EventArgs e)
  1293.         {
  1294.             if (MessageBox.Show("Are you sure you want to start a new search?",
  1295.                 "Attention", MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
  1296.                 != DialogResult.Yes)
  1297.                 return;
  1298.             ResetSearch();
  1299.         }
  1300.  
  1301.         private void PAddress_KeyPress(object sender, KeyPressEventArgs e)
  1302.         {
  1303.             if ((Byte)e.KeyChar == 13)
  1304.             {
  1305.                 PValue.Focus();
  1306.                 e.Handled = true;
  1307.             }
  1308.         }
  1309.  
  1310.         private void PValue_KeyPress(object sender, KeyPressEventArgs e)
  1311.         {
  1312.             if ((Byte)e.KeyChar == 13)
  1313.             {
  1314.                 PkAddress_Click(sender, e);
  1315.                 e.Handled = true;
  1316.             }
  1317.         }
  1318.  
  1319.  
  1320.         private void BpSAddress_Click(object sender, EventArgs e)
  1321.         {
  1322.             if (SearchResults.SelectedRows.Count != 1)
  1323.                 return;
  1324.  
  1325.             StringResult foundCode = search.GetResult(SearchResults.SelectedRows[0].Index);
  1326.             BPAddress.Text = foundCode.SAddress;
  1327.  
  1328.             // If BPType is Execute, change to Read/Write
  1329.             if (BPType.SelectedIndex == 3)
  1330.             {
  1331.                 BPType.SelectedIndex = 2;
  1332.             }
  1333.  
  1334.             MainControl.SelectedTab = BreakpointPage;
  1335.         }
  1336.  
  1337.  
  1338.         private void ShowInDiss_Click(object sender, EventArgs e)
  1339.         {
  1340.             if (SearchResults.SelectedRows.Count != 1)
  1341.                 return;
  1342.  
  1343.             UInt32 address = search.GetAddress(SearchResults.SelectedRows[0].Index);
  1344.             disassembler.DissToBox(address);
  1345.             MainControl.SelectedTab = DisPage;
  1346.         }
  1347.  
  1348.         private void ShowInMemView_Click(object sender, EventArgs e)
  1349.         {
  1350.             if (SearchResults.SelectedRows.Count != 1)
  1351.                 return;
  1352.             UInt32 mAddress = search.GetAddress(SearchResults.SelectedRows[0].Index);
  1353.             CenteredMemViewSelection(sender, e, mAddress);
  1354.         }
  1355.  
  1356.         private void CenteredMemView(object sender, EventArgs e, UInt32 mAddress)
  1357.         {
  1358.             int oldSelectedRow = memViewGrid.CurrentCell.RowIndex;
  1359.             int oldSelectedCol = memViewGrid.CurrentCell.ColumnIndex;
  1360.  
  1361.             CenteredMemViewSelection(sender, e, mAddress);
  1362.  
  1363.             memViewGrid.CurrentCell = memViewGrid[oldSelectedCol, oldSelectedRow];
  1364.         }
  1365.  
  1366.         private void CenteredMemViewSelection(object sender, EventArgs e, UInt32 mAddress)
  1367.         {
  1368.             // Let users blindly throw addresses in here and we can check the validity
  1369.             if (!ValidMemory.validAddress(mAddress)) return;
  1370.  
  1371.             UInt32 tAddress = (mAddress & 0xFFFFFFF0) - 0x70;
  1372.             tAddress = Math.Max(tAddress, ValidMemory.ValidAreas[ValidMemory.rangeCheckId(mAddress)].low);
  1373.             tAddress = Math.Min(tAddress, ValidMemory.ValidAreas[ValidMemory.rangeCheckId(mAddress)].high - 0x100);
  1374.             //tAddress = Math.Max(tAddress, ValidMemory.ValidAreas[MemViewARange.SelectedIndex].low);
  1375.             //tAddress = Math.Min(tAddress, ValidMemory.ValidAreas[MemViewARange.SelectedIndex].high - 0x100);
  1376.             UInt32 offset = mAddress - tAddress;
  1377.  
  1378.             // Turn off the SelectedIndexChanged event to prevent it from changing the MemViewAValue
  1379.             MemViewARange.SelectedIndexChanged -= MemViewARange_SelectedIndexChanged;
  1380.             MemViewARange.SelectedIndex = ValidMemory.rangeCheckId(mAddress);
  1381.             MemViewARange.SelectedIndexChanged += MemViewARange_SelectedIndexChanged;
  1382.  
  1383.             memViewAValue.Text = GlobalFunctions.toHex(mAddress);
  1384.  
  1385.             MainControl.SelectedTab = MemView;
  1386.             if (memViewGrid.Rows.Count == 0)
  1387.             {
  1388.                 viewer.Update();    // trick the memviewgrid into being populated
  1389.             }
  1390.  
  1391.             memViewGrid.Rows[(int)offset / 0x10].Cells[((int)mAddress & 0xF) / 4 + 1].Selected = true;
  1392.  
  1393.             tAddress &= 0xFFFFFFFC;
  1394.             viewer.address = tAddress;
  1395.             viewer.Update();
  1396.         }
  1397.  
  1398.         private void showInWatchList_Click(object sender, EventArgs e)
  1399.         {
  1400.             List<UInt32> addresses = new List<UInt32>();
  1401.             UInt32 address;
  1402.             int i;
  1403.             for (i = 0; i < SearchResults.SelectedRows.Count; i++)
  1404.             {
  1405.                 address = search.GetAddress(SearchResults.SelectedRows[i].Index);
  1406.                 addresses.Add(address);
  1407.             }
  1408.  
  1409.             addresses.Sort();
  1410.  
  1411.             int valLength = PValue.MaxLength;
  1412.             WatchDataSize ws;
  1413.             switch (valLength)
  1414.             {
  1415.                 case 1: ws = WatchDataSize.Bit8; break;
  1416.                 case 2: ws = WatchDataSize.Bit16; break;
  1417.                 default: ws = WatchDataSize.Bit32; break;
  1418.             }
  1419.  
  1420.             foreach (UInt32 watchadd in addresses)
  1421.             {
  1422.                 watcher.AddWatch(GlobalFunctions.toHex(watchadd), new UInt32[] { watchadd }, ws);
  1423.             }
  1424.  
  1425.             MainControl.SelectedTab = WatchTab;
  1426.         }
  1427.  
  1428.  
  1429.         #endregion
  1430.  
  1431.         #region Memory Viewer stuff
  1432.         private void tabPage2_Enter(object sender, EventArgs e)
  1433.         {
  1434.             UInt32 Address;
  1435.             if (memViewAValue.IsValidGet(out Address))
  1436.             {
  1437.                 CenteredMemViewSelection(sender, e, Address);
  1438.             }
  1439.             toolStripTextBoxMemViewFontSize_KeyDown(null, new KeyEventArgs(Keys.Enter));
  1440.         }
  1441.  
  1442.         private void MemViewARange_SelectedIndexChanged(object sender, EventArgs e)
  1443.         {
  1444.             //if (MemViewARange.SelectedIndex !=
  1445.             UInt32 oldValue, oldRange;
  1446.             double percent = 0;
  1447.             if (memViewAValue.IsValidGet(out oldValue))
  1448.             {
  1449.                 int index = ValidMemory.rangeCheckId(oldValue);
  1450.                 oldRange = ValidMemory.ValidAreas[index].high - ValidMemory.ValidAreas[index].low;
  1451.                 percent = (oldValue - ValidMemory.ValidAreas[index].low) / (double)(oldRange);
  1452.             }
  1453.             UInt32 newRange = ValidMemory.ValidAreas[MemViewARange.SelectedIndex].high - ValidMemory.ValidAreas[MemViewARange.SelectedIndex].low;
  1454.             UInt32 sAddress = ValidMemory.ValidAreas[MemViewARange.SelectedIndex].low + (uint)(percent * newRange);
  1455.             memViewAValue.Text = GlobalFunctions.toHex(sAddress);
  1456.             viewer.address = sAddress;
  1457.             if (MainControl.SelectedTab == MemView)
  1458.                 CenteredMemViewSelection(sender, e, sAddress);
  1459.         }
  1460.  
  1461.         // TODO: Move the body of this code to MemViewer and have this function call into MemViewer instead and pass MemViewARange
  1462.         private void MemViewUpdate_Click(object sender, EventArgs e)
  1463.         {
  1464.             UInt32 vAddress;
  1465.             //if (GlobalFunctions.tryToHex(memViewAValue.Text, out vAddress))
  1466.             if (memViewAValue.IsValidGet(out vAddress))
  1467.             {
  1468.                 CenteredMemViewSelection(sender, e, vAddress);
  1469.             }
  1470.  
  1471.             //if (!GlobalFunctions.tryToHex(memViewAValue.Text, out vAddress))
  1472.             //{
  1473.             //    MessageBox.Show("Invalid input");
  1474.             //    return;
  1475.             //}
  1476.             //if (!ValidMemory.validAddress(vAddress))
  1477.             //{
  1478.             //    MessageBox.Show("Invalid address");
  1479.             //    return;
  1480.             //}
  1481.  
  1482.             //CenteredMemViewSelection(sender, e, vAddress);
  1483.  
  1484.             //UInt32 iAddress =vAddress & 0xFFFFFFFC;
  1485.             //vAddress &= 0xFFFFFFFC;
  1486.             //viewer.address = vAddress;
  1487.             //memViewAValue.Text = GlobalFunctions.toHex(vAddress);
  1488.             //viewer.Update();
  1489.         }
  1490.  
  1491.         private void MemViewShowMode_SelectedIndexChanged(object sender, EventArgs e)
  1492.         {
  1493.             MemoryViewMode vMode;
  1494.             switch (MemViewShowMode.SelectedIndex)
  1495.             {
  1496.                 case 0:
  1497.                     vMode = MemoryViewMode.Hex;
  1498.                     break;
  1499.                 case 1:
  1500.                     vMode = MemoryViewMode.ASCII;
  1501.                     break;
  1502.                 case 2:
  1503.                     vMode = MemoryViewMode.ANSI;
  1504.                     break;
  1505.                 case 3:
  1506.                     vMode = MemoryViewMode.Unicode;
  1507.                     break;
  1508.                 case 4:
  1509.                     vMode = MemoryViewMode.Single;
  1510.                     break;
  1511.                 case 5:
  1512.                     vMode = MemoryViewMode.AutoZero;
  1513.                     break;
  1514.                 case 6:
  1515.                     vMode = MemoryViewMode.AutoDot;
  1516.                     break;
  1517.                 default:
  1518.                     vMode = MemoryViewMode.AutoDot;
  1519.                     break;
  1520.             }
  1521.             viewer.viewMode = vMode;
  1522.             if (MainControl.SelectedTab == MemView)
  1523.                 viewer.Update();
  1524.         }
  1525.  
  1526.         private void MemViewAutoUp_Click(object sender, EventArgs e)
  1527.         {
  1528.             if (MemViewAutoUp.Checked)
  1529.             {
  1530.                 DateTime start = DateTime.Now;
  1531.                 DateTime now;
  1532.                 TimeSpan sub;
  1533.                 int msec, odps;
  1534.                 double dps;
  1535.                 int dumpcount = 0;
  1536.                 while (MemViewAutoUp.Checked)
  1537.                 {
  1538.                     UInt32 addr = viewer.selectedAddress;
  1539.                     //viewer.address = addr;
  1540.                     viewer.Update(true);        // do a fast update
  1541.                     dumpcount++;
  1542.                     now = DateTime.Now;
  1543.                     sub = now - start;
  1544.                     if (sub.Seconds >= 1)
  1545.                     {
  1546.                         msec = (sub.Seconds * 1000 + sub.Milliseconds);
  1547.                         dps = (double)dumpcount * 1000.0 / (double)msec;
  1548.                         odps = (int)Math.Round(dps);
  1549.                         MemViewAutoUp.Text = "Auto update (" + odps.ToString() + " dps)";
  1550.                         start = DateTime.Now;
  1551.                         dumpcount = 0;
  1552.                     }
  1553.                     Application.DoEvents();
  1554.                 }
  1555.                 MemViewAutoUp.Text = "Auto update";
  1556.             }
  1557.             else
  1558.             {
  1559.                 MemViewAutoUp.Text = "Auto update";
  1560.             }
  1561.         }
  1562.  
  1563.         private void MemViewAValue_KeyPress(object sender, KeyPressEventArgs e)
  1564.         {
  1565.             if ((Byte)e.KeyChar == 13)
  1566.             {
  1567.                 MemViewUpdate_Click(sender, e);
  1568.                 e.Handled = true;
  1569.             }
  1570.         }
  1571.  
  1572.         private void MemViewScrollbar_ValueChanged(object sender, EventArgs e)
  1573.         {
  1574.             UInt32 vAddress;
  1575.             if (!GlobalFunctions.tryToHex(memViewAValue.Text, out vAddress))
  1576.             {
  1577.                 MessageBox.Show("Invalid input");
  1578.                 return;
  1579.             }
  1580.             if (!ValidMemory.validAddress(vAddress))
  1581.             {
  1582.                 MessageBox.Show("Invalid address");
  1583.                 return;
  1584.             }
  1585.             vAddress &= 0xFFFFFFFC;
  1586.             if (MemViewScrollbar.Value == 0)
  1587.                 vAddress += 0x100;
  1588.             else if (MemViewScrollbar.Value == 2)
  1589.                 vAddress -= 0x100;
  1590.             else
  1591.                 return;
  1592.  
  1593.             CenteredMemViewSelection(sender, e, vAddress);
  1594.  
  1595.             //MemViewARange.SelectedIndexChanged -= MemViewARange_SelectedIndexChanged;
  1596.             //MemViewARange.SelectedIndex = ValidMemory.rangeCheckId(vAddress);
  1597.             //MemViewARange.SelectedIndexChanged += MemViewARange_SelectedIndexChanged;
  1598.  
  1599.             //viewer.address = vAddress;
  1600.             //memViewAValue.Text = GlobalFunctions.toHex(vAddress);
  1601.             //viewer.Update();
  1602.  
  1603.             MemViewScrollbar.ValueChanged -= MemViewScrollbar_ValueChanged;
  1604.             MemViewScrollbar.Value = 1;
  1605.             MemViewScrollbar.ValueChanged += MemViewScrollbar_ValueChanged;
  1606.         }
  1607.  
  1608.         private void memViewSetBP_Click(object sender, EventArgs e)
  1609.         {
  1610.             uint byteOffset;
  1611.             GlobalFunctions.tryToHex(address.HeaderText.Trim(), out byteOffset);
  1612.             BPAddress.Text = GlobalFunctions.toHex(viewer.selectedAddress + (byteOffset & 0x3));
  1613.  
  1614.             // If the current BPType is Execute, change to Read/Write
  1615.             if (BPType.SelectedIndex == 3)
  1616.             {
  1617.                 BPType.SelectedIndex = 2;
  1618.             }
  1619.             MainControl.SelectedTab = BreakpointPage;
  1620.         }
  1621.  
  1622.         private void memViewAddToWatch_Click(object sender, EventArgs e)
  1623.         {
  1624.             UInt32 vAdd = viewer.selectedAddress;
  1625.             watcher.AddWatch(GlobalFunctions.toHex(vAdd), new UInt32[] { vAdd }, WatchDataSize.Bit32);
  1626.             MainControl.SelectedTab = WatchTab;
  1627.         }
  1628.  
  1629.         private void memViewAddGCTCode_Click(object sender, EventArgs e)
  1630.         {
  1631.             try
  1632.             {
  1633.                 UInt32 vAdd = viewer.selectedAddress;
  1634.                 UInt32 cRegion = vAdd & 0xFE000000;
  1635.                 UInt32 value = gecko.peek(vAdd);
  1636.                 vAdd = vAdd - cRegion + 0x04000000;
  1637.                 int nCodeId = GCTCodeContents.Count;
  1638.  
  1639.                 String name;
  1640.                 if (!InputBox.Show("Code name", "Insert code name", "New code", out name))
  1641.                 {
  1642.                     name = "New code " + (nCodeId + 1).ToString();
  1643.                 }
  1644.                 CodeContent nCode = new CodeContent();
  1645.                 bool addlines = false;
  1646.                 if (cRegion != 0x80000000)
  1647.                 {
  1648.                     addlines = true;
  1649.                     nCode.addLine(0x42000000, cRegion);
  1650.                 }
  1651.                 nCode.addLine(vAdd, value);
  1652.                 if (addlines)
  1653.                     nCode.addLine(0xE0000000, 0x80008000);
  1654.  
  1655.                 GCTCodeContents.AddCode(nCode, name);
  1656.                 MainControl.SelectedTab = GCTPage;
  1657.             }
  1658.             catch (EUSBGeckoException exc)
  1659.             {
  1660.                 exceptionHandling.HandleException(exc);
  1661.             }
  1662.         }
  1663.  
  1664.         private void memViewUpload_Click(object sender, EventArgs e)
  1665.         {
  1666.             if (openBinary.ShowDialog() == DialogResult.OK)
  1667.             {
  1668.                 UInt32 vAdd = viewer.selectedAddress;
  1669.                 FileStream fs = new FileStream(openBinary.FileName, FileMode.Open, FileAccess.Read);
  1670.                 fs.Position = 0;
  1671.                 UInt32 endAdd = vAdd + (UInt32)fs.Length;
  1672.                 if (!ValidMemory.validAddress(endAdd))
  1673.                 {
  1674.                     MessageBox.Show("File too large to be uploaded to this address!");
  1675.                     fs.Close();
  1676.                     return;
  1677.                 }
  1678.                 try
  1679.                 {
  1680.                     gecko.Upload(vAdd, endAdd, fs);
  1681.                 }
  1682.                 catch (EUSBGeckoException exc)
  1683.                 {
  1684.                     exceptionHandling.HandleException(exc);
  1685.                 }
  1686.                 fs.Close();
  1687.             }
  1688.         }
  1689.  
  1690.         private void MemViewSearchPerfom_Click(object sender, EventArgs e)
  1691.         {
  1692.             if (viewer.Searching)
  1693.             {
  1694.                 // Let the user cancel the search by pressing the button again
  1695.                 viewer.Searching = false;
  1696.                 return;
  1697.             }
  1698.  
  1699.             String sString = MemViewSearchString.Text;
  1700.             bool hex = MemViewSearchType.SelectedIndex == 4;
  1701.             bool caseSensitive = (MemViewSearchType.SelectedIndex % 2 == 1) || hex;
  1702.             bool unicode = (MemViewSearchType.SelectedIndex >= 2);
  1703.  
  1704.             byte[] stringBytes;
  1705.             if (unicode)
  1706.             {
  1707.                 stringBytes = Encoding.Unicode.GetBytes(sString);
  1708.             }
  1709.             else
  1710.             {
  1711.                 stringBytes = Encoding.ASCII.GetBytes(sString);
  1712.             }
  1713.  
  1714.             if (hex)
  1715.             {
  1716.                 sString = System.Text.RegularExpressions.Regex.Replace(sString.ToUpper(), "[^0-9A-F]", String.Empty);
  1717.                 if (!GlobalFunctions.tryToHex(sString, out stringBytes))
  1718.                 {
  1719.                     return;
  1720.                 }
  1721.             }
  1722.  
  1723.             viewer.Searching = true;
  1724.             MemViewSearchPerfom.Text = "Cancel";
  1725.             viewer.SearchString(stringBytes, caseSensitive, unicode, hex);  // Synchronous, but pumps messages!
  1726.             viewer.Searching = false;
  1727.             MemViewSearchPerfom.Text = "Search";
  1728.             CenteredMemViewSelection(sender, e, viewer.address);
  1729.         }
  1730.  
  1731.         #endregion
  1732.  
  1733.         #region Breakpoint tab
  1734.         private void BPMode(bool mode)
  1735.         {
  1736.             bool enable = !mode;
  1737.  
  1738.             // Don't EVER let Memory Viewer Auto Update be on while doing a breakpoint
  1739.             MemViewAutoUp.Checked = false;
  1740.  
  1741.             // If there's no breakpoint pending...
  1742.             // Enable non-tabbed buttons
  1743.             PGame.Enabled = enable;
  1744.             //RGame.Enabled = enable;
  1745.             CUSBGecko.Enabled = enable;
  1746.  
  1747.             // Enable tabbed buttons and controls
  1748.             EnableMainControls(enable);
  1749.  
  1750.             // *Disable* cancel button
  1751.             BPCancel.Enabled = !enable;
  1752.  
  1753.             // If we are disabled, lock the tab to the current tab
  1754.             if (!enable)
  1755.             {
  1756.                 TabLock = MainControl.SelectedTab;
  1757.             }
  1758.             else
  1759.             {
  1760.                 TabLock = null;
  1761.             }
  1762.  
  1763.             if (enable && bpHandler.BreakpointNext)
  1764.             {
  1765.                 // We've hit the code handler breakpoint after pressing next
  1766.                 RGame.Text = "Run game";
  1767.                 bpHandler.BreakpointNext = false;
  1768.  
  1769.                 // Update memory view if we're looking at it and we pressed next
  1770.                 if (MainControl.SelectedTab == MemView)
  1771.                 {
  1772.                     viewer.Update();
  1773.                 }
  1774.             }
  1775.  
  1776.             if (enable)
  1777.             {
  1778.                 // Color the Show Mem button's text
  1779.                 UpdateShowMemColor();
  1780.  
  1781.                 // Update the BP condition value
  1782.                 UpdateBPCondValue();
  1783.  
  1784.                 // If a breakpoint was hit, log the data
  1785.                 if (checkBoxLogSteps.Checked)
  1786.                 {
  1787.                     BPStepLogWriter.WriteLine();
  1788.                     BPStepLogWriter.WriteLine(bpHandler.GetStepLog());
  1789.                     BPStepLogWriter.Flush();
  1790.                 }
  1791.             }
  1792.         }
  1793.  
  1794.         private void UpdateShowMemColor()
  1795.         {
  1796.             // Color the Show Mem button's text
  1797.             switch (bpHandler.BranchState)
  1798.             {
  1799.                 case ConditionalBranchState.Taken:
  1800.                     buttonShowMem.ForeColor = Color.LightGreen;
  1801.                     buttonShowMem.Text = "Taken";
  1802.                     break;
  1803.                 case ConditionalBranchState.NotTaken:
  1804.                     buttonShowMem.ForeColor = Color.Red;
  1805.                     buttonShowMem.Text = "Not Taken";
  1806.                     break;
  1807.                 default:
  1808.                     buttonShowMem.ForeColor = Color.Black;
  1809.                     buttonShowMem.Text = "Show Mem";
  1810.                     break;
  1811.             }
  1812.         }
  1813.  
  1814.         private void BPStopped(bool hit)
  1815.         {
  1816.             BPMode(false);
  1817.         }
  1818.  
  1819.         private void BPOutSwap_Click(object sender, EventArgs e)
  1820.         {
  1821.             if (BPList.Visible)
  1822.             {
  1823.                 BPList.Hide();
  1824.                 BPClassic.Show();
  1825.                 BPOutSwap.Text = "Edit view";
  1826.             }
  1827.             else
  1828.             {
  1829.                 BPList.Show();
  1830.                 BPClassic.Hide();
  1831.                 BPOutSwap.Text = "Text view";
  1832.             }
  1833.         }
  1834.  
  1835.         private void BPFire_Click(object sender, EventArgs e)
  1836.         {
  1837.             BreakpointType bptp;
  1838.  
  1839.             BPSkipCount.Text = "0";
  1840.  
  1841.             switch (BPType.SelectedIndex)
  1842.             {
  1843.                 case 0:
  1844.                     bptp = BreakpointType.Read;
  1845.                     break;
  1846.                 case 1:
  1847.                     bptp = BreakpointType.Write;
  1848.                     break;
  1849.                 case 2:
  1850.                     bptp = BreakpointType.ReadWrite;
  1851.                     break;
  1852.                 default:
  1853.                     bptp = BreakpointType.Execute;
  1854.                     break;
  1855.             }
  1856.  
  1857.             bool exact = BPExact.Checked;
  1858.  
  1859.             UInt32 bAddress;
  1860.             if (!GlobalFunctions.tryToHex(BPAddress.Text, out bAddress))
  1861.             {
  1862.                 MessageBox.Show("Invalid input");
  1863.                 return;
  1864.             }
  1865.             if (!ValidMemory.validAddress(bAddress))
  1866.             {
  1867.                 MessageBox.Show("Invalid address");
  1868.                 return;
  1869.             }
  1870.  
  1871.             bpHandler.ClearLogIndent();
  1872.  
  1873.             if (bpHandler.SetBreakpoint(bAddress, bptp, exact))
  1874.                 BPMode(true);
  1875.         }
  1876.  
  1877.         private void BPCancel_Click(object sender, EventArgs e)
  1878.         {
  1879.             bpHandler.CancelBreakpoint();
  1880.             PGame.Text = "Pause Game";
  1881.         }
  1882.  
  1883.         private void BPStepButton_Click(object sender, EventArgs e)
  1884.         {
  1885.             try
  1886.             {
  1887.                 if (gecko.status() == WiiStatus.Breakpoint)
  1888.                 {
  1889.                     gecko.Step();
  1890.                     System.Threading.Thread.Sleep(100);
  1891.                     bpHandler.GetRegisters();
  1892.                     // Color Show Mem according to branch state
  1893.                     UpdateShowMemColor();
  1894.                     UpdateBPCondValue();
  1895.  
  1896.                     if (checkBoxLogSteps.Checked)
  1897.                     {
  1898.                         BPStepLogWriter.WriteLine(bpHandler.GetStepLog());
  1899.  
  1900.                         BPStepLogWriter.Flush();
  1901.                     }
  1902.                 }
  1903.             }
  1904.             catch (EUSBGeckoException exc)
  1905.             {
  1906.                 exceptionHandling.HandleException(exc);
  1907.             }
  1908.         }
  1909.  
  1910.  
  1911.         private void BPStepOverButton_Click(object sender, EventArgs e)
  1912.         {
  1913.             try
  1914.             {
  1915.                 if (gecko.status() == WiiStatus.Breakpoint)
  1916.                 {
  1917.                     if (bpHandler.stepOver)
  1918.                     {
  1919.                         if (bpHandler.SetBreakpoint(bpHandler.hitAddress + 4, BreakpointType.Execute, true))
  1920.                         {
  1921.                             BPMode(true);
  1922.                         }
  1923.                         bpHandler.DecIndent();  // account for the bl we're skipping over
  1924.                     }
  1925.                     else
  1926.                     {
  1927.                         BPStepButton_Click(sender, e);
  1928.                     }
  1929.                 }
  1930.             }
  1931.             catch (EUSBGeckoException exc)
  1932.             {
  1933.                 exceptionHandling.HandleException(exc);
  1934.             }
  1935.         }
  1936.  
  1937.         private void BPSkipped(int skipCount)
  1938.         {
  1939.             BPSkipCount.Text = skipCount.ToString();
  1940.         }
  1941.  
  1942.         private void BPConditionAdd_Click(object sender, EventArgs e)
  1943.         {
  1944.             UInt32 value;
  1945.             if (!GlobalFunctions.tryToHex(BPCondValue.Text, out value))
  1946.             {
  1947.                 MessageBox.Show("Invalid value!");
  1948.                 return;
  1949.             }
  1950.             int register = BPConditionRegSelect.SelectedIndex;
  1951.             if (register < 0)
  1952.             {
  1953.                 MessageBox.Show("Invalid register!");
  1954.                 return;
  1955.             }
  1956.             BreakpointComparison condition;
  1957.             switch (BPConditionCompare.SelectedIndex)
  1958.             {
  1959.                 case 0:
  1960.                     condition = BreakpointComparison.Equal; break;
  1961.                 case 1:
  1962.                     condition = BreakpointComparison.NotEqual; break;
  1963.                 case 2:
  1964.                     condition = BreakpointComparison.GreaterEqual; break;
  1965.                 case 3:
  1966.                     condition = BreakpointComparison.Greater; break;
  1967.                 case 4:
  1968.                     condition = BreakpointComparison.LowerEqual; break;
  1969.                 default:
  1970.                     condition = BreakpointComparison.Lower; break;
  1971.             }
  1972.  
  1973.             BreakpointCondition cond;
  1974.  
  1975.             int index = BPCondList.SelectedIndex;
  1976.  
  1977.             if (index > -1)
  1978.             {
  1979.                 cond = new BreakpointCondition(register, value, condition, bpHandler.conditions.GetIndexedConditionGroup(index));
  1980.                 bpHandler.conditions.Insert(index, cond);
  1981.             }
  1982.             else
  1983.             {
  1984.                 cond = new BreakpointCondition(register, value, condition, 1);
  1985.                 bpHandler.conditions.Add(cond);
  1986.             }
  1987.  
  1988.             // Add and insert will unselect the current item, so let's re-select it
  1989.             BPCondList.SelectedIndex = index;
  1990.         }
  1991.  
  1992.         private void BPCondDel_Click(object sender, EventArgs e)
  1993.         {
  1994.             List<int> indices = new List<int>();
  1995.             for (int i = BPCondList.SelectedItems.Count - 1; i >= 0; i--)
  1996.             {
  1997.                 indices.Add(BPCondList.SelectedIndices[i]);
  1998.             }
  1999.             BPCondList.ClearSelected();
  2000.             foreach (int index in indices)
  2001.             {
  2002.                 bpHandler.conditions.Delete(index);
  2003.             }
  2004.         }
  2005.  
  2006.         private void BPCondClear_Click(object sender, EventArgs e)
  2007.         {
  2008.             BPCondList.ClearSelected();
  2009.             bpHandler.conditions.Clear();
  2010.         }
  2011.  
  2012.  
  2013.         #endregion
  2014.  
  2015.         #region Disassembler tab
  2016.         private void DisPage_Enter(object sender, EventArgs e)
  2017.         {
  2018.             disassembler.DissToBox();
  2019.         }
  2020.  
  2021.         private void DisUpDown_ValueChanged(object sender, EventArgs e)
  2022.         {
  2023.             if (DisUpDown.Value == 1)
  2024.                 return;
  2025.             if (DisUpDown.Value == 2)
  2026.                 disassembler.Decrease();
  2027.             if (DisUpDown.Value == 0)
  2028.                 disassembler.Increase();
  2029.  
  2030.             DisUpDown.Value = 1;
  2031.         }
  2032.  
  2033.         private void DisUpdateBtn_Click(object sender, EventArgs e)
  2034.         {
  2035.             UInt32 vAddress;
  2036.             if (!GlobalFunctions.tryToHex(DisRegion.Text, out vAddress))
  2037.             {
  2038.                 MessageBox.Show("Invalid input");
  2039.                 return;
  2040.             }
  2041.             if (!ValidMemory.validAddress(vAddress))
  2042.             {
  2043.                 MessageBox.Show("Invalid address");
  2044.                 return;
  2045.             }
  2046.  
  2047.             vAddress &= 0xFFFFFFFC;
  2048.             disassembler.DissToBox(vAddress);
  2049.         }
  2050.  
  2051.         private void DisRegion_KeyPress(object sender, KeyPressEventArgs e)
  2052.         {
  2053.             if ((Byte)e.KeyChar == 13)
  2054.             {
  2055.                 DisUpdateBtn_Click(sender, e);
  2056.                 e.Handled = true;
  2057.             }
  2058.         }
  2059.  
  2060.         private void Assemble_Click(object sender, EventArgs e)
  2061.         {
  2062.             // Clean up the assembly text
  2063.             String assembly = AsText.Text;
  2064.             if (assembly == "")
  2065.             {
  2066.                 MessageBox.Show("No assembly given");
  2067.                 return;
  2068.             }
  2069.  
  2070.             string potentialAddress = String.Empty;
  2071.             // Trim any address from a previous history item
  2072.             if (assembly.Length > 8)
  2073.             {
  2074.                 potentialAddress = assembly.Substring(0, 8);
  2075.             }
  2076.  
  2077.             uint address;
  2078.  
  2079.             if (GlobalFunctions.tryToHex(potentialAddress, out address))
  2080.             {
  2081.                 // If the address is trimmed, make permanent changes to AsText and AsAddress
  2082.                 assembly = assembly.Substring(8);
  2083.                 AsText.Text = assembly;
  2084.                 AsAddress.Text = GlobalFunctions.toHex((long)address);
  2085.             }
  2086.  
  2087.  
  2088.             UInt32 vAddress;
  2089.             if (!GlobalFunctions.tryToHex(AsAddress.Text, out vAddress))
  2090.             {
  2091.                 MessageBox.Show("Invalid input");
  2092.                 return;
  2093.             }
  2094.             if (!ValidMemory.validAddress(vAddress))
  2095.             {
  2096.                 MessageBox.Show("Invalid address");
  2097.                 return;
  2098.             }
  2099.             vAddress &= 0xFFFFFFFC;
  2100.  
  2101.             string oldLine = disassembler.Disassemble(vAddress, 1)[0];
  2102.  
  2103.             oldLine = System.Text.RegularExpressions.Regex.Replace(oldLine, ":[^\t]*\t", " ");
  2104.  
  2105.             oldLine = System.Text.RegularExpressions.Regex.Replace(oldLine, "\t", " ");
  2106.  
  2107.             AsText.AddTextToHistory(oldLine);
  2108.  
  2109.             disassembler.Assemble(vAddress, assembly);
  2110.         }
  2111.  
  2112.         private void DisAssSetBP_Click(object sender, EventArgs e)
  2113.         {
  2114.             BPAddress.Text = GlobalFunctions.toHex(disassembler.disAddress);
  2115.             BPType.SelectedIndex = 3;
  2116.             MainControl.SelectedTab = BreakpointPage;
  2117.         }
  2118.  
  2119.         private void disAssContextMenu_Opening(object sender, CancelEventArgs e)
  2120.         {
  2121.             if (!ValidMemory.validAddress(disassembler.disAddress))
  2122.             {
  2123.                 e.Cancel = true;
  2124.             }
  2125.         }
  2126.  
  2127.         private void DisAssPoke_Click(object sender, EventArgs e)
  2128.         {
  2129.             PAddress.Text = GlobalFunctions.toHex(disassembler.disAddress);
  2130.             try
  2131.             {
  2132.                 PValue.Text = GlobalFunctions.toHex(gecko.peek(disassembler.disAddress));
  2133.             }
  2134.             catch (EUSBGeckoException exc)
  2135.             {
  2136.                 exceptionHandling.HandleException(exc);
  2137.             }
  2138.             MainControl.SelectedTab = searchPage;
  2139.         }
  2140.  
  2141.         private void disAssGCTCode_Click(object sender, EventArgs e)
  2142.         {
  2143.             try
  2144.             {
  2145.                 UInt32 address = disassembler.disAddress;
  2146.                 UInt32 value = gecko.peek(address);
  2147.                 CodeContent nCode = new CodeContent();
  2148.                 UInt32 memReg = address & 0xFE000000;
  2149.                 bool addDelimiters = false;
  2150.                 if (memReg != 0x80000000)
  2151.                     addDelimiters = true;
  2152.                 if (addDelimiters)
  2153.                     nCode.addLine(0x42000000, memReg);
  2154.                 address = address - memReg + 0x04000000;
  2155.                 nCode.addLine(address, value);
  2156.                 if (addDelimiters)
  2157.                     nCode.addLine(0xE0000000, 0x80008000);
  2158.                 int nCodeId = GCTCodeContents.Count;
  2159.                 String name;
  2160.                 if (!InputBox.Show("Code name", "Insert code name", "New code", out name))
  2161.                 {
  2162.                     name = "New code " + (nCodeId + 1).ToString();
  2163.                 }
  2164.                 //nCode.name = "New code " + (nCodeId + 1).ToString();
  2165.                 GCTCodeContents.AddCode(nCode, name);
  2166.  
  2167.                 GCTCodeList.Items[nCodeId].Selected = true;
  2168.                 MainControl.SelectedTab = GCTPage;
  2169.             }
  2170.             catch (EUSBGeckoException exc)
  2171.             {
  2172.                 exceptionHandling.HandleException(exc);
  2173.             }
  2174.         }
  2175.         #endregion
  2176.  
  2177.         #region Screenshot tab
  2178.         private void shotPage_Enter(object sender, EventArgs e)
  2179.         {
  2180.             if (!GameNameStored)
  2181.             {
  2182.                 ShotFilename.Text = gamename;
  2183.                 GameNameStored = true;
  2184.             }
  2185.         }
  2186.  
  2187.         private ScreenshotSizingMode getSizingMode()
  2188.         {
  2189.             switch (ShotSizingType.SelectedIndex)
  2190.             {
  2191.                 case 1:
  2192.                     return ScreenshotSizingMode.StretchToWidescreen;
  2193.                 case 2:
  2194.                     return ScreenshotSizingMode.StretchToFullscreen;
  2195.                 default:
  2196.                     return ScreenshotSizingMode.None;
  2197.             }
  2198.         }
  2199.  
  2200.         private bool createPreview(bool unpause, out Image shot)
  2201.         {
  2202.             Image screenshot;
  2203.             try
  2204.             {
  2205.                 if (gecko.status() != WiiStatus.Running)
  2206.                     unpause = false;
  2207.                 else
  2208.                     gecko.Pause();
  2209.  
  2210.                 ScreenshotSizingMode sizing = getSizingMode();
  2211.                 screenshot = gecko.Screenshot();
  2212.  
  2213.                 if (sizing != ScreenshotSizingMode.None)
  2214.                     screenshot = Screenshots.resizeImage(screenshot, sizing);
  2215.  
  2216.                 ScreenshotCapBox.Image = screenshot;
  2217.  
  2218.                 if (unpause)
  2219.                     gecko.Resume();
  2220.  
  2221.                 shot = screenshot;
  2222.                 return true;
  2223.             }
  2224.             catch (EUSBGeckoException exc)
  2225.             {
  2226.                 screenshot = new Bitmap(256, 256);
  2227.                 shot = screenshot;
  2228.                 exceptionHandling.HandleException(exc);
  2229.                 return false;
  2230.             }
  2231.         }
  2232.  
  2233.         private void ShotGetFormat(out ScreenshotFormat format, out String extension)
  2234.         {
  2235.             switch (ImgFormat.SelectedIndex)
  2236.             {
  2237.                 case 1:
  2238.                     format = ScreenshotFormat.BMP;
  2239.                     extension = ".bmp";
  2240.                     break;
  2241.                 case 2:
  2242.                     format = ScreenshotFormat.JPEG;
  2243.                     extension = ".jpg";
  2244.                     SettingsFile.SetValue("Screenshots", "JPEGQuality", JPGQual.Value);
  2245.                     break;
  2246.                 case 3:
  2247.                     format = ScreenshotFormat.TIFF;
  2248.                     extension = ".tif";
  2249.                     break;
  2250.                 default:
  2251.                     format = ScreenshotFormat.PNG;
  2252.                     extension = ".png";
  2253.                     break;
  2254.             }
  2255.         }
  2256.  
  2257.         private void ShotGetFormat(out ScreenshotFormat format)
  2258.         {
  2259.             String ext;
  2260.             ShotGetFormat(out format, out ext);
  2261.         }
  2262.  
  2263.         private void ShotCapture_Click(object sender, EventArgs e)
  2264.         {
  2265.             Image screenshot;
  2266.             bool okay = createPreview(false, out screenshot);
  2267.  
  2268.             if (okay)
  2269.             {
  2270.                 String fileName = ShotFilename.Text;
  2271.                 if (fileName == "")
  2272.                     fileName = gamename;
  2273.  
  2274.                 char delim = Path.DirectorySeparatorChar;
  2275.  
  2276.                 if (!Directory.Exists("shots"))
  2277.                     Directory.CreateDirectory("shots");
  2278.                 if (!Directory.Exists("shots" + delim + gamename))
  2279.                     Directory.CreateDirectory("shots" + delim + gamename);
  2280.  
  2281.                 String fNameAppend = "";
  2282.                 int i = 1;
  2283.                 String finalFile = "";
  2284.                 do
  2285.                 {
  2286.                     fNameAppend = "-" + String.Format("{0:000}", i);
  2287.                     finalFile = "shots" + delim + gamename + delim + fileName + fNameAppend;
  2288.                     i++;
  2289.                 } while (
  2290.                     File.Exists(finalFile + ".jpg") || File.Exists(finalFile + ".jpeg") ||
  2291.                     File.Exists(finalFile + ".tif") || File.Exists(finalFile + ".tiff") ||
  2292.                     File.Exists(finalFile + ".png") || File.Exists(finalFile + ".bmp"));
  2293.  
  2294.                 ScreenshotFormat request;
  2295.                 String extension;
  2296.                 ShotGetFormat(out request, out extension);
  2297.  
  2298.                 ImageCodecInfo codec = Screenshots.getImageCodec(request);
  2299.                 EncoderParameters parameters = Screenshots.getParameters(
  2300.                     JPGQual.Value, request);
  2301.  
  2302.                 screenshot.Save(finalFile + extension, codec, parameters);
  2303.                 try
  2304.                 {
  2305.                     gecko.Resume();
  2306.                 }
  2307.                 catch (EUSBGeckoException exc)
  2308.                 {
  2309.                     exceptionHandling.HandleException(exc);
  2310.                 }
  2311.             }
  2312.         }
  2313.  
  2314.         private void ShotPreview_Click(object sender, EventArgs e)
  2315.         {
  2316.             Image bla;
  2317.             createPreview(true, out bla);
  2318.         }
  2319.  
  2320.         private void JPGQual_Scroll(object sender, EventArgs e)
  2321.         {
  2322.             JPGQualLabel.Text = JPGQual.Value.ToString() + "%";
  2323.         }
  2324.  
  2325.         private void ShotSizingType_SelectedIndexChanged(object sender, EventArgs e)
  2326.         {
  2327.             SettingsFile.SetValue("Screenshots", "Sizing", ShotSizingType.SelectedIndex);
  2328.         }
  2329.  
  2330.         private void ImgFormat_SelectedIndexChanged(object sender, EventArgs e)
  2331.         {
  2332.             SettingsFile.SetValue("Screenshots", "Format", ImgFormat.SelectedIndex);
  2333.             ScreenshotFormat format;
  2334.             ShotGetFormat(out format);
  2335.             JPGQual.Enabled = format == ScreenshotFormat.JPEG;
  2336.         }
  2337.  
  2338.         #endregion
  2339.  
  2340.         #region GCT codes
  2341.         private bool codesModified;
  2342.  
  2343.         private bool VerifyCodesAreSaved()
  2344.         {
  2345.             if (codesModified)
  2346.             {
  2347.                 if (MessageBox.Show("The GCT list has changed.\n" +
  2348.                     "Do you want to store the code list?", "Gecko dotNET",
  2349.                     MessageBoxButtons.YesNo, MessageBoxIcon.Warning) ==
  2350.                     DialogResult.Yes)
  2351.                 {
  2352.                     GCTSaveCodes(false);
  2353.                     codesModified = false;
  2354.                 }
  2355.             }
  2356.  
  2357.             return !codesModified;
  2358.         }
  2359.  
  2360.         private void GCTAddCode_Click(object sender, EventArgs e)
  2361.         {
  2362.             String codeName;
  2363.  
  2364.             if (InputBox.Show("Code name", "Insert code name", "New code", out codeName))
  2365.             {
  2366.                 GCTCodeContents.AddCode(codeName);
  2367.                 codesModified = true;
  2368.             }
  2369.         }
  2370.  
  2371.         private void GCTDelBtn_Click(object sender, EventArgs e)
  2372.         {
  2373.             if (GCTCodeList.SelectedIndices.Count > 0)
  2374.             {
  2375.                 if (MessageBox.Show("Are you sure you want to delete the selected code?",
  2376.                     "Gecko dotNET", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) ==
  2377.                     DialogResult.Yes)
  2378.                 {
  2379.                     GCTCodeContents.Remove(GCTCodeList.SelectedIndices[0]);
  2380.                     codesModified = true;
  2381.                 }
  2382.             }
  2383.         }
  2384.  
  2385.         private void GCTStoreImm_Click(object sender, EventArgs e)
  2386.         {
  2387.             GCTCodeContents.UpdateCode();
  2388.         }
  2389.  
  2390.         private void GCTSndButton_Click(object sender, EventArgs e)
  2391.         {
  2392.             if (!GCTCodeContents.UpdateCode()) return;
  2393.  
  2394.             MemoryStream memStream = new MemoryStream();
  2395.             GCTCodeContents.GenerateCheatStream(memStream);
  2396.  
  2397.             try
  2398.             {
  2399.                 if (checkBoxPauseCodes.Checked)
  2400.                 {
  2401.                     // Pause the game with a code-handler-breakpoint...
  2402.                     PGame_Click(sender, e);
  2403.                     // Wait for the breakpoint to hit (and keep pumping events!)
  2404.                     while (TabLock != null) Application.DoEvents();
  2405.                 }
  2406.  
  2407.                 // Send the cheats...
  2408.                 gecko.sendCheats(memStream);
  2409.  
  2410.                 if (checkBoxPauseCodes.Checked)
  2411.                 {
  2412.                     // Unpause the game
  2413.                     RGame_Click(sender, e);
  2414.                 }
  2415.  
  2416.                 memStream.Close();
  2417.  
  2418.                 MessageBox.Show("Cheats sent!");
  2419.             }
  2420.             catch (EUSBGeckoException exc)
  2421.             {
  2422.                 memStream.Close();
  2423.                 exceptionHandling.HandleException(exc);
  2424.             }
  2425.         }
  2426.  
  2427.         private void GCTPage_Enter(object sender, EventArgs e)
  2428.         {
  2429.             GCTListFileName.Text = "Code list: " + gamename + ".wgc";
  2430.         }
  2431.  
  2432.         private void GCTSaveList_Click(object sender, EventArgs e)
  2433.         {
  2434.             GCTSaveCodes(true);
  2435.         }
  2436.  
  2437.         private void GCTSaveCodes(bool inform)
  2438.         {
  2439.             char delim = Path.DirectorySeparatorChar;
  2440.             if (!Directory.Exists("codes"))
  2441.                 Directory.CreateDirectory("codes");
  2442.  
  2443.             String storeName = "codes" + delim + gamename + ".wgc";
  2444.             if (File.Exists(storeName))
  2445.                 File.Delete(storeName);
  2446.  
  2447.             GCTCodeContents.toWGCFile(storeName);
  2448.  
  2449.             if (inform)
  2450.                 MessageBox.Show("Codes stored!");
  2451.         }
  2452.  
  2453.         private void GCTLoadCodes()
  2454.         {
  2455.             if (codesModified)
  2456.             {
  2457.                 if (!VerifyCodesAreSaved())
  2458.                 {
  2459.                     if (MessageBox.Show("The GCT list has changed.\n" +
  2460.                         "If you continue, changes will be lost.\n" +
  2461.                         "Are you sure?", "Gecko dotNET",
  2462.                         MessageBoxButtons.YesNo, MessageBoxIcon.Warning) ==
  2463.                         DialogResult.No)
  2464.                     {
  2465.                         return;
  2466.                     }
  2467.                 }
  2468.             }
  2469.  
  2470.             char delim = Path.DirectorySeparatorChar;
  2471.             GCTCodeContents.Clear();
  2472.  
  2473.             String storeName = "codes" + delim + gamename + ".wgc";
  2474.             if (File.Exists(storeName))
  2475.                 GCTCodeContents.fromWGCFile(storeName);
  2476.             codesModified = false;
  2477.         }
  2478.  
  2479.         private void GCTLoadList_Click(object sender, EventArgs e)
  2480.         {
  2481.             GCTLoadCodes();
  2482.         }
  2483.  
  2484.         private void GCTDisable_Click(object sender, EventArgs e)
  2485.         {
  2486.             MemoryStream memStream = new MemoryStream();
  2487.             GlobalFunctions.WriteStream(memStream, 0x00D0C0DE);
  2488.             GlobalFunctions.WriteStream(memStream, 0x00D0C0DE);
  2489.             GlobalFunctions.WriteStream(memStream, 0xF0000000);
  2490.             GlobalFunctions.WriteStream(memStream, 0x00000000);
  2491.             try
  2492.             {
  2493.                 gecko.sendCheats(memStream);
  2494.                 memStream.Close();
  2495.             }
  2496.             catch (EUSBGeckoException exc)
  2497.             {
  2498.                 exceptionHandling.HandleException(exc);
  2499.             }
  2500.         }
  2501.  
  2502.         private void GCTModified()
  2503.         {
  2504.             codesModified = true;
  2505.         }
  2506.         #endregion
  2507.  
  2508.         #region Watch List
  2509.         private void WatchAdd_Click(object sender, EventArgs e)
  2510.         {
  2511.             watcher.SuspendThread();
  2512.             if (addWatchDialog == null)
  2513.                 addWatchDialog = new WatchDialog();
  2514.             if (addWatchDialog.AddCodeDialog())
  2515.             {
  2516.                 watcher.AddWatch(addWatchDialog.WName, addWatchDialog.WAddress,
  2517.                             addWatchDialog.WDataSize);
  2518.             }
  2519.             watcher.ResumeThread();
  2520.         }
  2521.  
  2522.         private void WatchEditCM_Click(object sender, EventArgs e)
  2523.         {
  2524.             WatchEntry entry;
  2525.             watcher.GetSelected(out entry);
  2526.             if (entry != null)
  2527.             {
  2528.                 if (addWatchDialog == null)
  2529.                     addWatchDialog = new WatchDialog();
  2530.                 watcher.SuspendThread();
  2531.                 if (addWatchDialog.EditWatchDialog(entry))
  2532.                 {
  2533.                     watcher.UpdateEntry(addWatchDialog.WName, addWatchDialog.WAddress,
  2534.                             addWatchDialog.WDataSize);
  2535.                 }
  2536.                 watcher.ResumeThread();
  2537.             }
  2538.         }
  2539.  
  2540.         private void WatchCM_Opening(object sender, CancelEventArgs e)
  2541.         {
  2542.             bool enable = WatchList.SelectedRows.Count > 0;
  2543.             WatchEditCM.Enabled = enable;
  2544.             WatchDeleteCM.Enabled = enable;
  2545.             WatchPokeCM.Enabled = enable;
  2546.         }
  2547.  
  2548.         private void WatchAddWatchCM_Click(object sender, EventArgs e)
  2549.         {
  2550.             WatchAdd_Click(sender, e);
  2551.         }
  2552.  
  2553.         private void WatchDeleteCM_Click(object sender, EventArgs e)
  2554.         {
  2555.             watcher.DeleteSelected();
  2556.         }
  2557.  
  2558.         private void WatchPokeCM_Click(object sender, EventArgs e)
  2559.         {
  2560.             WatchEntry entry;
  2561.             if (watcher.GetSelected(out entry))
  2562.             {
  2563.                 if (watchValueInput == null)
  2564.                     watchValueInput = new ValueInput();
  2565.                 int maxLength;
  2566.                 switch (entry.dataSize)
  2567.                 {
  2568.                     case WatchDataSize.Bit8:
  2569.                         maxLength = 2;
  2570.                         break;
  2571.                     case WatchDataSize.Bit16:
  2572.                         maxLength = 4;
  2573.                         break;
  2574.                     default:
  2575.                         maxLength = 8;
  2576.                         break;
  2577.                 }
  2578.                 UInt32 pValue = entry.lastValue;
  2579.                 try
  2580.                 {
  2581.                     watcher.SuspendThread();
  2582.                     if (watchValueInput.ShowDialog(entry.updatedAddress, ref pValue, maxLength))
  2583.                     {
  2584.                         switch (maxLength)
  2585.                         {
  2586.                             case 2:
  2587.                                 gecko.poke08(entry.updatedAddress, (Byte)pValue);
  2588.                                 break;
  2589.                             case 4:
  2590.                                 gecko.poke16(entry.updatedAddress, (UInt16)pValue);
  2591.                                 break;
  2592.                             default:
  2593.                                 gecko.poke32(entry.updatedAddress, (UInt32)pValue);
  2594.                                 break;
  2595.                         }
  2596.                     }
  2597.                     watcher.ResumeThread();
  2598.                 }
  2599.                 catch (EUSBGeckoException exc)
  2600.                 {
  2601.                     exceptionHandling.HandleException(exc);
  2602.                 }
  2603.             }
  2604.             else
  2605.                 MessageBox.Show("Address not availible!");
  2606.         }
  2607.  
  2608.         private void WatchList_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
  2609.         {
  2610.             WatchPokeCM_Click(sender, e);
  2611.         }
  2612.  
  2613.         private void WatchListSaveButton_Click(object sender, EventArgs e)
  2614.         {
  2615.             if (!watcher.hasContent)
  2616.             {
  2617.                 MessageBox.Show("The watch list is empty!");
  2618.                 return;
  2619.             }
  2620.             if (WatchListSave.FileName == "")
  2621.                 WatchListSave.FileName = gamename + ".xwl";
  2622.             if (WatchListSave.ShowDialog() == DialogResult.OK)
  2623.             {
  2624.                 watcher.SaveToFile(WatchListSave.FileName);
  2625.             }
  2626.         }
  2627.  
  2628.         private void WatchListClear_Click(object sender, EventArgs e)
  2629.         {
  2630.             if (watcher.hasContent)
  2631.             {
  2632.                 if (MessageBox.Show("Are you sure?", "Gecko dotNet", MessageBoxButtons.YesNo,
  2633.                     MessageBoxIcon.Warning) == DialogResult.Yes)
  2634.                 {
  2635.                     watcher.Clear();
  2636.                 }
  2637.             }
  2638.         }
  2639.  
  2640.         private void WatchListOpenButton_Click(object sender, EventArgs e)
  2641.         {
  2642.             bool merge = false;
  2643.             bool abort = false;
  2644.             if (watcher.hasContent)
  2645.             {
  2646.                 switch (MessageBox.Show("There is already a watch list in use.\r\n" +
  2647.                     "Do you want to merge the loaded list with the exsiting (Yes),\r\n" +
  2648.                     "drop the existing (No) or cancel loading a new list (Cancel)?",
  2649.                     "Gecko dotNet", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning))
  2650.                 {
  2651.                     case DialogResult.Yes:
  2652.                         merge = true;
  2653.                         break;
  2654.                     case DialogResult.No:
  2655.                         merge = false;
  2656.                         break;
  2657.                     default:
  2658.                         abort = true;
  2659.                         break;
  2660.                 }
  2661.             }
  2662.  
  2663.             if (abort)
  2664.                 return;
  2665.  
  2666.             if (WatchListOpen.ShowDialog() == DialogResult.OK)
  2667.             {
  2668.                 watcher.LoadFromFile(WatchListOpen.FileName, merge);
  2669.             }
  2670.         }
  2671.         #endregion
  2672.  
  2673.         #region FST tab
  2674.         private void FSTRead_Click(object sender, EventArgs e)
  2675.         {
  2676.             fst.DumpTree();
  2677.         }
  2678.         #endregion
  2679.  
  2680.         #region Tools Tab
  2681.         private void ToolsDisableProtection_CheckedChanged(object sender, EventArgs e)
  2682.         {
  2683.             if (ToolsDisableProtection.Checked)
  2684.             {
  2685.                 ToolsDisableWatchProtection.Enabled = true;
  2686.                 ValidMemory.addressDebug = true;
  2687.             }
  2688.             else
  2689.             {
  2690.                 ValidMemory.addressDebug = false;
  2691.                 watcher.addressDebug = false;
  2692.                 ToolsDisableWatchProtection.Checked = false;
  2693.                 ToolsDisableWatchProtection.Enabled = false;
  2694.             }
  2695.         }
  2696.  
  2697.         private void ToolsDisableWatchProtection_CheckedChanged(object sender, EventArgs e)
  2698.         {
  2699.             watcher.addressDebug =
  2700.                 (ToolsDisableWatchProtection.Checked);
  2701.         }
  2702.  
  2703.         private void ToolsDumpRegions_SelectedIndexChanged(object sender, EventArgs e)
  2704.         {
  2705.             int id = ToolsDumpRegions.SelectedIndex;
  2706.             ToolsDumpStart.Text =
  2707.                 GlobalFunctions.toHex(ValidMemory.ValidAreas[id].low);
  2708.             ToolsDumpEnd.Text =
  2709.                 GlobalFunctions.toHex(ValidMemory.ValidAreas[id].high);
  2710.             if (ToolsDumpFileName.Text == "" ||
  2711.              (ToolsDumpFileName.Text.Length == 10 &&
  2712.               ToolsDumpFileName.Text.Substring(0, 4).ToUpper() == "DUMP"))
  2713.                 ToolsDumpFileName.Text = "DUMP" + ToolsDumpRegions.Items[id] + ".BIN";
  2714.         }
  2715.  
  2716.         private void ToolsBrowseDump_Click(object sender, EventArgs e)
  2717.         {
  2718.             if (ToolsDumpSave.ShowDialog() == DialogResult.OK)
  2719.             {
  2720.                 ToolsDumpFileName.Text = ToolsDumpSave.FileName;
  2721.             }
  2722.         }
  2723.  
  2724.         private void ToolsDump_Click(object sender, EventArgs e)
  2725.         {
  2726.             UInt32 lowAddress, highAddress;
  2727.  
  2728.             if (!GlobalFunctions.tryToHex(ToolsDumpStart.Text, out lowAddress))
  2729.             {
  2730.                 MessageBox.Show("Start address cannot be parsed.");
  2731.                 return;
  2732.             }
  2733.  
  2734.             if (!GlobalFunctions.tryToHex(ToolsDumpEnd.Text, out highAddress))
  2735.             {
  2736.                 MessageBox.Show("End address cannot be parsed.");
  2737.                 return;
  2738.             }
  2739.  
  2740.             if (!ValidMemory.validRange(lowAddress, highAddress))
  2741.             {
  2742.                 MessageBox.Show("Invalid memory range!");
  2743.                 return;
  2744.             }
  2745.  
  2746.             String fileName = ToolsDumpFileName.Text;
  2747.             if (fileName == "")
  2748.             {
  2749.                 MessageBox.Show("No file name given!");
  2750.                 return;
  2751.             }
  2752.  
  2753.             try
  2754.             {
  2755.                 FormStop(false);
  2756.                 if (File.Exists(fileName))
  2757.                     File.Delete(fileName);
  2758.                 FileStream newFile = new FileStream(fileName, FileMode.Create);
  2759.                 gecko.Dump(lowAddress, highAddress, newFile);
  2760.                 newFile.Close();
  2761.                 FormStop(true);
  2762.             }
  2763.             catch (EUSBGeckoException exc)
  2764.             {
  2765.                 exceptionHandling.HandleException(exc);
  2766.             }
  2767.         }
  2768.         #endregion
  2769.  
  2770.         #region Input converter
  2771.         private TextBox selectedInputBox;
  2772.  
  2773.         private void lowerValue_MouseClick(object sender, MouseEventArgs e)
  2774.         {
  2775.             if (e.Button == MouseButtons.Right)
  2776.             {
  2777.                 selectedInputBox = (TextBox)sender;
  2778.                 if (selectedInputBox.MaxLength < 8)
  2779.                 {
  2780.                     CvFloatHex.Enabled = false;
  2781.                     cvHexFloat.Enabled = false;
  2782.                 }
  2783.                 else
  2784.                 {
  2785.                     CvFloatHex.Enabled = true;
  2786.                     cvHexFloat.Enabled = true;
  2787.                 }
  2788.                 return;
  2789.             }
  2790.         }
  2791.  
  2792.         private void CvDecHexClick(object sender, EventArgs e)
  2793.         {
  2794.             int length = 8;
  2795.  
  2796.             if (selectedInputBox == textBoxComparisonValue || selectedInputBox == PValue)
  2797.                 switch (comboBoxSearchDataType.SelectedIndex)
  2798.                 {
  2799.                     case 0: length = 2; break;
  2800.                     case 1: length = 4; break;
  2801.                 }
  2802.             UInt32 intV;
  2803.             if (UInt32.TryParse(selectedInputBox.Text, out intV))
  2804.             {
  2805.                 String hexV = GlobalFunctions.toHex(intV, length);
  2806.                 selectedInputBox.Text = hexV;
  2807.             }
  2808.             else
  2809.             {
  2810.                 MessageBox.Show("Invalid input value");
  2811.             }
  2812.         }
  2813.  
  2814.         private void CvHexDec_Click(object sender, EventArgs e)
  2815.         {
  2816.             UInt32 intval;
  2817.             if (GlobalFunctions.tryToHex(selectedInputBox.Text, out intval))
  2818.             {
  2819.                 selectedInputBox.Text = intval.ToString();
  2820.             }
  2821.             else
  2822.             {
  2823.                 MessageBox.Show("Invalid input value");
  2824.             }
  2825.         }
  2826.  
  2827.  
  2828.         private void InputCvCopy_Click(object sender, EventArgs e)
  2829.         {
  2830.             Clipboard.SetText(selectedInputBox.SelectedText);
  2831.         }
  2832.  
  2833.         private void InputCvCut_Click(object sender, EventArgs e)
  2834.         {
  2835.             Clipboard.SetText(selectedInputBox.SelectedText);
  2836.             int oldpos = selectedInputBox.SelectionStart;
  2837.             selectedInputBox.Text = selectedInputBox.Text.Remove(selectedInputBox.SelectionStart, selectedInputBox.SelectionLength);
  2838.             selectedInputBox.SelectionStart = oldpos;
  2839.         }
  2840.  
  2841.         private void InputCvPaste_Click(object sender, EventArgs e)
  2842.         {
  2843.             if (!Clipboard.ContainsText())
  2844.                 return;
  2845.             int clength = Clipboard.GetText().Length;
  2846.             int oldpos = selectedInputBox.SelectionStart;
  2847.             int olength = selectedInputBox.Text.Length;
  2848.             String selText = selectedInputBox.Text.Remove(selectedInputBox.SelectionStart, selectedInputBox.SelectionLength);
  2849.             clength = Math.Min(selectedInputBox.MaxLength - olength, clength);
  2850.             selText = selectedInputBox.Text.Insert(selectedInputBox.SelectionStart, Clipboard.GetText().Substring(0, clength));
  2851.             fixString(selText, selectedInputBox.MaxLength);
  2852.             selectedInputBox.Text = selText;
  2853.             selectedInputBox.SelectionStart = oldpos + clength;
  2854.         }
  2855.  
  2856.         private void InputCvUndo_Click(object sender, EventArgs e)
  2857.         {
  2858.             selectedInputBox.Undo();
  2859.         }
  2860.  
  2861.         private void InputCvSelectAll_Click(object sender, EventArgs e)
  2862.         {
  2863.             selectedInputBox.SelectionStart = 0;
  2864.             selectedInputBox.SelectionLength = selectedInputBox.Text.Length;
  2865.         }
  2866.  
  2867.         private void CvFloatHex_Click(object sender, EventArgs e)
  2868.         {
  2869.             String inputText = selectedInputBox.Text;
  2870.             float value;
  2871.             if (float.TryParse(inputText, out value))
  2872.             {
  2873.                 UInt32 uval = GlobalFunctions.SingleToUInt(value);
  2874.                 selectedInputBox.Text = GlobalFunctions.toHex(uval);
  2875.             }
  2876.             else
  2877.                 MessageBox.Show("Invalid input. Please make sure to input floating point values in the manner specified in your operating system.\n" +
  2878.                     "This means, if your language uses a comma as a decimal seperator, please use that one for input and not a point!");
  2879.         }
  2880.  
  2881.         private void cvHexFloat_Click(object sender, EventArgs e)
  2882.         {
  2883.             String inputText = selectedInputBox.Text;
  2884.             UInt32 value;
  2885.             if (GlobalFunctions.tryToHex(inputText, out value))
  2886.             {
  2887.                 Single sval = GlobalFunctions.UIntToSingle(value);
  2888.                 selectedInputBox.Text = sval.ToString("G8");
  2889.             }
  2890.             else
  2891.                 MessageBox.Show("Invalid input.");
  2892.         }
  2893.  
  2894.         #endregion
  2895.  
  2896.  
  2897.         // Organize these according to the region blocks above...
  2898.         private void checkBoxAutoPreview_Click(object sender, EventArgs e)
  2899.         {
  2900.             if (checkBoxAutoPreview.Checked)
  2901.             {
  2902.                 DateTime start = DateTime.Now;
  2903.                 DateTime now;
  2904.                 TimeSpan sub;
  2905.                 int msec, odps;
  2906.                 double dps;
  2907.                 int previewcount = 0;
  2908.                 while (checkBoxAutoPreview.Checked)
  2909.                 {
  2910.                     ShotPreview_Click(null, null);
  2911.                     previewcount++;
  2912.                     now = DateTime.Now;
  2913.                     sub = now - start;
  2914.                     if (sub.Seconds >= 1)
  2915.                     {
  2916.                         msec = (sub.Seconds * 1000 + sub.Milliseconds);
  2917.                         dps = (double)previewcount * 1000.0 / (double)msec;
  2918.                         odps = (int)Math.Round(dps);
  2919.                         start = DateTime.Now;
  2920.                         previewcount = 0;
  2921.                     }
  2922.                     Application.DoEvents();
  2923.                 }
  2924.             }
  2925.  
  2926.         }
  2927.  
  2928.         private void MainControl_Selecting(object sender, TabControlCancelEventArgs e)
  2929.         {
  2930.             // If there's a breakpoint pending, keep the breakpoints tab up
  2931.             // Note that we're hooking the Selecting event, because this fires before the tab is actually switched
  2932.             // If you hook SelectedIndexChanged (the default) then you'll see the other tabs load...
  2933.             // ...which causes things like MemoryViewer.Update() to be called if you switch to the Memory Viewer tab
  2934.             // which will crash the USB Gecko, but a reconnect fixes that
  2935.             //if (BPCancel.Enabled)
  2936.             //{
  2937.             //    MainControl.SelectedTab = BreakpointPage;
  2938.             //}
  2939.  
  2940.             //if (buttonCancelSearch.Enabled)
  2941.             //{
  2942.             //    MainControl.SelectedTab = searchPage;
  2943.             //}
  2944.  
  2945.             if (TabLock != null)
  2946.             {
  2947.                 MainControl.SelectedTab = TabLock;
  2948.             }
  2949.         }
  2950.  
  2951.         private void memViewGrid_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
  2952.         {
  2953.             // Does the current cell have a valid address?
  2954.             UInt32 bAddress;
  2955.             if (GlobalFunctions.tryToHex(memViewGrid.SelectedCells[0].Value.ToString(), out bAddress) && ValidMemory.validAddress(bAddress))
  2956.             {
  2957.                 // Jump memory viewer there
  2958.                 //memViewAValue.Text = GlobalFunctions.toHex(bAddress);
  2959.                 CenteredMemViewSelection(sender, e, bAddress);
  2960.             }
  2961.         }
  2962.  
  2963.         private void memViewGrid_KeyDown(object sender, KeyEventArgs e)
  2964.         {
  2965.             UInt32 bAddress = ValidMemory.ValidAreas[MemViewARange.SelectedIndex].low + (uint)vScrollBarMemViewGrid.Value;
  2966.             uint smallChange = (uint)vScrollBarMemViewGrid.SmallChange;
  2967.             uint largeChange = (uint)vScrollBarMemViewGrid.LargeChange;
  2968.  
  2969.             //UInt32 bAddress = viewer.address;
  2970.             int currentRow = memViewGrid.SelectedCells[0].RowIndex, currentCol = memViewGrid.SelectedCells[0].ColumnIndex;
  2971.             bool keepSelectedCell = false;
  2972.  
  2973.             if (e.KeyCode == Keys.Up)
  2974.             {
  2975.                 // Watch for edge cases; at the top and user presses up, don't change selected cell
  2976.                 if ((viewer.address & 0xFFFFFFF0) == (viewer.selectedAddress & 0xFFFFFFF0))
  2977.                 {
  2978.                     bAddress -= smallChange;
  2979.                 }
  2980.                 else if (e.Shift)
  2981.                 {
  2982.                     bAddress -= smallChange;
  2983.                     e.Handled = true;
  2984.                 }
  2985.                 else
  2986.                 {
  2987.                     // Otherwise, update the memory viewer or the user won't see the selected cell scrolling up
  2988.                     MemView.Update();
  2989.                 }
  2990.             }
  2991.  
  2992.             if (e.KeyCode == Keys.Down)
  2993.             {
  2994.                 // at the bottom and user presses down
  2995.                 if (((viewer.address + 0xF0) & 0xFFFFFFF0) == (viewer.selectedAddress & 0xFFFFFFF0))
  2996.                 {
  2997.                     bAddress += smallChange;
  2998.                 }
  2999.                 else if (e.Shift)
  3000.                 {
  3001.                     bAddress += smallChange;
  3002.                     e.Handled = true;
  3003.                 }
  3004.                 else
  3005.                 {
  3006.                     // Otherwise, update the memory viewer or the user won't see the selected cell scrolling down
  3007.                     MemView.Update();
  3008.                 }
  3009.             }
  3010.  
  3011.             if (e.KeyCode == Keys.PageUp)
  3012.             {
  3013.                 bAddress -= largeChange;
  3014.                 e.Handled = true;
  3015.             }
  3016.  
  3017.             if (e.KeyCode == Keys.PageDown)
  3018.             {
  3019.                 bAddress += largeChange;
  3020.                 e.Handled = true;
  3021.             }
  3022.  
  3023.             if (bAddress != viewer.address && ValidMemory.validAddress(bAddress))
  3024.             {
  3025.                 // Jump memory viewer there
  3026.                 //memViewAValue.Text = GlobalFunctions.toHex(bAddress);
  3027.                 //MemViewUpdate_Click(sender, e);
  3028.  
  3029.                 CenteredMemView(sender, e, bAddress);
  3030.  
  3031.                 //viewer.address = bAddress;
  3032.                 //viewer.Update();
  3033.                 //memViewGrid.Update();
  3034.             }
  3035.  
  3036.             if (e.KeyCode == Keys.Enter)
  3037.             {
  3038.                 // Always prevent the enter key from moving to the next row
  3039.                 e.Handled = true;
  3040.                 UInt32 destinationAddress;
  3041.                 if (GlobalFunctions.tryToHex(memViewGrid.SelectedCells[0].Value.ToString(), out destinationAddress) &&
  3042.                     ValidMemory.validAddress(destinationAddress))
  3043.                 {
  3044.                     // Jump memory viewer there
  3045.                     CenteredMemViewSelection(sender, e, destinationAddress);
  3046.                 }
  3047.             }
  3048.  
  3049.             if (e.Control && e.KeyCode == Keys.C)
  3050.             {
  3051.                 if (!e.Shift)
  3052.                 {
  3053.                     // No shift, only copy selected cell
  3054.                     Clipboard.SetText(memViewGrid.SelectedCells[0].Value.ToString());
  3055.                 }
  3056.                 else
  3057.                 {
  3058.                     Clipboard.SetText(MemoryViewerContentsAsString());
  3059.                 }
  3060.             }
  3061.         }
  3062.  
  3063.         private String MemoryViewerContentsAsString()
  3064.         {
  3065.             String returnResult = String.Empty;
  3066.  
  3067.             foreach (DataGridViewRow gridRow in memViewGrid.Rows)
  3068.             {
  3069.                 foreach (DataGridViewCell rowCell in gridRow.Cells)
  3070.                 {
  3071.                     if (rowCell == memViewGrid.CurrentCell)
  3072.                     {
  3073.                         returnResult += "*" + rowCell.Value.ToString() + "*";
  3074.                     }
  3075.                     else
  3076.                     {
  3077.                         returnResult += rowCell.Value.ToString();
  3078.                     }
  3079.                     if (rowCell != gridRow.Cells[gridRow.Cells.Count - 1])
  3080.                     {
  3081.                         // Add a tab to all but the last row cell
  3082.                         returnResult += "\t";
  3083.                     }
  3084.                 }
  3085.                 returnResult += "\r\n";
  3086.             }
  3087.  
  3088.             return returnResult;
  3089.         }
  3090.  
  3091.         private void memViewGrid_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
  3092.         {
  3093.             int row = e.RowIndex, col = e.ColumnIndex;
  3094.             if (col >= 0 && row >= 0 && e.Button == MouseButtons.Right)
  3095.             {
  3096.                 //memViewGrid[col, row].Selected = true;
  3097.                 memViewGrid.CurrentCell = memViewGrid[col, row];
  3098.             }
  3099.         }
  3100.  
  3101.         private void checkBoxAlwaysOnTop_CheckedChanged(object sender, EventArgs e)
  3102.         {
  3103.             TopMost = checkBoxAlwaysOnTop.Checked;
  3104.             codeWizard.TopMost = checkBoxAlwaysOnTop.Checked;
  3105.             GeckoApp.Properties.Settings.Default.AlwaysOnTop = TopMost;
  3106.             GeckoApp.Properties.Settings.Default.Save();        // don't forget to save!
  3107.         }
  3108.  
  3109.         private bool wasRunning;
  3110.         private void checkBoxFPS_CheckedChanged(object sender, EventArgs e)
  3111.         {
  3112.             if (checkBoxFPS.Checked)
  3113.             {
  3114.                 // Remember whether we were paused
  3115.                 WiiStatus status = gecko.status();
  3116.                 wasRunning = status == WiiStatus.Running;
  3117.             }
  3118.  
  3119.             timerFPS.Enabled = checkBoxFPS.Checked;
  3120.  
  3121.             if (!checkBoxFPS.Checked && wasRunning)
  3122.             {
  3123.                 // Hit the run button whenever the checkbox is unchecked
  3124.                 RGame_Click(sender, e);
  3125.             }
  3126.         }
  3127.  
  3128.         private void timerFPS_Tick(object sender, EventArgs e)
  3129.         {
  3130.             PGame_Click(sender, e);
  3131.         }
  3132.  
  3133.         private void numericUpDownFPS_ValueChanged(object sender, EventArgs e)
  3134.         {
  3135.             timerFPS.Interval = (int)(1000 / Convert.ToDouble(numericUpDownFPS.Value));
  3136.             GeckoApp.Properties.Settings.Default.FPS = numericUpDownFPS.Value;
  3137.             GeckoApp.Properties.Settings.Default.Save();
  3138.         }
  3139.  
  3140.         private void DisRegion_TextChanged(object sender, EventArgs e)
  3141.         {
  3142.             GeckoApp.Properties.Settings.Default.DisAsmAddr = DisRegion.Text;
  3143.             GeckoApp.Properties.Settings.Default.Save();
  3144.         }
  3145.  
  3146.         private void BPAddress_TextChanged(object sender, EventArgs e)
  3147.         {
  3148.             GeckoApp.Properties.Settings.Default.BPAddr = BPAddress.Text;
  3149.             GeckoApp.Properties.Settings.Default.Save();
  3150.         }
  3151.  
  3152.         private void memViewAValue_TextChanged(object sender, EventArgs e)
  3153.         {
  3154.             GeckoApp.Properties.Settings.Default.MemViewAddr = memViewAValue.Text;
  3155.             GeckoApp.Properties.Settings.Default.Save();
  3156.  
  3157.             // Update scrollbar
  3158.             uint address;
  3159.             if (GlobalFunctions.tryToHex(memViewAValue.Text, out address) && ValidMemory.validAddress(address))
  3160.             {
  3161.                 int rangeID = ValidMemory.rangeCheckId(address);
  3162.                 uint range = ValidMemory.ValidAreas[rangeID].high;
  3163.                 range -= ValidMemory.ValidAreas[rangeID].low;
  3164.                 vScrollBarMemViewGrid.Maximum = (int)range;
  3165.  
  3166.                 uint offset = address - ValidMemory.ValidAreas[rangeID].low;
  3167.                 //uint offset = address - ValidMemory.ValidAreas[MemViewARange.SelectedIndex].low;
  3168.  
  3169.                 vScrollBarMemViewGrid.Value = (int)offset;
  3170.             }
  3171.         }
  3172.  
  3173.         private void BPType_SelectedIndexChanged(object sender, EventArgs e)
  3174.         {
  3175.             GeckoApp.Properties.Settings.Default.BPType = BPType.SelectedIndex;
  3176.             GeckoApp.Properties.Settings.Default.Save();
  3177.         }
  3178.  
  3179.         // Unfortunately, we can't intercept the Sorting event and cancel it
  3180.         // So the GridView is going to end up sorted
  3181.         // But only the page that's visible
  3182.         // So we have to tell the *whole* search results list to sort itself
  3183.         // It will take care of updating the current page
  3184.         private void SearchResults_Sorted(object sender, EventArgs e)
  3185.         {
  3186.             search.SortResults();
  3187.         }
  3188.  
  3189.         // If we wait until "UserDeletedRow", we won't know what row was deleted
  3190.         private void SearchResults_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
  3191.         {
  3192.             // Cancel the deletion because we'll handle it ourselves
  3193.             // Otherwise both the gridview and the list will delete an item
  3194.             e.Cancel = true;
  3195.  
  3196.             // Activates once per row that is deleted when multiple are selected
  3197.             // Instead we'll delete all the selected rows just once
  3198.             if (SearchResults.SelectedRows[0] == e.Row)
  3199.             {
  3200.                 search.DeleteResults(SearchResults.SelectedRows);
  3201.             }
  3202.             //search.DeleteResult(e.Row.Index);
  3203.         }
  3204.  
  3205.         // But after a row is deleted, the DataGridView resets the selected row's index to 0
  3206.         // So we need to tell the DataGridView to restore the row that was selected before deleting
  3207.         //private void SearchResults_UserDeletedRow(object sender, DataGridViewRowEventArgs e)
  3208.         //{
  3209.         //    search.RestoreSelectedRow();
  3210.         //    SearchResults.Update();
  3211.         //}
  3212.  
  3213.         private void buttonLoadSearch_Click(object sender, EventArgs e)
  3214.         {
  3215.             // Load whole history folder and adjust the dump numbers
  3216.  
  3217.             DialogResult LoadFileResult = openFileDialogSearch.ShowDialog();
  3218.             bool LoadSearchResult = false;
  3219.             if (LoadFileResult == DialogResult.OK)
  3220.             {
  3221.                 LoadSearchResult = search.LoadSearchHistory(openFileDialogSearch.FileName);
  3222.  
  3223.                 if (LoadSearchResult)
  3224.                 {
  3225.                     Search.Text = "Refine";
  3226.                     comboBoxComparisonRHS.Items[1] = (String)"Last value";
  3227.                     ResSrch.Enabled = true;
  3228.                     numericUpDownNewSearchIndex.Value = search.DumpNum;
  3229.                     numericUpDownOldSearchIndex.Value = search.DumpNum - 1;
  3230.                     UpdateValueTypeDropDown();
  3231.                     search.UpdateGridViewPage(true);
  3232.                 }
  3233.                 else
  3234.                 {
  3235.                     Search.Text = "Search";
  3236.                     comboBoxComparisonRHS.Items[1] = (String)"Unknown value";
  3237.                     ResSrch.Enabled = false;
  3238.                     search.Reset();
  3239.                     buttonUndoSearch.Enabled = search.CanUndo();
  3240.                     UpdateValueTypeDropDown();
  3241.                 }
  3242.             }
  3243.         }
  3244.  
  3245.         private void buttonSaveSearch_Click(object sender, EventArgs e)
  3246.         {
  3247.             // Save whole history folder
  3248.  
  3249.  
  3250.             DialogResult SaveFileResult = saveFileDialogSearch.ShowDialog();
  3251.             if (SaveFileResult == DialogResult.OK)
  3252.             {
  3253.                 search.SaveSearchHistory(saveFileDialogSearch.FileName);
  3254.             }
  3255.         }
  3256.  
  3257.         private void buttonCancelSearch_Click(object sender, EventArgs e)
  3258.         {
  3259.             DialogResult confirmationPrompt = MessageBox.Show("Are you sure you want to cancel?", "Confirm Cancel", MessageBoxButtons.OKCancel);
  3260.             if (confirmationPrompt == DialogResult.OK)
  3261.             {
  3262.                 buttonCancelSearch.Enabled = false;
  3263.                 gecko.CancelDump = true;
  3264.             }
  3265.         }
  3266.  
  3267.         // Selectively disable specific types of controls
  3268.         // So callers can selectively enable the ones they might want afterward
  3269.         protected void EnableControlTypes(Control parent, bool enabled)
  3270.         {
  3271.             foreach (Control c in parent.Controls)
  3272.             {
  3273.                 if (c is Button || c is ComboBox || c is TextBox || c is BPList || c is CheckBox)
  3274.                 {
  3275.                     if (!enabled && !c.Enabled)
  3276.                     {
  3277.                         // We are disabling controls but this one is already disabled
  3278.                         WasAlreadyDisabled.Add(c);
  3279.                     }
  3280.  
  3281.                     if (enabled && c.Enabled)
  3282.                     {
  3283.                         // We were disabled but someone enabled us
  3284.                         // so we want to make sure we weren't in the WasAlreadyDisabled list
  3285.                         WasAlreadyDisabled.Remove(c);
  3286.                     }
  3287.  
  3288.                     c.Enabled = enabled;
  3289.                 }
  3290.  
  3291.                 EnableControlTypes(c, enabled);
  3292.             }
  3293.         }
  3294.  
  3295.         private void EnableMainControls(bool enabled)
  3296.         {
  3297.             EnableControlTypes(MainControl, enabled);
  3298.  
  3299.             if (enabled)
  3300.             {
  3301.                 foreach (Control c in WasAlreadyDisabled)
  3302.                 {
  3303.                     c.Enabled = false;
  3304.                 }
  3305.                 WasAlreadyDisabled.Clear();
  3306.             }
  3307.         }
  3308.  
  3309.         private void existingGCTCodeToolStripMenuItem_Click(object sender, EventArgs e)
  3310.         {
  3311.             // If there is no selected existing code, make a new one
  3312.             if (GCTCodeList.SelectedItems.Count == 0)
  3313.             {
  3314.                 makeCode_Click(sender, e);
  3315.                 return;
  3316.             }
  3317.  
  3318.             if (SearchResults.SelectedRows.Count == 0)
  3319.                 return;
  3320.             List<UInt32> addresses = new List<UInt32>();
  3321.             UInt32 address;
  3322.             int i;
  3323.             for (i = 0; i < SearchResults.SelectedRows.Count; i++)
  3324.             {
  3325.                 address = search.GetAddress(SearchResults.SelectedRows[i].Index);
  3326.                 addresses.Add(address);
  3327.             }
  3328.  
  3329.             addresses.Sort();
  3330.  
  3331.             CodeContent nCode = new CodeContent();
  3332.             UInt32 cAddressR = 0x80000000;
  3333.             UInt32 rAddressR;
  3334.             UInt32 offset;
  3335.             bool firstLine = false;
  3336.             UInt32 add;
  3337.             switch (search.searchSize)
  3338.             {
  3339.                 case SearchSize.Bit8:
  3340.                     add = 0;
  3341.                     break;
  3342.                 case SearchSize.Bit16:
  3343.                     add = 0x02000000;
  3344.                     break;
  3345.                 default:
  3346.                     add = 0x04000000;
  3347.                     break;
  3348.             }
  3349.  
  3350.             for (i = 0; i < addresses.Count; i++)
  3351.             {
  3352.                 rAddressR = addresses[i] & 0xFE000000;
  3353.                 if (firstLine && cAddressR != rAddressR && cAddressR != 0x80000000)
  3354.                     nCode.addLine(0xE0000000, 0x80008000);
  3355.                 if (cAddressR != rAddressR)
  3356.                     if (rAddressR != 0x80000000)
  3357.                         nCode.addLine(0x42000000, rAddressR);
  3358.                 cAddressR = rAddressR;
  3359.  
  3360.                 offset = addresses[i] + add - rAddressR;
  3361.                 nCode.addLine(offset, 0);
  3362.  
  3363.                 firstLine = true;
  3364.             }
  3365.             if (cAddressR != 0x80000000)
  3366.                 nCode.addLine(0xE0000000, 0x80008000);
  3367.  
  3368.             // Must de-select current item before changing it
  3369.             int index = GCTCodeList.SelectedItems[0].Index;
  3370.  
  3371.             GCTCodeList.Items[index].Selected = false;
  3372.  
  3373.             GCTCodeContents.AddCode(nCode, index);
  3374.  
  3375.             GCTCodeList.Items[index].Selected = true;
  3376.  
  3377.             MainControl.SelectedTab = GCTPage;
  3378.         }
  3379.  
  3380.         private void buttonShowMem_Click(object sender, EventArgs e)
  3381.         {
  3382.             if (buttonShowMem.Text == "Show Mem")
  3383.             {
  3384.                 try
  3385.                 {
  3386.                     if (ValidMemory.validAddress(bpHandler.MemoryAddress))
  3387.                     {
  3388.                         CenteredMemViewSelection(sender, e, bpHandler.MemoryAddress);
  3389.                     }
  3390.  
  3391.                     //uint vAddress = bpHandler.MemoryAddress;
  3392.                     //if (ValidMemory.validAddress(vAddress))
  3393.                     //{
  3394.                     //    viewer.address = vAddress;
  3395.                     //    memViewAValue.Text = GlobalFunctions.toHex(vAddress);
  3396.                     //    MainControl.SelectedTab = MemView;
  3397.                     //    viewer.Update();
  3398.                     //}
  3399.                 }
  3400.                 catch (EUSBGeckoException exc)
  3401.                 {
  3402.                     exceptionHandling.HandleException(exc);
  3403.                 }
  3404.             }
  3405.             else
  3406.             {
  3407.                 bpHandler.BranchToggle();
  3408.                 UpdateShowMemColor();
  3409.             }
  3410.         }
  3411.  
  3412.         private void memViewGrid_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e)
  3413.         {
  3414.             // Avoid processing if the mouse isn't over an actual data cell
  3415.             if (e.ColumnIndex < 1) return;
  3416.             if (e.RowIndex < 0) return;
  3417.  
  3418.             // Figure out what byte the mouse is over
  3419.             // The point location in e is relative to the upper left corner
  3420.             uint offset;
  3421.             if (e.X < 21)
  3422.             {
  3423.                 offset = 0;
  3424.             }
  3425.             else if (e.X < 35)
  3426.             {
  3427.                 offset = 1;
  3428.             }
  3429.             else if (e.X < 49)
  3430.             {
  3431.                 offset = 2;
  3432.             }
  3433.             else
  3434.             {
  3435.                 offset = 3;
  3436.             }
  3437.  
  3438.             // Change the DataGridView's 0th column's header
  3439.             uint hoverAddress = viewer.address;
  3440.             hoverAddress += 0x10 * (uint)e.RowIndex;
  3441.             hoverAddress += (uint)(e.ColumnIndex - 1) * 4;
  3442.             hoverAddress += offset;
  3443.             // Pad with some white space so that the cell width doesn't change
  3444.             address.HeaderText = GlobalFunctions.toHex(hoverAddress, 8);
  3445.         }
  3446.  
  3447.         private void WalkToBLR()
  3448.         {
  3449.             if (SteppingOut)
  3450.             {
  3451.                 SteppingOut = false;
  3452.                 buttonStepOutOf.Text = "Step out";
  3453.                 return;
  3454.             }
  3455.  
  3456.             try
  3457.             {
  3458.                 if (gecko.status() == WiiStatus.Breakpoint)
  3459.                 {
  3460.                     SteppingOut = true;
  3461.                     buttonStepOutOf.Text = "Cancel";
  3462.                     // Repeatedly Step Over until we hit a BLR
  3463.                     while (!bpHandler.IsBLR() && SteppingOut)
  3464.                     {
  3465.                         BPStepOverButton_Click(null, null);
  3466.                         do
  3467.                         {
  3468.                             Application.DoEvents();
  3469.                         } while (BPCancel.Enabled);
  3470.                         MainControl.Update();
  3471.                     }
  3472.                     SteppingOut = false;
  3473.                     buttonStepOutOf.Text = "Step out";
  3474.                 }
  3475.             }
  3476.             catch (EUSBGeckoException exc)
  3477.             {
  3478.                 exceptionHandling.HandleException(exc);
  3479.             }
  3480.         }
  3481.  
  3482.         private void comboBoxDisplayType_SelectedIndexChanged(object sender, EventArgs e)
  3483.         {
  3484.             search.DisplayType = comboBoxDisplayType.SelectedItem.ToString();
  3485.             comboBoxDisplayType.Update();
  3486.             search.UpdateGridViewPage();
  3487.             ResizeSearchResults();
  3488.         }
  3489.  
  3490.         private void SearchResults_ColumnDividerDoubleClick(object sender, DataGridViewColumnDividerDoubleClickEventArgs e)
  3491.         {
  3492.             SearchResults.AutoResizeColumn(e.ColumnIndex, DataGridViewAutoSizeColumnMode.AllCells);
  3493.         }
  3494.  
  3495.         public void ResizeSearchResults()
  3496.         {
  3497.             SearchResults.AutoResizeColumn(1, DataGridViewAutoSizeColumnMode.AllCells);
  3498.             SearchResults.AutoResizeColumn(2, DataGridViewAutoSizeColumnMode.AllCells);
  3499.             SearchResults.AutoResizeColumn(3, DataGridViewAutoSizeColumnMode.AllCells);
  3500.         }
  3501.  
  3502.         private void SearchResults_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
  3503.         {
  3504.             int row = e.RowIndex, col = e.ColumnIndex;
  3505.             if (row >= 0 && e.Button == MouseButtons.Right && SearchResults[col, row].Selected == false)
  3506.             {
  3507.                 foreach (DataGridViewRow selRow in SearchResults.SelectedRows)
  3508.                 {
  3509.                     selRow.Selected = false;
  3510.                 }
  3511.  
  3512.                 SearchResults[col, row].Selected = true;
  3513.                 SearchResults.CurrentCell = SearchResults[col, row];
  3514.             }
  3515.         }
  3516.  
  3517.         private void gCTWizardToolStripMenuItem_Click(object sender, EventArgs e)
  3518.         {
  3519.             int indexToSelect = GCTCodeContents.Count;  // will pick "New Code"
  3520.             bool wasSelected = false;
  3521.             if (GCTCodeList.SelectedItems.Count != 0)
  3522.             {
  3523.                 // If there is a selected code in the GCT Code List, pick it instead
  3524.                 indexToSelect = GCTCodeList.SelectedIndices[0];
  3525.                 wasSelected = true;
  3526.             }
  3527.  
  3528.             if (GCTCodeList.SelectedItems.Count > 0)
  3529.             {
  3530.                 // Must de-select current item before changing it
  3531.                 GCTCodeList.SelectedItems[0].Selected = false;
  3532.             }
  3533.  
  3534.             uint address = 0x80000000;
  3535.             string value = (0).ToString();
  3536.             if (SearchResults.SelectedRows.Count > 0)
  3537.             {
  3538.                 address = search.GetAddress(SearchResults.SelectedRows[0].Index);
  3539.                 value = search.GetResult(SearchResults.SelectedRows[0].Index).SValue;
  3540.             }
  3541.             codeWizard.textBoxAddress.Text = GlobalFunctions.toHex(address);
  3542.             codeWizard.textBoxValue.Text = value;
  3543.             codeWizard.comboBoxCodeType.SelectedIndex = 0;
  3544.  
  3545.             switch (comboBoxSearchDataType.SelectedIndex)
  3546.             {
  3547.                 case 0: codeWizard.radioButton8Bit.Checked = true; break;
  3548.                 case 1: codeWizard.radioButton16Bit.Checked = true; break;
  3549.                 case 2:
  3550.                 case 3: codeWizard.radioButton32Bit.Checked = true; break;
  3551.                 default: codeWizard.radioButton32Bit.Checked = true; break;
  3552.             }
  3553.  
  3554.  
  3555.             codeWizard.PrepareGCTWizard(indexToSelect);
  3556.             DialogResult dialogResult = codeWizard.ShowDialog();
  3557.             if (dialogResult == DialogResult.OK)
  3558.             {
  3559.             }
  3560.  
  3561.             if (wasSelected)
  3562.             {
  3563.                 GCTCodeList.Items[indexToSelect].Selected = true;
  3564.             }
  3565.         }
  3566.  
  3567.         private void gCTWizardToolStripMenuItemMemView_Click(object sender, EventArgs e)
  3568.         {
  3569.             int indexToSelect = GCTCodeContents.Count;  // will pick "New Code"
  3570.             bool wasSelected = false;
  3571.             if (GCTCodeList.SelectedItems.Count != 0)
  3572.             {
  3573.                 // If there is a selected code in the GCT Code List, pick it instead
  3574.                 indexToSelect = GCTCodeList.SelectedIndices[0];
  3575.                 wasSelected = true;
  3576.             }
  3577.  
  3578.             if (GCTCodeList.SelectedItems.Count > 0)
  3579.             {
  3580.                 // Must de-select current item before changing it
  3581.                 GCTCodeList.SelectedItems[0].Selected = false;
  3582.             }
  3583.  
  3584.             UInt32 vAdd = viewer.selectedAddress;
  3585.             UInt32 value = gecko.peek(vAdd);
  3586.  
  3587.             codeWizard.textBoxAddress.Text = GlobalFunctions.toHex(vAdd);
  3588.             codeWizard.textBoxValue.Text = GlobalFunctions.toHex(value);
  3589.  
  3590.             codeWizard.comboBoxCodeType.SelectedIndex = 0;
  3591.  
  3592.             codeWizard.radioButton32Bit.Checked = true;
  3593.  
  3594.             codeWizard.PrepareGCTWizard(indexToSelect);
  3595.             DialogResult dialogResult = codeWizard.ShowDialog();
  3596.             if (dialogResult == DialogResult.OK)
  3597.             {
  3598.             }
  3599.  
  3600.             if (wasSelected)
  3601.             {
  3602.                 GCTCodeList.Items[indexToSelect].Selected = true;
  3603.             }
  3604.         }
  3605.  
  3606.         private void copyToolStripMenuItem_Click(object sender, EventArgs e)
  3607.         {
  3608.             Clipboard.Clear();
  3609.             String clipboardText = String.Empty;
  3610.             foreach (DataGridViewRow row in SearchResults.SelectedRows)
  3611.             {
  3612.                 for (int i = 0; i < SearchResults.ColumnCount; i++)
  3613.                 {
  3614.                     clipboardText += row.Cells[i].Value.ToString();
  3615.                     if (i + 1 < SearchResults.ColumnCount)
  3616.                     {
  3617.                         clipboardText += "\t";
  3618.                     }
  3619.                     else
  3620.                     {
  3621.                         clipboardText += "\r\n";
  3622.                     }
  3623.                 }
  3624.             }
  3625.             Clipboard.SetText(clipboardText);
  3626.         }
  3627.  
  3628.         private void splitContainerRegASM_SplitterMoved(object sender, SplitterEventArgs e)
  3629.         {
  3630.             GeckoApp.Properties.Settings.Default.LastSplitterSize = splitContainerRegASM.SplitterDistance;
  3631.             GeckoApp.Properties.Settings.Default.Save();
  3632.         }
  3633.  
  3634.         private void checkBoxPauseCodes_CheckedChanged(object sender, EventArgs e)
  3635.         {
  3636.             GeckoApp.Properties.Settings.Default.PauseCodes = checkBoxPauseCodes.Checked;
  3637.             GeckoApp.Properties.Settings.Default.Save();
  3638.         }
  3639.  
  3640.         private void checkBoxBPNext_CheckedChanged(object sender, EventArgs e)
  3641.         {
  3642.             GeckoApp.Properties.Settings.Default.BPNext = checkBoxBPNext.Checked;
  3643.             GeckoApp.Properties.Settings.Default.Save();
  3644.         }
  3645.  
  3646.         private void MainForm_ResizeEnd(object sender, EventArgs e)
  3647.         {
  3648.             GeckoApp.Properties.Settings.Default.LastSize = Size;
  3649.             GeckoApp.Properties.Settings.Default.Save();
  3650.         }
  3651.  
  3652.         private void memViewAValue_KeyDown(object sender, KeyEventArgs e)
  3653.         {
  3654.             if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down || e.KeyCode == Keys.PageUp || e.KeyCode == Keys.PageDown)
  3655.             {
  3656.                 KeyEventArgs newArgs = new KeyEventArgs(e.KeyCode | Keys.Shift);
  3657.                 memViewGrid_KeyDown(sender, newArgs);
  3658.                 memViewAValue.Text = GlobalFunctions.toHex(viewer.selectedAddress);
  3659.                 e.Handled = true;
  3660.             }
  3661.             if (e.KeyCode == Keys.Enter)
  3662.             {
  3663.                 uint address;
  3664.                 if (GlobalFunctions.tryToHex(memViewAValue.Text, out address))
  3665.                 {
  3666.                     CenteredMemViewSelection(sender, e, address);
  3667.                 }
  3668.             }
  3669.         }
  3670.  
  3671.         private void vScrollBarMemViewGrid_Scroll(object sender, ScrollEventArgs e)
  3672.         {
  3673.             uint vAddress;
  3674.             memViewAValue.IsValidGet(out vAddress);
  3675.             int index = ValidMemory.rangeCheckId(vAddress);
  3676.             vAddress = ValidMemory.ValidAreas[index].low + (uint)e.NewValue;
  3677.             if (vAddress >= ValidMemory.ValidAreas[index].high)
  3678.             {
  3679.                 vAddress = ValidMemory.ValidAreas[index].low;
  3680.             }
  3681.             if (!ValidMemory.validAddress(vAddress))
  3682.             {
  3683.                 MessageBox.Show("Invalid address");
  3684.                 return;
  3685.             }
  3686.             vAddress &= 0xFFFFFFFC;
  3687.  
  3688.             MemViewARange.SelectedIndexChanged -= MemViewARange_SelectedIndexChanged;
  3689.             MemViewARange.SelectedIndex = ValidMemory.rangeCheckId(vAddress);
  3690.             MemViewARange.SelectedIndexChanged += MemViewARange_SelectedIndexChanged;
  3691.  
  3692.             //int oldSelectedRow = memViewGrid.CurrentCell.RowIndex;
  3693.             //int oldSelectedCol = memViewGrid.CurrentCell.ColumnIndex;
  3694.  
  3695.             //CenteredMemViewSelection(sender, e, vAddress);
  3696.  
  3697.             //memViewGrid.CurrentCell = memViewGrid[oldSelectedCol, oldSelectedRow];
  3698.  
  3699.             CenteredMemView(sender, e, vAddress);
  3700.  
  3701.             //viewer.address = vAddress;
  3702.             //memViewAValue.Text = GlobalFunctions.toHex(vAddress);
  3703.             //viewer.Update();
  3704.         }
  3705.  
  3706.         private void disassemblerToolStripMenuItem_Click(object sender, EventArgs e)
  3707.         {
  3708.             DisRegion.Text = GlobalFunctions.toHex(viewer.selectedAddress);
  3709.  
  3710.             DisUpdateBtn_Click(sender, e);
  3711.  
  3712.             MainControl.SelectedTab = DisPage;
  3713.         }
  3714.  
  3715.         private void memoryViewerToolStripMenuItem_Click(object sender, EventArgs e)
  3716.         {
  3717.             CenteredMemViewSelection(sender, e, disassembler.disAddress);
  3718.             MainControl.SelectedTab = MemView;
  3719.         }
  3720.  
  3721.         private void SortToolStripMenuItem_Click(object sender, EventArgs e)
  3722.         {
  3723.             ListSortDirection SortDirection = ListSortDirection.Ascending;
  3724.             DataGridViewColumn currentSelectedColumn = SearchResults.Columns[SearchResults.CurrentCell.ColumnIndex];
  3725.  
  3726.             // Sort descending if the current selected cell is already the current column and we were already sorted ascending
  3727.             if (SearchResults.SortedColumn == currentSelectedColumn && SearchResults.SortOrder == SortOrder.Ascending)
  3728.             {
  3729.                 SortDirection = ListSortDirection.Descending;
  3730.             }
  3731.             SearchResults.Sort(currentSelectedColumn, SortDirection);
  3732.         }
  3733.  
  3734.         private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
  3735.         {
  3736.             // Pretend it was the user who hit the delete key
  3737.             SendKeys.Send("{DELETE}");
  3738.             SendKeys.Flush();
  3739.         }
  3740.  
  3741.         private void copySelectionToolStripMenuItem_Click(object sender, EventArgs e)
  3742.         {
  3743.             // Send ctrl+c
  3744.             memViewGrid_KeyDown(sender, new KeyEventArgs(Keys.C | Keys.Control));
  3745.             //SendKeys.Send("^C");
  3746.             //SendKeys.Flush();
  3747.             //Application.DoEvents();
  3748.         }
  3749.  
  3750.         private void copyAllCellsToolStripMenuItem_Click(object sender, EventArgs e)
  3751.         {
  3752.             // Send ctrl+shift+c
  3753.             memViewGrid_KeyDown(sender, new KeyEventArgs(Keys.C | Keys.Control | Keys.Shift));
  3754.         }
  3755.  
  3756.         private void disableToolStripMenuItem_Click(object sender, EventArgs e)
  3757.         {
  3758.             CodeContent code = GCTCodeContents[GCTCodeList.SelectedIndices[0]];
  3759.             CodeContent commentedCode = new CodeContent();
  3760.             for (int i = 0; i < code.lines.Count; i++)
  3761.             {
  3762.                 commentedCode.addLine(code.lines[i].left, code.lines[i].right, false);
  3763.             }
  3764.  
  3765.             GCTCodeValues.Text = CodeController.CodeContentToCodeTextBox(commentedCode);
  3766.         }
  3767.  
  3768.         private void enableToolStripMenuItem_Click(object sender, EventArgs e)
  3769.         {
  3770.             CodeContent code = GCTCodeContents[GCTCodeList.SelectedIndices[0]];
  3771.             CodeContent uncommentedCode = new CodeContent();
  3772.             for (int i = 0; i < code.lines.Count; i++)
  3773.             {
  3774.                 uncommentedCode.addLine(code.lines[i].left, code.lines[i].right, true);
  3775.             }
  3776.  
  3777.             GCTCodeValues.Text = CodeController.CodeContentToCodeTextBox(uncommentedCode);
  3778.         }
  3779.  
  3780.         private void addToolStripMenuItem_Click(object sender, EventArgs e)
  3781.         {
  3782.             GeckoApp.external.AddressTextBox addressBox = GetAddressBoxFromSender(sender);
  3783.             if (addressBox != null)
  3784.             {
  3785.                 addressBox.SendKeyCode(new KeyEventArgs(Keys.Control | Keys.Enter));
  3786.             }
  3787.         }
  3788.  
  3789.         private void removeToolStripMenuItem_Click(object sender, EventArgs e)
  3790.         {
  3791.             GeckoApp.external.AddressTextBox addressBox = GetAddressBoxFromSender(sender);
  3792.             if (addressBox != null)
  3793.             {
  3794.                 addressBox.SendKeyCode(new KeyEventArgs(Keys.Control | Keys.Delete));
  3795.             }
  3796.         }
  3797.  
  3798.         private void clearAllHistoryToolStripMenuItem_Click(object sender, EventArgs e)
  3799.         {
  3800.             GeckoApp.external.AddressTextBox addressBox = GetAddressBoxFromSender(sender);
  3801.             if (addressBox != null)
  3802.             {
  3803.                 addressBox.SendKeyCode(new KeyEventArgs(Keys.Control | Keys.Shift | Keys.Delete));
  3804.             }
  3805.         }
  3806.  
  3807.         private void cutAllHistoryToolStripMenuItem_Click(object sender, EventArgs e)
  3808.         {
  3809.             GeckoApp.external.AddressTextBox addressBox = GetAddressBoxFromSender(sender);
  3810.             if (addressBox != null)
  3811.             {
  3812.                 addressBox.SendKeyCode(new KeyEventArgs(Keys.Control | Keys.Shift | Keys.X));
  3813.             }
  3814.         }
  3815.  
  3816.         private void copyAllHistoryToolStripMenuItem_Click(object sender, EventArgs e)
  3817.         {
  3818.             GeckoApp.external.AddressTextBox addressBox = GetAddressBoxFromSender(sender);
  3819.             if (addressBox != null)
  3820.             {
  3821.                 addressBox.SendKeyCode(new KeyEventArgs(Keys.Control | Keys.Shift | Keys.C));
  3822.             }
  3823.         }
  3824.  
  3825.         private void pasteAllHistoryToolStripMenuItem_Click(object sender, EventArgs e)
  3826.         {
  3827.             GeckoApp.external.AddressTextBox addressBox = GetAddressBoxFromSender(sender);
  3828.             if (addressBox != null)
  3829.             {
  3830.                 addressBox.SendKeyCode(new KeyEventArgs(Keys.Control | Keys.Shift | Keys.V));
  3831.             }
  3832.         }
  3833.  
  3834.         private void autoHistoryToolStripMenuItem_Click(object sender, EventArgs e)
  3835.         {
  3836.             GeckoApp.external.AddressTextBox addressBox = GetAddressBoxFromSender(sender);
  3837.             if (addressBox != null)
  3838.             {
  3839.                 addressBox.AutoHistory = !addressBox.AutoHistory;
  3840.             }
  3841.         }
  3842.  
  3843.         private void addressContextMenu_Opened(object sender, EventArgs e)
  3844.         {
  3845.             GeckoApp.external.AddressTextBox addressBox = GetAddressBoxFromSender(sender);
  3846.             GeckoApp.external.HistoryTextBox historyBox = GetHistoryBoxFromSender(sender);
  3847.             if (addressBox != null)
  3848.             {
  3849.                 autoHistoryToolStripMenuItem.Checked = addressBox.AutoHistory;
  3850.                 AddressContextMenuOwner = addressBox;
  3851.                 HistoryContextMenuOwner = null;
  3852.             }
  3853.             else if (historyBox != null)
  3854.             {
  3855.                 autoHistoryToolStripMenuItem.Checked = historyBox.AutoHistory;
  3856.                 AddressContextMenuOwner = null;
  3857.                 HistoryContextMenuOwner = historyBox;
  3858.             }
  3859.            
  3860.         }
  3861.  
  3862.         private GeckoApp.external.AddressTextBox GetAddressBoxFromSender(object sender)
  3863.         {
  3864.             //Make sure the sender is a ToolStripMenuItem
  3865.             ToolStripMenuItem myItem = sender as ToolStripMenuItem;
  3866.  
  3867.             // If that fails, the sender might actually be a ContextMenuStrip already
  3868.             // This is the case when called from ContextMenuStrip_Opened
  3869.             if (myItem == null)
  3870.             {
  3871.                 //Get the ContextMenuString (owner of the ToolsStripMenuItem)
  3872.                 ContextMenuStrip theStrip = sender as ContextMenuStrip;
  3873.                 if (theStrip != null)
  3874.                 {
  3875.                     return theStrip.SourceControl as GeckoApp.external.AddressTextBox;
  3876.                 }
  3877.             }
  3878.  
  3879.             // If it didn't fail, get the ContextMenuStrip out of it
  3880.             if (myItem != null)
  3881.             {
  3882.                 ContextMenuStrip theStrip = myItem.Owner as ContextMenuStrip;
  3883.                 if (theStrip != null)
  3884.                 {
  3885.                     return theStrip.SourceControl as GeckoApp.external.AddressTextBox;
  3886.                 }
  3887.             }
  3888.  
  3889.             // If above casts fail, return nothing
  3890.             return null;
  3891.         }
  3892.  
  3893.         private GeckoApp.external.HistoryTextBox GetHistoryBoxFromSender(object sender)
  3894.         {
  3895.             //Make sure the sender is a ToolStripMenuItem
  3896.             ToolStripMenuItem myItem = sender as ToolStripMenuItem;
  3897.  
  3898.             // If that fails, the sender might actually be a ContextMenuStrip already
  3899.             // This is the case when called from ContextMenuStrip_Opened
  3900.             if (myItem == null)
  3901.             {
  3902.                 //Get the ContextMenuString (owner of the ToolsStripMenuItem)
  3903.                 ContextMenuStrip theStrip = sender as ContextMenuStrip;
  3904.                 if (theStrip != null)
  3905.                 {
  3906.                     return theStrip.SourceControl as GeckoApp.external.HistoryTextBox;
  3907.                 }
  3908.             }
  3909.  
  3910.             // If it didn't fail, get the ContextMenuStrip out of it
  3911.             if (myItem != null)
  3912.             {
  3913.                 ContextMenuStrip theStrip = myItem.Owner as ContextMenuStrip;
  3914.                 if (theStrip != null)
  3915.                 {
  3916.                     return theStrip.SourceControl as GeckoApp.external.HistoryTextBox;
  3917.                 }
  3918.             }
  3919.  
  3920.             // If above casts fail, return nothing
  3921.             return null;
  3922.         }
  3923.  
  3924.         private void showHistoryToolStripMenuItem_Click(object sender, EventArgs e)
  3925.         {
  3926.             GeckoApp.external.AddressTextBox addressBox = GetAddressBoxFromSender(sender);
  3927.             if (addressBox != null)
  3928.             {
  3929.                 addressBox.ShowHistory(true);
  3930.             }
  3931.         }
  3932.  
  3933.         private void BPConditionRegSelect_SelectedIndexChanged(object sender, EventArgs e)
  3934.         {
  3935.             UpdateBPCondValue();
  3936.         }
  3937.  
  3938.         private void UpdateBPCondValue()
  3939.         {
  3940.             BPCondValue.Text = GlobalFunctions.toHex(bpHandler.GetRegisterValue(BPConditionRegSelect.SelectedIndex));
  3941.         }
  3942.  
  3943.         private void copyToolStripMenuItem1_Click(object sender, EventArgs e)
  3944.         {
  3945.             if (AddressContextMenuOwner != null)
  3946.                 Clipboard.SetText(AddressContextMenuOwner.Text);
  3947.             else if (HistoryContextMenuOwner != null)
  3948.                 Clipboard.SetText(HistoryContextMenuOwner.Text);
  3949.         }
  3950.  
  3951.         private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
  3952.         {
  3953.             if (AddressContextMenuOwner != null)
  3954.                 AddressContextMenuOwner.Text = Clipboard.GetText();
  3955.             else if (HistoryContextMenuOwner != null)
  3956.                 HistoryContextMenuOwner.Text = Clipboard.GetText();
  3957.         }
  3958.  
  3959.         private void MemViewScrollbar_KeyDown(object sender, KeyEventArgs e)
  3960.         {
  3961.             if (e.KeyCode == Keys.PageDown)
  3962.             {
  3963.                 MemViewScrollbar.Value = 0;
  3964.             }
  3965.             else if (e.KeyCode == Keys.PageUp)
  3966.             {
  3967.                 MemViewScrollbar.Value = 2;
  3968.             }
  3969.         }
  3970.  
  3971.         private void deleteToolStripMenuItem1_Click(object sender, EventArgs e)
  3972.         {
  3973.             BPCondDel_Click(sender, e);
  3974.         }
  3975.  
  3976.         private void clearAllToolStripMenuItem_Click(object sender, EventArgs e)
  3977.         {
  3978.             BPCondClear_Click(sender, e);
  3979.         }
  3980.  
  3981.         private void copyToolStripMenuItem2_Click(object sender, EventArgs e)
  3982.         {
  3983.             string clipboardText = String.Empty;
  3984.             foreach (string cond in BPCondList.Items)
  3985.             {
  3986.                 clipboardText += cond.ToString() + "\r\n";
  3987.             }
  3988.             Clipboard.SetText(clipboardText);
  3989.         }
  3990.  
  3991.         private void SRR0NEQToolStripMenuItem_Click(object sender, EventArgs e)
  3992.         {
  3993.             int reg = (int)GeckoApp.BPList.RegisterList.SRR0;
  3994.             BreakpointCondition cond = new BreakpointCondition(
  3995.                 reg, bpHandler.GetRegisterValue(reg), BreakpointComparison.NotEqual);
  3996.  
  3997.             bpHandler.conditions.Add(cond);
  3998.         }
  3999.  
  4000.         private void SRR0EQToolStripMenuItem_Click(object sender, EventArgs e)
  4001.         {
  4002.             int reg = (int)GeckoApp.BPList.RegisterList.SRR0;
  4003.             BreakpointCondition cond = new BreakpointCondition(
  4004.                  reg, bpHandler.GetRegisterValue(reg), BreakpointComparison.Equal);
  4005.  
  4006.             bpHandler.conditions.Add(cond);
  4007.         }
  4008.  
  4009.         private void copyToolStripMenuItem3_Click(object sender, EventArgs e)
  4010.         {
  4011.             string clipboardText = String.Empty;
  4012.             foreach (string asm in DisAssBox.Items)
  4013.             {
  4014.                 clipboardText += asm.ToString() + "\r\n";
  4015.             }
  4016.             Clipboard.SetText(clipboardText);
  4017.         }
  4018.  
  4019.         private void BPCondList_KeyDown(object sender, KeyEventArgs e)
  4020.         {
  4021.             if (e.KeyCode == Keys.Delete)
  4022.             {
  4023.                 BPCondDel_Click(sender, e);
  4024.                 e.Handled = true;
  4025.             }
  4026.         }
  4027.  
  4028.         private void AsText_KeyDown(object sender, KeyEventArgs e)
  4029.         {
  4030.             if (e.KeyCode == Keys.Enter)
  4031.             {
  4032.                 e.Handled = true;
  4033.                 Assemble_Click(sender, e);
  4034.             }
  4035.         }
  4036.  
  4037.         private void SetConditionGroupTextBox_KeyDown(object sender, KeyEventArgs e)
  4038.         {
  4039.             if (e.KeyCode == Keys.Enter)
  4040.             {
  4041.                 List<int> indices = new List<int>();
  4042.                 for (int i = BPCondList.SelectedItems.Count - 1; i >= 0; i--)
  4043.                 {
  4044.                     indices.Add(BPCondList.SelectedIndices[i]);
  4045.                 }
  4046.  
  4047.                 foreach (int index in indices)
  4048.                 {
  4049.                     bpHandler.conditions.SetIndexedConditionGroup(index, Convert.ToUInt32(SetConditionGroupTextBox.Text));
  4050.                 }
  4051.                 BPCondMenu.Hide();
  4052.             }
  4053.         }
  4054.  
  4055.         private void BPCondMenu_Opened(object sender, EventArgs e)
  4056.         {
  4057.             int index = BPCondList.SelectedIndex;
  4058.             String newText;
  4059.  
  4060.             if (index == -1)
  4061.             {
  4062.                 newText = "1";
  4063.             }
  4064.             else
  4065.             {
  4066.                 newText = bpHandler.conditions.GetIndexedConditionGroup(BPCondList.SelectedIndex).ToString();
  4067.             }
  4068.             SetConditionGroupTextBox.Text = newText;
  4069.         }
  4070.  
  4071.         private void SetConditionGroupTextBox_TextChanged(object sender, EventArgs e)
  4072.         {
  4073.             String text = SetConditionGroupTextBox.Text;
  4074.             text = System.Text.RegularExpressions.Regex.Replace(text, "[^0-9]", String.Empty);
  4075.             SetConditionGroupTextBox.Text = text;
  4076.         }
  4077.  
  4078.         private void setConditionGroupToolStripMenuItem_MouseMove(object sender, MouseEventArgs e)
  4079.         {
  4080.             SetConditionGroupTextBox.Focus();
  4081.             SetConditionGroupTextBox.SelectAll();
  4082.         }
  4083.  
  4084.         private void BPCondList_MouseDown(object sender, MouseEventArgs e)
  4085.         {
  4086.             int index = BPCondList.IndexFromPoint(e.Location);
  4087.             if (e.Button == MouseButtons.Right && !BPCondList.SelectedIndices.Contains(index))
  4088.             {
  4089.                 BPCondList.ClearSelected();
  4090.                 BPCondList.SelectedIndex = index;
  4091.             }
  4092.         }
  4093.  
  4094.         private void pasteToolStripMenuItem1_Click(object sender, EventArgs e)
  4095.         {
  4096.             String[] sep = Clipboard.GetText().Split(new char[] { '\r', '\n' });
  4097.             foreach (String entry in sep)
  4098.             {
  4099.                 BreakpointCondition cond = BreakpointCondition.FromString(entry);
  4100.                 if (cond != null)
  4101.                 {
  4102.                     bpHandler.conditions.Add(cond);
  4103.                 }
  4104.             }
  4105.         }
  4106.  
  4107.         private void copyToolStripMenuItem4_Click(object sender, EventArgs e)
  4108.         {
  4109.             string clipboardText = String.Empty;
  4110.             foreach (string cond in BPCondList.SelectedItems)
  4111.             {
  4112.                 clipboardText += cond.ToString() + "\r\n";
  4113.             }
  4114.             Clipboard.SetText(clipboardText);
  4115.         }
  4116.  
  4117.         private void buttonStepUntil_Click(object sender, EventArgs e)
  4118.         {
  4119.             if (SteppingUntil)
  4120.             {
  4121.                 SteppingUntil = false;
  4122.                 buttonStepUntil.Text = "Step until";
  4123.                 return;
  4124.             }
  4125.  
  4126.             try
  4127.             {
  4128.                 if (gecko.status() == WiiStatus.Breakpoint)
  4129.                 {
  4130.                     SteppingUntil = true;
  4131.                     buttonStepUntil.Text = "Cancel";
  4132.                     // Repeatedly Step Into until the conditions are matched
  4133.                     MemoryStream regStream = new MemoryStream();
  4134.                     gecko.GetRegisters(regStream);
  4135.  
  4136.                     while (!bpHandler.conditions.Check(regStream, BreakpointType.Step, 0, gecko) && SteppingUntil)
  4137.                     {
  4138.                         BPStepButton_Click(sender, e);
  4139.                         System.Threading.Thread.Sleep(100);
  4140.                         MainControl.Update();
  4141.                         regStream.Seek(0, SeekOrigin.Begin);
  4142.                         regStream.SetLength(0);
  4143.                         gecko.GetRegisters(regStream);
  4144.                         Application.DoEvents();
  4145.                     }
  4146.                     SteppingUntil = false;
  4147.                     checkBoxBPCondEnable.Checked = false;
  4148.                     buttonStepUntil.Text = "Step until";
  4149.                 }
  4150.             }
  4151.             catch (EUSBGeckoException exc)
  4152.             {
  4153.                 exceptionHandling.HandleException(exc);
  4154.                 SteppingUntil = false;
  4155.                 buttonStepUntil_Click(sender, e);
  4156.             }
  4157.         }
  4158.  
  4159.         private void checkBoxBPCondEnable_CheckedChanged(object sender, EventArgs e)
  4160.         {
  4161.             bpHandler.conditions.Enabled = checkBoxBPCondEnable.Checked;
  4162.         }
  4163.  
  4164.         private void checkBoxLogSteps_CheckedChanged(object sender, EventArgs e)
  4165.         {
  4166.             if (BPStepLogWriter != null)
  4167.             {
  4168.                 BPStepLogWriter.Close();
  4169.                 BPStepLogWriter.Dispose();
  4170.                 BPStepLogWriter = null;
  4171.             }
  4172.  
  4173.             if (checkBoxLogSteps.Checked)
  4174.             {
  4175.                 DialogResult SaveFileResult = saveFileDialogLogSteps.ShowDialog();
  4176.                 if (SaveFileResult == DialogResult.OK)
  4177.                 {
  4178.                     BPStepLogWriter = new StreamWriter(saveFileDialogLogSteps.FileName, true);
  4179.                     BPStepLogWriter.WriteLine();
  4180.                     BPStepLogWriter.WriteLine();
  4181.                 }
  4182.                 else
  4183.                 {
  4184.                     checkBoxLogSteps.Checked = false;
  4185.                 }
  4186.             }
  4187.         }
  4188.  
  4189.         private void buttonUndoSearch_Click(object sender, EventArgs e)
  4190.         {
  4191.             DialogResult confirmationPrompt = MessageBox.Show("Are you sure you want to undo?", "Confirm Undo", MessageBoxButtons.OKCancel);
  4192.             if (confirmationPrompt == DialogResult.OK)
  4193.             {
  4194.                 search.UndoSearch();
  4195.             }
  4196.  
  4197.             buttonUndoSearch.Enabled = search.CanUndo();
  4198.         }
  4199.  
  4200.         private void numericUpDownNewSearchIndex_ValueChanged(object sender, EventArgs e)
  4201.         {
  4202.             if (numericUpDownNewSearchIndex.Value > search.DumpNum)
  4203.             {
  4204.                 numericUpDownNewSearchIndex.Value = search.DumpNum;
  4205.             }
  4206.             else if (numericUpDownNewSearchIndex.Value != 0)
  4207.             {
  4208.                 search.LoadIndexIntoNewSearchDump(Convert.ToInt32(numericUpDownNewSearchIndex.Value));
  4209.                 search.LoadIndexIntoSearchList(Convert.ToInt32(numericUpDownNewSearchIndex.Value));
  4210.                 search.UpdateGridViewPage(false);
  4211.             }
  4212.             UpdateValueTypeDropDown();
  4213.         }
  4214.  
  4215.  
  4216.         private void numericUpDownOldSearchIndex_ValueChanged(object sender, EventArgs e)
  4217.         {
  4218.             if (numericUpDownOldSearchIndex.Value > search.DumpNum - 1)
  4219.             {
  4220.                 if (search.DumpNum == 0)
  4221.                 {
  4222.                     numericUpDownOldSearchIndex.Value = 0;
  4223.                 }
  4224.                 else
  4225.                 {
  4226.                     numericUpDownOldSearchIndex.Value = search.DumpNum - 1;
  4227.                 }
  4228.             }
  4229.             else if (numericUpDownOldSearchIndex.Value != 0)
  4230.             {
  4231.                 search.LoadIndexIntoOldSearchDump(Convert.ToInt32(numericUpDownOldSearchIndex.Value));
  4232.                 search.UpdateGridViewPage(false);
  4233.             }
  4234.             UpdateValueTypeDropDown();
  4235.         }
  4236.  
  4237.         private void buttonAddSearchGroup_Click(object sender, EventArgs e)
  4238.         {
  4239.             UInt32 lValue;
  4240.             if (!GlobalFunctions.tryToHex(textBoxComparisonValue.Text, out lValue))
  4241.             {
  4242.                 lValue = 0;
  4243.             }
  4244.  
  4245.             searchComparisons.Add(new SearchComparisonInfo(GetCmpType(), lValue, GetCmpRHS()));
  4246.             SearchGroupIndex = searchComparisons.Count - 1;
  4247.             groupBoxSearchGroups.Text = "Search Groups (" + searchComparisons.Count + ")";
  4248.         }
  4249.  
  4250.         private int SearchGroupIndex
  4251.         {
  4252.             get
  4253.             {
  4254.                 return Convert.ToInt32(numericUpDownSearchGroup.Value) - 1;
  4255.             }
  4256.             set
  4257.             {
  4258.                 numericUpDownSearchGroup.Value = value + 1;
  4259.             }
  4260.         }
  4261.  
  4262.         private void buttonRemoveGroup_Click(object sender, EventArgs e)
  4263.         {
  4264.             if (searchComparisons.Count > 1)
  4265.             {
  4266.                 searchComparisons.RemoveAt(SearchGroupIndex);
  4267.             }
  4268.             if (SearchGroupIndex >= searchComparisons.Count)
  4269.             {
  4270.                 SearchGroupIndex = searchComparisons.Count - 1;
  4271.             }
  4272.             groupBoxSearchGroups.Text = "Search Groups (" + searchComparisons.Count + ")";
  4273.         }
  4274.  
  4275.         private void buttonClearSearchGroup_Click(object sender, EventArgs e)
  4276.         {
  4277.             while (searchComparisons.Count > 1)
  4278.             {
  4279.                 searchComparisons.RemoveAt(1);
  4280.             }
  4281.             SearchGroupIndex = 0;
  4282.             groupBoxSearchGroups.Text = "Search Groups (" + searchComparisons.Count + ")";
  4283.         }
  4284.  
  4285.         private void lowerValue_TextChanged(object sender, EventArgs e)
  4286.         {
  4287.             UInt32 value;
  4288.             if (GlobalFunctions.tryToHex(textBoxComparisonValue.Text, out value))
  4289.             {
  4290.                 searchComparisons[SearchGroupIndex].value = value;
  4291.             }
  4292.         }
  4293.  
  4294.         private void numericUpDownSearchGroup_ValueChanged(object sender, EventArgs e)
  4295.         {
  4296.             Int32 value = SearchGroupIndex;
  4297.             if (value >= searchComparisons.Count)
  4298.             {
  4299.                 SearchGroupIndex = searchComparisons.Count - 1;
  4300.                 return;
  4301.             }
  4302.             SearchComparisonInfo comp = searchComparisons[value];
  4303.             SetCmpRHS(comp.searchType);
  4304.             SetCmpType(comp.comparisonType);
  4305.             textBoxComparisonValue.Text = GlobalFunctions.toHex(comp.value);
  4306.         }
  4307.  
  4308.         private void GCTCodeValues_KeyDown(object sender, KeyEventArgs e)
  4309.         {
  4310.             if (e.KeyCode == Keys.A && e.Control)
  4311.             {
  4312.                 GCTCodeValues.SelectAll();
  4313.             }
  4314.         }
  4315.  
  4316.         private void setSRR0HereToolStripMenuItem_Click(object sender, EventArgs e)
  4317.         {
  4318.             bpHandler.SetSRR0(disassembler.disAddress);
  4319.             MainControl.SelectedTab = BreakpointPage;
  4320.         }
  4321.  
  4322.         private void ShowMemContextMenu_Opening(object sender, CancelEventArgs e)
  4323.         {
  4324.             if (ValidMemory.validAddress(bpHandler.MemoryAddress))
  4325.             {
  4326.                 toolStripTextBoxShowMemAddress.Text = GlobalFunctions.toHex(bpHandler.MemoryAddress);
  4327.                 toolStripTextBoxShowMemValue.Text = GlobalFunctions.toHex(gecko.peek(bpHandler.MemoryAddress));
  4328.             }
  4329.             else
  4330.             {
  4331.                 toolStripTextBoxShowMemAddress.Text = "00000000";
  4332.                 toolStripTextBoxShowMemValue.Text = "00000000";
  4333.                 //e.Cancel = true;
  4334.             }
  4335.         }
  4336.  
  4337.         private void ShowMemAddressToolStripMenuItem_Click(object sender, EventArgs e)
  4338.         {
  4339.             Clipboard.SetText(toolStripTextBoxShowMemAddress.Text);
  4340.         }
  4341.  
  4342.         private void ShowMemValueToolStripMenuItem_Click(object sender, EventArgs e)
  4343.         {
  4344.             Clipboard.SetText(toolStripTextBoxShowMemValue.Text);
  4345.         }
  4346.  
  4347.         // Scrolls a given textbox. handle: an handle to our textbox. pixles:
  4348.         // number of pixels to scroll.
  4349.         public void ScrollBPDissToLine(int line)
  4350.         {
  4351.             //ScrollInfo foo = new ScrollInfo();
  4352.             //foo.fMask = SIF_POS;
  4353.             //foo.nPos = 10*line;
  4354.             //SetScrollInfo(richTextBox1.Handle, SIF_POS, ref foo, true);
  4355.             //SendMessage(richTextBox1.Handle, WM_VSCROLL,
  4356.         }
  4357.  
  4358.         private const int WM_HSCROLL = 0x114;
  4359.         private const int WM_VSCROLL = 0x115;
  4360.  
  4361.         private const int SB_HORZ = 0;
  4362.         private const int SB_VERT = 1;
  4363.  
  4364.         private const int SB_LINELEFT = 0;
  4365.         private const int SB_LINERIGHT = 1;
  4366.         private const int SB_PAGELEFT = 2;
  4367.         private const int SB_PAGERIGHT = 3;
  4368.         private const int SB_THUMBPOSITION = 4;
  4369.         private const int SB_THUMBTRACK = 5;
  4370.         private const int SB_LEFT = 6;
  4371.         private const int SB_RIGHT = 7;
  4372.         private const int SB_ENDSCROLL = 8;
  4373.  
  4374.         private const int SIF_TRACKPOS = 0x10;
  4375.         private const int SIF_RANGE = 0x1;
  4376.         private const int SIF_POS = 0x4;
  4377.         private const int SIF_PAGE = 0x2;
  4378.         private const int SIF_ALL = SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS;
  4379.  
  4380.         private void walkToBlrToolStripMenuItem_Click(object sender, EventArgs e)
  4381.         {
  4382.             WalkToBLR();
  4383.         }
  4384.  
  4385.         private void ParseStackFrame(uint stackPointer, out uint LRSaveWord, ref uint nextFramePointer)
  4386.         {
  4387.             LRSaveWord = 0;
  4388.             nextFramePointer = 0;
  4389.             try
  4390.             {
  4391.                 if (gecko.status() == WiiStatus.Breakpoint)
  4392.                 {
  4393.                     // Walk the linked list
  4394.                     uint potentialNextFramePointer = gecko.peek(stackPointer);
  4395.                     // Return the matching LR from that frame
  4396.                     uint PotentialLRSaveWord = gecko.peek(potentialNextFramePointer + 4);
  4397.                     // Modify the stack pointer so that it points to the next frame
  4398.                     if (ValidMemory.rangeCheck(potentialNextFramePointer) == AddressType.UncachedMem1)
  4399.                         nextFramePointer = potentialNextFramePointer;
  4400.  
  4401.                     if (ValidMemory.rangeCheck(PotentialLRSaveWord) == AddressType.UncachedMem1)
  4402.                         LRSaveWord = PotentialLRSaveWord;
  4403.                 }
  4404.             }
  4405.             catch (EUSBGeckoException exc)
  4406.             {
  4407.                 exceptionHandling.HandleException(exc);
  4408.             }
  4409.         }
  4410.  
  4411.         private void stackFrameToolStripMenuItem_Click(object sender, EventArgs e)
  4412.         {
  4413.             uint LRSaveWord = 0;
  4414.             uint nextFramePointer = bpHandler.GetRegisterValue((int)GeckoApp.BPList.RegisterList.r1);
  4415.             ParseStackFrame(nextFramePointer, out LRSaveWord, ref nextFramePointer);
  4416.  
  4417.             try
  4418.             {
  4419.                 if (LRSaveWord != 0)
  4420.                 {
  4421.                     if (bpHandler.SetBreakpoint(LRSaveWord, BreakpointType.Execute, true))
  4422.                     {
  4423.                         BPMode(true);
  4424.                     }
  4425.                     bpHandler.DecIndent();  // account for the bl we're skipping over
  4426.                 }
  4427.             }
  4428.             catch (EUSBGeckoException exc)
  4429.             {
  4430.                 exceptionHandling.HandleException(exc);
  4431.             }
  4432.         }
  4433.  
  4434.         private void leafToolStripMenuItem_Click(object sender, EventArgs e)
  4435.         {
  4436.             try
  4437.             {
  4438.                 if (gecko.status() == WiiStatus.Breakpoint)
  4439.                 {
  4440.                     if (bpHandler.SetBreakpoint(bpHandler.GetRegisterValue((int)GeckoApp.BPList.RegisterList.LR), BreakpointType.Execute, true))
  4441.                     {
  4442.                         BPMode(true);
  4443.                     }
  4444.                     bpHandler.DecIndent();  // account for the bl we're skipping over
  4445.                 }
  4446.             }
  4447.             catch (EUSBGeckoException exc)
  4448.             {
  4449.                 exceptionHandling.HandleException(exc);
  4450.             }
  4451.         }
  4452.  
  4453.         private uint RecursivePromptDisassemblySearch(uint searchStartAddress, bool searchDown, string regex, int count)
  4454.         {
  4455.             UInt32 bAddress;
  4456.             do
  4457.             {
  4458.                 bAddress = FindRegexAddressInDisassembly(ref searchStartAddress, searchDown, regex, count);
  4459.             } while (bAddress == 0 && SearchingDisassembly);
  4460.  
  4461.  
  4462.  
  4463.  
  4464.             if (bAddress != 0)
  4465.             {
  4466.                 // Found something!  return it
  4467.                 return bAddress;
  4468.             }
  4469.             else
  4470.             {
  4471.                 // found nothing...
  4472.                 DialogResult result = MessageBox.Show("Could not find " + textBoxDisassemblySearch.Text + "\n\nContinue searching?", "", MessageBoxButtons.YesNo);
  4473.                 if (result == DialogResult.Yes)
  4474.                 {
  4475.                     // if FindRegexAddressInDisassembly fails, it replaces searchStartAddress with the next chunk
  4476.                     if (ValidMemory.validAddress(searchStartAddress))
  4477.                     {
  4478.                         return RecursivePromptDisassemblySearch(searchStartAddress, searchDown, regex, count);
  4479.                     }
  4480.                     else return 0;
  4481.                 }
  4482.                 else return 0;
  4483.             }
  4484.         }
  4485.  
  4486.         private void buttonDisassemblySearch_Click(object sender, EventArgs e)
  4487.         {
  4488.             if (SearchingDisassembly)
  4489.             {
  4490.                 SearchingDisassembly = false;
  4491.                 return;
  4492.             }
  4493.             uint searchStartAddress;
  4494.             if (!AsAddress.IsValidGet(out searchStartAddress))
  4495.             {
  4496.                 MessageBox.Show("Start address fail!");
  4497.                 return;
  4498.             }
  4499.  
  4500.             if (textBoxDisassemblySearch.Text == String.Empty)
  4501.             {
  4502.                 MessageBox.Show("Regex fail!");
  4503.                 return;
  4504.             }
  4505.  
  4506.             string searchString = textBoxDisassemblySearch.Text;
  4507.  
  4508.             if (!checkBoxRegexSearch.Checked)
  4509.             {
  4510.                 searchString = System.Text.RegularExpressions.Regex.Escape(searchString);
  4511.             }
  4512.  
  4513.             SearchingDisassembly = true;
  4514.             buttonDisassemblySearch.Text = "Cancel";
  4515.  
  4516.  
  4517.             //UInt32 bAddress = RecursivePromptDisassemblySearch(searchStartAddress, radioButtonSearchDisassemblyDown.Checked,
  4518.                                                             //searchString, 16256);   // should be one full packet of dump
  4519.             UInt32 bAddress;
  4520.             UInt32 searchStartAddressCopy = searchStartAddress;
  4521.             bool searchDown = radioButtonSearchDisassemblyDown.Checked;
  4522.             do
  4523.             {
  4524.                 bAddress = FindRegexAddressInDisassembly(ref searchStartAddressCopy, searchDown, searchString, 0xFE00 / 4 * 2);
  4525.             } while (bAddress == 0 && SearchingDisassembly && searchStartAddressCopy != 0x817FFFFC && searchStartAddressCopy != 0x80000000);
  4526.  
  4527.  
  4528.            
  4529.  
  4530.             if (bAddress != 0)
  4531.             {
  4532.                 // Found something!  Go there
  4533.                 disassembler.DissToBox(bAddress);
  4534.             }
  4535.             else
  4536.             {
  4537.                 if (SearchingDisassembly)
  4538.                     MessageBox.Show("Could not find search query");
  4539.             }
  4540.            
  4541.             SearchingDisassembly = false;
  4542.             buttonDisassemblySearch.Text = "Search";
  4543.         }
  4544.  
  4545.         public uint FindRegexAddressInDisassembly(ref uint searchStartAddress, bool searchDown, string regex, int count)
  4546.         {
  4547.             uint disassemblyStartAddress;
  4548.             uint retVal = 0;
  4549.             string[] searchDisassemblyStrings;
  4550.             disassemblyStartAddress = searchStartAddress + 4;
  4551.             if (!searchDown)
  4552.             {
  4553.                 // if searching up, move our start address back
  4554.                 disassemblyStartAddress = searchStartAddress - (uint)(count * 4);
  4555.                 // make sure we don't walk off the top of MEM1
  4556.                 if (disassemblyStartAddress < 0x80000000)
  4557.                 {
  4558.                     uint diff = 0x80000000 - disassemblyStartAddress;
  4559.                     disassemblyStartAddress = 0x80000000;
  4560.                     count -= (int)(diff / 4);
  4561.                 }
  4562.             }
  4563.  
  4564.             //searchEndAddress = disassemblyStartAddress + (uint)((count - 1) * 4);
  4565.  
  4566.             // Get the disassembly we will search through
  4567.             searchDisassemblyStrings = disassembler.Disassemble(disassemblyStartAddress, count);
  4568.  
  4569.             // Reverse the array if we're searching up
  4570.             if (!searchDown)
  4571.             {
  4572.                 Array.Reverse(searchDisassemblyStrings);
  4573.             }
  4574.  
  4575.             String foundLine = String.Empty;
  4576.  
  4577.             // Look for the string
  4578.             foreach (String line in searchDisassemblyStrings)
  4579.             {
  4580.  
  4581.                 //if (line.Contains(textBoxDisassemblySearch.Text))
  4582.                 if (System.Text.RegularExpressions.Regex.Match(line.Substring(20), regex).Success)
  4583.                 {
  4584.                     foundLine = line;
  4585.                     break;
  4586.                 }
  4587.             }
  4588.  
  4589.  
  4590.             if (foundLine != String.Empty)
  4591.             {
  4592.                 // Found something!  Put it in retVal
  4593.                 if (!(GlobalFunctions.tryToHex(foundLine.Substring(0, 8), out retVal) && ValidMemory.validAddress(retVal)))
  4594.                 {
  4595.                     // ...it didn't work?  fail
  4596.                     retVal = 0;
  4597.                 }
  4598.             }
  4599.             else
  4600.             {
  4601.                 // replace the start address with the next start address
  4602.                 int end = searchDisassemblyStrings.Length - 1;
  4603.                 uint bAddress;
  4604.                 if (GlobalFunctions.tryToHex(searchDisassemblyStrings[end].Substring(0, 8), out bAddress) && ValidMemory.validAddress(bAddress))
  4605.                 {
  4606.                     searchStartAddress = bAddress;
  4607.                 }
  4608.                 else
  4609.                 {
  4610.                     searchStartAddress = 0;
  4611.                 }
  4612.  
  4613.             }
  4614.  
  4615.             return retVal;
  4616.         }
  4617.  
  4618.         private void buttonSerialPoke_Click(object sender, EventArgs e)
  4619.         {
  4620.             // Poke
  4621.             PButton_Click(sender, e);
  4622.             //            Application.DoEvents();
  4623.             // Get next address
  4624.             PAddress.ShowHistory(true);
  4625.             PAddress.SendKeyCode(new KeyEventArgs(Keys.Down));
  4626.             //            Application.DoEvents();
  4627.             // Commit and hide the history
  4628.             PAddress.SendKeyCode(new KeyEventArgs(Keys.Enter));
  4629.         }
  4630.  
  4631.         private uint GetFunctionStartAddress(uint searchStartAddress)
  4632.         {
  4633.             string prologueString = "^(blr|b..lr|\\.)";
  4634.             uint prologueAddress = RecursivePromptDisassemblySearch(searchStartAddress, false, prologueString, 1000) + 4;
  4635.             return prologueAddress;
  4636.         }
  4637.  
  4638.         private uint GetFunctionEndAddress(uint searchStartAddress)
  4639.         {
  4640.             string epilogueString = "^(blr|b..lr)";
  4641.             uint epilogueAddress = RecursivePromptDisassemblySearch(searchStartAddress, true, epilogueString, 1000);
  4642.             return epilogueAddress;
  4643.         }
  4644.  
  4645.         private void copyFunctionToolStripMenuItem_Click(object sender, EventArgs e)
  4646.         {
  4647.             uint searchStartAddress;
  4648.             if (!AsAddress.IsValidGet(out searchStartAddress))
  4649.             {
  4650.                 MessageBox.Show("Start address fail!");
  4651.                 return;
  4652.             }
  4653.  
  4654.             uint prologueAddress = GetFunctionStartAddress(searchStartAddress);
  4655.             uint epilogueAddress = GetFunctionEndAddress(searchStartAddress);
  4656.  
  4657.             int count = (int)(epilogueAddress - prologueAddress) + 4;
  4658.             count /= 4;
  4659.  
  4660.             String[] searchDisassemblyStrings = disassembler.Disassemble(prologueAddress, count);
  4661.  
  4662.             String BigDisassemblyString = String.Empty;
  4663.  
  4664.             foreach (string line in searchDisassemblyStrings)
  4665.             {
  4666.                 BigDisassemblyString += line + "\r\n";
  4667.             }
  4668.  
  4669.             Clipboard.SetText(BigDisassemblyString);
  4670.         }
  4671.  
  4672.         private void toolStripTextBoxShowMemValue_KeyDown(object sender, KeyEventArgs e)
  4673.         {
  4674.             if (e.KeyCode == Keys.Enter && !e.Control)
  4675.             {
  4676.                 e.Handled = true;
  4677.                 uint address, value;
  4678.                 if (GlobalFunctions.tryToHex(toolStripTextBoxShowMemAddress.Text, out address) &&
  4679.                     ValidMemory.validAddress(address) &&
  4680.                     GlobalFunctions.tryToHex(toolStripTextBoxShowMemValue.Text, out value))
  4681.                 {
  4682.                     gecko.poke(address, value);
  4683.                 }
  4684.             }
  4685.         }
  4686.  
  4687.         private void ChangeMemViewFontSize(float newSize)
  4688.         {
  4689.             foreach (DataGridViewRow row in memViewGrid.Rows)
  4690.             {
  4691.                 foreach (DataGridViewCell cell in row.Cells)
  4692.                 {
  4693.                     Font newFont = null;
  4694.                     if (cell.Style.Font != null)
  4695.                     {
  4696.                         newFont = new Font(cell.Style.Font.FontFamily, newSize);
  4697.                     }
  4698.                     else if (cell.InheritedStyle.Font != null)
  4699.                     {
  4700.                         newFont = new Font(cell.InheritedStyle.Font.FontFamily, newSize);
  4701.                     }
  4702.  
  4703.                     if (newFont != null)
  4704.                     {
  4705.                         cell.Style.Font = newFont;
  4706.                     }
  4707.                 }
  4708.             }
  4709.  
  4710.  
  4711.             //Font newRowTemplateFont = new Font(memViewGrid.RowTemplate.DefaultCellStyle.Font.FontFamily, newSize);
  4712.  
  4713.            
  4714.             //Font newColumnHeaderFont = new Font(memViewGrid.ColumnHeadersDefaultCellStyle.Font.FontFamily, newSize);
  4715.  
  4716.  
  4717.             Font newColumnHeaderFont = new Font(memViewGrid.ColumnHeadersDefaultCellStyle.Font.FontFamily, newSize);
  4718.  
  4719.            
  4720.             //memViewGrid.RowTemplate.DefaultCellStyle.Font = newRowTemplateFont;
  4721.             memViewGrid.ColumnHeadersDefaultCellStyle.Font = newColumnHeaderFont;
  4722.         }
  4723.  
  4724.         private void toolStripTextBoxMemViewFontSize_KeyDown(object sender, KeyEventArgs e)
  4725.         {
  4726.             if (e.KeyCode == Keys.Enter)
  4727.             {
  4728.                 try
  4729.                 {
  4730.                     float casted = Convert.ToSingle(toolStripTextBoxMemViewFontSize.Text);
  4731.                     ChangeMemViewFontSize(casted);
  4732.                     GeckoApp.Properties.Settings.Default.MemViewFontSize = casted;
  4733.                     GeckoApp.Properties.Settings.Default.Save();
  4734.                     memViewContextMenu.Close();
  4735.                 }
  4736.                 catch (FormatException)
  4737.                 {
  4738.                     toolStripTextBoxMemViewFontSize.Text = (10).ToString();
  4739.                 }
  4740.             }
  4741.         }
  4742.  
  4743.         private void fontSizeToolStripMenuItem_MouseMove(object sender, MouseEventArgs e)
  4744.         {
  4745.             toolStripTextBoxMemViewFontSize.Focus();
  4746.             toolStripTextBoxMemViewFontSize.SelectAll();
  4747.         }
  4748.  
  4749.         private void viewFloatsInHexToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
  4750.         {
  4751.             bpHandler.ShowFloatsInHex = viewFloatsInHexToolStripMenuItem.Checked;
  4752.             GeckoApp.Properties.Settings.Default.ViewFloatsInHex = viewFloatsInHexToolStripMenuItem.Checked;
  4753.             GeckoApp.Properties.Settings.Default.Save();
  4754.         }
  4755.  
  4756.         private void IntelligentStepOut()
  4757.         {
  4758.             if (IsLeafFunction() != 0)
  4759.             {
  4760.                 leafToolStripMenuItem_Click(null, null);
  4761.             }
  4762.             else
  4763.             {
  4764.                 stackFrameToolStripMenuItem_Click(null, null);
  4765.             }
  4766.         }
  4767.  
  4768.         private uint IsLeafFunction()
  4769.         {
  4770.             try
  4771.             {
  4772.                 if (gecko.status() == WiiStatus.Breakpoint)
  4773.                 {
  4774.                     // Get the LR and current address and its ASM
  4775.                     uint potentialBLAddress = bpHandler.GetRegisterValue((int)GeckoApp.BPList.RegisterList.LR) - 4;
  4776.                     uint currentAddress = bpHandler.GetRegisterValue((int)GeckoApp.BPList.RegisterList.SRR0);
  4777.                     string [] asmArray = disassembler.Disassemble(potentialBLAddress, 1);
  4778.                     string asm = string.Empty;
  4779.                     if (asmArray.Length > 0) asm = asmArray[0];
  4780.                     uint potentialStartAddress = 0;
  4781.  
  4782.                     // Is it a bl?
  4783.                     if (System.Text.RegularExpressions.Regex.Match(asm, "bl\\t0x").Success)
  4784.                     {
  4785.                         int addressIndex = asm.LastIndexOf("bl\t0x") + 5;
  4786.  
  4787.                         // Is it valid?
  4788.                         if (GlobalFunctions.tryToHex(asm.Substring(addressIndex), out potentialStartAddress) &&
  4789.                             ValidMemory.validAddress(potentialStartAddress))
  4790.                         {
  4791.                             uint startAddressCopy = potentialStartAddress;
  4792.                             // Find the ending blr|b..lr (TODO: if we're after a b..lr but in a leaf, it will accidentally do a stack walk)
  4793.                             uint potentialEndAddress = RecursivePromptDisassemblySearch(potentialStartAddress, true, "^(blr|b..lr)", 5000);
  4794.                             int range = (int)(potentialEndAddress - potentialStartAddress + 10);
  4795.  
  4796.                             // If we are in between the start and end, inclusive, and there's no stwu r1 to create a stack frame (guards against recursion)
  4797.                             // Then we are a leaf function
  4798.                             if (currentAddress >= potentialStartAddress && currentAddress <= potentialEndAddress &&
  4799.                                 FindRegexAddressInDisassembly(ref startAddressCopy, true, "stwu r1,", range) == 0)
  4800.                             {
  4801.                                 return potentialBLAddress + 4;
  4802.                             }
  4803.                         }
  4804.                     }
  4805.                 }
  4806.             }
  4807.             catch (EUSBGeckoException exc)
  4808.             {
  4809.                 exceptionHandling.HandleException(exc);
  4810.             }
  4811.  
  4812.             return 0;
  4813.         }
  4814.  
  4815.         private void buttonStepOutOf_Click(object sender, EventArgs e)
  4816.         {
  4817.             if (SteppingOut)
  4818.             {
  4819.                 SteppingOut = false;
  4820.                 buttonStepOutOf.Text = "Step out";
  4821.                 return;
  4822.             }
  4823.  
  4824.             IntelligentStepOut();
  4825.         }
  4826.  
  4827.         private List<uint> GetBreakpointCallStack()
  4828.         {
  4829.             List<uint> callStack = new List<uint>();
  4830.  
  4831.             // First add the current address
  4832.             uint address = bpHandler.GetRegisterValue((int)GeckoApp.BPList.RegisterList.SRR0);
  4833.             if (address != 0) callStack.Add(address);
  4834.                
  4835.             // Then, if it is a leaf function, add it's LR
  4836.             address = IsLeafFunction();
  4837.             if (address != 0) callStack.Add(address - 4);
  4838.  
  4839.             uint stackPointer = bpHandler.GetRegisterValue((int)GeckoApp.BPList.RegisterList.r1);
  4840.  
  4841.             do
  4842.             {
  4843.                 ParseStackFrame(stackPointer, out address, ref stackPointer);
  4844.                 if (address != 0) callStack.Add(address - 4);
  4845.             } while (stackPointer != 0);
  4846.  
  4847.             return callStack;
  4848.         }
  4849.  
  4850.         private void listBoxCallStack_DoubleClick(object sender, EventArgs e)
  4851.         {
  4852.             uint disasmAddress = 0;
  4853.             if (listBoxCallStack.Items.Count == 0)
  4854.             {
  4855.                 LoadCallStack();
  4856.                 return;
  4857.             }
  4858.             if (GlobalFunctions.tryToHex(listBoxCallStack.SelectedItem.ToString(), out disasmAddress))
  4859.             {
  4860.                 if (ValidMemory.validAddress(disasmAddress))
  4861.                 {
  4862.                     DisRegion.Text = listBoxCallStack.SelectedItem.ToString();
  4863.  
  4864.                     DisUpdateBtn_Click(sender, e);
  4865.                 }
  4866.             }
  4867.         }
  4868.  
  4869.         private void LoadCallStack()
  4870.         {
  4871.             if (gecko.status() == WiiStatus.Breakpoint)
  4872.             {
  4873.                 listBoxCallStack.Items.Clear();
  4874.                 listBoxCallStack.Items.Add("Loading call stack...");
  4875.                 List<uint> callStack = GetBreakpointCallStack();
  4876.                 listBoxCallStack.Items.Clear();
  4877.                 foreach (uint address in callStack)
  4878.                 {
  4879.                     string Hex = String.Format("{0:X}", address);
  4880.                     listBoxCallStack.Items.Add(Hex);
  4881.                 }
  4882.             }
  4883.             else
  4884.             {
  4885.                 MessageBox.Show("Must be in a breakpoint to show call stack");
  4886.             }
  4887.         }
  4888.  
  4889.         private void gotoFunctionStartToolStripMenuItem_Click(object sender, EventArgs e)
  4890.         {
  4891.             uint startAddress;
  4892.             if (GlobalFunctions.tryToHex(AsAddress.Text, out startAddress))
  4893.             {
  4894.                 if (ValidMemory.validAddress(startAddress))
  4895.                 {
  4896.                     startAddress = GetFunctionStartAddress(startAddress);
  4897.                     if (ValidMemory.validAddress(startAddress))
  4898.                     {
  4899.                         DisRegion.Text = String.Format("{0:X}", startAddress);
  4900.  
  4901.                         DisUpdateBtn_Click(sender, e);
  4902.                     }
  4903.                 }
  4904.             }
  4905.         }
  4906.  
  4907.         private void gotoFunctionEndToolStripMenuItem_Click(object sender, EventArgs e)
  4908.         {
  4909.             uint startAddress;
  4910.             if (GlobalFunctions.tryToHex(AsAddress.Text, out startAddress))
  4911.             {
  4912.                 if (ValidMemory.validAddress(startAddress))
  4913.                 {
  4914.                     startAddress = GetFunctionEndAddress(startAddress);
  4915.                     if (ValidMemory.validAddress(startAddress))
  4916.                     {
  4917.                         DisRegion.Text = String.Format("{0:X}", startAddress - 0x40);
  4918.  
  4919.                         DisUpdateBtn_Click(sender, e);
  4920.  
  4921.                         DisAssBox.SelectedIndex = 0x10;
  4922.                     }
  4923.                 }
  4924.             }
  4925.         }
  4926.  
  4927.         private void copyToolStripMenuItem5_Click(object sender, EventArgs e)
  4928.         {
  4929.             Clipboard.SetText(listBoxCallStack.SelectedItem.ToString());
  4930.         }
  4931.  
  4932.         private void copyAllToolStripMenuItem_Click(object sender, EventArgs e)
  4933.         {
  4934.             string clipboard = String.Empty;
  4935.             foreach (object item in listBoxCallStack.Items)
  4936.             {
  4937.                 clipboard += item.ToString() + "\r\n";
  4938.             }
  4939.             Clipboard.SetText(clipboard);
  4940.         }
  4941.  
  4942.         private void loadToolStripMenuItem_Click(object sender, EventArgs e)
  4943.         {
  4944.             LoadCallStack();
  4945.         }
  4946.  
  4947.         private void convertASCIIToHexToolStripMenuItem_Click(object sender, EventArgs e)
  4948.         {
  4949.  
  4950.         }
  4951.  
  4952.         private void convertHexToASCIIToolStripMenuItem_Click(object sender, EventArgs e)
  4953.         {
  4954.  
  4955.         }
  4956.  
  4957.         private void jumpToOffsetToolStripMenuItem_MouseMove(object sender, MouseEventArgs e)
  4958.         {
  4959.             toolStripTextBoxMemViewOffset.Focus();
  4960.             toolStripTextBoxMemViewOffset.SelectAll();
  4961.         }
  4962.  
  4963.         private void toolStripTextBoxMemViewOffset_KeyDown(object sender, KeyEventArgs e)
  4964.         {
  4965.             if (e.KeyCode == Keys.Enter)
  4966.             {
  4967.                 //try
  4968.                 //{
  4969.                 //    bool negative = false;
  4970.                 //    if (toolStripTextBoxMemViewOffset.Text.Contains("-"))
  4971.                 //    {
  4972.                 //        toolStripTextBoxMemViewOffset.Text = toolStripTextBoxMemViewOffset.Text.Replace("-", String.Empty);
  4973.                 //        negative = true;
  4974.                 //    }
  4975.                 //    uint casted = Convert.ToUInt32(toolStripTextBoxMemViewOffset.Text, 16);
  4976.                 //    // get current memview addr, add casted to it, set memview addr
  4977.  
  4978.                 //    uint address = Convert.ToUInt32(memViewAValue.Text, 16);
  4979.                 //    address = negative ? address - casted : address + casted;
  4980.                 //    memViewAValue.Text = String.Format("{0:X}", address);
  4981.                 //    CenteredMemViewSelection(sender, e, address);
  4982.                 //    //viewer.address = address;
  4983.                 //    //viewer.Update();
  4984.                 //    memViewContextMenu.Close();
  4985.                 //}
  4986.                 //catch (FormatException)
  4987.                 //{
  4988.                 //}
  4989.                 memViewAValue.AddOffsetToAddress(toolStripTextBoxAddressAddOffset.Text);
  4990.                 MemViewUpdate_Click(sender, e);
  4991.                 memViewContextMenu.Close();
  4992.                 toolStripTextBoxMemViewOffset.Text = (0).ToString();
  4993.             }
  4994.         }
  4995.  
  4996.         private void addOffsetToolStripMenuItem_MouseMove(object sender, MouseEventArgs e)
  4997.         {
  4998.             toolStripTextBoxAddressAddOffset.Focus();
  4999.             toolStripTextBoxAddressAddOffset.SelectAll();
  5000.         }
  5001.  
  5002.         private void toolStripTextBoxAddressAddOffset_KeyDown(object sender, KeyEventArgs e)
  5003.         {
  5004.             if (e.KeyCode == Keys.Enter)
  5005.             {
  5006.                 if (AddressContextMenuOwner != null)
  5007.                     AddressContextMenuOwner.AddOffsetToAddress(toolStripTextBoxAddressAddOffset.Text);
  5008.                 HistoryContextMenu.Close();
  5009.                 toolStripTextBoxAddressAddOffset.Text = (0).ToString();
  5010.             }
  5011.         }
  5012.  
  5013.         private void MEM2UpperBoundary_SelectedIndexChanged(object sender, EventArgs e)
  5014.         {
  5015.             switch(MEM2UpperBoundary.SelectedIndex)
  5016.             {
  5017.                 case 1: ValidMemory.setMEM2Upper(0x93800000);
  5018.                     return;
  5019.                 case 2: ValidMemory.setMEM2Upper(0x93C00000);
  5020.                     return;
  5021.                 case 3: ValidMemory.setMEM2Upper(0x94000000);
  5022.                     return;
  5023.                 default: ValidMemory.setMEM2Upper(0x93400000);
  5024.                     return;
  5025.             }
  5026.            
  5027.         }
  5028.     }
  5029. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement