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

📄 nestreme.cpp

📁 nes游戏模拟器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//------------------------------------------------------------------------------
// Name: Nestreme.cpp
// Desc: 
//
// Things still left to add in the debugger.
// =========================================
// 1.  Viewing all the memory, main, stack, prg-rom, chr-rom
// 2.  Adding the memory registers to the register list view.
// 3.  Better breakpoints, adding in dialog box, setting when dissassembling.
// 4.  Step over.
// 5.  View screen shot.
// 6.  Editing memory.
// 7.  
//
// Things to add to the CPU.
// =========================
// 1.  More acurate cpu cycle emulation.
// 2.  Test all the instructions.
// 3.  Update cpu bytes and cycles array.
//
// Things to add to the PPU.
// =========================
// 1.  Accurate emulation of registers 2005/2006.
//------------------------------------------------------------------------------


// Includes
#include <windows.h>
#include <commctrl.h>
#include <afxres.h>
#include <stdio.h>
#include "resource.h"

#include "Nestreme.h"
#include "Cpu.h"
#include "Io.h"
#include "PrintInstrToString.h"
#include "Gfx.h"
#include "Sound.h"
#include "NESData.h"


//------------------------------------------------------------------------------
// Name: WinMain()
// Desc: Main entry point for a windows application.
//------------------------------------------------------------------------------
INT WINAPI WinMain(HINSTANCE hInstance,
				   HINSTANCE hPrevInst,
				   LPSTR lpCmdLine,
				   int nCmdShow)
{
	MSG    msg;
	HACCEL hAccel;

	// Save the global variables
	g_hInstance = hInstance;

	// Initialize our classes.
	if (InitializeApp() != S_OK)
		return TRUE;

	// Create our main window
	hwndMain = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
							  strClassName,
							  strAppName,
							  WS_OVERLAPPEDWINDOW,
							  CW_USEDEFAULT,
							  CW_USEDEFAULT,
							  CW_USEDEFAULT,
							  CW_USEDEFAULT,
							  NULL,
							  NULL,
							  hInstance,
							  NULL);

	// Make sure we could create our window.
	if (hwndMain == NULL)
		return TRUE;

	// Load the keyboard accelerators.
	hAccel = LoadAccelerators(g_hInstance, MAKEINTRESOURCE(IDR_MAINACCEL));

	// Show and update our window.
	ShowWindow(hwndMain, SW_SHOWMAXIMIZED);
	UpdateWindow(hwndMain);

	// Now enter our main windows messaging loop.
	while (GetMessage(&msg, NULL, 0, 0))
	{
	    if (!TranslateAccelerator(hwndMain, hAccel, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	} // end windows messaging loop.

	// Make sure to delete everything we allocate.
	CleanUp();

	return msg.wParam;
} // end WinMain()


//------------------------------------------------------------------------------
// Name: WndProcMain()
// Desc: Our message handling procedure for windows messages.
//------------------------------------------------------------------------------
LRESULT CALLBACK WndProcMain(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	HANDLE hThreadGo;    // Handle to the thread created when go is selected.
	DWORD  dwThreadIDGo; // Thread ID of the thread created when go is selected.

	switch (uMsg)
	{
		case WM_QUIT:
		case WM_DESTROY:
			PostQuitMessage(0);
			break;

		case WM_CREATE: 
			CreateMDIClientWindow(hwnd);
			break;

		case WM_COMMAND:
			switch (LOWORD(wParam))
			{
				case ID_DEBUG_BREAK:
					bBreak = TRUE;
					break;

				case ID_DEBUG_GO:
					hThreadGo = CreateThread(NULL, 0, CPU_RunUntilBreak, 
						NULL, NULL, &dwThreadIDGo);
					if (hThreadGo == NULL)
						FATAL(hwnd, "Couldn't create thread for execution.");
					break;

				case ID_DEBUG_RESTART:
					ResetNES();
					break;

				case ID_DEBUG_STEPINTO:
					CPU_Step();
					break;

				case ID_FILE_FREE:
					FreeNESFile();
					break;

				case ID_FILE_OPEN:
					LoadNESFile(hwnd);
					break;

				case ID_FILE_RUN:
					bRunning = TRUE;
					hThreadRun = CreateThread(NULL, 0, CPU_Run, 
						NULL, NULL, &dwThreadIDRun);
					if (hThreadRun == NULL)
						FATAL(hwnd, "Couldn't create thread for execution.");
					break;

				case ID_FILE_EXIT:
					PostQuitMessage(0);
					break;

				case ID_VIEW_MEMORY:
					CreateMemoryWindow(hwnd);
					break;

				case ID_VIEW_DISASSEMBLY:
					CreateDebugWindow(hwnd);
					DissassembleROM();
					UpdateDebugInfo();
					break;

				case ID_WINDOW_TILEHORIZONTALLY:
					SendMessage(hwndMDIClient, WM_MDITILE, MDITILE_HORIZONTAL, 0);
					break;

				case ID_WINDOW_TILEVERTICALLY:
					SendMessage(hwndMDIClient, WM_MDITILE, MDITILE_VERTICAL, 0);
					break;
			}

		default:
			return DefFrameProc(hwnd, hwndMDIClient, uMsg, wParam, lParam);
	}

	return 0;
} // end WndProcMain()


//------------------------------------------------------------------------------
// Name: WndProcDebug()
// Desc: Our message handling procedure for windows messages.
//------------------------------------------------------------------------------
LRESULT CALLBACK WndProcDebug(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
		case WM_NOTIFY:
			// Process notification messages.            
			switch (((LPNMHDR)lParam)->code) 
			{ 
				case NM_DBLCLK:
					ToggleBreakpoint(((LPNMITEMACTIVATE)lParam)->iItem);
					break;
			}
			break;

		case WM_SIZE:
			ResizeDebugControls(hwndDebugWnd, hwndCodeLV, hwndRegsLV);

		default:
			return DefMDIChildProc(hwnd, uMsg, wParam, lParam);
	}

	return 0;
} // end WndProcDebug()


