📄 infones_system_win.cpp
字号:
/*===================================================================*/
/* */
/* InfoNES_System_Win.cpp : The function which depends on a system */
/* (for Windows) */
/* */
/* 2000/05/12 InfoNES Project */
/* */
/*===================================================================*/
/*-------------------------------------------------------------------*/
/* Include files */
/*-------------------------------------------------------------------*/
#include <windows.h>
#include <mmsystem.h>
#include <limits.h>
#include <stdio.h>
#include <crtdbg.h>
#include "../InfoNES.h"
#include "../InfoNES_System.h"
#include "InfoNES_Resource_Win.h"
#include "InfoNES_Sound_Win.h"
#include "../InfoNES_pAPU.h"
/*-------------------------------------------------------------------*/
/* ROM image file information */
/*-------------------------------------------------------------------*/
char szRomName[ 256 ];
char szSaveName[ 256 ];
int nSRAM_SaveFlag;
/*-------------------------------------------------------------------*/
/* Variables for Windows */
/*-------------------------------------------------------------------*/
#define APP_NAME "InfoNES v0.79J"
HWND hWndMain;
WNDCLASS wc;
HACCEL hAccel; //加速键表句柄
byte *pScreenMem;
HBITMAP hScreenBmp;
LOGPALETTE *plpal;
BITMAPINFO *bmi;
// Palette data
WORD NesPalette[ 64 ] =
{
0x39ce, 0x1071, 0x0015, 0x2013, 0x440e, 0x5402, 0x5000, 0x3c20,
0x20a0, 0x0100, 0x0140, 0x00e2, 0x0ceb, 0x0000, 0x0000, 0x0000,
0x5ef7, 0x01dd, 0x10fd, 0x401e, 0x5c17, 0x700b, 0x6ca0, 0x6521,
0x45c0, 0x0240, 0x02a0, 0x0247, 0x0211, 0x0000, 0x0000, 0x0000,
0x7fff, 0x1eff, 0x2e5f, 0x223f, 0x79ff, 0x7dd6, 0x7dcc, 0x7e67,
0x7ae7, 0x4342, 0x2769, 0x2ff3, 0x03bb, 0x0000, 0x0000, 0x0000,
0x7fff, 0x579f, 0x635f, 0x6b3f, 0x7f1f, 0x7f1b, 0x7ef6, 0x7f75,
0x7f94, 0x73f4, 0x57d7, 0x5bf9, 0x4ffe, 0x0000, 0x0000, 0x0000
};
// Screen Size Magnification
WORD wScreenMagnification = 1;
#define NES_MENU_HEIGHT 46
/*-------------------------------------------------------------------*/
/* Variables for Emulation Thread */
/*-------------------------------------------------------------------*/
HANDLE m_hThread;
DWORD m_ThreadID = NULL;
/*-------------------------------------------------------------------*/
/* Variables for Timer & Wait loop */
/*-------------------------------------------------------------------*/
#define LINE_PER_TIMER 789
#define TIMER_PER_LINE 50
WORD wLines;
WORD wLinePerTimer;
MMRESULT uTimerID;
BOOL bWaitFlag;
CRITICAL_SECTION WaitFlagCriticalSection;
BOOL bAutoFrameskip = TRUE;
/*-------------------------------------------------------------------*/
/* Variables for Sound Emulation */
/*-------------------------------------------------------------------*/
DIRSOUND* lpSndDevice;
/*-------------------------------------------------------------------*/
/* Variables for Expiration */
/*-------------------------------------------------------------------*/
#define EXPIRED_YEAR 2001
#define EXPIRED_MONTH 3
#define EXPIRED_MSG "This software has been expired.\nPlease download newer one."
/*-------------------------------------------------------------------*/
/* Function prototypes ( Windows specific ) */
/*-------------------------------------------------------------------*/
LRESULT CALLBACK MainWndproc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );
LRESULT CALLBACK AboutDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
void ShowTitle( HWND hWnd );
void SetWindowSize( WORD wMag );
int LoadSRAM();
int SaveSRAM();
static void InfoNES_StartTimer();
static void InfoNES_StopTimer();
static void CALLBACK TimerFunc( UINT nID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2);
/*===================================================================*/
/* */
/* WinMain() : Application main */
/* */
/*===================================================================*/
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
/*-------------------------------------------------------------------*/
/* Create a window */
/*-------------------------------------------------------------------*/
wc.style = 0;
wc.lpfnWndProc = MainWndproc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(IDI_ICON) );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
wc.lpszClassName = "InfoNESClass";
if ( !RegisterClass( &wc ) )
return FALSE;
hWndMain = CreateWindowEx( 0,
"InfoNESClass",
APP_NAME,
WS_VISIBLE | WS_POPUP | WS_OVERLAPPEDWINDOW,
200,
120,
NES_DISP_WIDTH,
NES_DISP_HEIGHT + NES_MENU_HEIGHT,
NULL,
NULL,
hInstance,
NULL );
if ( !hWndMain )
return FALSE;
ShowWindow( hWndMain, nCmdShow );
UpdateWindow( hWndMain );
#if 0
/*-------------------------------------------------------------------*/
/* Expired or Not? */
/*-------------------------------------------------------------------*/
SYSTEMTIME st;
GetLocalTime( &st );
if ( st.wYear > EXPIRED_YEAR || st.wMonth > EXPIRED_MONTH)
{
InfoNES_MessageBox( EXPIRED_MSG );
exit( -1 );
}
#endif
/*-------------------------------------------------------------------*/
/* Create a InfoNES screen */
/*-------------------------------------------------------------------*/
HDC hDC = GetDC( hWndMain );
BITMAPINFOHEADER bi;
bi.biSize = sizeof( BITMAPINFOHEADER );
bi.biWidth = NES_DISP_WIDTH;
bi.biHeight = NES_DISP_HEIGHT * -1;
bi.biPlanes = 1;
bi.biBitCount = 16;
bi.biCompression = BI_RGB;
bi.biSizeImage = NES_DISP_WIDTH * NES_DISP_HEIGHT * 2;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
hScreenBmp = CreateDIBSection( hDC,
(BITMAPINFO *)&bi,
DIB_RGB_COLORS,
(void **)&pScreenMem,
0,
0 );
if ( !hScreenBmp )
return -1;
ReleaseDC( hWndMain, hDC );
/*-------------------------------------------------------------------*/
/* Show Title Screen */
/*-------------------------------------------------------------------*/
ShowTitle( hWndMain );
/*-------------------------------------------------------------------*/
/* Get Wait Value */
/*-------------------------------------------------------------------*/
InfoNES_StartTimer();
/*-------------------------------------------------------------------*/
/* For Drag and Drop Function */
/*-------------------------------------------------------------------*/
if ( lpCmdLine[ 0 ] != '\0' )
{
#if 0
// Debug Message
MessageBox( hWndMain, TEXT( lpCmdLine ), TEXT( "file name:" ), MB_OK );
#endif
// If included space characters, strip dobule quote marks
if ( lpCmdLine[ 0 ] == '"' )
{
lpCmdLine[ strlen( lpCmdLine ) - 1 ] = '\0';
lpCmdLine++;
}
#if 0
// Debug Message
MessageBox( hWndMain, TEXT( lpCmdLine ), TEXT( "file name:" ), MB_OK );
#endif
// Load cassette
if ( InfoNES_Load( lpCmdLine ) == 0 )
{
// Set a ROM image name
strcpy( szRomName, lpCmdLine );
// Load SRAM
LoadSRAM();
// Create Emulation Thread
m_hThread = CreateThread( (LPSECURITY_ATTRIBUTES)NULL, (DWORD)0,
(LPTHREAD_START_ROUTINE)InfoNES_Main, (LPVOID)NULL, (DWORD)0, &m_ThreadID);
}
}
/*-------------------------------------------------------------------*/
/* The Message Pump */
/*-------------------------------------------------------------------*/
MSG msg;
while (TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (!GetMessage(&msg, NULL, 0, 0 ))
break;
// Translate and dispatch the message
if (0 == TranslateAccelerator(hWndMain, hAccel, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
// Make sure we go to sleep if we have nothing else to do
WaitMessage();
}
}
InfoNES_StopTimer();
return 0;
}
/*===================================================================*/
/* */
/* MainWndProc() : Window procedure */
/* */
/*===================================================================*/
LRESULT CALLBACK MainWndproc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
OPENFILENAME ofn;
char szFileName[ 256 ];
switch ( message )
{
case WM_ERASEBKGND:
return 1;
case WM_DESTROY:
PostQuitMessage( 0 );
break;
case WM_ACTIVATE:
// Show title screen if emulation thread dosent exist
if ( NULL == m_hThread )
ShowTitle( hWnd );
break;
case WM_COMMAND:
switch ( LOWORD( wParam ) )
{
case IDC_BTN_OPEN:
/*-------------------------------------------------------------------*/
/* Open button */
/*-------------------------------------------------------------------*/
// Do nothing if emulation thread exists
if (NULL != m_hThread)
break;
memset( &ofn, 0, sizeof ofn );
szFileName[ 0 ] = '\0';
ofn.lStructSize = sizeof ofn;
ofn.hwndOwner = hWnd;
ofn.hInstance = wc.hInstance;
ofn.lpstrFilter = NULL;
ofn.lpstrCustomFilter = NULL;
ofn.nMaxCustFilter = 0;
ofn.nFilterIndex = 0;
ofn.lpstrFile = szFileName;
ofn.nMaxFile = sizeof szFileName;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = NULL;
ofn.Flags = 0;
ofn.nFileOffset;
ofn.nFileExtension = 0;
ofn.lpstrDefExt = NULL;
ofn.lCustData = 0;
ofn.lpfnHook = NULL;
ofn.lpTemplateName = NULL;
if ( GetOpenFileName( &ofn ) )
{
// Load cassette
if ( InfoNES_Load( szFileName ) == 0 )
{
// Set a ROM image name
strcpy( szRomName, szFileName );
// Load SRAM
LoadSRAM();
// Create Emulation Thread
m_hThread=CreateThread((LPSECURITY_ATTRIBUTES)NULL, (DWORD)0,
(LPTHREAD_START_ROUTINE)InfoNES_Main, (LPVOID)NULL,
(DWORD)0, &m_ThreadID);
}
}
break;
case IDC_BTN_STOP:
/*-------------------------------------------------------------------*/
/* Stop button */
/*-------------------------------------------------------------------*/
// Terminate Emulation Thread
if (NULL != m_hThread)
{
TerminateThread(m_hThread, (DWORD)0);
m_hThread=NULL;
// Save SRAM File
SaveSRAM();
// Finalize
InfoNES_Fin();
}
// Show Title Screen
ShowTitle( hWnd );
break;
case IDC_BTN_RESET:
/*-------------------------------------------------------------------*/
/* Reset button */
/*-------------------------------------------------------------------*/
// Show Title Screen
ShowTitle( hWnd );
// Do nothing if emulation thread does not exists
if (NULL != m_hThread)
{
// Terminate Emulation Thread
TerminateThread(m_hThread, (DWORD)0);
m_hThread=NULL;
// Stop timer
InfoNES_StopTimer();
// Save SRAM File
SaveSRAM();
// Finalize pAPU
InfoNES_pAPUDone();
// Reset InfoNES
InfoNES_Reset();
// Create Emulation Thread
m_hThread=CreateThread((LPSECURITY_ATTRIBUTES)NULL, (DWORD)0,
(LPTHREAD_START_ROUTINE)InfoNES_Main, (LPVOID)NULL,
(DWORD)0, &m_ThreadID);
// Restart timer
InfoNES_StartTimer();
}
break;
case IDC_BTN_EXIT:
/*-------------------------------------------------------------------*/
/* Exit button */
/*-------------------------------------------------------------------*/
// Terminate Emulation Thread
if (NULL != m_hThread)
{
TerminateThread(m_hThread, (DWORD)0);
// Save SRAM File
SaveSRAM();
// Finalize
InfoNES_Fin();
}
// Received key/menu command to exit app
PostMessage(hWnd, WM_CLOSE, 0, 0);
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -