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-11-28 22:06:38 +00:00
using BizHawk.Common ;
2014-07-03 15:35:50 +00:00
using BizHawk.Common.NumberExtensions ;
2014-07-03 16:00:57 +00:00
using BizHawk.Common.StringExtensions ;
2014-07-03 18:29:51 +00:00
using BizHawk.Common.IOExtensions ;
2013-11-04 01:39:19 +00:00
using BizHawk.Emulation.Common ;
2014-09-01 18:43:41 +00:00
using BizHawk.Emulation.Common.IEmulatorExtensions ;
2014-07-03 15:35:50 +00:00
using BizHawk.Client.Common ;
2014-07-27 15:22:30 +00:00
using BizHawk.Client.EmuHawk.WinFormExtensions ;
2014-07-28 01:51:11 +00:00
using BizHawk.Client.EmuHawk.ToolExtensions ;
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
{
2015-01-18 16:00:20 +00:00
// int to long TODO: 32 bit domains have more digits than the hex editor can account for and the address covers up the 0 column
2015-01-01 14:54:26 +00:00
public partial class HexEditor : Form , IToolFormAutoConfig
2011-06-19 23:39:25 +00:00
{
2014-12-15 03:19:23 +00:00
[RequiredService]
2015-01-14 21:55:48 +00:00
private IMemoryDomains MemoryDomains { get ; set ; }
2014-12-13 21:54:59 +00:00
2014-12-17 03:57:07 +00:00
[RequiredService]
private IEmulator Emulator { get ; set ; }
2014-09-13 15:39:18 +00:00
private int fontWidth ;
private int fontHeight ;
2013-11-28 22:06:38 +00:00
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
2015-01-18 18:01:27 +00:00
private readonly List < long > _secondaryHighlightedAddresses = new List < long > ( ) ;
2013-11-28 22:06:38 +00:00
2014-03-23 20:27:20 +00:00
private readonly Dictionary < int , char > _textTable = new Dictionary < int , char > ( ) ;
2013-11-28 14:43:27 +00:00
private int _rowsVisible ;
private int _numDigits = 4 ;
private string _numDigitsStr = "{0:X4}" ;
private string _digitFormatString = "{0:X2}" ;
2015-01-18 18:01:27 +00:00
private long _addressHighlighted = - 1 ;
private long _addressOver = - 1 ;
2013-11-28 22:06:38 +00:00
2015-01-18 18:13:38 +00:00
private long _maxRow ;
2013-11-28 22:06:38 +00:00
private MemoryDomain _domain = new MemoryDomain (
2015-01-18 15:25:47 +00:00
"NULL" , 1024 , MemoryDomain . Endian . Little , addr = > 0 , delegate ( long a , byte v ) { v = 0 ; } ) ;
2013-11-28 22:06:38 +00:00
2015-01-18 20:15:03 +00:00
private long _row ;
2015-01-18 18:59:23 +00:00
private long _addr ;
2014-01-30 03:10:17 +00:00
private string _findStr = string . Empty ;
2013-11-28 14:43:27 +00:00
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
2015-01-01 14:54:26 +00:00
[ConfigPersist]
private bool BigEndian { get ; set ; }
[ConfigPersist]
private int DataSize { get ; set ; }
[ConfigPersist]
private RecentFiles RecentTables { get ; set ; }
2012-03-09 16:13:40 +00:00
2011-06-19 23:39:25 +00:00
public HexEditor ( )
{
2015-01-01 14:54:26 +00:00
RecentTables = new RecentFiles ( 8 ) ;
DataSize = 1 ;
2014-09-13 14:50:58 +00:00
var font = new Font ( "Courier New" , 8 ) ;
2015-03-06 02:45:53 +00:00
// Measure the font. There seems to be some extra horizontal padding on the first
// character so we'll see how much the width increases on the second character.
var fontSize1 = TextRenderer . MeasureText ( "0" , font ) ;
var fontSize2 = TextRenderer . MeasureText ( "00" , font ) ;
fontWidth = fontSize2 . Width - fontSize1 . Width ;
fontHeight = fontSize1 . Height ;
2014-09-13 14:50:58 +00:00
2011-06-19 23:39:25 +00:00
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 ( ) ;
2014-09-13 14:50:58 +00:00
Header . Font = font ;
AddressesLabel . Font = font ;
AddressLabel . Font = font ;
2011-06-19 23:39:25 +00:00
}
2015-01-18 18:01:27 +00:00
private long? HighlightedAddress
2013-11-28 22:06:38 +00:00
{
get
{
if ( _addressHighlighted > = 0 )
{
return _addressHighlighted ;
}
2014-03-01 15:21:17 +00:00
return null ; // Negative = no address highlighted
2013-11-28 22:06:38 +00:00
}
}
2015-11-28 21:47:16 +00:00
private WatchSize WatchSize
2013-11-28 22:06:38 +00:00
{
get
{
2015-11-28 21:47:16 +00:00
return ( WatchSize ) DataSize ;
2013-11-28 22:06:38 +00:00
}
}
#region API
public bool UpdateBefore
{
2014-04-25 20:02:57 +00:00
get { return false ; }
2013-11-28 22:06:38 +00:00
}
2014-08-19 19:24:17 +00:00
public bool AskSaveChanges ( )
2013-11-28 22:06:38 +00:00
{
return true ;
}
2013-11-28 20:02:32 +00:00
public void UpdateValues ( )
2012-03-09 16:13:40 +00:00
{
2015-08-31 16:37:46 +00:00
AddressesLabel . Text = GenerateMemoryViewString ( true ) ;
2013-11-28 20:02:32 +00:00
AddressLabel . Text = GenerateAddressString ( ) ;
2012-03-09 16:13:40 +00:00
}
2014-07-25 01:55:21 +00:00
public void FastUpdate ( )
{
// Do nothing
}
2015-08-23 16:59:27 +00:00
private string _lastRom = string . Empty ;
2013-11-28 20:02:32 +00:00
public void Restart ( )
2011-06-19 23:39:25 +00:00
{
2015-01-14 00:08:20 +00:00
_rom = GetRomBytes ( ) ;
2015-01-21 17:36:22 +00:00
_romDomain = MemoryDomain . FromByteArray ( "File on Disk" , MemoryDomain . Endian . Little , _rom ) ;
2013-11-28 20:02:32 +00:00
2015-01-14 00:08:20 +00:00
if ( _domain . Name = = _romDomain . Name )
{
_domain = _romDomain ;
}
else if ( MemoryDomains . Any ( x = > x . Name = = _domain . Name ) )
{
_domain = MemoryDomains [ _domain . Name ] ;
}
else
2012-06-23 18:45:01 +00:00
{
2015-01-14 00:08:20 +00:00
_domain = MemoryDomains . MainMemory ;
2012-06-23 18:45:01 +00:00
}
2015-01-14 00:08:20 +00:00
BigEndian = _domain . EndianType = = MemoryDomain . Endian . Big ;
2015-01-18 18:59:23 +00:00
_maxRow = _domain . Size / 2 ;
2015-01-14 00:08:20 +00:00
2015-08-23 16:59:27 +00:00
// Don't reset scroll bar if restarting the same rom
if ( _lastRom ! = GlobalWin . MainForm . CurrentlyOpenRom )
{
_lastRom = GlobalWin . MainForm . CurrentlyOpenRom ;
ResetScrollBar ( ) ;
}
2015-01-01 14:54:26 +00:00
SetDataSize ( DataSize ) ;
2015-08-23 18:04:00 +00:00
SetHeader ( ) ;
2013-11-28 20:02:32 +00:00
UpdateValues ( ) ;
AddressLabel . Text = GenerateAddressString ( ) ;
}
2015-11-28 21:47:16 +00:00
public void SetToAddresses ( IEnumerable < long > addresses , MemoryDomain domain , WatchSize size )
2013-11-28 20:02:32 +00:00
{
2015-01-01 14:54:26 +00:00
DataSize = ( int ) size ;
SetDataSize ( DataSize ) ;
2013-11-28 20:02:32 +00:00
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 ( ) ;
}
}
2014-03-23 23:47:20 +00:00
public byte [ ] ConvertTextToBytes ( string str )
{
if ( _textTable . Any ( ) )
{
var byteArr = new List < byte > ( ) ;
foreach ( var chr in str )
{
byteArr . Add ( ( byte ) _textTable . FirstOrDefault ( kvp = > kvp . Value = = chr ) . Key ) ;
}
return byteArr . ToArray ( ) ;
}
return str . Select ( Convert . ToByte ) . ToArray ( ) ;
}
2013-11-28 20:02:32 +00:00
public void FindNext ( string value , bool wrap )
{
2015-01-18 18:01:27 +00:00
long found = - 1 ;
2013-11-28 20:02:32 +00:00
2014-01-30 03:10:17 +00:00
var search = value . Replace ( " " , string . Empty ) . ToUpper ( ) ;
if ( string . IsNullOrEmpty ( search ) )
2013-11-28 20:02:32 +00:00
{
return ;
}
var numByte = search . Length / 2 ;
2015-01-18 18:01:27 +00:00
long startByte ;
2013-11-28 20:02:32 +00:00
if ( _addressHighlighted = = - 1 )
{
startByte = 0 ;
}
2015-01-18 16:00:20 +00:00
else if ( _addressHighlighted > = ( _domain . Size - 1 - numByte ) )
2013-11-28 20:02:32 +00:00
{
startByte = 0 ;
}
else
{
2015-01-01 14:54:26 +00:00
startByte = _addressHighlighted + DataSize ;
2013-11-28 20:02:32 +00:00
}
2015-01-18 16:00:20 +00:00
for ( var i = startByte ; i < ( _domain . Size - numByte ) ; i + + )
2013-11-28 20:02:32 +00:00
{
var ramblock = new StringBuilder ( ) ;
for ( var j = 0 ; j < numByte ; j + + )
{
2014-01-30 03:10:17 +00:00
ramblock . Append ( string . Format ( "{0:X2}" , ( int ) _domain . PeekByte ( i + j ) ) ) ;
2013-11-28 20:02:32 +00:00
}
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 ;
}
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
}
2014-03-23 19:55:56 +00:00
_hexFind . Close ( ) ;
2013-11-28 20:02:32 +00:00
}
public void FindPrev ( string value , bool wrap )
{
2015-01-18 18:01:27 +00:00
long found = - 1 ;
2013-11-28 20:02:32 +00:00
2013-11-28 22:06:38 +00:00
var search = value . Replace ( " " , string . Empty ) . ToUpper ( ) ;
2014-03-23 19:55:56 +00:00
if ( string . IsNullOrEmpty ( search ) )
2013-11-28 20:02:32 +00:00
{
return ;
}
var numByte = search . Length / 2 ;
2015-01-18 18:01:27 +00:00
long startByte ;
2013-11-28 20:02:32 +00:00
if ( _addressHighlighted = = - 1 )
{
2015-01-19 02:42:58 +00:00
startByte = _domain . Size - DataSize ;
2013-11-28 20:02:32 +00:00
}
else
{
startByte = _addressHighlighted - 1 ;
}
for ( var i = startByte ; i > = 0 ; i - - )
{
var ramblock = new StringBuilder ( ) ;
for ( var j = 0 ; j < numByte ; j + + )
{
2014-01-30 03:10:17 +00:00
ramblock . Append ( string . Format ( "{0:X2}" , ( int ) _domain . PeekByte ( i + j ) ) ) ;
2013-11-28 20:02:32 +00:00
}
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 ;
}
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
}
2014-03-23 19:55:56 +00:00
_hexFind . Close ( ) ;
2011-06-19 23:39:25 +00:00
}
2013-11-28 20:02:32 +00:00
#endregion
2014-03-23 20:27:20 +00:00
private char Remap ( byte val )
2013-11-28 22:06:38 +00:00
{
2014-03-23 20:27:20 +00:00
if ( _textTable . Any ( ) )
2013-11-28 22:06:38 +00:00
{
2014-03-23 20:27:20 +00:00
if ( _textTable . ContainsKey ( val ) )
{
return _textTable [ val ] ;
}
return '?' ;
2013-11-28 22:06:38 +00:00
}
2014-03-23 20:27:20 +00:00
else
2013-11-28 22:06:38 +00:00
{
2014-03-23 20:27:20 +00:00
if ( val < ' ' )
{
return '.' ;
}
if ( val > = 0x80 )
{
return '.' ;
}
return ( char ) val ;
2013-11-28 22:06:38 +00:00
}
}
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 ( )
{
2015-11-19 03:17:34 +00:00
var path = GlobalWin . MainForm . CurrentlyOpenRomArgs . OpenAdvanced . SimplePath ;
if ( string . IsNullOrEmpty ( path ) )
2013-11-28 22:06:38 +00:00
{
return new byte [ ] { 0xFF } ;
}
using ( var file = new HawkFile ( ) )
{
file . Open ( path ) ;
if ( ! file . Exists )
{
return null ;
}
if ( file . IsArchive )
{
var stream = file . GetStream ( ) ;
2014-07-03 18:29:51 +00:00
return stream . ReadAllBytes ( ) ;
2013-11-28 22:06:38 +00:00
}
2014-03-01 15:21:17 +00:00
return File . ReadAllBytes ( path ) ;
2013-11-28 22:06:38 +00:00
}
}
2014-09-11 21:55:38 +00:00
private static int GetNumDigits ( long i )
2013-11-28 22:06:38 +00:00
{
if ( i < = 0x10000 )
{
return 4 ;
}
return i < = 0x1000000 ? 6 : 8 ;
}
2014-01-31 04:26:39 +00:00
private static char ForceCorrectKeyString ( char keycode )
2013-11-28 22:06:38 +00:00
{
2014-02-08 21:47:39 +00:00
return ( char ) keycode ;
2013-11-28 22:06:38 +00:00
}
private static bool IsHexKeyCode ( char key )
{
2014-02-08 21:47:39 +00:00
if ( key > = '0' & & key < = '9' ) // 0-9
2013-11-28 22:06:38 +00:00
{
return true ;
}
2014-03-01 15:21:17 +00:00
if ( key > = 'a' & & key < = 'f' ) // A-F
2013-11-28 22:06:38 +00:00
{
return true ;
}
2014-03-01 15:21:17 +00:00
if ( key > = 'A' & & key < = 'F' ) // A-F
2013-11-28 22:06:38 +00:00
{
return true ;
}
2014-03-01 15:21:17 +00:00
return false ;
2013-11-28 22:06:38 +00:00
}
2011-06-19 23:39:25 +00:00
private void HexEditor_Load ( object sender , EventArgs e )
{
2015-02-24 10:18:20 +00:00
DataSize = _domain . ByteSize ;
2015-01-01 14:54:26 +00:00
SetDataSize ( DataSize ) ;
2014-03-23 20:27:20 +00:00
2015-01-01 14:54:26 +00:00
if ( RecentTables . AutoLoad )
2014-03-23 20:27:20 +00:00
{
2015-01-01 14:54:26 +00:00
LoadFileFromRecent ( RecentTables [ 0 ] ) ;
2014-03-23 20:27:20 +00:00
}
2011-08-25 02:23:12 +00:00
UpdateValues ( ) ;
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 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
}
2015-01-01 14:54:26 +00:00
// TODO: rename me
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
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 ;
2015-01-18 16:00:20 +00:00
if ( _addr > = _domain . Size )
2013-11-28 14:43:27 +00:00
{
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
2015-12-20 19:51:07 +00:00
addrStr . AppendLine ( _addr . ToHexString ( _numDigits ) + " |" ) ;
2012-06-18 03:34:14 +00:00
}
return addrStr . ToString ( ) ;
}
2015-08-31 16:37:46 +00:00
private string GenerateMemoryViewString ( bool forWindow )
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 ;
2015-01-18 16:00:20 +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
2015-01-01 14:54:26 +00:00
for ( var j = 0 ; j < 16 ; j + = DataSize )
2011-08-27 04:32:54 +00:00
{
2015-01-18 16:00:20 +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
{
2015-01-01 14:54:26 +00:00
for ( var t = 0 ; t < DataSize ; t + + )
2013-11-28 14:43:27 +00:00
{
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
2015-12-20 19:51:07 +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
{
2015-01-18 16:00:20 +00:00
if ( _addr + k < _domain . Size )
2012-09-02 22:45:06 +00:00
{
2015-08-31 16:37:46 +00:00
byte b = MakeByte ( _addr + k ) ;
char c = Remap ( b ) ;
rowStr . Append ( c ) ;
//winforms will be using these as escape codes for hotkeys
if ( forWindow ) if ( c = = '&' ) rowStr . Append ( '&' ) ;
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
}
2015-01-18 18:13:38 +00:00
private byte MakeByte ( long address )
2014-01-01 03:19:08 +00:00
{
2015-01-18 18:59:23 +00:00
return Global . CheatList . IsActive ( _domain , address )
? Global . CheatList . GetByteValue ( _domain , address ) . Value
2014-01-01 03:19:08 +00:00
: _domain . PeekByte ( address ) ;
}
2015-09-29 07:29:19 +00:00
private int MakeValue ( int dataSize , long address )
2011-08-22 02:48:12 +00:00
{
2015-01-18 18:59:23 +00:00
if ( Global . CheatList . IsActive ( _domain , address ) )
2014-01-01 03:19:08 +00:00
{
2015-11-28 21:47:16 +00:00
return Global . CheatList . GetCheatValue ( _domain , address , ( WatchSize ) DataSize ) . Value ;
2014-01-01 03:19:08 +00:00
}
2015-09-29 07:29:19 +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 :
2015-01-01 14:54:26 +00:00
return _domain . PeekWord ( address , BigEndian ) ;
2011-08-27 04:32:54 +00:00
case 4 :
2015-01-01 14:54:26 +00:00
return ( int ) _domain . PeekDWord ( address , BigEndian ) ;
2011-08-22 02:48:12 +00:00
}
}
2015-09-29 07:29:19 +00:00
private int MakeValue ( long address )
{
return MakeValue ( DataSize , address ) ;
}
2015-01-14 00:08:20 +00:00
private void SetMemoryDomain ( string name )
2011-08-22 02:48:12 +00:00
{
2015-01-14 00:08:20 +00:00
if ( name = = _romDomain . Name )
{
_domain = _romDomain ;
}
else
{
_domain = MemoryDomains [ name ] ;
}
2014-09-11 21:55:38 +00:00
2015-01-14 00:08:20 +00:00
BigEndian = _domain . EndianType = = MemoryDomain . Endian . Big ;
2015-01-18 18:13:38 +00:00
_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
2015-01-25 15:42:07 +00:00
if ( _domain . CanPoke ( ) )
{
AddressesLabel . ForeColor = SystemColors . ControlText ;
}
else
{
AddressesLabel . ForeColor = SystemColors . ControlDarkDark ;
}
2015-01-14 00:08:20 +00:00
UpdateGroupBoxTitle ( ) ;
2015-08-23 18:04:00 +00:00
SetHeader ( ) ;
2015-01-14 00:08:20 +00:00
UpdateValues ( ) ;
2011-08-22 02:48:12 +00:00
}
2013-11-28 20:02:32 +00:00
private void SetDomain ( MemoryDomain domain )
{
2015-01-25 15:42:07 +00:00
SetMemoryDomain ( domain . Name ) ;
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
{
2015-01-18 16:00:20 +00:00
var addressesString = "0x" + string . Format ( "{0:X8}" , _domain . Size / DataSize ) . TrimStart ( '0' ) ;
2015-01-25 15:42:07 +00:00
MemoryViewerBox . Text = Emulator . SystemId + " " + _domain + ( _domain . CanPoke ( ) ? "" : " (READ-ONLY)" ) +
" - " + addressesString + " addresses" ;
2011-06-19 23:39:25 +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
}
2015-01-18 18:01:27 +00:00
private void GoToAddress ( long 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
2015-01-18 16:00:20 +00:00
if ( address > = _domain . Size )
2013-04-14 23:56:45 +00:00
{
2015-01-19 02:42:58 +00:00
address = _domain . Size - DataSize ;
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
2015-01-18 18:01:27 +00:00
private void SetHighlighted ( long address )
2011-08-22 02:48:12 +00:00
{
2013-04-14 23:56:45 +00:00
if ( address < 0 )
{
address = 0 ;
}
2015-01-18 16:00:20 +00:00
if ( address > = _domain . Size )
2013-04-14 23:56:45 +00:00
{
2015-01-19 02:42:58 +00:00
address = _domain . Size - DataSize ;
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
2015-01-18 18:01:27 +00:00
HexScrollBar . Value = ( int ) value ; // This will fail on a sufficiently large domain
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 ( )
{
2015-12-20 19:51:07 +00:00
Text = "Hex Editor" ;
2013-11-28 14:43:27 +00:00
if ( _addressHighlighted > = 0 )
2013-11-28 22:06:38 +00:00
{
2015-12-20 19:51:07 +00:00
Text + = " - Editing Address 0x" + string . Format ( _numDigitsStr , _addressHighlighted ) ;
if ( _secondaryHighlightedAddresses . Any ( ) )
{
Text + = string . Format ( " (Selected 0x{0:X})" , _secondaryHighlightedAddresses . Count ( ) +
( _secondaryHighlightedAddresses . Contains ( _addressHighlighted ) ? 0 : 1 ) ) ;
}
2013-11-28 22:06:38 +00:00
}
2011-08-25 23:49:13 +00:00
}
2015-01-18 18:01:27 +00:00
private bool IsVisible ( long 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 ( )
{
2015-01-01 14:54:26 +00:00
switch ( DataSize )
2011-08-22 02:48:12 +00:00
{
case 1 :
2015-12-20 19:51:07 +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 :
2015-12-20 19:51:07 +00:00
Header . Text = " 0 2 4 6 8 A C E" ;
2011-08-22 02:48:12 +00:00
break ;
case 4 :
2015-12-20 19:51:07 +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
2015-01-18 16:00:20 +00:00
_numDigits = GetNumDigits ( _domain . Size ) ;
2013-11-28 14:43:27 +00:00
_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
{
2015-01-01 14:54:26 +00:00
DataSize = size ;
_digitFormatString = "{0:X" + ( DataSize * 2 ) + "} " ;
2013-11-28 20:02:32 +00:00
SetHeader ( ) ;
UpdateGroupBoxTitle ( ) ;
UpdateValues ( ) ;
2015-09-29 04:54:26 +00:00
_secondaryHighlightedAddresses . Clear ( ) ;
2013-11-28 20:02:32 +00:00
}
2011-06-19 23:39:25 +00:00
}
2015-01-18 18:01:27 +00:00
private Watch MakeWatch ( long address )
2012-06-19 02:42:07 +00:00
{
2015-01-01 14:54:26 +00:00
switch ( DataSize )
2012-06-19 02:42:07 +00:00
{
default :
2015-11-28 21:47:16 +00:00
case 1 :
return Watch . GenerateWatch ( _domain , address , WatchSize . Byte , Client . Common . DisplayType . Hex , BigEndian , string . Empty ) ;
case 2 :
return Watch . GenerateWatch ( _domain , address , WatchSize . Word , Client . Common . DisplayType . Hex , BigEndian , string . Empty ) ;
2012-06-19 02:42:07 +00:00
case 4 :
2015-11-28 21:47:16 +00:00
return Watch . GenerateWatch ( _domain , address , WatchSize . DWord , Client . Common . DisplayType . Hex , BigEndian , string . Empty ) ;
2012-06-19 02:42:07 +00:00
}
}
2015-01-18 18:01:27 +00:00
private bool IsFrozen ( long address )
2012-03-09 01:24:46 +00:00
{
2015-01-18 18:59:23 +00:00
return Global . CheatList . IsActive ( _domain , address ) ;
2012-03-09 01:24:46 +00:00
}
2015-01-18 18:01:27 +00:00
private void UnFreezeAddress ( long 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 (
2015-01-18 18:59:23 +00:00
Global . CheatList . Where ( x = > x . Contains ( address ) ) . ToList ( ) ) ;
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-11-28 22:06:38 +00:00
// TODO refactor to int?
2015-01-18 18:01:27 +00:00
private void FreezeAddress ( long 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 ,
2015-01-18 18:59:23 +00:00
address ,
2013-10-06 16:40:51 +00:00
WatchSize ,
2015-11-28 21:47:16 +00:00
Client . Common . DisplayType . Hex ,
2015-01-01 14:54:26 +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 ,
2015-11-29 16:13:32 +00:00
watch . Value ) ) ;
2011-06-19 23:39:25 +00:00
}
}
2014-03-01 18:04:21 +00:00
private void FreezeSecondaries ( )
{
var cheats = new List < Cheat > ( ) ;
foreach ( var address in _secondaryHighlightedAddresses )
{
var watch = Watch . GenerateWatch (
_domain ,
2015-01-18 18:59:23 +00:00
address ,
2014-03-01 18:04:21 +00:00
WatchSize ,
2015-11-28 21:47:16 +00:00
Client . Common . DisplayType . Hex ,
2015-01-01 14:54:26 +00:00
BigEndian ) ;
2014-03-01 18:04:21 +00:00
cheats . Add ( new Cheat (
watch ,
2015-11-29 16:13:32 +00:00
watch . Value ) ) ;
2014-03-01 18:04:21 +00:00
}
Global . CheatList . AddRange ( cheats ) ;
}
private void UnfreezeSecondaries ( )
{
Global . CheatList . RemoveRange (
Global . CheatList . Where (
cheat = > ! cheat . IsSeparator & & cheat . Domain = = _domain & & _secondaryHighlightedAddresses . Contains ( cheat . Address . Value ) ) ) ;
}
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
{
2015-01-18 16:00:20 +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 ( )
{
2014-02-10 01:15:11 +00:00
if ( _domain . Name = = "File on Disk" )
2012-09-02 23:12:00 +00:00
{
2015-08-23 16:34:13 +00:00
var extension = Path . GetExtension ( RomName ) ;
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
}
2014-03-01 15:21:17 +00:00
return "Binary (*.bin)|*.bin|All Files|*.*" ;
2012-09-02 23:12:00 +00:00
}
2015-08-23 16:34:13 +00:00
private string RomDirectory
{
get
{
string path = Global . Config . RecentRoms . MostRecent ;
if ( string . IsNullOrWhiteSpace ( path ) )
{
return path ;
}
if ( path . Contains ( "|" ) )
{
path = path . Split ( '|' ) . First ( ) ;
}
return Path . GetDirectoryName ( path ) ;
}
}
private string RomName
{
get
{
string path = Global . Config . RecentRoms . MostRecent ;
if ( string . IsNullOrWhiteSpace ( path ) )
{
return path ;
}
if ( path . Contains ( "|" ) )
{
path = path . Split ( '|' ) . Last ( ) ;
}
return Path . GetFileName ( path ) ;
}
}
2013-11-28 14:43:27 +00:00
private string GetBinarySaveFileFromUser ( )
2012-06-10 17:28:38 +00:00
{
2014-03-26 00:34:43 +00:00
var sfd = new SaveFileDialog
{
Filter = GetSaveFileFilter ( ) ,
2014-11-30 18:22:44 +00:00
RestoreDirectory = true ,
2015-08-23 16:34:13 +00:00
InitialDirectory = RomDirectory
} ;
if ( _domain . Name = = "File on Disk" )
{
sfd . FileName = RomName ;
}
else
{
sfd . FileName = PathManager . FilesystemSafeName ( Global . Game ) ;
}
var result = sfd . ShowHawkDialog ( ) ;
return result = = DialogResult . OK ? sfd . FileName : string . Empty ;
}
private string GetSaveFileFromUser ( )
{
var sfd = new SaveFileDialog
{
Filter = "Text (*.txt)|*.txt|All Files|*.*" ,
RestoreDirectory = true ,
InitialDirectory = RomDirectory
2014-03-26 00:34:43 +00:00
} ;
2012-06-10 17:28:38 +00:00
2014-11-30 18:22:44 +00:00
if ( _domain . Name = = "File on Disk" )
2013-11-28 14:43:27 +00:00
{
2015-08-23 16:34:13 +00:00
sfd . FileName = Path . GetFileNameWithoutExtension ( RomName ) + ".txt" ;
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
{
2014-11-30 18:22:44 +00:00
sfd . FileName = PathManager . FilesystemSafeName ( Global . Game ) ;
2013-11-28 14:43:27 +00:00
}
2012-06-10 17:28:38 +00:00
2013-11-28 22:39:00 +00:00
var result = sfd . ShowHawkDialog ( ) ;
2013-11-28 14:43:27 +00:00
2014-01-30 03:10:17 +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
{
2014-09-13 15:39:18 +00:00
_rowsVisible = ( MemoryViewerBox . Height - ( fontHeight * 2 ) - ( fontHeight / 2 ) ) / fontHeight ;
2015-01-18 16:00:20 +00:00
var totalRows = ( int ) ( ( _domain . Size + 15 ) / 16 ) ;
2013-10-09 15:28:45 +00:00
2013-12-21 20:06:52 +00:00
if ( totalRows < _rowsVisible )
{
_rowsVisible = totalRows ;
}
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
}
2015-01-18 18:13:38 +00:00
private long GetPointedAddress ( int x , int y )
2011-08-22 02:48:12 +00:00
{
2015-01-18 18:13:38 +00:00
long address ;
2013-11-28 22:06:38 +00:00
// Scroll value determines the first row
2015-01-18 20:15:03 +00:00
long i = HexScrollBar . Value ;
2014-09-13 15:39:18 +00:00
var rowoffset = y / fontHeight ;
2013-04-14 23:56:45 +00:00
i + = rowoffset ;
2015-01-01 14:54:26 +00:00
int colWidth = DataSize * 2 + 1 ;
2013-11-28 22:06:38 +00:00
2014-09-13 15:39:18 +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 )
{
2015-01-01 14:54:26 +00:00
column = ( x - start ) / ( fontWidth / DataSize ) ;
2012-09-10 23:52:42 +00:00
}
2012-09-03 00:49:59 +00:00
2015-01-01 14:54:26 +00:00
if ( i > = 0 & & i < = _maxRow & & column > = 0 & & column < ( 16 / DataSize ) )
2011-08-22 02:48:12 +00:00
{
2015-01-01 14:54:26 +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 ( )
{
2015-01-18 16:00:20 +00:00
if ( _addressOver > = 0 & & _addressOver < _domain . Size )
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
{
2015-01-01 14:54:26 +00:00
for ( var x = _addressOver ; x < _addressHighlighted ; x + = DataSize )
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
{
2015-01-01 14:54:26 +00:00
for ( var x = _addressHighlighted + DataSize ; x < = _addressOver ; x + = DataSize )
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
}
}
2015-12-20 19:51:07 +00:00
if ( ! IsVisible ( _addressOver ) )
{
var value = ( _addressOver / 16 ) + 1 - ( ( _addressOver / 16 ) < HexScrollBar . Value ? 1 : _rowsVisible ) ;
if ( value < 0 )
{
value = 0 ;
}
HexScrollBar . Value = ( int ) value ; // This will fail on a sufficiently large domain
}
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
}
2015-01-18 18:01:27 +00:00
private Point GetAddressCoordinates ( long address )
2011-08-23 22:22:24 +00:00
{
2015-01-01 14:54:26 +00:00
var extra = ( address % DataSize ) * fontWidth * 2 ;
2014-09-13 16:18:36 +00:00
var xOffset = AddressesLabel . Location . X + fontWidth / 2 - 2 ;
2014-09-13 14:50:58 +00:00
var yOffset = AddressesLabel . Location . Y ;
return new Point (
2015-01-18 18:01:27 +00:00
( int ) ( ( ( ( address % 16 ) / DataSize ) * ( fontWidth * ( DataSize * 2 + 1 ) ) ) + xOffset + extra ) ,
( int ) ( ( ( ( address / 16 ) - HexScrollBar . Value ) * fontHeight ) + yOffset )
2014-09-13 14:50:58 +00:00
) ;
2011-08-23 22:22:24 +00:00
}
2014-03-23 15:39:47 +00:00
// TODO: rename this, but it is a hack work around for highlighting misaligned addresses that result from highlighting on in a smaller data size and switching size
2015-01-18 18:01:27 +00:00
private bool NeedsExtra ( long val )
2014-03-23 15:39:47 +00:00
{
2015-01-01 14:54:26 +00:00
return val % DataSize > 0 ;
2014-03-23 15:39:47 +00:00
}
2012-09-03 00:49:59 +00:00
private int GetTextOffset ( )
{
2015-01-01 14:54:26 +00:00
int start = ( 16 / DataSize ) * fontWidth * ( DataSize * 2 + 1 ) ;
2014-09-13 15:39:18 +00:00
start + = AddressesLabel . Location . X + fontWidth / 2 ;
start + = fontWidth * 4 ;
2012-09-03 00:49:59 +00:00
return start ;
}
2015-01-18 18:01:27 +00:00
private long GetTextX ( long address )
2012-09-03 00:49:59 +00:00
{
2014-09-13 15:39:18 +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 ( )
{
2014-01-30 03:10:17 +00:00
var str = string . Empty ;
2015-01-01 14:54:26 +00:00
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
2015-01-18 18:01:27 +00:00
private void AddToSecondaryHighlights ( long address )
2013-11-28 20:02:32 +00:00
{
2015-12-20 19:51:07 +00:00
if ( address > = 0 & & address < _domain . Size & & ! _secondaryHighlightedAddresses . Contains ( address ) )
2013-11-28 20:02:32 +00:00
{
_secondaryHighlightedAddresses . Add ( address ) ;
}
}
2012-09-28 17:24:44 +00:00
2013-11-28 22:06:38 +00:00
// TODO: obsolete me
2015-01-18 18:01:27 +00:00
private void PokeWord ( long address , byte _1 , byte _2 )
2011-08-24 02:31:45 +00:00
{
2015-01-01 14:54:26 +00:00
if ( BigEndian )
2011-08-24 02:31:45 +00:00
{
2015-01-19 02:42:58 +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
{
2015-01-19 02:42:58 +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
2015-01-18 18:01:27 +00:00
private void IncrementAddress ( long address )
2013-11-28 20:02:32 +00:00
{
2015-01-19 02:42:58 +00:00
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
{
2015-01-01 14:54:26 +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 ,
2014-03-01 15:21:17 +00:00
( byte ) ( _domain . PeekByte ( address ) + 1 ) ) ;
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 ,
2015-01-01 14:54:26 +00:00
( ushort ) ( _domain . PeekWord ( address , BigEndian ) + 1 ) ,
BigEndian ) ;
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 ,
2015-01-01 14:54:26 +00:00
_domain . PeekDWord ( address , BigEndian ) + 1 ,
BigEndian ) ;
2012-03-08 18:33:57 +00:00
break ;
}
}
}
2015-01-18 18:01:27 +00:00
private void DecrementAddress ( long address )
2012-06-25 03:10:04 +00:00
{
2015-01-19 02:42:58 +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
{
2015-01-01 14:54:26 +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 ,
2014-03-01 15:21:17 +00:00
( byte ) ( _domain . PeekByte ( address ) - 1 ) ) ;
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 ,
2015-01-01 14:54:26 +00:00
( ushort ) ( _domain . PeekWord ( address , BigEndian ) - 1 ) ,
BigEndian ) ;
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 ,
2015-01-01 14:54:26 +00:00
_domain . PeekDWord ( address , BigEndian ) - 1 ,
BigEndian ) ;
2012-03-08 18:33:57 +00:00
break ;
}
}
}
2015-01-18 18:01:27 +00:00
private string ValueString ( long 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
{
2014-01-30 03:10:17 +00:00
return string . Format ( _digitFormatString , MakeValue ( address ) ) . Trim ( ) ;
2012-06-10 16:34:35 +00:00
}
2014-03-01 15:21: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
}
2014-03-01 15:21:17 +00:00
return string . Empty ;
2012-06-23 18:45:01 +00:00
}
2015-01-18 18:01:27 +00:00
private void HighlightSecondaries ( string value , long 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
2015-01-01 14:54:26 +00:00
var addrLength = DataSize * 2 ;
2013-11-28 20:02:32 +00:00
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
2015-01-01 14:54:26 +00:00
for ( var i = 0 ; i < numToHighlight ; i + = DataSize )
2013-11-28 20:02:32 +00:00
{
2015-01-01 14:54:26 +00:00
_secondaryHighlightedAddresses . Add ( found + DataSize + i ) ;
2013-11-28 20:02:32 +00:00
}
}
2012-06-23 18:45:01 +00:00
2014-03-23 20:27:20 +00:00
private bool LoadTable ( string path )
{
var file = new FileInfo ( path ) ;
if ( ! file . Exists )
{
return false ;
}
using ( var sr = file . OpenText ( ) )
{
string line ;
while ( ( line = sr . ReadLine ( ) ) ! = null )
{
var parts = line . Split ( '=' ) ;
_textTable . Add (
int . Parse ( parts [ 0 ] ,
NumberStyles . HexNumber ) , parts [ 1 ] . First ( ) ) ;
}
}
return true ;
}
2013-11-28 20:02:32 +00:00
#region Events
#region File Menu
private void FileSubMenu_DropDownOpened ( object sender , EventArgs e )
{
2014-02-10 01:15:11 +00:00
if ( _domain . Name = = "File on Disk" )
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
}
2014-03-23 22:47:28 +00:00
CloseTableFileMenuItem . Enabled = _textTable . Any ( ) ;
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
{
2014-02-10 01:01:36 +00:00
var path = GetBinarySaveFileFromUser ( ) ;
if ( ! string . IsNullOrEmpty ( path ) )
{
SaveFileBinary ( path ) ;
}
2013-11-28 20:02:32 +00:00
}
private void SaveAsTextMenuItem_Click ( object sender , EventArgs e )
{
var path = GetSaveFileFromUser ( ) ;
2014-01-30 03:10:17 +00:00
if ( ! string . IsNullOrWhiteSpace ( path ) )
2013-11-28 20:02:32 +00:00
{
var file = new FileInfo ( path ) ;
using ( var sw = new StreamWriter ( file . FullName ) )
{
var sb = new StringBuilder ( ) ;
2015-01-18 16:00:20 +00:00
for ( var i = 0 ; i < _domain . Size / 16 ; i + + )
2013-11-28 20:02:32 +00:00
{
for ( var j = 0 ; j < 16 ; j + + )
{
2014-01-30 03:10:17 +00:00
sb . Append ( string . Format ( "{0:X2} " , _domain . PeekByte ( ( i * 16 ) + j ) ) ) ;
2013-11-28 20:02:32 +00:00
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
sb . AppendLine ( ) ;
}
sw . WriteLine ( sb ) ;
}
}
}
2014-03-23 20:27:20 +00:00
private void LoadTableFileMenuItem_Click ( object sender , EventArgs e )
{
2015-02-22 03:36:54 +00:00
string romName ;
string intialDirectory ;
if ( Global . Config . RecentRoms . MostRecent . Contains ( '|' ) )
{
romName = Global . Config . RecentRoms . MostRecent . Split ( '|' ) . Last ( ) ;
intialDirectory = Global . Config . RecentRoms . MostRecent . Split ( '|' ) . First ( ) ;
}
else
{
romName = Global . Config . RecentRoms . MostRecent ;
intialDirectory = Path . GetDirectoryName ( PathManager . MakeAbsolutePath ( romName , null ) ) ;
}
2014-03-23 20:27:20 +00:00
var ofd = new OpenFileDialog
{
2015-02-22 03:36:54 +00:00
FileName = Path . GetFileNameWithoutExtension ( romName ) + ".tbl" ,
InitialDirectory = intialDirectory ,
2014-03-23 20:27:20 +00:00
Filter = "Text Table files (*.tbl)|*.tbl|All Files|*.*" ,
RestoreDirectory = false
} ;
2015-02-22 03:36:54 +00:00
var result = ofd . ShowHawkDialog ( ) ;
2014-03-23 20:27:20 +00:00
if ( result = = DialogResult . OK )
{
LoadTable ( ofd . FileName ) ;
2015-01-01 14:54:26 +00:00
RecentTables . Add ( ofd . FileName ) ;
2014-03-23 20:27:20 +00:00
UpdateValues ( ) ;
}
}
2014-03-23 22:47:28 +00:00
private void CloseTableFileMenuItem_Click ( object sender , EventArgs e )
{
_textTable . Clear ( ) ;
}
2014-03-23 20:27:20 +00:00
public void LoadFileFromRecent ( string path )
{
var result = LoadTable ( path ) ;
if ( ! result )
{
2015-01-01 14:54:26 +00:00
RecentTables . HandleLoadError ( path ) ;
2014-03-23 20:27:20 +00:00
}
else
{
2015-01-01 14:54:26 +00:00
RecentTables . Add ( path ) ;
2014-03-23 20:27:20 +00:00
UpdateValues ( ) ;
}
}
private void RecentTablesSubMenu_DropDownOpened ( object sender , EventArgs e )
{
RecentTablesSubMenu . DropDownItems . Clear ( ) ;
RecentTablesSubMenu . DropDownItems . AddRange (
2015-01-01 14:54:26 +00:00
RecentTables . RecentMenu ( LoadFileFromRecent , true ) ) ;
2014-03-23 20:27:20 +00:00
}
2013-11-28 20:02:32 +00:00
private void ExitMenuItem_Click ( object sender , EventArgs e )
{
Close ( ) ;
}
#endregion
#region Edit
private void EditMenuItem_DropDownOpened ( object sender , EventArgs e )
{
2015-01-25 15:42:07 +00:00
var data = Clipboard . GetDataObject ( ) ;
PasteMenuItem . Enabled =
_domain . CanPoke ( ) & &
( HighlightedAddress . HasValue | | _secondaryHighlightedAddresses . Any ( ) ) & &
data ! = null & &
data . GetDataPresent ( DataFormats . Text ) ;
2014-01-30 03:10:17 +00:00
FindNextMenuItem . Enabled = ! string . IsNullOrWhiteSpace ( _findStr ) ;
2013-11-28 20:02:32 +00:00
}
2015-09-29 07:29:19 +00:00
string MakeCopyExportString ( bool export )
2013-11-28 20:02:32 +00:00
{
2015-09-29 07:29:19 +00:00
//make room for an array with _secondaryHighlightedAddresses and optionally HighlightedAddress
long [ ] addresses = new long [ _secondaryHighlightedAddresses . Count + ( HighlightedAddress . HasValue ? 1 : 0 ) ] ;
//if there was actually nothing to do, return
if ( addresses . Length = = 0 )
return null ;
//fill the array with _secondaryHighlightedAddresses
for ( int i = 0 ; i < _secondaryHighlightedAddresses . Count ; i + + )
addresses [ i ] = _secondaryHighlightedAddresses [ i ] ;
//and add HighlightedAddress if present
if ( HighlightedAddress . HasValue )
addresses [ addresses . Length - 1 ] = HighlightedAddress . Value ;
//these need to be sorted. it's not just for HighlightedAddress, _secondaryHighlightedAddresses can even be jumbled
Array . Sort ( addresses ) ;
//find the maximum length of the exported string
int maximumLength = addresses . Length * ( export ? 3 : 2 ) + 8 ;
StringBuilder sb = new StringBuilder ( maximumLength ) ;
//generate it differently for export (as you see it) or copy (raw bytes)
if ( export )
for ( int i = 0 ; i < addresses . Length ; i + + )
{
sb . Append ( ValueString ( addresses [ i ] ) ) ;
if ( i ! = addresses . Length - 1 )
sb . Append ( ' ' ) ;
}
else
2013-12-21 17:51:07 +00:00
{
2015-09-29 07:29:19 +00:00
for ( int i = 0 ; i < addresses . Length ; i + + )
{
long start = addresses [ i ] ;
long end = addresses [ i ] + DataSize - 1 ;
for ( long a = start ; a < = end ; a + + )
sb . AppendFormat ( "{0:X2}" , MakeValue ( 1 , a ) ) ;
}
2013-12-21 17:51:07 +00:00
}
2015-09-29 07:29:19 +00:00
return sb . ToString ( ) ;
}
private void ExportMenuItem_Click ( object sender , EventArgs e )
{
var value = MakeCopyExportString ( true ) ;
if ( ! string . IsNullOrEmpty ( value ) )
Clipboard . SetDataObject ( value ) ;
}
private void CopyMenuItem_Click ( object sender , EventArgs e )
{
var value = MakeCopyExportString ( false ) ;
if ( ! string . IsNullOrEmpty ( value ) )
Clipboard . SetDataObject ( value ) ;
2013-11-28 20:02:32 +00:00
}
private void PasteMenuItem_Click ( object sender , EventArgs e )
{
2013-12-21 17:51:07 +00:00
var data = Clipboard . GetDataObject ( ) ;
2015-09-29 07:29:19 +00:00
if ( data ! = null & & ! data . GetDataPresent ( DataFormats . Text ) )
return ;
var clipboardRaw = ( string ) data . GetData ( DataFormats . Text ) ;
var hex = clipboardRaw . OnlyHex ( ) ;
2013-12-21 17:51:07 +00:00
2015-09-29 07:29:19 +00:00
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 ) ;
2013-12-21 17:51:07 +00:00
}
2015-09-29 07:29:19 +00:00
UpdateValues ( ) ;
}
2013-11-28 20:02:32 +00:00
private void FindMenuItem_Click ( object sender , EventArgs e )
{
_findStr = GetFindValues ( ) ;
if ( ! _hexFind . IsHandleCreated | | _hexFind . IsDisposed )
{
2015-01-31 01:16:41 +00:00
_hexFind = new HexFind
{
InitialLocation = PointToScreen ( AddressesLabel . Location ) ,
InitialValue = _findStr
} ;
2013-11-28 20:02:32 +00:00
_hexFind . Show ( ) ;
}
else
{
2015-01-31 01:16:41 +00:00
_hexFind . InitialValue = _findStr ;
2013-11-28 20:02:32 +00:00
_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 )
{
2015-01-01 14:54:26 +00:00
BigEndianMenuItem . Checked = BigEndian ;
DataSizeByteMenuItem . Checked = DataSize = = 1 ;
DataSizeWordMenuItem . Checked = DataSize = = 2 ;
DataSizeDWordMenuItem . Checked = DataSize = = 4 ;
2013-11-28 20:02:32 +00:00
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 =
HighlightedAddress . HasValue ;
2015-01-25 15:42:07 +00:00
PokeAddressMenuItem . Enabled =
FreezeAddressMenuItem . Enabled =
HighlightedAddress . HasValue & &
_domain . CanPoke ( ) ;
2013-11-28 20:02:32 +00:00
}
private void MemoryDomainsMenuItem_DropDownOpened ( object sender , EventArgs e )
{
2015-01-14 00:08:20 +00:00
MemoryDomainsMenuItem . DropDownItems . Clear ( ) ;
MemoryDomainsMenuItem . DropDownItems . AddRange (
MemoryDomains . MenuItems ( SetMemoryDomain , _domain . Name )
. ToArray ( ) ) ;
var romMenuItem = new ToolStripMenuItem
2013-11-28 20:02:32 +00:00
{
2015-01-14 00:08:20 +00:00
Text = _romDomain . Name ,
Checked = _domain . Name = = _romDomain . Name
} ;
MemoryDomainsMenuItem . DropDownItems . Add ( new ToolStripSeparator ( ) ) ;
MemoryDomainsMenuItem . DropDownItems . Add ( romMenuItem ) ;
romMenuItem . Click + = ( o , ev ) = > SetMemoryDomain ( _romDomain . Name ) ;
2013-11-28 20:02:32 +00:00
}
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 )
{
2015-01-01 14:54:26 +00:00
BigEndian ^ = true ;
2013-11-28 20:02:32 +00:00
UpdateValues ( ) ;
}
private void GoToAddressMenuItem_Click ( object sender , EventArgs e )
{
2014-07-28 02:31:51 +00:00
var inputPrompt = new InputPrompt
{
Text = "Go to Address" ,
2014-07-28 02:40:30 +00:00
StartLocation = this . ChildPointToScreen ( MemoryViewerBox ) ,
Message = "Enter a hexadecimal value"
2014-07-28 02:31:51 +00:00
} ;
2014-07-28 02:40:30 +00:00
2014-07-15 23:43:17 +00:00
var result = inputPrompt . ShowHawkDialog ( ) ;
2013-11-28 20:02:32 +00:00
2014-07-28 02:40:30 +00:00
if ( result = = DialogResult . OK & & inputPrompt . PromptText . IsHex ( ) )
2013-11-28 20:02:32 +00:00
{
2015-01-18 18:01:27 +00:00
GoToAddress ( long . Parse ( inputPrompt . PromptText , NumberStyles . HexNumber ) ) ;
2013-11-28 20:02:32 +00:00
}
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 = >
2014-03-01 15:21:17 +00:00
GlobalWin . Tools . RamWatch . AddWatch ( MakeWatch ( addr ) ) ) ;
2013-11-28 20:02:32 +00:00
}
private void FreezeAddressMenuItem_Click ( object sender , EventArgs e )
{
2015-01-25 15:42:07 +00:00
if ( ! _domain . CanPoke ( ) )
{
return ;
}
2013-11-28 20:02:32 +00:00
if ( HighlightedAddress . HasValue )
{
if ( IsFrozen ( HighlightedAddress . Value ) )
{
UnFreezeAddress ( HighlightedAddress . Value ) ;
2014-03-01 18:04:21 +00:00
UnfreezeSecondaries ( ) ;
2013-11-28 20:02:32 +00:00
}
else
{
FreezeAddress ( HighlightedAddress . Value ) ;
2014-03-01 18:04:21 +00:00
FreezeSecondaries ( ) ;
2013-11-28 20:02:32 +00:00
}
}
2013-12-21 16:42:36 +00:00
ToolHelpers . UpdateCheatRelatedTools ( null , null ) ;
2014-03-01 18:09:09 +00:00
MemoryViewerBox . Refresh ( ) ;
2013-11-28 20:02:32 +00:00
}
private void UnfreezeAllMenuItem_Click ( object sender , EventArgs e )
{
2014-03-23 13:21:48 +00:00
Global . CheatList . RemoveAll ( ) ;
2013-11-28 20:02:32 +00:00
}
private void PokeAddressMenuItem_Click ( object sender , EventArgs e )
{
2015-01-25 15:42:07 +00:00
if ( ! _domain . CanPoke ( ) )
{
return ;
}
2015-01-18 18:01:27 +00:00
var addresses = new List < long > ( ) ;
2013-11-28 20:02:32 +00:00
if ( HighlightedAddress . HasValue )
{
addresses . Add ( HighlightedAddress . Value ) ;
}
if ( _secondaryHighlightedAddresses . Any ( ) )
{
addresses . AddRange ( _secondaryHighlightedAddresses ) ;
}
if ( addresses . Any ( ) )
{
var poke = new RamPoke
{
2015-01-19 01:49:56 +00:00
InitialLocation = this . ChildPointToScreen ( AddressLabel ) ,
2015-01-19 01:39:47 +00:00
ParentTool = this
2013-11-28 20:02:32 +00:00
} ;
2013-11-28 22:06:38 +00:00
var watches = addresses . Select (
address = > Watch . GenerateWatch (
_domain ,
2015-01-19 02:42:58 +00:00
address ,
2015-11-28 21:47:16 +00:00
( WatchSize ) DataSize ,
Client . Common . DisplayType . Hex ,
2015-01-01 14:54:26 +00:00
BigEndian ) ) ;
2013-11-28 20:02:32 +00:00
2013-11-28 22:06:38 +00:00
poke . SetWatch ( watches ) ;
2013-11-28 22:39:00 +00:00
poke . ShowHawkDialog ( ) ;
2013-11-28 20:02:32 +00:00
UpdateValues ( ) ;
}
}
#endregion
#region Settings Menu
private void SetColorsMenuItem_Click ( object sender , EventArgs e )
{
2013-11-28 22:39:00 +00:00
new HexColorsForm ( ) . ShowHawkDialog ( ) ;
2013-11-28 20:02:32 +00:00
}
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 ;
}
#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 ;
}
2015-01-18 18:01:27 +00:00
long newHighlighted ;
2013-11-28 20:02:32 +00:00
switch ( e . KeyCode )
{
case Keys . Up :
newHighlighted = _addressHighlighted - 16 ;
if ( e . Modifiers = = Keys . Shift )
{
2015-01-01 14:54:26 +00:00
for ( var i = newHighlighted + DataSize ; i < = _addressHighlighted ; i + = DataSize )
2013-11-28 20:02:32 +00:00
{
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 )
{
2015-01-01 14:54:26 +00:00
for ( var i = _addressHighlighted ; i < newHighlighted ; i + = DataSize )
2013-11-28 20:02:32 +00:00
{
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 :
2015-01-01 14:54:26 +00:00
newHighlighted = _addressHighlighted - ( 1 * DataSize ) ;
2013-11-28 20:02:32 +00:00
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 :
2015-01-01 14:54:26 +00:00
newHighlighted = _addressHighlighted + ( 1 * DataSize ) ;
2013-11-28 20:02:32 +00:00
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 )
{
2015-01-01 14:54:26 +00:00
for ( var i = newHighlighted + 1 ; i < = _addressHighlighted ; i + = DataSize )
2013-11-28 20:02:32 +00:00
{
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 )
{
2015-01-01 14:54:26 +00:00
for ( var i = _addressHighlighted + 1 ; i < newHighlighted ; i + = DataSize )
2013-11-28 20:02:32 +00:00
{
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 )
{
2015-01-01 14:54:26 +00:00
for ( var i = 1 ; i < = _addressHighlighted ; i + = DataSize )
2013-11-28 20:02:32 +00:00
{
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 :
2015-01-18 18:59:23 +00:00
newHighlighted = _domain . Size - DataSize ;
2013-11-28 20:02:32 +00:00
if ( e . Modifiers = = Keys . Shift )
{
2015-01-01 14:54:26 +00:00
for ( var i = _addressHighlighted ; i < newHighlighted ; i + = DataSize )
2013-11-28 20:02:32 +00:00
{
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 )
{
2014-03-23 13:21:48 +00:00
Global . CheatList . RemoveAll ( ) ;
2013-11-28 20:02:32 +00:00
}
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 ;
}
}
2014-01-31 04:26:39 +00:00
private void HexEditor_KeyPress ( object sender , KeyPressEventArgs e )
2013-11-28 20:02:32 +00:00
{
2014-01-31 04:26:39 +00:00
if ( ! IsHexKeyCode ( e . KeyChar ) )
2013-11-28 20:02:32 +00:00
{
e . Handled = true ;
return ;
}
2014-05-04 14:10:28 +00:00
if ( ( ModifierKeys & ( Keys . Control | Keys . Shift | Keys . Alt ) ) ! = 0 )
2013-11-28 20:02:32 +00:00
{
return ;
}
2015-01-25 15:42:07 +00:00
if ( ! _domain . CanPoke ( ) )
{
return ;
}
2015-01-01 14:54:26 +00:00
switch ( DataSize )
2013-11-28 20:02:32 +00:00
{
default :
case 1 :
if ( _nibbles [ 0 ] = = 'G' )
{
2014-01-31 04:26:39 +00:00
_nibbles [ 0 ] = ForceCorrectKeyString ( e . KeyChar ) ;
2013-11-28 20:02:32 +00:00
}
else
{
2014-01-31 04:26:39 +00:00
var temp = _nibbles [ 0 ] . ToString ( ) + ForceCorrectKeyString ( e . KeyChar ) ;
2013-11-28 20:02:32 +00:00
var x = byte . Parse ( temp , NumberStyles . HexNumber ) ;
_domain . PokeByte ( _addressHighlighted , x ) ;
ClearNibbles ( ) ;
SetHighlighted ( _addressHighlighted + 1 ) ;
UpdateValues ( ) ;
2015-10-18 23:44:57 +00:00
Refresh ( ) ;
2013-11-28 20:02:32 +00:00
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
break ;
case 2 :
if ( _nibbles [ 0 ] = = 'G' )
{
2014-01-31 04:26:39 +00:00
_nibbles [ 0 ] = ForceCorrectKeyString ( e . KeyChar ) ;
2013-11-28 20:02:32 +00:00
}
else if ( _nibbles [ 1 ] = = 'G' )
{
2014-01-31 04:26:39 +00:00
_nibbles [ 1 ] = ForceCorrectKeyString ( e . KeyChar ) ;
2013-11-28 20:02:32 +00:00
}
else if ( _nibbles [ 2 ] = = 'G' )
{
2014-01-31 04:26:39 +00:00
_nibbles [ 2 ] = ForceCorrectKeyString ( e . KeyChar ) ;
2013-11-28 20:02:32 +00:00
}
else if ( _nibbles [ 3 ] = = 'G' )
{
var temp = _nibbles [ 0 ] . ToString ( ) + _nibbles [ 1 ] ;
var x1 = byte . Parse ( temp , NumberStyles . HexNumber ) ;
2014-01-31 04:26:39 +00:00
var temp2 = _nibbles [ 2 ] . ToString ( ) + ( ( char ) e . KeyChar ) ;
2013-11-28 20:02:32 +00:00
var x2 = byte . Parse ( temp2 , NumberStyles . HexNumber ) ;
PokeWord ( _addressHighlighted , x1 , x2 ) ;
ClearNibbles ( ) ;
SetHighlighted ( _addressHighlighted + 2 ) ;
UpdateValues ( ) ;
2015-10-18 23:44:57 +00:00
Refresh ( ) ;
2013-11-28 20:02:32 +00:00
}
2013-11-28 22:06:38 +00:00
2013-11-28 20:02:32 +00:00
break ;
case 4 :
if ( _nibbles [ 0 ] = = 'G' )
{
2014-01-31 04:26:39 +00:00
_nibbles [ 0 ] = ForceCorrectKeyString ( e . KeyChar ) ;
2013-11-28 20:02:32 +00:00
}
else if ( _nibbles [ 1 ] = = 'G' )
{
2014-01-31 04:26:39 +00:00
_nibbles [ 1 ] = ForceCorrectKeyString ( e . KeyChar ) ;
2013-11-28 20:02:32 +00:00
}
else if ( _nibbles [ 2 ] = = 'G' )
{
2014-01-31 04:26:39 +00:00
_nibbles [ 2 ] = ForceCorrectKeyString ( e . KeyChar ) ;
2013-11-28 20:02:32 +00:00
}
else if ( _nibbles [ 3 ] = = 'G' )
{
2014-01-31 04:26:39 +00:00
_nibbles [ 3 ] = ForceCorrectKeyString ( e . KeyChar ) ;
2013-11-28 20:02:32 +00:00
}
else if ( _nibbles [ 4 ] = = 'G' )
{
2014-01-31 04:26:39 +00:00
_nibbles [ 4 ] = ForceCorrectKeyString ( e . KeyChar ) ;
2013-11-28 20:02:32 +00:00
}
else if ( _nibbles [ 5 ] = = 'G' )
{
2014-01-31 04:26:39 +00:00
_nibbles [ 5 ] = ForceCorrectKeyString ( e . KeyChar ) ;
2013-11-28 20:02:32 +00:00
}
else if ( _nibbles [ 6 ] = = 'G' )
{
2014-01-31 04:26:39 +00:00
_nibbles [ 6 ] = ForceCorrectKeyString ( e . KeyChar ) ;
2013-11-28 20:02:32 +00:00
}
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
2014-01-31 04:26:39 +00:00
var temp4 = _nibbles [ 6 ] . ToString ( ) + ForceCorrectKeyString ( e . KeyChar ) ;
2013-11-28 20:02:32 +00:00
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 ( ) ;
2015-10-18 23:44:57 +00:00
Refresh ( ) ;
2013-11-28 20:02:32 +00:00
}
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-12-21 17:51:07 +00:00
private void ViewerContextMenuStrip_Opening ( object sender , CancelEventArgs e )
{
var data = Clipboard . GetDataObject ( ) ;
CopyContextItem . Visible =
AddToRamWatchContextItem . Visible =
2015-01-25 15:42:07 +00:00
HighlightedAddress . HasValue | | _secondaryHighlightedAddresses . Any ( ) ;
FreezeContextItem . Visible =
2013-12-21 17:51:07 +00:00
PokeContextItem . Visible =
IncrementContextItem . Visible =
DecrementContextItem . Visible =
ContextSeparator2 . Visible =
2015-01-25 15:42:07 +00:00
( HighlightedAddress . HasValue | | _secondaryHighlightedAddresses . Any ( ) ) & &
_domain . CanPoke ( ) ;
2013-12-21 17:51:07 +00:00
UnfreezeAllContextItem . Visible = Global . CheatList . ActiveCount > 0 ;
2015-01-25 15:42:07 +00:00
PasteContextItem . Visible = _domain . CanPoke ( ) & & data ! = null & & data . GetDataPresent ( DataFormats . Text ) ;
2013-12-21 17:51:07 +00:00
ContextSeparator1 . Visible =
HighlightedAddress . HasValue | |
_secondaryHighlightedAddresses . Any ( ) | |
( data ! = null & & data . GetDataPresent ( DataFormats . Text ) ) ;
if ( HighlightedAddress . HasValue & & IsFrozen ( HighlightedAddress . Value ) )
{
FreezeContextItem . Text = "Un&freeze" ;
FreezeContextItem . Image = Properties . Resources . Unfreeze ;
}
else
{
FreezeContextItem . Text = "&Freeze" ;
FreezeContextItem . Image = Properties . Resources . Freeze ;
}
2015-01-22 01:15:06 +00:00
2015-01-25 15:42:07 +00:00
toolStripMenuItem1 . Visible = viewN64MatrixToolStripMenuItem . Visible = DataSize = = 4 ;
2013-12-21 17:51:07 +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
{
2015-01-25 15:42:07 +00:00
if ( ! _domain . CanPoke ( ) )
{
return ;
}
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
{
2015-01-25 15:42:07 +00:00
if ( ! _domain . CanPoke ( ) )
{
return ;
}
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 )
{
2015-01-01 14:54:26 +00:00
var gaps = ( int ) cheat . Size - ( int ) DataSize ;
2014-07-28 01:01:32 +00:00
2015-11-28 21:47:16 +00:00
if ( cheat . Size = = WatchSize . DWord & & DataSize = = 2 )
2014-07-28 01:01:32 +00:00
{
gaps - = 1 ;
}
if ( gaps < 0 ) { gaps = 0 ; }
2014-09-13 15:39:18 +00:00
var width = ( fontWidth * 2 * ( int ) cheat . Size ) + ( gaps * fontWidth ) ;
2014-07-28 01:01:32 +00:00
2014-09-13 15:39:18 +00:00
var rect = new Rectangle ( GetAddressCoordinates ( cheat . Address ? ? 0 ) , new Size ( width , fontHeight ) ) ;
2013-11-28 20:02:32 +00:00
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 ) )
{
2014-09-13 16:18:36 +00:00
// Create a slight offset to increase rectangle sizes
2013-11-28 20:02:32 +00:00
var point = GetAddressCoordinates ( _addressHighlighted ) ;
2015-01-18 18:01:27 +00:00
var textX = ( int ) GetTextX ( _addressHighlighted ) ;
2013-11-28 20:02:32 +00:00
var textpoint = new Point ( textX , point . Y ) ;
2012-06-10 22:43:43 +00:00
2015-01-01 14:54:26 +00:00
var rect = new Rectangle ( point , new Size ( fontWidth * 2 * DataSize + ( NeedsExtra ( _addressHighlighted ) ? fontWidth : 0 ) + 2 , fontHeight ) ) ;
2013-11-28 20:02:32 +00:00
e . Graphics . DrawRectangle ( new Pen ( Brushes . Black ) , rect ) ;
2012-06-10 22:43:43 +00:00
2015-01-01 14:54:26 +00:00
var textrect = new Rectangle ( textpoint , new Size ( fontWidth * DataSize , fontHeight ) ) ;
2012-06-19 02:42:07 +00:00
2015-01-18 18:59:23 +00:00
if ( Global . CheatList . IsActive ( _domain , _addressHighlighted ) )
2013-11-28 20:02:32 +00:00
{
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 )
{
2015-01-19 01:49:56 +00:00
if ( IsVisible ( address ) )
{
var point = GetAddressCoordinates ( address ) ;
var textX = ( int ) GetTextX ( address ) ;
var textpoint = new Point ( textX , point . Y ) ;
2012-06-19 02:42:07 +00:00
2015-01-19 01:49:56 +00:00
var rect = new Rectangle ( point , new Size ( fontWidth * 2 * DataSize + 2 , fontHeight ) ) ;
e . Graphics . DrawRectangle ( new Pen ( Brushes . Black ) , rect ) ;
2012-06-23 18:45:01 +00:00
2015-01-19 01:49:56 +00:00
var textrect = new Rectangle ( textpoint , new Size ( fontWidth * DataSize , fontHeight ) ) ;
2012-06-23 18:45:01 +00:00
2015-01-19 02:42:58 +00:00
if ( Global . CheatList . IsActive ( _domain , address ) )
2015-01-19 01:49:56 +00:00
{
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 20:02:32 +00:00
}
}
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 ( ) ;
2015-12-20 19:51:07 +00:00
UpdateFormText ( ) ;
2013-11-28 20:02:32 +00:00
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
{
2015-01-18 20:15:03 +00:00
var pointedAddress = GetPointedAddress ( e . X , e . Y ) ;
if ( pointedAddress > = 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
{
2015-01-18 20:15:03 +00:00
if ( pointedAddress = = _addressHighlighted )
2012-10-15 00:56:47 +00:00
{
ClearHighlighted ( ) ;
}
2015-01-18 20:15:03 +00:00
else if ( _secondaryHighlightedAddresses . Contains ( pointedAddress ) )
2012-10-15 00:56:47 +00:00
{
2015-01-18 20:15:03 +00:00
_secondaryHighlightedAddresses . Remove ( pointedAddress ) ;
2012-10-15 00:56:47 +00:00
}
else
{
2015-01-18 20:15:03 +00:00
_secondaryHighlightedAddresses . Add ( pointedAddress ) ;
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
{
2015-01-18 20:15:03 +00:00
SetHighlighted ( pointedAddress ) ;
2013-11-28 14:43:27 +00:00
_secondaryHighlightedAddresses . Clear ( ) ;
2014-01-30 03:10:17 +00:00
_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
2014-09-13 13:50:29 +00:00
bool _programmaticallyChangingValue = false ;
2013-11-28 20:02:32 +00:00
private void HexScrollBar_ValueChanged ( object sender , EventArgs e )
2013-11-28 14:58:15 +00:00
{
2014-09-13 13:50:29 +00:00
if ( ! _programmaticallyChangingValue )
{
if ( HexScrollBar . Value < 0 )
{
_programmaticallyChangingValue = true ;
HexScrollBar . Value = 0 ;
_programmaticallyChangingValue = false ;
}
UpdateValues ( ) ;
}
2013-11-28 14:58:15 +00:00
}
#endregion
2013-11-28 20:02:32 +00:00
2015-01-22 01:15:06 +00:00
private void HexMenuStrip_ItemClicked ( object sender , ToolStripItemClickedEventArgs e )
{
}
2013-11-28 14:58:15 +00:00
#endregion
2015-01-22 01:15:06 +00:00
private void viewN64MatrixToolStripMenuItem_Click ( object sender , EventArgs e )
{
if ( ! HighlightedAddress . HasValue )
return ;
bool bigend = true ;
long addr = HighlightedAddress . Value ;
//ushort = _domain.PeekWord(addr,bigend);
float [ , ] matVals = new float [ 4 , 4 ] ;
2015-01-25 13:24:18 +00:00
for ( int i = 0 ; i < 4 ; i + + )
{
for ( int j = 0 ; j < 4 ; j + + )
{
ushort hi = _domain . PeekWord ( ( ( addr + ( i < < 3 ) + ( j < < 1 ) ) ^ 0x0 ) , bigend ) ;
2015-01-22 01:15:06 +00:00
ushort lo = _domain . PeekWord ( ( ( addr + ( i < < 3 ) + ( j < < 1 ) + 32 ) ^ 0x0 ) , bigend ) ;
2015-01-25 13:24:18 +00:00
matVals [ i , j ] = ( int ) ( ( ( hi < < 16 ) | lo ) ) / 65536.0f ;
}
2015-01-22 01:15:06 +00:00
}
//if needed
//var mat = new SlimDX.Matrix();
//mat.M11 = matVals[0, 0]; mat.M12 = matVals[0, 1]; mat.M13 = matVals[0, 2]; mat.M14 = matVals[0, 3];
//mat.M21 = matVals[1, 0]; mat.M22 = matVals[1, 1]; mat.M23 = matVals[1, 2]; mat.M24 = matVals[1, 3];
//mat.M31 = matVals[2, 0]; mat.M32 = matVals[2, 1]; mat.M33 = matVals[2, 2]; mat.M34 = matVals[2, 3];
//mat.M41 = matVals[3, 0]; mat.M42 = matVals[3, 1]; mat.M43 = matVals[3, 2]; mat.M44 = matVals[3, 3];
//MessageBox.Show(mat.ToString());
StringWriter sw = new StringWriter ( ) ;
for ( int i = 0 ; i < 4 ; i + + )
sw . WriteLine ( "{0,18:0.00000} {1,18:0.00000} {2,18:0.00000} {3,18:0.00000}" , matVals [ i , 0 ] , matVals [ i , 1 ] , matVals [ i , 2 ] , matVals [ i , 3 ] ) ;
var str = sw . ToString ( ) ;
MessageBox . Show ( str ) ;
}
2015-09-29 07:29:19 +00:00
2011-06-19 23:39:25 +00:00
}
2012-06-25 03:10:04 +00:00
}