//------------------------------------------------------------------------------
// Name: WndProcMemory()
// Desc: Our message handling procedure for windows messages.
//------------------------------------------------------------------------------
LRESULT CALLBACK WndProcMemory(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static HWND hwndEdit = NULL;      // Handle to the edit control to hold the memory contents.
	static HWND hwndButton = NULL;    // Handle to the refresh button.
	static HWND hwndMemoryTab = NULL; // Handle to the memory tab control.

	switch (uMsg)
	{
		case WM_COMMAND:
			if (HIWORD(wParam) == BN_CLICKED) 
			{
				// Display the memory that corresponds, on what tab is selected.
				switch (TabCtrl_GetCurSel(hwndMemoryTab))
				{
					case 0:
						// Dump the main memory to the control.
						DisplayMainMemDump(hwndEdit);
						break;
					
					case 1:
						// Dump the stack memory to the control.
						DisplayStackMemDump(hwndEdit);
						break;

					case 2:
						// Dump the PRG-ROM memory to the control.
						DisplayPRGROMMemDump(hwndEdit);
						break;

					case 3:
						// Dump the PPU memory to the control.
						DisplayPPUMemDump(hwndEdit);
						break;

					case 4:
						// Dump the Sprite memory to the control.
						DisplaySpriteMemDump(hwndEdit);
						break;

					default:
						break;
				}
			}
			break;

		case WM_CREATE:
			// Create the tab control to hold all the different types of memory.
			if ((hwndMemoryTab = CreateTabControl(hwnd, IDS_MEMORY_MAIN, 5)) == NULL)
				FATAL(hwnd, "Couldn't create tab control.");

			// Create the edit control and initialize it.
			if (CreateMemoryDump(hwnd, &hwndEdit, &hwndButton) != S_OK)
				FATAL(hwnd, "Couldn't create the edit window.")

			// Dump the memory to the control.
			DisplayMainMemDump(hwndEdit);
			break;

		case WM_NOTIFY: 
			switch (((LPNMHDR) lParam)->code)
			{ 
				case TCN_SELCHANGE: 
				{
					RECT rc;
					
					// Create the edit control and initialize it.
					if (CreateMemoryDump(hwnd, &hwndEdit, &hwndButton) != S_OK)
						FATAL(hwnd, "Couldn't create the edit window.")

					// Display the memory that corresponds, on what tab is selected.
					switch (TabCtrl_GetCurSel(hwndMemoryTab))
					{
						case 0:
							// Dump the main memory to the control.
							DisplayMainMemDump(hwndEdit);
							break;
						
						case 1:
							// Dump the stack memory to the control.
							DisplayStackMemDump(hwndEdit);
							break;

						case 2:
							// Dump the PRG-ROM memory to the control.
							DisplayPRGROMMemDump(hwndEdit);
							break;

						case 3:
							// Dump the PPU memory to the control.
							DisplayPPUMemDump(hwndEdit);
							break;

						case 4:
							// Dump the Sprite memory to the control.
							DisplaySpriteMemDump(hwndEdit);
							break;

						default:
							break;
					}

					// Update the window by calling sending the size message.
					GetClientRect(hwnd, &rc);
					SendMessage(hwnd, WM_SIZE, SIZE_RESTORED, MAKELPARAM(rc.right-rc.left, rc.bottom-rc.top));
					break; 
				}

				case TCN_SELCHANGING:
					DestroyWindow(hwndEdit);
					DestroyWindow(hwndButton);
					break;
			} 
			break; 
	
        case WM_SIZE: 
			{ 
                HDWP hdwp; 
                RECT rc; 
 
                // Calculate the display rectangle, assuming the 
                // tab control is the size of the client area. 
                SetRect(&rc, 0, 0, LOWORD(lParam), HIWORD(lParam)); 
                TabCtrl_AdjustRect(hwndMemoryTab, FALSE, &rc); 
 
                // Size the tab control to fit the client area. 
                hdwp = BeginDeferWindowPos(3); 
                DeferWindowPos(hdwp, hwndMemoryTab, NULL, 0, 0, 
                    LOWORD(lParam), HIWORD(lParam), SWP_NOMOVE | SWP_NOZORDER); 
 
                // Position and size the button control to fit at
				// the bottom of the tab control window.
                DeferWindowPos(hdwp, hwndButton, HWND_TOP, rc.left,
					rc.bottom-rc.top, 70, 20, 0); 

				// Position and size the edit control to fit the 
                // tab control's display area minus some room for
				// the button, and make sure the edit control is 
				// in front of the tab control. 
                DeferWindowPos(hdwp, hwndEdit, HWND_TOP, rc.left, rc.top, 
                    rc.right-rc.left, rc.bottom-rc.top-30, 0); 
                EndDeferWindowPos(hdwp); 
			} 

		default:
			return DefMDIChildProc(hwnd, uMsg, wParam, lParam);
	}

	return 0;
} // end WndProcMemory()


//------------------------------------------------------------------------------
// Name: WndProcRun()
// Desc: Our message handling procedure for windows messages.
//------------------------------------------------------------------------------
LRESULT CALLBACK WndProcRun(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
		case WM_DESTROY:
		case WM_CLOSE:
			// Tell the thread that runs the program to exit.
			bRunning = FALSE;
			break;

		case WM_KEYDOWN:
			switch (wParam)
			{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -