⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cheatdlg.cpp

📁 著名的任天堂FC游戏机模拟器VirtuaNes 085版的源码!
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// 僠乕僩僟僀傾儘僌僋儔僗
//
//
#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 + -