📄 cheatdlg.cpp
字号:
//
// 僠乕僩僟僀傾儘僌僋儔僗
//
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shellapi.h>
#include <commdlg.h>
#include <mbstring.h>
#include <string>
using namespace std;
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Pathlib.h"
#include "Config.h"
#include "Wnd.h"
#include "CheatDlg.h"
#include "EmuThread.h"
//
// 僒乕僠僟僀傾儘僌
//
DLG_MESSAGE_BEGIN(CSearchDlg)
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
DLG_ON_MESSAGE( WM_ACTIVATE, OnActivate )
DLG_ON_MESSAGE( WM_CLOSE, OnClose )
DLG_ON_MESSAGE( WM_CONTEXTMENU, OnContextMenu )
DLG_COMMAND_BEGIN()
//DLG_ON_COMMAND( IDOK, OnOK )
//DLG_ON_COMMAND( IDCANCEL, OnCancel )
DLG_ON_COMMAND( IDC_SCH_START, OnStart )
DLG_ON_COMMAND( IDC_SCH_UPDATE, OnUpdate )
DLG_ON_COMMAND( IDC_SCH_UNDO, OnUndo )
DLG_ON_COMMAND_RANGE( IDC_SCH_RADIX_DEC, IDC_SCH_RADIX_HEX, OnRadixCommand )
DLG_ON_COMMAND_RANGE( IDC_SCH_LENGTH_1BYTE, IDC_SCH_LENGTH_4BYTE, OnLengthCommand )
DLG_ON_COMMAND_RANGE( IDC_SCH_EQUAL, IDC_SCH_GRATEREQUAL, OnSearchCommand )
DLG_ON_COMMAND( IDC_SCH_SEARCH, OnSearchData )
DLG_ON_COMMAND( IDC_SCH_WRITE, OnWriteData )
DLG_ON_COMMAND( ID_SCH_APPEND, OnCodeAppend )
//DLG_ON_COMMAND( IDC_VER_WEBSITE, OnWebsite )
DLG_COMMAND_END()
// Notify 儊僢僙乕僕
DLG_NOTIFY_BEGIN()
DLG_ON_NOTIFY( IDC_SCH_RESULT_LIST, NM_DBLCLK, OnDoubleClickListView )
DLG_NOTIFY_END()
DLG_MESSAGE_END()
BOOL CSearchDlg::Create( HWND hWndParent )
{
m_hMenu = NULL;
m_bShortCutDisable = FALSE;
m_hWnd = ::CreateDialogParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_SEARCH),
hWndParent, g_DlgProc, (LPARAM)this );
if( !m_hWnd )
return FALSE;
// 儌乕僪儗僗僟僀傾儘僌儕僗僩偵壛偊傞
CWndList::Add( this );
return TRUE;
}
void CSearchDlg::Destroy()
{
if( m_hWnd ) {
// 埵抲曐懚
::GetWindowRect( m_hWnd, &Config.general.rcSearchDlgPos );
// 儊僯儏乕嶍彍
if( m_hMenu )
::DestroyMenu( m_hMenu );
m_hMenu = NULL;
// 儌乕僪儗僗僟僀傾儘僌儕僗僩偐傜嶍彍
CWndList::Del( this );
::DestroyWindow( m_hWnd );
m_hWnd = NULL;
}
}
void CSearchDlg::OnListUpdate()
{
HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_SCH_RESULT_LIST );
ListView_DeleteAllItems( hWndCtrl );
INT i;
DWORD data;
CHAR szStr[256], szTemp[256];
INT index;
LVITEM lvitem;
lvitem.mask = LVIF_TEXT|LVIF_PARAM;
lvitem.iSubItem = 0;
index = 0;
if( m_nRadix == 10 ) {
::wsprintf( szTemp, "%%lu" );
} else {
::wsprintf( szTemp, "%%0%dX", (m_nLength+1)*2 );
}
if( IsBTNCHECK( IDC_SCH_AREA_RAM ) ) {
for( i = 0; i < 0x0800-m_nLength; i++ ) {
if( m_Result.RAM_F[i] ) {
// Address
::wsprintf( szStr, "%04X", i );
lvitem.pszText = szStr;
lvitem.iItem = index;
lvitem.lParam = (LPARAM)i;
ListView_InsertItem( hWndCtrl, &lvitem );
// OLD
data = GetSearchMemoryOld( m_nLength, i );
::wsprintf( szStr, szTemp, data );
ListView_SetItemText( hWndCtrl, index, 1, (LPSTR)szStr );
// NEW
data = GetSearchMemory( m_nLength, i );
::wsprintf( szStr, szTemp, data );
ListView_SetItemText( hWndCtrl, index, 2, (LPSTR)szStr );
index++;
}
}
}
if( IsBTNCHECK( IDC_SCH_AREA_SRAM ) ) {
for( i = 0; i < 0x2000-m_nLength; i++ ) {
if( m_Result.SRAM_F[i] ) {
// Address
::wsprintf( szStr, "%04X", i+0x6000 );
lvitem.pszText = szStr;
lvitem.iItem = index;
lvitem.lParam = (LPARAM)(i+0x6000);
ListView_InsertItem( hWndCtrl, &lvitem );
// OLD
data = GetSearchMemoryOld( m_nLength, i+0x6000 );
::wsprintf( szStr, szTemp, data );
ListView_SetItemText( hWndCtrl, index, 1, (LPSTR)szStr );
// NEW
data = GetSearchMemory( m_nLength, i+0x6000 );
::wsprintf( szStr, szTemp, data );
ListView_SetItemText( hWndCtrl, index, 2, (LPSTR)szStr );
index++;
}
}
}
}
DWORD CSearchDlg::GetNesMemory( INT length, DWORD addr )
{
DWORD data = 0;
for( INT i = 0; i <= length; i++ ) {
data |= (DWORD)Emu.GetNES()->Read( (WORD)addr+i )*(1<<(i*8));
}
return data;
}
DWORD CSearchDlg::GetSearchMemory( INT length, DWORD addr )
{
BYTE* lpRAM;
if( addr < 0x0800 ) {
lpRAM = m_Result.RAM_N;
} else if( addr < 0x8000 ) {
lpRAM = m_Result.SRAM_N - 0x6000;
}
DWORD data = 0;
for( INT i = 0; i <= length; i++ ) {
data |= (DWORD)lpRAM[ (WORD)addr+i ]*(1<<(i*8));
}
return data;
}
DWORD CSearchDlg::GetSearchMemoryOld( INT length, DWORD addr )
{
BYTE* lpRAM;
if( addr < 0x0800 ) {
lpRAM = m_Result.RAM_O;
} else if( addr < 0x8000 ) {
lpRAM = m_Result.SRAM_O - 0x6000;
}
DWORD data = 0;
for( INT i = 0; i <= length; i++ ) {
data |= (DWORD)lpRAM[ (WORD)addr+i ]*(1<<(i*8));
}
return data;
}
BOOL CSearchDlg::CompareData( INT type, DWORD dataA, DWORD dataB )
{
switch( type ) {
case 0: // EQUAL
if( dataA == dataB )
return TRUE;
break;
case 1: // NOTEQUAL
if( dataA != dataB )
return TRUE;
break;
case 2: // LESS
if( dataA < dataB )
return TRUE;
break;
case 3: // GRATER
if( dataA > dataB )
return TRUE;
break;
case 4: // LESSEQUAL
if( dataA <= dataB )
return TRUE;
break;
case 5: // GRATEREQUAL
if( dataA >= dataB )
return TRUE;
break;
}
return FALSE;
}
BOOL CSearchDlg::CompareRange( INT length, DWORD dataA, DWORD dataB, DWORD range )
{
DWORD dmin, dmax;
switch( length ) {
case 0: // 1byte
dataA &= 0x000000FF;
dataB &= 0x000000FF;
range &= 0x000000FF;
dmin = dataB-range;
dmax = dataB+range;
if( dataB < dmin )
dmin = 0;
if( dataB > dmax )
dmax = 0xFF;
break;
case 1: // 2byte
dataA &= 0x0000FFFF;
dataB &= 0x0000FFFF;
range &= 0x0000FFFF;
dmin = dataB-range;
dmax = dataB+range;
if( dataB < dmin )
dmin = 0;
if( dataB > dmax )
dmax = 0xFFFF;
break;
case 2: // 3byte
dataA &= 0x00FFFFFF;
dataB &= 0x00FFFFFF;
range &= 0x00FFFFFF;
dmin = dataB-range;
dmax = dataB+range;
if( dataB < dmin )
dmin = 0;
if( dataB > dmax )
dmax = 0xFFFFFF;
break;
case 3: // 4byte
// dataA &= 0xFFFFFFFF;
// dataB &= 0xFFFFFFFF;
// range &= 0xFFFFFFFF;
dmin = dataB-range;
dmax = dataB+range;
if( dataB < dmin )
dmin = 0;
if( dataB > dmax )
dmax = 0xFFFFFFFF;
break;
}
if( dataA >= dmin && dataA <= dmax )
return TRUE;
return FALSE;
}
DLGMSG CSearchDlg::OnInitDialog( DLGMSGPARAM )
{
// DEBUGOUT( "CSearchDlg::OnInitDialog\n" );
m_nRadix = 10;
m_nLength = 0;
HWND hWndCtrl;
INT i, j;
CHAR szStr[256];
// 埵抲廋惓
if( Config.general.rcSearchDlgPos.right-Config.general.rcSearchDlgPos.left != 0
&& Config.general.rcSearchDlgPos.bottom-Config.general.rcSearchDlgPos.top != 0 ) {
::SetWindowPos( m_hWnd, HWND_NOTOPMOST, Config.general.rcSearchDlgPos.left, Config.general.rcSearchDlgPos.top,
0, 0, SWP_NOSIZE | SWP_NOZORDER );
}
// 僒乕僠寢壥弶婜壔
::memset( &m_Result, 0, sizeof(m_Result) );
::memset( &m_ResultOld, 0, sizeof(m_ResultOld) );
// 婎悢儔僕僆儃僞儞
BTNCHECK( IDC_SCH_RADIX_DEC, TRUE );
// BTNCHECK( IDC_SCH_RADIX_HEX, FALSE );
// 僨乕僞挿儔僕僆儃僞儞
BTNCHECK( IDC_SCH_LENGTH_1BYTE, TRUE );
// BTNCHECK( IDC_SCH_LENGTH_2BYTE, FALSE );
// BTNCHECK( IDC_SCH_LENGTH_3BYTE, FALSE );
// BTNCHECK( IDC_SCH_LENGTH_4BYTE, FALSE );
// 専嶕斖埻僠僃僢僋儃僢僋僗
BTNCHECK( IDC_SCH_AREA_RAM, TRUE );
BTNCHECK( IDC_SCH_AREA_SRAM, FALSE );
BTNCHECK( IDC_SCH_AREA_EXRAM, FALSE );
// 儕僗僩價儏乕
hWndCtrl = ::GetDlgItem( m_hWnd, IDC_SCH_RESULT_LIST );
ListView_SetExtendedListViewStyle( hWndCtrl, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES );
ListView_DeleteAllItems( hWndCtrl );
ListView_SetItemCount( hWndCtrl, 16384 );
// 僿僢僟僐儞僩儘乕儖偺愝掕
LVCOLUMN lvColumn;
lvColumn.mask = LVCF_FMT|LVCF_TEXT|LVCF_SUBITEM|LVCF_WIDTH;
lvColumn.fmt = LVCFMT_RIGHT;
lvColumn.pszText = szStr;
RECT rc;
::GetClientRect( hWndCtrl, &rc );
INT nWidth = RCWIDTH(rc) - ::GetSystemMetrics( SM_CXVSCROLL );
CApp::LoadString( IDS_CHT_ADDRESS, szStr, sizeof(szStr) );
lvColumn.iSubItem = 0;
lvColumn.cx = nWidth*2/8;
ListView_InsertColumn( hWndCtrl, 0, &lvColumn );
CApp::LoadString( IDS_CHT_DATA_OLD, szStr, sizeof(szStr) );
lvColumn.iSubItem = 1;
lvColumn.cx = nWidth*3/8;
ListView_InsertColumn( hWndCtrl, 1, &lvColumn );
CApp::LoadString( IDS_CHT_DATA_NOW, szStr, sizeof(szStr) );
lvColumn.iSubItem = 2;
lvColumn.cx = nWidth*3/8;
ListView_InsertColumn( hWndCtrl, 2, &lvColumn );
// 僨乕僞摍愝掕
::SetDlgItemText( m_hWnd, IDC_SCH_DATA_EDIT, "0" );
::SetDlgItemText( m_hWnd, IDC_SCH_WADDR_EDIT, "0000" );
::SetDlgItemText( m_hWnd, IDC_SCH_WDATA_EDIT, "0" );
// Undo儃僞儞傪僨傿僙乕僽儖
::EnableWindow( ::GetDlgItem( m_hWnd, IDC_SCH_UNDO ), FALSE );
// 弶婜僨乕僞愝掕
for( i = 0; i < 0x0800; i++ ) {
m_Result.RAM_N[i] = m_Result.RAM_O[i] = Emu.GetNES()->Read( (WORD)i );
m_Result.RAM_F[i] = 1;
}
j = 0;
BYTE da = Emu.GetNES()->Read( 0x6000 );
for( i = 0; i < 0x2000; i++ ) {
m_Result.SRAM_N[i] = m_Result.SRAM_O[i] = Emu.GetNES()->Read( (WORD)i+0x6000 );
m_Result.SRAM_F[i] = 1;
if( m_Result.SRAM_N[i] != da )
j = 1;
}
// SRAM偑巊梡偝傟偰偄偨傜帺摦偱ON偵
if( j ) {
BTNCHECK( IDC_SCH_AREA_SRAM, TRUE );
}
// 儊僯儏乕
m_hMenu = CApp::LoadMenu( IDR_SCH_MENU );
m_hSubMenu = ::GetSubMenu( m_hMenu, 0 );
OnListUpdate();
return TRUE;
}
DLGMSG CSearchDlg::OnActivate( DLGMSGPARAM )
{
// DEBUGOUT( "CSearchDlg::OnActivate\n" );
if( LOWORD(wParam) == WA_INACTIVE ) {
DEBUGOUT( "CSearchDlg::OnActivate:Inactive\n" );
if( !m_bShortCutDisable )
::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)TRUE, 0 );
if( Emu.IsRunning() )
Emu.Resume();
} else {
DEBUGOUT( "CSearchDlg::OnActivate:Active\n" );
::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)FALSE, 0 );
if( Emu.IsRunning() )
Emu.Pause();
}
return FALSE;
}
DLGMSG CSearchDlg::OnClose( DLGMSGPARAM )
{
// DEBUGOUT( "CSearchDlg::OnClose\n" );
::ShowWindow( m_hWnd, SW_HIDE ); // 旕昞帵偵偡傞偩偗
return TRUE;
}
DLGMSG CSearchDlg::OnContextMenu( DLGMSGPARAM )
{
// DEBUGOUT( "CSearchDlg::OnContextMenu\n" );
HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_SCH_RESULT_LIST );
POINT pt;
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
LVHITTESTINFO lvhti;
lvhti.pt = pt;
::ScreenToClient( hWndCtrl, &lvhti.pt );
INT nItem = ListView_HitTest( hWndCtrl, &lvhti );
//DEBUGOUT( "OnContextMenu nItem=%d\n", nItem );
if( nItem >= 0 ) {
CHAR szStr[256];
ListView_GetItemText( hWndCtrl, nItem, 0, szStr, sizeof(szStr) );
m_Address = (WORD)::strtoul( szStr, NULL, 16 );
::TrackPopupMenu( m_hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN, pt.x, pt.y, 0, m_hWnd, NULL );
}
return TRUE;
}
DLGCMD CSearchDlg::OnOK( DLGCMDPARAM )
{
// DEBUGOUT( "CSearchDlg::OnOK\n" );
// ::EndDialog( m_hWnd, IDOK );
}
DLGCMD CSearchDlg::OnCancel( DLGCMDPARAM )
{
// DEBUGOUT( "CSearchDlg::OnCancel\n" );
::ShowWindow( m_hWnd, SW_HIDE ); // 旕昞帵偵偡傞偩偗
}
DLGCMD CSearchDlg::OnRadixCommand( DLGCMDPARAM )
{
if( uID == IDC_SCH_RADIX_DEC )
m_nRadix = 10;
if( uID == IDC_SCH_RADIX_HEX )
m_nRadix = 16;
OnListUpdate();
}
DLGCMD CSearchDlg::OnLengthCommand( DLGCMDPARAM )
{
m_nLength = (INT)uID - IDC_SCH_LENGTH_1BYTE;
OnListUpdate();
}
DLGCMD CSearchDlg::OnStart( DLGCMDPARAM )
{
// DEBUGOUT( "CSearchDlg::OnStart\n" );
INT i;
// Undo僶僢僼傽偵僙乕僽
m_ResultOld = m_Result;
// 崱夞僨乕僞偺弶婜壔
::memset( &m_Result, 0, sizeof(m_Result) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -