2011-03-06 15:03:17 +00:00
using System ;
using System.Collections.Generic ;
using System.ComponentModel ;
using System.Drawing ;
2013-11-28 22:06:38 +00:00
using System.Globalization ;
using System.IO ;
2011-03-06 15:03:17 +00:00
using System.Linq ;
using System.Text ;
using System.Windows.Forms ;
2013-10-25 00:57:23 +00:00
using BizHawk.Client.Common ;
2013-11-28 22:06:38 +00:00
using BizHawk.Common ;
2013-11-04 01:39:19 +00:00
using BizHawk.Emulation.Common ;
2013-10-25 00:57:23 +00:00
2013-11-03 03:54:37 +00:00
namespace BizHawk.Client.EmuHawk
2011-03-06 15:03:17 +00:00
{
2013-11-28 22:06:38 +00:00
using System.Diagnostics.CodeAnalysis ;
2013-11-02 20:25:53 +00:00
public partial class HexEditor : Form , IToolForm
2011-06-19 23:39:25 +00:00
{
2013-11-28 22:06:38 +00:00
private const int FontWidth = 7 ; // Width of 1 digits
private readonly List < ToolStripMenuItem > _domainMenuItems = new List < ToolStripMenuItem > ( ) ;
private readonly char [ ] _nibbles = { 'G' , 'G' , 'G' , 'G' , 'G' , 'G' , 'G' , 'G' } ; // G = off 0-9 & A-F are acceptable values
private readonly List < int > _secondaryHighlightedAddresses = new List < int > ( ) ;
2013-11-28 14:43:27 +00:00
private int _defaultWidth ;
private int _defaultHeight ;
private int _rowsVisible ;
private int _numDigits = 4 ;
private string _numDigitsStr = "{0:X4}" ;
private string _digitFormatString = "{0:X2}" ;
private int _addressHighlighted = - 1 ;
private int _addressOver = - 1 ;
2013-11-28 22:06:38 +00:00
2013-11-28 14:43:27 +00:00
private int _maxRow ;
2013-11-28 22:06:38 +00:00
private MemoryDomain _domain = new MemoryDomain (
"NULL" , 1024 , MemoryDomain . Endian . Little , addr = > 0 , delegate ( int a , byte v ) { v = 0 ; } ) ;
2013-11-28 14:43:27 +00:00
private int _row ;
private int _addr ;
private string _findStr = String . Empty ;
private bool _loaded ;
private bool _mouseIsDown ;
private byte [ ] _rom ;
private MemoryDomain _romDomain ;
2013-11-28 20:02:32 +00:00
private HexFind _hexFind = new HexFind ( ) ;
2012-09-02 19:22:51 +00:00
2012-06-10 16:34:35 +00:00
// Configurations
2013-11-28 14:43:27 +00:00
private int _wndx = - 1 ;
private int _wndy = - 1 ;
private int _width = - 1 ;
private int _height = - 1 ;
private bool _bigEndian ;
private int _dataSize ;
2012-03-09 16:13:40 +00:00
2011-06-19 23:39:25 +00:00
public HexEditor ( )
{
InitializeComponent ( ) ;
2011-08-23 01:43:19 +00:00
AddressesLabel . BackColor = Color . Transparent ;
2012-03-09 16:13:40 +00:00
LoadConfigSettings ( ) ;
2011-08-22 02:48:12 +00:00
SetHeader ( ) ;
2011-06-19 23:39:25 +00:00
Closing + = ( o , e ) = > SaveConfigSettings ( ) ;
2012-06-13 02:18:34 +00:00
Header . Font = new Font ( "Courier New" , 8 ) ;
AddressesLabel . Font = new Font ( "Courier New" , 8 ) ;
2012-06-18 03:34:14 +00:00
AddressLabel . Font = new Font ( "Courier New" , 8 ) ;
2013-11-28 20:02:32 +00:00
TopMost = Global . Config . HexEditorAlwaysOnTop ;
2011-06-19 23:39:25 +00:00
}
2013-11-28 22:06:38 +00:00
private int? HighlightedAddress
{
get
{
if ( _addressHighlighted > = 0 )
{
return _addressHighlighted ;
}
else
{
return null ; // Negative = no address highlighted
}
}
}
private Watch . WatchSize WatchSize
{
get
{
return ( Watch . WatchSize ) _dataSize ;
}
}
#region API
public bool UpdateBefore
{
get
{
return false ;
}
}
public bool AskSave ( )
{
return true ;
}
2013-11-28 20:02:32 +00:00
public void UpdateValues ( )
2012-03-09 16:13:40 +00:00
{
2013-11-28 22:06:38 +00:00
if ( ! IsHandleCreated | | IsDisposed )
{
return ;
}
2012-06-13 02:44:19 +00:00
2013-11-28 20:02:32 +00:00
AddressesLabel . Text = GenerateMemoryViewString ( ) ;
AddressLabel . Text = GenerateAddressString ( ) ;
2012-03-09 16:13:40 +00:00
}
2013-11-28 20:02:32 +00:00
public void Restart ( )
2011-06-19 23:39:25 +00:00
{
2013-11-28 22:06:38 +00:00
if ( ! IsHandleCreated | | IsDisposed )
{
return ;
}
2013-11-28 20:02:32 +00:00
var theDomain = _domain . Name . ToLower ( ) = = "rom file" ? 999 : GetDomainInt ( _domain . Name ) ;
2013-11-28 22:06:38 +00:00
SetMemoryDomainMenu ( ) ; // Calls update routines, TODO: refactor, that is confusing!
2013-11-28 20:02:32 +00:00
if ( theDomain . HasValue )
2012-06-23 18:45:01 +00:00
{
2013-11-28 20:02:32 +00:00
SetMemoryDomain ( theDomain . Value ) ;
2012-06-23 18:45:01 +00:00
}
2013-11-28 20:02:32 +00:00
SetHeader ( ) ;
ResetScrollBar ( ) ;
SetDataSize ( _dataSize ) ;
UpdateValues ( ) ;
AddressLabel . Text = GenerateAddressString ( ) ;
}
public void SetToAddresses ( IEnumerable < int > addresses , MemoryDomain domain )
{
var addrList = addresses . ToList ( ) ;
if ( addrList . Any ( ) )
2011-06-19 23:39:25 +00:00
{
2013-11-28 20:02:32 +00:00
SetDomain ( domain ) ;
SetHighlighted ( addrList [ 0 ] ) ;
_secondaryHighlightedAddresses . Clear ( ) ;
_secondaryHighlightedAddresses . AddRange ( addrList . Where ( addr = > addr ! = addrList [ 0 ] ) . ToList ( ) ) ;
ClearNibbles ( ) ;
UpdateValues ( ) ;
MemoryViewerBox . Refresh ( ) ;
AddressLabel . Text = GenerateAddressString ( ) ;
}
}
public void FindNext ( string value , bool wrap )
{
var found = - 1 ;
2013-11-28 22:06:38 +00:00
var search = value . Replace ( " " , String . Empty ) . ToUpper ( ) ;
2013-11-28 20:02:32 +00:00
if ( String . IsNullOrEmpty ( search ) )
{
return ;
}
var numByte = search . Length / 2 ;
int startByte ;
if ( _addressHighlighted = = - 1 )
{
startByte = 0 ;
}
else if ( _addressHighlighted > = ( _domain . Size - 1 - numByte ) )
{
startByte = 0 ;
}
else
{
startByte = _addressHighlighted + _dataSize ;
}
for ( var i = startByte ; i < ( _domain . Size - numByte ) ; i + + )
{
var ramblock = new StringBuilder ( ) ;
for ( var j = 0 ; j < numByte ; j + + )
{
ramblock . Append ( String . Format ( "{0:X2}" , ( int ) _domain . PeekByte ( i + j ) ) ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
var block = ramblock . ToString ( ) . ToUpper ( ) ;
if ( search = = block )
{
found = i ;
break ;
}
}
if ( found > - 1 )
{
HighlightSecondaries ( search , found ) ;
GoToAddress ( found ) ;
_findStr = search ;
MemoryViewerBox . Focus ( ) ;
}
2013-11-28 22:06:38 +00:00
else if ( wrap = = false )
2013-11-28 20:02:32 +00:00
{
2013-11-28 22:06:38 +00:00
FindPrev ( value , true ) ; // Search the opposite direction if not found
2013-11-28 20:02:32 +00:00
}
}
public void FindPrev ( string value , bool wrap )
{
var found = - 1 ;
2013-11-28 22:06:38 +00:00
var search = value . Replace ( " " , string . Empty ) . ToUpper ( ) ;
2013-11-28 20:02:32 +00:00
if ( ! String . IsNullOrEmpty ( search ) )
{
return ;
}
var numByte = search . Length / 2 ;
int startByte ;
if ( _addressHighlighted = = - 1 )
{
startByte = _domain . Size - _dataSize ;
}
else
{
startByte = _addressHighlighted - 1 ;
}
for ( var i = startByte ; i > = 0 ; i - - )
{
var ramblock = new StringBuilder ( ) ;
for ( var j = 0 ; j < numByte ; j + + )
{
ramblock . Append ( String . Format ( "{0:X2}" , ( int ) _domain . PeekByte ( i + j ) ) ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
var block = ramblock . ToString ( ) . ToUpper ( ) ;
if ( search = = block )
{
found = i ;
break ;
}
}
if ( found > - 1 )
{
HighlightSecondaries ( search , found ) ;
GoToAddress ( found ) ;
_findStr = search ;
MemoryViewerBox . Focus ( ) ;
}
2013-11-28 22:06:38 +00:00
else if ( wrap = = false )
2013-11-28 20:02:32 +00:00
{
2013-11-28 22:06:38 +00:00
FindPrev ( value , true ) ; // Search the opposite direction if not found
2011-06-19 23:39:25 +00:00
}
}
2013-11-28 20:02:32 +00:00
#endregion
2013-11-28 22:06:38 +00:00
private static char Remap ( byte val )
{
if ( val < ' ' )
{
return '.' ;
}
else if ( val > = 0x80 )
{
return '.' ;
}
else
{
return ( char ) val ;
}
}
private static int? GetDomainInt ( string name )
{
for ( var i = 0 ; i < Global . Emulator . MemoryDomains . Count ; i + + )
{
if ( Global . Emulator . MemoryDomains [ i ] . Name = = name )
{
return i ;
}
}
return null ;
}
private static bool CurrentRomIsArchive ( )
{
var path = GlobalWin . MainForm . CurrentlyOpenRom ;
if ( path = = null )
{
return false ;
}
using ( var file = new HawkFile ( ) )
{
file . Open ( path ) ;
if ( ! file . Exists )
{
return false ;
}
return file . IsArchive ;
}
}
private static byte [ ] GetRomBytes ( )
{
var path = GlobalWin . MainForm . CurrentlyOpenRom ;
if ( path = = null )
{
return new byte [ ] { 0xFF } ;
}
using ( var file = new HawkFile ( ) )
{
file . Open ( path ) ;
if ( ! file . Exists )
{
return null ;
}
if ( file . IsArchive )
{
var stream = file . GetStream ( ) ;
return Util . ReadAllBytes ( stream ) ;
}
else
{
return File . ReadAllBytes ( path ) ;
}
}
}
private static int GetNumDigits ( Int32 i )
{
if ( i < = 0x10000 )
{
return 4 ;
}
return i < = 0x1000000 ? 6 : 8 ;
}
// Winform key events suck at the numberpad, so this is necessary
private static char ForceCorrectKeyString ( Keys keycode )
{
if ( ( int ) keycode > = 96 & & ( int ) keycode < = 106 )
{
return ( char ) ( ( int ) keycode - 48 ) ;
}
else
{
return ( char ) keycode ;
}
}
private static string GetSaveFileFromUser ( )
{
var sfd = new SaveFileDialog ( ) ;
if ( ! ( Global . Emulator is NullEmulator ) )
{
sfd . FileName = PathManager . FilesystemSafeName ( Global . Game ) ;
}
else
{
sfd . FileName = "MemoryDump" ;
}
sfd . InitialDirectory = PathManager . GetPlatformBase ( Global . Emulator . SystemId ) ;
sfd . Filter = "Text (*.txt)|*.txt|All Files|*.*" ;
sfd . RestoreDirectory = true ;
GlobalWin . Sound . StopSound ( ) ;
var result = sfd . ShowDialog ( ) ;
GlobalWin . Sound . StartSound ( ) ;
return result = = DialogResult . OK ? sfd . FileName : String . Empty ;
}
private static bool IsHexKeyCode ( char key )
{
if ( key > = 48 & & key < = 57 ) // 0-9
{
return true ;
}
else if ( key > = 65 & & key < = 70 ) // A-F
{
return true ;
}
else if ( key > = 96 & & key < = 106 ) // 0-9 Numpad
{
return true ;
}
else
{
return false ;
}
}
2011-06-19 23:39:25 +00:00
private void HexEditor_Load ( object sender , EventArgs e )
{
2013-11-28 22:06:38 +00:00
_defaultWidth = Size . Width ; // Save these first so that the user can restore to its original size
2013-11-28 14:43:27 +00:00
_defaultHeight = Size . Height ;
2013-11-28 20:02:32 +00:00
if ( Global . Config . SaveWindowPosition )
2011-06-19 23:39:25 +00:00
{
2013-11-28 14:43:27 +00:00
if ( _wndx > = 0 & & _wndy > = 0 )
2013-04-14 23:56:45 +00:00
{
2013-11-28 14:43:27 +00:00
Location = new Point ( _wndx , _wndy ) ;
2013-04-14 23:56:45 +00:00
}
2011-06-19 23:39:25 +00:00
2013-11-28 14:43:27 +00:00
if ( _width > = 0 & & _height > = 0 )
2013-04-14 23:56:45 +00:00
{
2013-11-28 14:43:27 +00:00
Size = new Size ( _width , _height ) ;
2013-04-14 23:56:45 +00:00
}
2011-06-19 23:39:25 +00:00
}
2013-11-28 22:06:38 +00:00
2011-06-19 23:39:25 +00:00
SetMemoryDomainMenu ( ) ;
2013-11-28 14:43:27 +00:00
SetDataSize ( _dataSize ) ;
2011-08-25 02:23:12 +00:00
UpdateValues ( ) ;
2013-11-28 14:43:27 +00:00
_loaded = true ;
2011-06-19 23:39:25 +00:00
}
2013-11-28 20:02:32 +00:00
private void LoadConfigSettings ( )
2011-06-19 23:39:25 +00:00
{
2013-11-28 20:02:32 +00:00
_wndx = Global . Config . HexEditorWndx ;
_wndy = Global . Config . HexEditorWndy ;
_width = Global . Config . HexEditorWidth ;
_height = Global . Config . HexEditorHeight ;
_bigEndian = Global . Config . HexEditorBigEndian ;
_dataSize = Global . Config . HexEditorDataSize ;
2013-11-28 22:06:38 +00:00
HexMenuStrip . BackColor = Global . Config . HexMenubarColor ;
2013-11-28 20:02:32 +00:00
MemoryViewerBox . BackColor = Global . Config . HexBackgrndColor ;
MemoryViewerBox . ForeColor = Global . Config . HexForegrndColor ;
Header . BackColor = Global . Config . HexBackgrndColor ;
Header . ForeColor = Global . Config . HexForegrndColor ;
2011-06-19 23:39:25 +00:00
}
2013-11-28 20:02:32 +00:00
private void SaveConfigSettings ( )
2011-06-19 23:39:25 +00:00
{
2013-11-28 20:02:32 +00:00
if ( _hexFind . IsHandleCreated | | ! _hexFind . IsDisposed )
{
_hexFind . Close ( ) ;
}
2011-08-22 02:48:12 +00:00
2013-11-28 20:02:32 +00:00
if ( Global . Config . SaveWindowPosition )
{
Global . Config . HexEditorWndx = _loaded ? Location . X : _wndx ;
Global . Config . HexEditorWndy = _loaded ? Location . Y : _wndy ;
Global . Config . HexEditorWidth = _loaded ? Right - Left : _width ;
Global . Config . HexEditorHeight = _loaded ? Bottom - Top : _height ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
Global . Config . HexEditorBigEndian = _bigEndian ;
Global . Config . HexEditorDataSize = _dataSize ;
2011-08-22 02:48:12 +00:00
}
2013-11-28 20:02:32 +00:00
private string GenerateAddressString ( )
2012-06-18 03:34:14 +00:00
{
2013-11-28 14:43:27 +00:00
var addrStr = new StringBuilder ( ) ;
2012-06-18 03:34:14 +00:00
2013-11-28 14:43:27 +00:00
for ( var i = 0 ; i < _rowsVisible ; i + + )
2012-06-18 03:34:14 +00:00
{
2013-11-28 20:02:32 +00:00
_row = i + HexScrollBar . Value ;
2013-11-28 22:06:38 +00:00
_addr = _row < < 4 ;
2013-11-28 14:43:27 +00:00
if ( _addr > = _domain . Size )
{
2012-06-18 03:34:14 +00:00
break ;
2013-11-28 14:43:27 +00:00
}
2012-09-11 00:17:54 +00:00
2013-11-28 14:43:27 +00:00
if ( _numDigits = = 4 )
2012-09-11 00:17:54 +00:00
{
2013-11-28 22:06:38 +00:00
addrStr . Append ( " " ) ; // Hack to line things up better between 4 and 6
2012-12-03 16:51:39 +00:00
}
2013-11-28 14:43:27 +00:00
else if ( _numDigits = = 6 )
2012-12-03 16:51:39 +00:00
{
addrStr . Append ( " " ) ;
2012-09-11 00:17:54 +00:00
}
2013-11-28 22:06:38 +00:00
2013-11-28 14:43:27 +00:00
addrStr . AppendLine ( _addr . ToHexString ( _numDigits ) ) ;
2012-06-18 03:34:14 +00:00
}
return addrStr . ToString ( ) ;
}
2013-11-28 20:02:32 +00:00
private string GenerateMemoryViewString ( )
2011-08-22 02:48:12 +00:00
{
2013-11-28 14:43:27 +00:00
var rowStr = new StringBuilder ( ) ;
2011-08-24 02:48:52 +00:00
2013-11-28 14:43:27 +00:00
for ( var i = 0 ; i < _rowsVisible ; i + + )
2011-08-27 04:32:54 +00:00
{
2013-11-28 20:02:32 +00:00
_row = i + HexScrollBar . Value ;
2013-11-28 22:06:38 +00:00
_addr = _row < < 4 ;
2013-11-28 14:43:27 +00:00
if ( _addr > = _domain . Size )
2013-11-28 22:06:38 +00:00
{
2011-08-27 04:32:54 +00:00
break ;
2013-11-28 22:06:38 +00:00
}
2012-06-18 03:39:21 +00:00
2013-11-28 14:43:27 +00:00
for ( var j = 0 ; j < 16 ; j + = _dataSize )
2011-08-27 04:32:54 +00:00
{
2013-11-28 14:43:27 +00:00
if ( _addr + j + _dataSize < = _domain . Size )
2012-09-02 22:45:06 +00:00
{
2013-11-28 14:43:27 +00:00
rowStr . AppendFormat ( _digitFormatString , MakeValue ( _addr + j ) ) ;
2012-09-02 22:45:06 +00:00
}
2012-12-03 16:51:39 +00:00
else
{
2013-11-28 14:43:27 +00:00
for ( var t = 0 ; t < _dataSize ; t + + )
{
2012-12-03 16:51:39 +00:00
rowStr . Append ( " " ) ;
2013-11-28 14:43:27 +00:00
}
2013-11-28 22:06:38 +00:00
2012-12-03 16:51:39 +00:00
rowStr . Append ( ' ' ) ;
}
2011-08-27 04:32:54 +00:00
}
2013-11-28 22:06:38 +00:00
2011-08-27 04:32:54 +00:00
rowStr . Append ( " | " ) ;
2013-11-28 14:43:27 +00:00
for ( var k = 0 ; k < 16 ; k + + )
2011-08-27 04:32:54 +00:00
{
2013-11-28 14:43:27 +00:00
if ( _addr + k < _domain . Size )
2012-09-02 22:45:06 +00:00
{
2013-11-28 14:43:27 +00:00
rowStr . Append ( Remap ( _domain . PeekByte ( _addr + k ) ) ) ;
2012-09-02 22:45:06 +00:00
}
2011-08-22 02:48:12 +00:00
}
2011-08-27 04:32:54 +00:00
2013-11-28 22:06:38 +00:00
rowStr . AppendLine ( ) ;
2011-08-22 02:48:12 +00:00
}
2013-11-28 22:06:38 +00:00
return rowStr . ToString ( ) ;
2011-08-22 02:48:12 +00:00
}
2013-04-14 23:56:45 +00:00
private int MakeValue ( int address )
2011-08-22 02:48:12 +00:00
{
2013-11-28 14:43:27 +00:00
switch ( _dataSize )
2011-08-22 02:48:12 +00:00
{
2011-08-27 04:32:54 +00:00
default :
case 1 :
2013-11-28 14:43:27 +00:00
return _domain . PeekByte ( address ) ;
2011-08-27 04:32:54 +00:00
case 2 :
2013-11-28 22:06:38 +00:00
return _domain . PeekWord ( address , _bigEndian ) ;
2011-08-27 04:32:54 +00:00
case 4 :
2013-11-28 22:06:38 +00:00
return ( int ) _domain . PeekDWord ( address , _bigEndian ) ;
2011-08-22 02:48:12 +00:00
}
}
2013-11-28 20:02:32 +00:00
private void SetMemoryDomain ( MemoryDomain d )
2011-08-22 02:48:12 +00:00
{
2013-11-28 14:43:27 +00:00
_domain = d ;
_bigEndian = d . EndianType = = MemoryDomain . Endian . Big ;
_maxRow = _domain . Size / 2 ;
2011-08-22 02:48:12 +00:00
SetUpScrollBar ( ) ;
2013-11-28 20:02:32 +00:00
if ( 0 > = HexScrollBar . Minimum & & 0 < = HexScrollBar . Maximum )
2012-12-23 02:49:08 +00:00
{
2013-11-28 20:02:32 +00:00
HexScrollBar . Value = 0 ;
2012-12-23 02:49:08 +00:00
}
2013-11-28 22:06:38 +00:00
2011-08-22 02:48:12 +00:00
Refresh ( ) ;
}
2013-11-28 20:02:32 +00:00
private void SetDomain ( MemoryDomain domain )
{
SetMemoryDomain ( GetDomainInt ( domain . Name ) ? ? 0 ) ;
SetHeader ( ) ;
}
2013-11-28 22:06:38 +00:00
// TODO: this should be removable or at least refactorable
2011-06-19 23:39:25 +00:00
private void SetMemoryDomain ( int pos )
{
2013-11-28 22:06:38 +00:00
// <zeromus> THIS IS HORRIBLE.
if ( pos = = 999 )
2012-09-02 19:22:51 +00:00
{
2013-11-28 22:06:38 +00:00
// <zeromus> THIS IS HORRIBLE.
_rom = GetRomBytes ( ) ;
2013-04-14 23:56:45 +00:00
2013-11-28 22:06:38 +00:00
// <zeromus> THIS IS HORRIBLE.
_romDomain = new MemoryDomain (
"ROM File" , _rom . Length , MemoryDomain . Endian . Little , i = > _rom [ i ] , ( i , value ) = > _rom [ i ] = value ) ;
2013-08-26 07:17:47 +00:00
2013-11-28 22:06:38 +00:00
// <zeromus> THIS IS HORRIBLE.
2013-11-28 14:43:27 +00:00
_domain = _romDomain ;
2012-09-02 19:22:51 +00:00
}
2013-11-28 22:06:38 +00:00
else if ( pos < Global . Emulator . MemoryDomains . Count )
2011-06-19 23:39:25 +00:00
{
2013-10-20 18:02:43 +00:00
SetMemoryDomain ( Global . Emulator . MemoryDomains [ pos ] ) ;
2011-06-19 23:39:25 +00:00
}
2013-11-28 22:06:38 +00:00
2012-12-03 16:51:39 +00:00
SetHeader ( ) ;
2011-08-23 23:48:22 +00:00
UpdateGroupBoxTitle ( ) ;
2011-08-22 02:48:12 +00:00
ResetScrollBar ( ) ;
2012-09-02 19:22:51 +00:00
UpdateValues ( ) ;
2011-09-17 16:39:43 +00:00
MemoryViewerBox . Refresh ( ) ;
2011-06-19 23:39:25 +00:00
}
2011-08-23 23:48:22 +00:00
private void UpdateGroupBoxTitle ( )
2011-06-19 23:39:25 +00:00
{
2013-11-28 14:43:27 +00:00
var memoryDomain = _domain . ToString ( ) ;
var systemID = Global . Emulator . SystemId ;
var addresses = _domain . Size / _dataSize ;
var addressesString = "0x" + string . Format ( "{0:X8}" , addresses ) . TrimStart ( '0' ) ;
2012-09-04 17:26:27 +00:00
MemoryViewerBox . Text = systemID + " " + memoryDomain + " - " + addressesString + " addresses" ;
2011-06-19 23:39:25 +00:00
}
private void SetMemoryDomainMenu ( )
{
2013-11-28 20:02:32 +00:00
MemoryDomainsMenuItem . DropDownItems . Clear ( ) ;
2013-10-09 15:28:45 +00:00
2013-11-28 14:43:27 +00:00
for ( var i = 0 ; i < Global . Emulator . MemoryDomains . Count ; i + + )
2011-06-19 23:39:25 +00:00
{
2013-10-20 18:02:43 +00:00
if ( Global . Emulator . MemoryDomains [ i ] . Size > 0 )
2012-09-02 19:22:51 +00:00
{
2013-11-28 14:43:27 +00:00
var str = Global . Emulator . MemoryDomains [ i ] . ToString ( ) ;
2013-10-09 15:28:45 +00:00
var item = new ToolStripMenuItem { Text = str } ;
2012-09-26 03:30:19 +00:00
{
2013-11-28 14:43:27 +00:00
var temp = i ;
item . Click + = ( o , ev ) = > SetMemoryDomain ( temp ) ;
2013-08-26 22:05:50 +00:00
}
2013-11-28 22:06:38 +00:00
2013-08-26 22:05:50 +00:00
if ( i = = 0 )
{
SetMemoryDomain ( i ) ;
2012-09-26 03:30:19 +00:00
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
MemoryDomainsMenuItem . DropDownItems . Add ( item ) ;
2013-11-28 14:43:27 +00:00
_domainMenuItems . Add ( item ) ;
2011-06-19 23:39:25 +00:00
}
}
2013-10-09 15:28:45 +00:00
2013-11-28 22:06:38 +00:00
// Add ROM File memory domain
// <zeromus> THIS IS HORRIBLE.
2013-10-09 15:28:45 +00:00
var rom_item = new ToolStripMenuItem { Text = "ROM File" } ;
2013-11-28 22:06:38 +00:00
rom_item . Click + = ( o , ev ) = > SetMemoryDomain ( 999 ) ; // 999 will denote ROM file
2013-11-28 20:02:32 +00:00
MemoryDomainsMenuItem . DropDownItems . Add ( rom_item ) ;
2013-11-28 14:43:27 +00:00
_domainMenuItems . Add ( rom_item ) ;
2011-06-19 23:39:25 +00:00
}
2013-10-07 19:33:06 +00:00
private Point GetPromptPoint ( )
{
2013-11-28 14:43:27 +00:00
return PointToScreen (
new Point ( MemoryViewerBox . Location . X + 30 , MemoryViewerBox . Location . Y + 30 )
) ;
2013-10-07 19:33:06 +00:00
}
2013-11-28 20:02:32 +00:00
private void ClearNibbles ( )
2011-08-22 02:48:12 +00:00
{
2013-11-28 20:02:32 +00:00
for ( var i = 0 ; i < 8 ; i + + )
2011-08-22 02:48:12 +00:00
{
2013-11-28 20:02:32 +00:00
_nibbles [ i ] = 'G' ;
2013-04-14 23:56:45 +00:00
}
2011-06-19 23:39:25 +00:00
}
2013-09-29 16:09:48 +00:00
private void GoToAddress ( int address )
2011-08-07 19:53:52 +00:00
{
2011-08-22 02:48:12 +00:00
if ( address < 0 )
2013-04-14 23:56:45 +00:00
{
2011-08-22 02:48:12 +00:00
address = 0 ;
2013-04-14 23:56:45 +00:00
}
2011-08-22 02:48:12 +00:00
2013-11-28 14:43:27 +00:00
if ( address > = _domain . Size )
2013-04-14 23:56:45 +00:00
{
2013-11-28 14:43:27 +00:00
address = _domain . Size - 1 ;
2013-04-14 23:56:45 +00:00
}
2011-08-22 02:48:12 +00:00
SetHighlighted ( address ) ;
ClearNibbles ( ) ;
2011-08-23 22:22:24 +00:00
UpdateValues ( ) ;
MemoryViewerBox . Refresh ( ) ;
2012-06-18 03:34:14 +00:00
AddressLabel . Text = GenerateAddressString ( ) ;
2011-08-07 19:53:52 +00:00
}
2011-06-19 23:39:25 +00:00
2013-11-28 22:06:38 +00:00
private void SetHighlighted ( int address )
2011-08-22 02:48:12 +00:00
{
2013-04-14 23:56:45 +00:00
if ( address < 0 )
{
address = 0 ;
}
2013-11-28 14:43:27 +00:00
if ( address > = _domain . Size )
2013-04-14 23:56:45 +00:00
{
2013-11-28 14:43:27 +00:00
address = _domain . Size - 1 ;
2013-04-14 23:56:45 +00:00
}
2011-08-22 02:48:12 +00:00
2013-04-14 23:56:45 +00:00
if ( ! IsVisible ( address ) )
2011-08-22 02:48:12 +00:00
{
2013-11-28 14:43:27 +00:00
var value = ( address / 16 ) - _rowsVisible + 1 ;
if ( value < 0 )
2013-04-14 23:56:45 +00:00
{
2013-11-28 14:43:27 +00:00
value = 0 ;
2013-04-14 23:56:45 +00:00
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
HexScrollBar . Value = value ;
2011-08-22 02:48:12 +00:00
}
2013-11-28 22:06:38 +00:00
2013-11-28 14:43:27 +00:00
_addressHighlighted = address ;
_addressOver = address ;
2011-08-25 23:58:16 +00:00
ClearNibbles ( ) ;
2011-08-25 23:49:13 +00:00
UpdateFormText ( ) ;
2011-08-22 02:48:12 +00:00
}
2011-08-25 23:49:13 +00:00
private void UpdateFormText ( )
{
2013-11-28 14:43:27 +00:00
if ( _addressHighlighted > = 0 )
2013-11-28 22:06:38 +00:00
{
2013-11-28 14:43:27 +00:00
Text = "Hex Editor - Editing Address 0x" + String . Format ( _numDigitsStr , _addressHighlighted ) ;
2013-11-28 22:06:38 +00:00
}
2011-08-25 23:49:13 +00:00
else
2013-11-28 22:06:38 +00:00
{
2011-08-25 23:49:13 +00:00
Text = "Hex Editor" ;
2013-11-28 22:06:38 +00:00
}
2011-08-25 23:49:13 +00:00
}
2013-11-28 22:06:38 +00:00
private bool IsVisible ( int address )
2011-08-22 02:48:12 +00:00
{
2013-11-28 14:43:27 +00:00
var i = address > > 4 ;
2013-11-28 20:02:32 +00:00
return i > = HexScrollBar . Value & & i < ( _rowsVisible + HexScrollBar . Value ) ;
2011-08-22 02:48:12 +00:00
}
private void SetHeader ( )
{
2013-11-28 14:43:27 +00:00
switch ( _dataSize )
2011-08-22 02:48:12 +00:00
{
case 1 :
2012-06-13 02:18:34 +00:00
Header . Text = " 0 1 2 3 4 5 6 7 8 9 A B C D E F" ;
2011-08-22 02:48:12 +00:00
break ;
case 2 :
2012-09-13 00:52:16 +00:00
Header . Text = " 0 2 4 6 8 A C E" ;
2011-08-22 02:48:12 +00:00
break ;
case 4 :
2012-09-13 00:52:16 +00:00
Header . Text = " 0 4 8 C" ;
2011-08-22 02:48:12 +00:00
break ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 14:43:27 +00:00
_numDigits = GetNumDigits ( _domain . Size ) ;
_numDigitsStr = "{0:X" + _numDigits + "} " ;
2011-08-22 02:48:12 +00:00
}
2013-11-28 22:06:38 +00:00
private void SetDataSize ( int size )
2011-08-22 02:48:12 +00:00
{
if ( size = = 1 | | size = = 2 | | size = = 4 )
2013-11-28 20:02:32 +00:00
{
2013-11-28 14:43:27 +00:00
_dataSize = size ;
2013-11-28 20:02:32 +00:00
_digitFormatString = "{0:X" + ( _dataSize * 2 ) + "} " ;
SetHeader ( ) ;
UpdateGroupBoxTitle ( ) ;
UpdateValues ( ) ;
}
2011-06-19 23:39:25 +00:00
}
2013-09-14 02:31:21 +00:00
private Watch MakeWatch ( int address )
2012-06-19 02:42:07 +00:00
{
2013-11-28 14:43:27 +00:00
switch ( _dataSize )
2012-06-19 02:42:07 +00:00
{
default :
case 1 :
2013-11-28 14:43:27 +00:00
return new ByteWatch ( _domain , address , Watch . DisplayType . Hex , _bigEndian , String . Empty ) ;
2012-06-19 02:42:07 +00:00
case 2 :
2013-11-28 14:43:27 +00:00
return new WordWatch ( _domain , address , Watch . DisplayType . Hex , _bigEndian , String . Empty ) ;
2012-06-19 02:42:07 +00:00
case 4 :
2013-11-28 14:43:27 +00:00
return new DWordWatch ( _domain , address , Watch . DisplayType . Hex , _bigEndian , String . Empty ) ;
2012-06-19 02:42:07 +00:00
}
}
2012-03-09 01:24:46 +00:00
private bool IsFrozen ( int address )
{
2013-11-28 14:43:27 +00:00
return Global . CheatList . IsActive ( _domain , address ) ;
2012-03-09 01:24:46 +00:00
}
2013-11-04 15:52:59 +00:00
private void UnFreezeAddress ( int address )
2012-03-09 01:24:46 +00:00
{
2013-11-28 22:06:38 +00:00
if ( address > = 0 )
2012-03-09 01:24:46 +00:00
{
2013-11-28 22:06:38 +00:00
// TODO: can't unfreeze address 0??
2013-11-28 14:43:27 +00:00
Global . CheatList . RemoveRange (
Global . CheatList . Where ( x = > x . Contains ( address ) )
) ;
2013-10-06 16:40:51 +00:00
}
2012-03-09 01:24:46 +00:00
2013-11-28 22:06:38 +00:00
MemoryViewerBox . Refresh ( ) ;
2012-03-09 01:24:46 +00:00
}
2013-10-06 16:40:51 +00:00
private void UpdateRelatedDialogs ( )
{
2013-11-03 16:07:58 +00:00
GlobalWin . Tools . UpdateValues < RamWatch > ( ) ;
GlobalWin . Tools . UpdateValues < RamSearch > ( ) ;
GlobalWin . Tools . UpdateValues < Cheats > ( ) ;
GlobalWin . MainForm . UpdateCheatStatus ( ) ;
2013-10-06 16:40:51 +00:00
UpdateValues ( ) ;
}
2013-11-28 22:06:38 +00:00
// TODO refactor to int?
private void FreezeAddress ( int address )
2011-06-19 23:39:25 +00:00
{
if ( address > = 0 )
{
2013-11-28 14:43:27 +00:00
var watch = Watch . GenerateWatch (
_domain ,
2013-10-06 16:40:51 +00:00
address ,
WatchSize ,
Watch . DisplayType . Hex ,
String . Empty ,
2013-11-28 14:43:27 +00:00
_bigEndian ) ;
2011-08-25 01:22:03 +00:00
2013-10-20 18:02:43 +00:00
Global . CheatList . Add ( new Cheat (
2013-10-06 18:44:51 +00:00
watch ,
2013-11-28 14:43:27 +00:00
watch . Value ? ? 0 ) ) ;
2013-10-06 16:40:51 +00:00
MemoryViewerBox . Refresh ( ) ;
UpdateRelatedDialogs ( ) ;
2011-06-19 23:39:25 +00:00
}
}
2013-11-28 14:43:27 +00:00
private void SaveFileBinary ( string path )
2012-09-02 23:12:00 +00:00
{
2013-11-28 14:43:27 +00:00
var file = new FileInfo ( path ) ;
using ( var binWriter = new BinaryWriter ( File . Open ( file . FullName , FileMode . Create ) ) )
2012-06-10 17:28:38 +00:00
{
2013-11-28 14:43:27 +00:00
for ( var i = 0 ; i < _domain . Size ; i + + )
2012-06-10 17:28:38 +00:00
{
2013-11-28 14:43:27 +00:00
binWriter . Write ( _domain . PeekByte ( i ) ) ;
2012-06-10 17:28:38 +00:00
}
}
}
2012-09-02 23:12:00 +00:00
private string GetSaveFileFilter ( )
{
2013-11-28 14:43:27 +00:00
if ( _domain . Name = = "ROM File" )
2012-09-02 23:12:00 +00:00
{
2013-11-28 14:43:27 +00:00
var extension = Path . GetExtension ( GlobalWin . MainForm . CurrentlyOpenRom ) ;
2012-09-02 23:12:00 +00:00
2013-10-09 15:28:45 +00:00
return "Binary (*" + extension + ")|*" + extension + "|All Files|*.*" ;
2012-09-02 23:12:00 +00:00
}
else
{
return "Binary (*.bin)|*.bin|All Files|*.*" ;
}
}
2013-11-28 14:43:27 +00:00
private string GetBinarySaveFileFromUser ( )
2012-06-10 17:28:38 +00:00
{
var sfd = new SaveFileDialog ( ) ;
2013-10-20 18:02:43 +00:00
if ( ! ( Global . Emulator is NullEmulator ) )
2013-11-28 14:43:27 +00:00
{
2012-06-10 17:28:38 +00:00
sfd . FileName = PathManager . FilesystemSafeName ( Global . Game ) ;
2013-11-28 14:43:27 +00:00
}
2012-06-10 17:28:38 +00:00
else
2013-11-28 14:43:27 +00:00
{
2012-06-10 17:28:38 +00:00
sfd . FileName = "MemoryDump" ;
2013-11-28 14:43:27 +00:00
}
2012-06-10 17:28:38 +00:00
2013-10-20 18:02:43 +00:00
sfd . InitialDirectory = PathManager . GetPlatformBase ( Global . Emulator . SystemId ) ;
2012-09-02 23:12:00 +00:00
sfd . Filter = GetSaveFileFilter ( ) ;
2012-06-10 17:28:38 +00:00
sfd . RestoreDirectory = true ;
2013-11-03 16:07:58 +00:00
GlobalWin . Sound . StopSound ( ) ;
2012-06-10 17:28:38 +00:00
var result = sfd . ShowDialog ( ) ;
2013-11-03 16:07:58 +00:00
GlobalWin . Sound . StartSound ( ) ;
2013-11-28 14:43:27 +00:00
return result = = DialogResult . OK ? sfd . FileName : String . Empty ;
2012-06-10 17:28:38 +00:00
}
2013-11-28 20:02:32 +00:00
private void ResetScrollBar ( )
2011-08-22 02:48:12 +00:00
{
2013-11-28 20:02:32 +00:00
HexScrollBar . Value = 0 ;
2011-08-22 02:48:12 +00:00
SetUpScrollBar ( ) ;
Refresh ( ) ;
}
2013-11-28 20:02:32 +00:00
private void SetUpScrollBar ( )
2011-08-22 02:48:12 +00:00
{
2013-11-28 22:06:38 +00:00
_rowsVisible = ( MemoryViewerBox . Height - ( fontHeight * 2 ) - ( fontHeight / 2 ) ) / fontHeight ;
2013-11-28 14:43:27 +00:00
var totalRows = _domain . Size / 16 ;
2013-10-09 15:28:45 +00:00
2013-11-28 20:02:32 +00:00
HexScrollBar . Maximum = totalRows - 1 ;
HexScrollBar . LargeChange = _rowsVisible ;
HexScrollBar . Visible = totalRows > _rowsVisible ;
2011-08-22 02:48:12 +00:00
2012-06-18 03:34:14 +00:00
AddressLabel . Text = GenerateAddressString ( ) ;
2011-08-22 02:48:12 +00:00
}
2013-11-28 22:06:38 +00:00
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1407:ArithmeticExpressionsMustDeclarePrecedence", Justification = "Reviewed. Suppression is OK here.")]
2012-06-19 02:42:07 +00:00
private int GetPointedAddress ( int x , int y )
2011-08-22 02:48:12 +00:00
{
2013-04-14 23:56:45 +00:00
int address ;
2013-11-28 22:06:38 +00:00
// Scroll value determines the first row
2013-11-28 20:02:32 +00:00
var i = HexScrollBar . Value ;
2013-11-28 14:43:27 +00:00
var rowoffset = y / fontHeight ;
2013-04-14 23:56:45 +00:00
i + = rowoffset ;
int colWidth ;
2013-11-28 14:43:27 +00:00
switch ( _dataSize )
2011-08-24 02:31:45 +00:00
{
default :
case 1 :
colWidth = 3 ;
break ;
case 2 :
colWidth = 5 ;
break ;
case 4 :
colWidth = 9 ;
break ;
}
2013-11-28 22:06:38 +00:00
var column = x / ( FontWidth * colWidth ) ;
2011-08-22 02:48:12 +00:00
2013-11-28 14:43:27 +00:00
var start = GetTextOffset ( ) - 50 ;
2012-09-10 23:52:42 +00:00
if ( x > start )
{
2013-11-28 14:43:27 +00:00
column = ( x - start ) / ( FontWidth / _dataSize ) ;
2012-09-10 23:52:42 +00:00
}
2012-09-03 00:49:59 +00:00
2013-11-28 14:43:27 +00:00
if ( i > = 0 & & i < = _maxRow & & column > = 0 & & column < ( 16 / _dataSize ) )
2011-08-22 02:48:12 +00:00
{
2013-11-28 14:43:27 +00:00
address = i * 16 + ( column * _dataSize ) ;
2011-08-22 02:48:12 +00:00
}
else
{
2012-06-19 02:42:07 +00:00
address = - 1 ;
2011-08-22 02:48:12 +00:00
}
2013-11-28 22:06:38 +00:00
2012-06-19 02:42:07 +00:00
return address ;
2011-08-22 02:48:12 +00:00
}
2012-09-29 21:13:11 +00:00
private void DoShiftClick ( )
{
2013-11-28 14:43:27 +00:00
if ( _addressOver > = 0 )
2011-08-23 01:43:19 +00:00
{
2013-11-28 14:43:27 +00:00
_secondaryHighlightedAddresses . Clear ( ) ;
if ( _addressOver < _addressHighlighted )
2012-06-19 02:42:07 +00:00
{
2013-11-28 14:43:27 +00:00
for ( var x = _addressOver ; x < _addressHighlighted ; x + + )
2012-06-19 02:42:07 +00:00
{
2013-11-28 14:43:27 +00:00
_secondaryHighlightedAddresses . Add ( x ) ;
2012-06-19 02:42:07 +00:00
}
}
2013-11-28 14:43:27 +00:00
else if ( _addressOver > _addressHighlighted )
2012-06-19 02:42:07 +00:00
{
2013-11-28 14:43:27 +00:00
for ( var x = _addressHighlighted + _dataSize ; x < = _addressOver ; x + + )
2012-06-19 02:42:07 +00:00
{
2013-11-28 14:43:27 +00:00
_secondaryHighlightedAddresses . Add ( x ) ;
2012-06-19 02:42:07 +00:00
}
}
2011-08-23 01:43:19 +00:00
}
2011-08-25 23:58:16 +00:00
}
private void ClearHighlighted ( )
{
2013-11-28 14:43:27 +00:00
_addressHighlighted = - 1 ;
2011-08-25 23:58:16 +00:00
UpdateFormText ( ) ;
MemoryViewerBox . Refresh ( ) ;
2011-08-23 01:43:19 +00:00
}
2011-08-23 22:22:24 +00:00
private Point GetAddressCoordinates ( int address )
{
2013-11-28 14:43:27 +00:00
switch ( _dataSize )
2011-08-24 02:31:45 +00:00
{
default :
case 1 :
2013-11-28 20:02:32 +00:00
return new Point ( ( ( address % 16 ) * ( FontWidth * 3 ) ) + 67 , ( ( ( address / 16 ) - HexScrollBar . Value ) * fontHeight ) + 30 ) ;
2011-08-24 02:31:45 +00:00
case 2 :
2013-11-28 20:02:32 +00:00
return new Point ( ( ( ( address % 16 ) / _dataSize ) * ( FontWidth * 5 ) ) + 67 , ( ( ( address / 16 ) - HexScrollBar . Value ) * fontHeight ) + 30 ) ;
2011-08-24 02:31:45 +00:00
case 4 :
2013-11-28 20:02:32 +00:00
return new Point ( ( ( ( address % 16 ) / _dataSize ) * ( FontWidth * 9 ) ) + 67 , ( ( ( address / 16 ) - HexScrollBar . Value ) * fontHeight ) + 30 ) ;
2011-08-24 02:31:45 +00:00
}
2011-08-23 22:22:24 +00:00
}
2012-09-03 00:49:59 +00:00
private int GetTextOffset ( )
{
2013-04-14 23:56:45 +00:00
int start ;
2013-11-28 14:43:27 +00:00
switch ( _dataSize )
2012-09-03 00:49:59 +00:00
{
default :
case 1 :
2013-11-28 14:43:27 +00:00
start = ( 16 * ( FontWidth * 3 ) ) + 67 ;
2012-09-03 00:49:59 +00:00
break ;
case 2 :
2013-11-28 14:43:27 +00:00
start = ( ( 16 / _dataSize ) * ( FontWidth * 5 ) ) + 67 ;
2012-09-03 00:49:59 +00:00
break ;
case 4 :
2013-11-28 14:43:27 +00:00
start = ( ( 16 / _dataSize ) * ( FontWidth * 9 ) ) + 67 ;
2012-09-03 00:49:59 +00:00
break ;
}
2013-11-28 22:06:38 +00:00
start + = FontWidth * 4 ;
2012-09-03 00:49:59 +00:00
return start ;
}
private int GetTextX ( int address )
{
2013-11-28 14:43:27 +00:00
return GetTextOffset ( ) + ( ( address % 16 ) * FontWidth ) ;
2012-09-03 00:49:59 +00:00
}
2013-11-28 20:02:32 +00:00
private bool HasNibbles ( )
2011-08-23 01:43:19 +00:00
{
2013-11-28 20:02:32 +00:00
return _nibbles . Any ( x = > x ! = 'G' ) ;
}
2013-10-06 16:40:51 +00:00
2013-11-28 20:02:32 +00:00
private string MakeNibbles ( )
{
var str = String . Empty ;
for ( var x = 0 ; x < ( _dataSize * 2 ) ; x + + )
2011-08-23 01:43:19 +00:00
{
2013-11-28 20:02:32 +00:00
if ( _nibbles [ x ] ! = 'G' )
2012-09-03 00:49:59 +00:00
{
2013-11-28 20:02:32 +00:00
str + = _nibbles [ x ] ;
2012-09-03 00:49:59 +00:00
}
2011-08-25 02:08:05 +00:00
else
2012-09-03 00:49:59 +00:00
{
2013-11-28 20:02:32 +00:00
break ;
2012-09-03 00:49:59 +00:00
}
2011-08-23 01:43:19 +00:00
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
return str ;
}
2012-06-23 20:48:17 +00:00
2013-11-28 20:02:32 +00:00
private void AddToSecondaryHighlights ( int address )
{
if ( address > = 0 & & address < _domain . Size )
{
_secondaryHighlightedAddresses . Add ( address ) ;
}
}
2012-09-28 17:24:44 +00:00
2013-11-28 22:06:38 +00:00
// TODO: obsolete me
2013-11-28 20:02:32 +00:00
private void PokeWord ( int address , byte _1 , byte _2 )
2011-08-24 02:31:45 +00:00
{
2013-11-28 20:02:32 +00:00
if ( _bigEndian )
2011-08-24 02:31:45 +00:00
{
2013-11-28 20:02:32 +00:00
_domain . PokeByte ( address , _2 ) ;
_domain . PokeByte ( address + 1 , _1 ) ;
2011-08-24 02:31:45 +00:00
}
2013-11-28 20:02:32 +00:00
else
2012-06-10 16:34:35 +00:00
{
2013-11-28 20:02:32 +00:00
_domain . PokeByte ( address , _1 ) ;
_domain . PokeByte ( address + 1 , _2 ) ;
2012-06-10 16:34:35 +00:00
}
2013-11-28 20:02:32 +00:00
}
2012-06-10 16:34:35 +00:00
2013-11-28 20:02:32 +00:00
private void IncrementAddress ( int address )
{
if ( Global . CheatList . IsActive ( _domain , address ) )
2013-10-09 15:28:45 +00:00
{
2013-11-28 22:06:38 +00:00
// TODO: Increment should be intelligent since IsActive is. If this address is part of a multi-byte cheat it should intelligently increment just that byte
2013-11-28 14:43:27 +00:00
Global . CheatList . FirstOrDefault ( x = > x . Domain = = _domain & & x . Address = = address ) . Increment ( ) ;
2013-10-09 15:28:45 +00:00
}
else
2012-03-08 18:33:57 +00:00
{
2013-11-28 14:43:27 +00:00
switch ( _dataSize )
2012-03-08 18:33:57 +00:00
{
default :
2013-10-09 15:28:45 +00:00
case 1 :
2013-11-28 14:43:27 +00:00
_domain . PokeByte (
2013-10-09 15:28:45 +00:00
address ,
2013-11-28 14:43:27 +00:00
( byte ) ( _domain . PeekByte ( address ) + 1 )
2013-10-09 15:28:45 +00:00
) ;
2012-03-08 18:33:57 +00:00
break ;
case 2 :
2013-11-28 14:43:27 +00:00
_domain . PokeWord (
2013-10-09 15:28:45 +00:00
address ,
2013-11-28 14:43:27 +00:00
( ushort ) ( _domain . PeekWord ( address , _bigEndian ) + 1 ) ,
_bigEndian
2013-10-09 15:28:45 +00:00
) ;
2012-03-08 18:33:57 +00:00
break ;
case 4 :
2013-11-28 14:43:27 +00:00
_domain . PokeDWord (
2013-10-09 15:28:45 +00:00
address ,
2013-11-28 14:43:27 +00:00
_domain . PeekDWord ( address , _bigEndian ) + 1 ,
_bigEndian
2013-10-09 15:28:45 +00:00
) ;
2012-03-08 18:33:57 +00:00
break ;
}
}
}
2013-10-09 15:28:45 +00:00
private void DecrementAddress ( int address )
2012-06-25 03:10:04 +00:00
{
2013-11-28 14:43:27 +00:00
if ( Global . CheatList . IsActive ( _domain , address ) )
2012-06-25 03:10:04 +00:00
{
2013-11-28 22:06:38 +00:00
// TODO: Increment should be intelligent since IsActive is. If this address is part of a multi-byte cheat it should intelligently increment just that byte
2013-11-28 14:43:27 +00:00
Global . CheatList . FirstOrDefault ( x = > x . Domain = = _domain & & x . Address = = address ) . Decrement ( ) ;
2012-06-25 03:10:04 +00:00
}
else
{
2013-11-28 14:43:27 +00:00
switch ( _dataSize )
2012-03-08 18:33:57 +00:00
{
default :
case 1 :
2013-11-28 14:43:27 +00:00
_domain . PokeByte (
2013-10-09 15:28:45 +00:00
address ,
2013-11-28 14:43:27 +00:00
( byte ) ( _domain . PeekByte ( address ) - 1 )
2013-10-09 15:28:45 +00:00
) ;
2012-03-08 18:33:57 +00:00
break ;
2012-06-25 03:10:04 +00:00
case 2 :
2013-11-28 14:43:27 +00:00
_domain . PokeWord (
2013-10-09 15:28:45 +00:00
address ,
2013-11-28 14:43:27 +00:00
( ushort ) ( _domain . PeekWord ( address , _bigEndian ) - 1 ) ,
_bigEndian
2013-10-09 15:28:45 +00:00
) ;
2012-03-08 18:33:57 +00:00
break ;
case 4 :
2013-11-28 14:43:27 +00:00
_domain . PokeDWord (
2013-10-09 15:28:45 +00:00
address ,
2013-11-28 14:43:27 +00:00
_domain . PeekDWord ( address , _bigEndian ) - 1 ,
_bigEndian
2013-10-09 15:28:45 +00:00
) ;
2012-03-08 18:33:57 +00:00
break ;
}
}
}
2012-03-09 01:33:55 +00:00
private void ViewerContextMenuStrip_Opening ( object sender , CancelEventArgs e )
{
2013-11-28 22:06:38 +00:00
var data = Clipboard . GetDataObject ( ) ;
2012-06-19 02:42:07 +00:00
2013-11-07 23:14:04 +00:00
CopyContextItem . Visible =
FreezeContextItem . Visible =
AddToRamWatchContextItem . Visible =
PokeContextItem . Visible =
IncrementContextItem . Visible =
DecrementContextItem . Visible =
ContextSeparator2 . Visible =
2013-11-28 14:43:27 +00:00
HighlightedAddress . HasValue | | _secondaryHighlightedAddresses . Any ( ) ;
2012-06-19 02:42:07 +00:00
2013-11-07 23:14:04 +00:00
UnfreezeAllContextItem . Visible = Global . CheatList . ActiveCount > 0 ;
2013-11-28 22:06:38 +00:00
PasteContextItem . Visible = data ! = null & & data . GetDataPresent ( DataFormats . Text ) ;
2013-11-07 23:14:04 +00:00
ContextSeparator1 . Visible =
HighlightedAddress . HasValue | |
2013-11-28 14:43:27 +00:00
_secondaryHighlightedAddresses . Any ( ) | |
2013-11-28 22:06:38 +00:00
( data ! = null & & data . GetDataPresent ( DataFormats . Text ) ) ;
2012-06-19 02:42:07 +00:00
2013-09-14 04:44:17 +00:00
if ( HighlightedAddress . HasValue & & IsFrozen ( HighlightedAddress . Value ) )
2012-03-09 01:33:55 +00:00
{
2013-11-07 23:14:04 +00:00
FreezeContextItem . Text = "Un&freeze" ;
FreezeContextItem . Image = Properties . Resources . Unfreeze ;
2012-03-09 01:33:55 +00:00
}
else
{
2013-11-07 23:14:04 +00:00
FreezeContextItem . Text = "&Freeze" ;
FreezeContextItem . Image = Properties . Resources . Freeze ;
2012-03-09 01:33:55 +00:00
}
}
2012-06-02 21:18:21 +00:00
2012-06-19 02:42:07 +00:00
private string ValueString ( int address )
2012-06-10 16:34:35 +00:00
{
2012-06-19 02:42:07 +00:00
if ( address ! = - 1 )
2012-06-10 16:34:35 +00:00
{
2013-11-28 14:43:27 +00:00
return String . Format ( _digitFormatString , MakeValue ( address ) ) . Trim ( ) ;
2012-06-10 16:34:35 +00:00
}
else
{
2013-09-14 04:44:17 +00:00
return String . Empty ;
2012-06-10 16:34:35 +00:00
}
}
2012-06-23 18:45:01 +00:00
private string GetFindValues ( )
{
2013-09-14 04:44:17 +00:00
if ( HighlightedAddress . HasValue )
2012-06-23 18:45:01 +00:00
{
2013-11-28 14:43:27 +00:00
var values = ValueString ( HighlightedAddress . Value ) ;
return _secondaryHighlightedAddresses . Aggregate ( values , ( current , x ) = > current + ValueString ( x ) ) ;
2013-04-14 23:56:45 +00:00
}
else
{
2013-11-28 20:02:32 +00:00
return String . Empty ;
2012-06-23 18:45:01 +00:00
}
}
2013-11-28 20:02:32 +00:00
private void HighlightSecondaries ( string value , int found )
2012-06-23 18:45:01 +00:00
{
2013-11-28 22:06:38 +00:00
// This function assumes that the primary highlighted value has been set and sets the remaining characters in this string
2013-11-28 20:02:32 +00:00
_secondaryHighlightedAddresses . Clear ( ) ;
2012-06-23 18:45:01 +00:00
2013-11-28 20:02:32 +00:00
var addrLength = _dataSize * 2 ;
if ( value . Length < = addrLength )
{
2012-06-23 18:45:01 +00:00
return ;
2013-11-28 20:02:32 +00:00
}
2013-11-28 22:06:38 +00:00
var numToHighlight = ( value . Length / addrLength ) - 1 ;
2012-06-23 18:45:01 +00:00
2013-11-28 20:02:32 +00:00
for ( var i = 0 ; i < numToHighlight ; i + + )
{
_secondaryHighlightedAddresses . Add ( found + 1 + i ) ;
}
}
2012-06-23 18:45:01 +00:00
2013-11-28 20:02:32 +00:00
private void Copy ( )
{
var value = HighlightedAddress . HasValue ? ValueString ( HighlightedAddress . Value ) : String . Empty ;
value = _secondaryHighlightedAddresses . Aggregate ( value , ( current , x ) = > current + ValueString ( x ) ) ;
if ( ! String . IsNullOrWhiteSpace ( value ) )
2012-06-23 18:45:01 +00:00
{
2013-11-28 20:02:32 +00:00
Clipboard . SetDataObject ( value ) ;
2012-06-23 18:45:01 +00:00
}
2013-11-28 20:02:32 +00:00
}
private void Paste ( )
{
2013-11-28 22:06:38 +00:00
var data = Clipboard . GetDataObject ( ) ;
2013-11-28 20:02:32 +00:00
2013-11-28 22:06:38 +00:00
if ( data ! = null & & data . GetDataPresent ( DataFormats . Text ) )
2012-06-23 18:45:01 +00:00
{
2013-11-28 22:06:38 +00:00
var clipboardRaw = ( String ) data . GetData ( DataFormats . Text ) ;
2013-11-28 20:02:32 +00:00
var hex = InputValidate . DoHexString ( clipboardRaw ) ;
var numBytes = hex . Length / 2 ;
for ( var i = 0 ; i < numBytes ; i + + )
{
var value = int . Parse ( hex . Substring ( i * 2 , 2 ) , NumberStyles . HexNumber ) ;
var address = _addressHighlighted + i ;
_domain . PokeByte ( address , ( byte ) value ) ;
}
UpdateValues ( ) ;
2012-06-23 18:45:01 +00:00
}
else
{
2013-11-28 22:06:38 +00:00
// Do nothing
2012-06-23 18:45:01 +00:00
}
2013-11-28 20:02:32 +00:00
}
2012-06-23 18:45:01 +00:00
2013-11-28 20:02:32 +00:00
#region Events
#region File Menu
private void FileSubMenu_DropDownOpened ( object sender , EventArgs e )
{
if ( _domain . Name = = "ROM File" )
2012-06-23 18:45:01 +00:00
{
2013-11-28 20:02:32 +00:00
SaveMenuItem . Visible = ! CurrentRomIsArchive ( ) ;
SaveAsBinaryMenuItem . Text = "Save as ROM..." ;
2012-06-23 18:45:01 +00:00
}
2013-11-28 20:02:32 +00:00
else
2012-06-23 18:45:01 +00:00
{
2013-11-28 20:02:32 +00:00
SaveAsBinaryMenuItem . Text = "Save as binary..." ;
2012-06-23 18:45:01 +00:00
}
2013-11-28 20:02:32 +00:00
}
private void SaveMenuItem_Click ( object sender , EventArgs e )
{
if ( ! CurrentRomIsArchive ( ) )
2012-09-26 04:25:45 +00:00
{
2013-11-28 20:02:32 +00:00
SaveFileBinary ( GlobalWin . MainForm . CurrentlyOpenRom ) ;
2012-09-26 04:25:45 +00:00
}
2012-06-23 18:45:01 +00:00
}
2013-11-28 20:02:32 +00:00
private void SaveAsBinaryMenuItem_Click ( object sender , EventArgs e )
2012-06-23 18:45:01 +00:00
{
2013-11-28 20:02:32 +00:00
SaveFileBinary ( GetBinarySaveFileFromUser ( ) ) ;
}
private void SaveAsTextMenuItem_Click ( object sender , EventArgs e )
{
var path = GetSaveFileFromUser ( ) ;
if ( ! String . IsNullOrWhiteSpace ( path ) )
{
var file = new FileInfo ( path ) ;
using ( var sw = new StreamWriter ( file . FullName ) )
{
var sb = new StringBuilder ( ) ;
for ( var i = 0 ; i < _domain . Size / 16 ; i + + )
{
for ( var j = 0 ; j < 16 ; j + + )
{
sb . Append ( String . Format ( "{0:X2} " , _domain . PeekByte ( ( i * 16 ) + j ) ) ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
sb . AppendLine ( ) ;
}
sw . WriteLine ( sb ) ;
}
}
}
private void ExitMenuItem_Click ( object sender , EventArgs e )
{
Close ( ) ;
}
#endregion
#region Edit
private void EditMenuItem_DropDownOpened ( object sender , EventArgs e )
{
FindNextMenuItem . Enabled = ! String . IsNullOrWhiteSpace ( _findStr ) ;
}
private void CopyMenuItem_Click ( object sender , EventArgs e )
{
Copy ( ) ;
}
private void PasteMenuItem_Click ( object sender , EventArgs e )
{
Paste ( ) ;
}
private void FindMenuItem_Click ( object sender , EventArgs e )
{
_findStr = GetFindValues ( ) ;
if ( ! _hexFind . IsHandleCreated | | _hexFind . IsDisposed )
{
_hexFind = new HexFind ( ) ;
_hexFind . SetLocation ( PointToScreen ( AddressesLabel . Location ) ) ;
_hexFind . SetInitialValue ( _findStr ) ;
_hexFind . Show ( ) ;
}
else
{
_hexFind . SetInitialValue ( _findStr ) ;
_hexFind . Focus ( ) ;
}
}
private void FindNextMenuItem_Click ( object sender , EventArgs e )
{
FindNext ( _findStr , false ) ;
}
private void FindPrevMenuItem_Click ( object sender , EventArgs e )
{
FindPrev ( _findStr , false ) ;
}
#endregion
#region Options
private void OptionsSubMenu_DropDownOpened ( object sender , EventArgs e )
{
BigEndianMenuItem . Checked = _bigEndian ;
DataSizeByteMenuItem . Checked = _dataSize = = 1 ;
DataSizeWordMenuItem . Checked = _dataSize = = 2 ;
DataSizeDWordMenuItem . Checked = _dataSize = = 4 ;
if ( HighlightedAddress . HasValue & & IsFrozen ( HighlightedAddress . Value ) )
{
FreezeAddressMenuItem . Image = Properties . Resources . Unfreeze ;
FreezeAddressMenuItem . Text = "Un&freeze Address" ;
}
else
{
FreezeAddressMenuItem . Image = Properties . Resources . Freeze ;
FreezeAddressMenuItem . Text = "&Freeze Address" ;
}
AddToRamWatchMenuItem . Enabled =
FreezeAddressMenuItem . Enabled =
HighlightedAddress . HasValue ;
}
private void MemoryDomainsMenuItem_DropDownOpened ( object sender , EventArgs e )
{
foreach ( var menuItem in _domainMenuItems )
{
menuItem . Checked = _domain . Name = = menuItem . Text ;
}
}
private void DataSizeByteMenuItem_Click ( object sender , EventArgs e )
{
SetDataSize ( 1 ) ;
}
private void DataSizeWordMenuItem_Click ( object sender , EventArgs e )
{
SetDataSize ( 2 ) ;
}
private void DataSizeDWordMenuItem_Click ( object sender , EventArgs e )
{
SetDataSize ( 4 ) ;
}
private void BigEndianMenuItem_Click ( object sender , EventArgs e )
{
_bigEndian ^ = true ;
UpdateValues ( ) ;
}
private void GoToAddressMenuItem_Click ( object sender , EventArgs e )
{
var inputPrompt = new InputPrompt { Text = "Go to Address" , _Location = GetPromptPoint ( ) } ;
inputPrompt . SetMessage ( "Enter a hexadecimal value" ) ;
GlobalWin . Sound . StopSound ( ) ;
inputPrompt . ShowDialog ( ) ;
GlobalWin . Sound . StartSound ( ) ;
if ( inputPrompt . UserOK & & InputValidate . IsValidHexNumber ( inputPrompt . UserText ) )
{
GoToAddress ( int . Parse ( inputPrompt . UserText , NumberStyles . HexNumber ) ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
AddressLabel . Text = GenerateAddressString ( ) ;
}
private void AddToRamWatchMenuItem_Click ( object sender , EventArgs e )
{
if ( HighlightedAddress . HasValue | | _secondaryHighlightedAddresses . Any ( ) )
{
GlobalWin . Tools . LoadRamWatch ( true ) ;
}
if ( HighlightedAddress . HasValue )
{
GlobalWin . Tools . RamWatch . AddWatch ( MakeWatch ( HighlightedAddress . Value ) ) ;
}
_secondaryHighlightedAddresses . ForEach ( addr = >
GlobalWin . Tools . RamWatch . AddWatch ( MakeWatch ( addr ) )
) ;
}
private void FreezeAddressMenuItem_Click ( object sender , EventArgs e )
{
if ( HighlightedAddress . HasValue )
{
if ( IsFrozen ( HighlightedAddress . Value ) )
{
UnFreezeAddress ( HighlightedAddress . Value ) ;
}
else
{
FreezeAddress ( HighlightedAddress . Value ) ;
}
}
foreach ( var addr in _secondaryHighlightedAddresses )
{
if ( IsFrozen ( addr ) )
{
UnFreezeAddress ( addr ) ;
}
else
{
FreezeAddress ( addr ) ;
}
}
UpdateRelatedDialogs ( ) ;
}
private void UnfreezeAllMenuItem_Click ( object sender , EventArgs e )
{
Global . CheatList . DisableAll ( ) ;
}
private void PokeAddressMenuItem_Click ( object sender , EventArgs e )
{
var addresses = new List < int > ( ) ;
if ( HighlightedAddress . HasValue )
{
addresses . Add ( HighlightedAddress . Value ) ;
}
if ( _secondaryHighlightedAddresses . Any ( ) )
{
addresses . AddRange ( _secondaryHighlightedAddresses ) ;
}
if ( addresses . Any ( ) )
{
var poke = new RamPoke
{
InitialLocation = GetAddressCoordinates ( addresses [ 0 ] )
} ;
2013-11-28 22:06:38 +00:00
var watches = addresses . Select (
address = > Watch . GenerateWatch (
_domain ,
address ,
2013-11-28 20:02:32 +00:00
( Watch . WatchSize ) _dataSize ,
Watch . DisplayType . Hex ,
String . Empty ,
_bigEndian
) ) ;
2013-11-28 22:06:38 +00:00
poke . SetWatch ( watches ) ;
2013-11-28 20:02:32 +00:00
GlobalWin . Sound . StopSound ( ) ;
poke . ShowDialog ( ) ;
UpdateValues ( ) ;
GlobalWin . Sound . StartSound ( ) ;
}
}
#endregion
#region Settings Menu
private void SettingsSubMenu_DropDownOpened ( object sender , EventArgs e )
{
AutoloadMenuItem . Checked = Global . Config . AutoLoadHexEditor ;
SaveWindowsPositionMenuItem . Checked = Global . Config . SaveWindowPosition ;
AlwaysOnTopMenuItem . Checked = Global . Config . HexEditorAlwaysOnTop ;
}
private void SetColorsMenuItem_Click ( object sender , EventArgs e )
{
GlobalWin . Sound . StopSound ( ) ;
new HexColorsForm ( ) . ShowDialog ( ) ;
GlobalWin . Sound . StartSound ( ) ;
}
private void ResetColorsToDefaultMenuItem_Click ( object sender , EventArgs e )
{
MemoryViewerBox . BackColor = Color . FromName ( "Control" ) ;
MemoryViewerBox . ForeColor = Color . FromName ( "ControlText" ) ;
2013-11-28 22:06:38 +00:00
this . HexMenuStrip . BackColor = Color . FromName ( "Control" ) ;
2013-11-28 20:02:32 +00:00
Header . BackColor = Color . FromName ( "Control" ) ;
Header . ForeColor = Color . FromName ( "ControlText" ) ;
Global . Config . HexMenubarColor = Color . FromName ( "Control" ) ;
Global . Config . HexForegrndColor = Color . FromName ( "ControlText" ) ;
Global . Config . HexBackgrndColor = Color . FromName ( "Control" ) ;
Global . Config . HexFreezeColor = Color . LightBlue ;
Global . Config . HexHighlightColor = Color . Pink ;
Global . Config . HexHighlightFreezeColor = Color . Violet ;
}
private void AutoloadMenuItem_Click ( object sender , EventArgs e )
{
Global . Config . AutoLoadHexEditor ^ = true ;
}
private void SaveWindowsPositionMenuItem_Click ( object sender , EventArgs e )
{
Global . Config . SaveWindowPosition ^ = true ;
}
private void AlwaysOnTopMenuItem_Click ( object sender , EventArgs e )
{
Global . Config . HexEditorAlwaysOnTop ^ = true ;
TopMost = Global . Config . HexEditorAlwaysOnTop ;
}
private void RestoreDefaultSettingsMenuItem_Click ( object sender , EventArgs e )
{
Size = new Size ( _defaultWidth , _defaultHeight ) ;
SetUpScrollBar ( ) ;
Global . Config . HexEditorAlwaysOnTop = false ;
Global . Config . HexEditorSaveWindowPosition = true ;
Global . Config . AutoLoadHexEditor = false ;
}
#endregion
#region Context Menu and Dialog Events
private void HexEditor_Resize ( object sender , EventArgs e )
{
SetUpScrollBar ( ) ;
UpdateValues ( ) ;
}
private void HexEditor_ResizeEnd ( object sender , EventArgs e )
{
SetUpScrollBar ( ) ;
}
private void HexEditor_KeyDown ( object sender , KeyEventArgs e )
{
if ( e . Control & & e . KeyCode = = Keys . G )
{
GoToAddressMenuItem_Click ( sender , e ) ;
return ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
if ( e . Control & & e . KeyCode = = Keys . P )
{
PokeAddressMenuItem_Click ( sender , e ) ;
return ;
}
int newHighlighted ;
switch ( e . KeyCode )
{
case Keys . Up :
newHighlighted = _addressHighlighted - 16 ;
if ( e . Modifiers = = Keys . Shift )
{
for ( var i = newHighlighted + 1 ; i < = _addressHighlighted ; i + + )
{
AddToSecondaryHighlights ( i ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
GoToAddress ( newHighlighted ) ;
}
else
{
_secondaryHighlightedAddresses . Clear ( ) ;
GoToAddress ( newHighlighted ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
break ;
case Keys . Down :
newHighlighted = _addressHighlighted + 16 ;
if ( e . Modifiers = = Keys . Shift )
{
for ( var i = newHighlighted - 16 ; i < newHighlighted ; i + + )
{
AddToSecondaryHighlights ( i ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
GoToAddress ( newHighlighted ) ;
}
else
{
_secondaryHighlightedAddresses . Clear ( ) ;
GoToAddress ( newHighlighted ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
break ;
case Keys . Left :
newHighlighted = _addressHighlighted - ( 1 * _dataSize ) ;
if ( e . Modifiers = = Keys . Shift )
{
AddToSecondaryHighlights ( _addressHighlighted ) ;
GoToAddress ( newHighlighted ) ;
}
else
{
_secondaryHighlightedAddresses . Clear ( ) ;
GoToAddress ( newHighlighted ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
break ;
case Keys . Right :
newHighlighted = _addressHighlighted + ( 1 * _dataSize ) ;
if ( e . Modifiers = = Keys . Shift )
{
AddToSecondaryHighlights ( _addressHighlighted ) ;
GoToAddress ( newHighlighted ) ;
}
else
{
_secondaryHighlightedAddresses . Clear ( ) ;
GoToAddress ( newHighlighted ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
break ;
case Keys . PageUp :
newHighlighted = _addressHighlighted - ( _rowsVisible * 16 ) ;
if ( e . Modifiers = = Keys . Shift )
{
for ( var i = newHighlighted + 1 ; i < = _addressHighlighted ; i + + )
{
AddToSecondaryHighlights ( i ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
GoToAddress ( newHighlighted ) ;
}
else
{
_secondaryHighlightedAddresses . Clear ( ) ;
GoToAddress ( newHighlighted ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
break ;
case Keys . PageDown :
newHighlighted = _addressHighlighted + ( _rowsVisible * 16 ) ;
if ( e . Modifiers = = Keys . Shift )
{
for ( var i = _addressHighlighted + 1 ; i < newHighlighted ; i + + )
{
AddToSecondaryHighlights ( i ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
GoToAddress ( newHighlighted ) ;
}
else
{
_secondaryHighlightedAddresses . Clear ( ) ;
GoToAddress ( newHighlighted ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
break ;
case Keys . Tab :
_secondaryHighlightedAddresses . Clear ( ) ;
if ( e . Modifiers = = Keys . Shift )
2013-11-28 22:06:38 +00:00
{
2013-11-28 20:02:32 +00:00
GoToAddress ( _addressHighlighted - 8 ) ;
2013-11-28 22:06:38 +00:00
}
2013-11-28 20:02:32 +00:00
else
2013-11-28 22:06:38 +00:00
{
2013-11-28 20:02:32 +00:00
GoToAddress ( _addressHighlighted + 8 ) ;
2013-11-28 22:06:38 +00:00
}
2013-11-28 20:02:32 +00:00
break ;
case Keys . Home :
if ( e . Modifiers = = Keys . Shift )
{
for ( var i = 1 ; i < = _addressHighlighted ; i + + )
{
AddToSecondaryHighlights ( i ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
GoToAddress ( 0 ) ;
}
else
{
_secondaryHighlightedAddresses . Clear ( ) ;
GoToAddress ( 0 ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
break ;
case Keys . End :
2013-11-28 22:06:38 +00:00
newHighlighted = _domain . Size - _dataSize ;
2013-11-28 20:02:32 +00:00
if ( e . Modifiers = = Keys . Shift )
{
for ( var i = _addressHighlighted ; i < newHighlighted ; i + + )
{
AddToSecondaryHighlights ( i ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
GoToAddress ( newHighlighted ) ;
}
else
{
_secondaryHighlightedAddresses . Clear ( ) ;
GoToAddress ( newHighlighted ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
break ;
case Keys . Add :
IncrementContextItem_Click ( sender , e ) ;
break ;
case Keys . Subtract :
DecrementContextItem_Click ( sender , e ) ;
break ;
case Keys . Space :
FreezeAddressMenuItem_Click ( sender , e ) ;
break ;
case Keys . Delete :
if ( e . Modifiers = = Keys . Shift )
{
Global . CheatList . DisableAll ( ) ;
}
else
{
if ( HighlightedAddress . HasValue )
{
UnFreezeAddress ( HighlightedAddress . Value ) ;
}
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
break ;
case Keys . W :
if ( e . Modifiers = = Keys . Control )
{
AddToRamWatchMenuItem_Click ( sender , e ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
break ;
case Keys . Escape :
_secondaryHighlightedAddresses . Clear ( ) ;
ClearHighlighted ( ) ;
break ;
}
}
private void HexEditor_KeyUp ( object sender , KeyEventArgs e )
{
if ( ! IsHexKeyCode ( ( char ) e . KeyCode ) )
{
e . Handled = true ;
return ;
}
2013-11-28 22:06:38 +00:00
if ( e . Control | | e . Shift | | e . Alt )
2013-11-28 20:02:32 +00:00
{
return ;
}
switch ( _dataSize )
{
default :
case 1 :
if ( _nibbles [ 0 ] = = 'G' )
{
_nibbles [ 0 ] = ForceCorrectKeyString ( e . KeyCode ) ;
}
else
{
var temp = _nibbles [ 0 ] . ToString ( ) + ForceCorrectKeyString ( e . KeyCode ) ;
var x = byte . Parse ( temp , NumberStyles . HexNumber ) ;
_domain . PokeByte ( _addressHighlighted , x ) ;
ClearNibbles ( ) ;
SetHighlighted ( _addressHighlighted + 1 ) ;
UpdateValues ( ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
break ;
case 2 :
if ( _nibbles [ 0 ] = = 'G' )
{
_nibbles [ 0 ] = ForceCorrectKeyString ( e . KeyCode ) ;
}
else if ( _nibbles [ 1 ] = = 'G' )
{
_nibbles [ 1 ] = ForceCorrectKeyString ( e . KeyCode ) ;
}
else if ( _nibbles [ 2 ] = = 'G' )
{
_nibbles [ 2 ] = ForceCorrectKeyString ( e . KeyCode ) ;
}
else if ( _nibbles [ 3 ] = = 'G' )
{
var temp = _nibbles [ 0 ] . ToString ( ) + _nibbles [ 1 ] ;
var x1 = byte . Parse ( temp , NumberStyles . HexNumber ) ;
var temp2 = _nibbles [ 2 ] . ToString ( ) + ( ( char ) e . KeyCode ) ;
var x2 = byte . Parse ( temp2 , NumberStyles . HexNumber ) ;
PokeWord ( _addressHighlighted , x1 , x2 ) ;
ClearNibbles ( ) ;
SetHighlighted ( _addressHighlighted + 2 ) ;
UpdateValues ( ) ;
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
break ;
case 4 :
if ( _nibbles [ 0 ] = = 'G' )
{
_nibbles [ 0 ] = ForceCorrectKeyString ( e . KeyCode ) ;
}
else if ( _nibbles [ 1 ] = = 'G' )
{
_nibbles [ 1 ] = ForceCorrectKeyString ( e . KeyCode ) ;
}
else if ( _nibbles [ 2 ] = = 'G' )
{
_nibbles [ 2 ] = ForceCorrectKeyString ( e . KeyCode ) ;
}
else if ( _nibbles [ 3 ] = = 'G' )
{
_nibbles [ 3 ] = ForceCorrectKeyString ( e . KeyCode ) ;
}
else if ( _nibbles [ 4 ] = = 'G' )
{
_nibbles [ 4 ] = ForceCorrectKeyString ( e . KeyCode ) ;
}
else if ( _nibbles [ 5 ] = = 'G' )
{
_nibbles [ 5 ] = ForceCorrectKeyString ( e . KeyCode ) ;
}
else if ( _nibbles [ 6 ] = = 'G' )
{
_nibbles [ 6 ] = ForceCorrectKeyString ( e . KeyCode ) ;
}
else if ( _nibbles [ 7 ] = = 'G' )
{
var temp = _nibbles [ 0 ] . ToString ( ) + _nibbles [ 1 ] ;
var x1 = byte . Parse ( temp , NumberStyles . HexNumber ) ;
2012-06-23 18:45:01 +00:00
2013-11-28 20:02:32 +00:00
var temp2 = _nibbles [ 2 ] . ToString ( ) + _nibbles [ 3 ] ;
var x2 = byte . Parse ( temp2 , NumberStyles . HexNumber ) ;
2012-06-23 18:45:01 +00:00
2013-11-28 20:02:32 +00:00
var temp3 = _nibbles [ 4 ] . ToString ( ) + _nibbles [ 5 ] ;
var x3 = byte . Parse ( temp3 , NumberStyles . HexNumber ) ;
2012-06-23 18:45:01 +00:00
2013-11-28 20:02:32 +00:00
var temp4 = _nibbles [ 6 ] . ToString ( ) + ForceCorrectKeyString ( e . KeyCode ) ;
var x4 = byte . Parse ( temp4 , NumberStyles . HexNumber ) ;
2012-06-23 18:45:01 +00:00
2013-11-28 20:02:32 +00:00
PokeWord ( _addressHighlighted , x1 , x2 ) ;
PokeWord ( _addressHighlighted + 2 , x3 , x4 ) ;
ClearNibbles ( ) ;
SetHighlighted ( _addressHighlighted + 4 ) ;
UpdateValues ( ) ;
}
2013-11-28 22:06:38 +00:00
2012-06-23 18:45:01 +00:00
break ;
2012-09-26 04:25:45 +00:00
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
UpdateValues ( ) ;
2012-06-23 18:45:01 +00:00
}
2013-11-28 20:02:32 +00:00
private void IncrementContextItem_Click ( object sender , EventArgs e )
2012-06-23 18:45:01 +00:00
{
2013-11-28 20:02:32 +00:00
if ( HighlightedAddress . HasValue )
2012-06-23 18:45:01 +00:00
{
2013-11-28 20:02:32 +00:00
IncrementAddress ( HighlightedAddress . Value ) ;
2012-06-23 18:45:01 +00:00
}
2013-11-28 20:02:32 +00:00
_secondaryHighlightedAddresses . ForEach ( IncrementAddress ) ;
2013-10-09 15:28:45 +00:00
2013-11-28 20:02:32 +00:00
UpdateValues ( ) ;
2012-06-23 18:45:01 +00:00
}
2013-11-28 20:02:32 +00:00
private void DecrementContextItem_Click ( object sender , EventArgs e )
2012-06-10 16:34:35 +00:00
{
2013-11-28 20:02:32 +00:00
if ( HighlightedAddress . HasValue )
2012-06-10 16:34:35 +00:00
{
2013-11-28 20:02:32 +00:00
DecrementAddress ( HighlightedAddress . Value ) ;
2012-06-10 16:34:35 +00:00
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
_secondaryHighlightedAddresses . ForEach ( DecrementAddress ) ;
2012-06-10 16:34:35 +00:00
2013-11-28 20:02:32 +00:00
UpdateValues ( ) ;
2012-06-19 02:42:07 +00:00
}
2013-11-28 20:02:32 +00:00
#endregion
2012-06-10 16:34:35 +00:00
2013-11-28 20:02:32 +00:00
#region MemoryViewer Events
2012-06-19 02:42:07 +00:00
2013-11-28 20:02:32 +00:00
private void HexEditor_MouseWheel ( object sender , MouseEventArgs e )
{
var delta = 0 ;
if ( e . Delta > 0 )
{
delta = - 1 ;
2012-06-10 16:34:35 +00:00
}
2013-11-28 20:02:32 +00:00
else if ( e . Delta < 0 )
2012-06-10 16:34:35 +00:00
{
2013-11-28 20:02:32 +00:00
delta = 1 ;
2012-06-10 16:34:35 +00:00
}
2013-11-28 20:02:32 +00:00
var newValue = HexScrollBar . Value + delta ;
2013-11-28 22:06:38 +00:00
if ( newValue < HexScrollBar . Minimum )
{
newValue = HexScrollBar . Minimum ;
}
if ( newValue > HexScrollBar . Maximum - HexScrollBar . LargeChange + 1 )
{
newValue = HexScrollBar . Maximum - HexScrollBar . LargeChange + 1 ;
}
2013-11-28 20:02:32 +00:00
if ( newValue ! = HexScrollBar . Value )
{
HexScrollBar . Value = newValue ;
MemoryViewerBox . Refresh ( ) ;
}
2012-06-19 02:42:07 +00:00
}
2013-11-28 20:02:32 +00:00
private void MemoryViewerBox_Paint ( object sender , PaintEventArgs e )
2012-06-10 16:34:35 +00:00
{
2013-11-28 20:02:32 +00:00
var activeCheats = Global . CheatList . Where ( x = > x . Enabled ) ;
foreach ( var cheat in activeCheats )
{
if ( IsVisible ( cheat . Address ? ? 0 ) )
{
if ( _domain . ToString ( ) = = cheat . Domain . Name )
{
var rect = new Rectangle ( GetAddressCoordinates ( cheat . Address ? ? 0 ) , new Size ( 15 * _dataSize , fontHeight ) ) ;
e . Graphics . DrawRectangle ( new Pen ( Brushes . Black ) , rect ) ;
e . Graphics . FillRectangle ( new SolidBrush ( Global . Config . HexFreezeColor ) , rect ) ;
}
}
}
2012-06-10 16:34:35 +00:00
2013-11-28 20:02:32 +00:00
if ( _addressHighlighted > = 0 & & IsVisible ( _addressHighlighted ) )
{
var point = GetAddressCoordinates ( _addressHighlighted ) ;
var textX = GetTextX ( _addressHighlighted ) ;
var textpoint = new Point ( textX , point . Y ) ;
2012-06-10 22:43:43 +00:00
2013-11-28 20:02:32 +00:00
var rect = new Rectangle ( point , new Size ( 15 * _dataSize , fontHeight ) ) ;
e . Graphics . DrawRectangle ( new Pen ( Brushes . Black ) , rect ) ;
2012-06-10 22:43:43 +00:00
2013-11-28 22:06:38 +00:00
var textrect = new Rectangle ( textpoint , new Size ( 8 * _dataSize , fontHeight ) ) ;
2012-06-19 02:42:07 +00:00
2013-11-28 20:02:32 +00:00
if ( Global . CheatList . IsActive ( _domain , _addressHighlighted ) )
{
e . Graphics . FillRectangle ( new SolidBrush ( Global . Config . HexHighlightFreezeColor ) , rect ) ;
e . Graphics . FillRectangle ( new SolidBrush ( Global . Config . HexHighlightFreezeColor ) , textrect ) ;
}
else
{
e . Graphics . FillRectangle ( new SolidBrush ( Global . Config . HexHighlightColor ) , rect ) ;
e . Graphics . FillRectangle ( new SolidBrush ( Global . Config . HexHighlightColor ) , textrect ) ;
}
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
foreach ( var address in _secondaryHighlightedAddresses )
{
var point = GetAddressCoordinates ( address ) ;
var textX = GetTextX ( address ) ;
var textpoint = new Point ( textX , point . Y ) ;
2012-06-19 02:42:07 +00:00
2013-11-28 20:02:32 +00:00
var rect = new Rectangle ( point , new Size ( 15 * _dataSize , fontHeight ) ) ;
e . Graphics . DrawRectangle ( new Pen ( Brushes . Black ) , rect ) ;
2012-06-23 18:45:01 +00:00
2013-11-28 20:02:32 +00:00
var textrect = new Rectangle ( textpoint , new Size ( 8 , fontHeight ) ) ;
2012-06-23 18:45:01 +00:00
2013-11-28 20:02:32 +00:00
if ( Global . CheatList . IsActive ( _domain , address ) )
{
e . Graphics . FillRectangle ( new SolidBrush ( Global . Config . HexHighlightFreezeColor ) , rect ) ;
e . Graphics . FillRectangle ( new SolidBrush ( Global . Config . HexHighlightFreezeColor ) , textrect ) ;
}
else
{
e . Graphics . FillRectangle ( new SolidBrush ( Color . FromArgb ( 0x77FFD4D4 ) ) , rect ) ;
e . Graphics . FillRectangle ( new SolidBrush ( Color . FromArgb ( 0x77FFD4D4 ) ) , textrect ) ;
}
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
if ( HasNibbles ( ) )
{
e . Graphics . DrawString ( MakeNibbles ( ) , new Font ( "Courier New" , 8 , FontStyle . Italic ) , Brushes . Black , new Point ( 158 , 4 ) ) ;
}
2012-06-23 18:45:01 +00:00
}
2013-11-28 20:02:32 +00:00
private void AddressesLabel_MouseUp ( object sender , MouseEventArgs e )
2012-06-23 18:45:01 +00:00
{
2013-11-28 20:02:32 +00:00
_mouseIsDown = false ;
2012-06-23 18:45:01 +00:00
}
2012-09-02 23:12:00 +00:00
2013-11-28 20:02:32 +00:00
private void AddressesLabel_MouseMove ( object sender , MouseEventArgs e )
2012-09-14 21:31:00 +00:00
{
2013-11-28 20:02:32 +00:00
_addressOver = GetPointedAddress ( e . X , e . Y ) ;
2012-09-14 21:31:00 +00:00
2013-11-28 20:02:32 +00:00
if ( _mouseIsDown )
{
DoShiftClick ( ) ;
MemoryViewerBox . Refresh ( ) ;
}
2012-09-14 21:31:00 +00:00
}
2012-09-21 06:33:57 +00:00
2013-11-28 20:02:32 +00:00
private void AddressesLabel_MouseLeave ( object sender , EventArgs e )
2012-09-21 06:33:57 +00:00
{
2013-11-28 20:02:32 +00:00
_addressOver = - 1 ;
MemoryViewerBox . Refresh ( ) ;
2012-09-21 06:33:57 +00:00
}
2012-09-29 21:13:11 +00:00
private void AddressesLabel_MouseDown ( object sender , MouseEventArgs e )
{
2012-10-15 00:56:47 +00:00
if ( e . Button = = MouseButtons . Left )
2012-09-29 21:13:11 +00:00
{
2013-11-28 14:43:27 +00:00
var pointed_address = GetPointedAddress ( e . X , e . Y ) ;
2013-04-14 23:56:45 +00:00
if ( pointed_address > = 0 )
2012-09-29 21:13:11 +00:00
{
2013-04-14 23:56:45 +00:00
if ( ( ModifierKeys & Keys . Control ) = = Keys . Control )
2012-09-29 21:13:11 +00:00
{
2013-11-28 14:43:27 +00:00
if ( pointed_address = = _addressHighlighted )
2012-10-15 00:56:47 +00:00
{
ClearHighlighted ( ) ;
}
2013-11-28 14:43:27 +00:00
else if ( _secondaryHighlightedAddresses . Contains ( pointed_address ) )
2012-10-15 00:56:47 +00:00
{
2013-11-28 14:43:27 +00:00
_secondaryHighlightedAddresses . Remove ( pointed_address ) ;
2012-10-15 00:56:47 +00:00
}
else
{
2013-11-28 14:43:27 +00:00
_secondaryHighlightedAddresses . Add ( pointed_address ) ;
2012-10-15 00:56:47 +00:00
}
2012-09-29 21:13:11 +00:00
}
2013-04-14 23:56:45 +00:00
else if ( ( ModifierKeys & Keys . Shift ) = = Keys . Shift )
2012-09-29 21:13:11 +00:00
{
2012-10-15 00:56:47 +00:00
DoShiftClick ( ) ;
2012-09-29 21:13:11 +00:00
}
else
{
2013-04-14 23:56:45 +00:00
SetHighlighted ( pointed_address ) ;
2013-11-28 14:43:27 +00:00
_secondaryHighlightedAddresses . Clear ( ) ;
_findStr = String . Empty ;
2012-09-29 21:13:11 +00:00
}
2012-10-15 00:56:47 +00:00
MemoryViewerBox . Refresh ( ) ;
2012-09-29 21:13:11 +00:00
}
2013-11-28 14:43:27 +00:00
_mouseIsDown = true ;
2012-09-29 21:13:11 +00:00
}
}
2012-09-21 06:33:57 +00:00
2013-11-28 20:02:32 +00:00
private void HexScrollBar_ValueChanged ( object sender , EventArgs e )
2013-11-28 14:58:15 +00:00
{
2013-11-28 20:02:32 +00:00
UpdateValues ( ) ;
2013-11-28 14:58:15 +00:00
}
#endregion
2013-11-28 20:02:32 +00:00
2013-11-28 14:58:15 +00:00
#endregion
2011-06-19 23:39:25 +00:00
}
2012-06-25 03:10:04 +00:00
}