home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ST-Computer Leser 2002 January
/
STC_CD_01_2002.iso
/
JAGUAR
/
JAG_SRC
/
SOURCE
/
JAGULATO.C
< prev
next >
Wrap
C/C++ Source or Header
|
2001-08-18
|
20KB
|
461 lines
////////////////////////////////////////////////////////////////////////////////
// Jagulator: Atari Jaguar Console Emulation Project (jagulator.c)
// -----------------------------------------------------------------------------
// Jagulator is the Copyright (c) RealityMan 1998-2001 and is provided "as is"
// without any expressed or implied warranty. I have no Trademarks, Legal or
// otherwise. Atari, Jaguar and the Atari Logo are copyright Hasbro Inc. All
// other Copyrights and Trademarks are acknowledged. This project is in no way
// linked to Atari/Hasbro or other associated Atari companies.
//
// 07-07-2001 GH: New Source, Rewritten for Release 1.5.0
// 00-00-0000 GH: All Previous Source Considered as Development Code Only
#include "core.h"
////////////////////////////////////////////////////////////////////////////////
// Globals
HANDLE hInst; // Global Application Instance
HWND hwndMain; // Handle to the Main App Window
HWND hwndStatus; // Handle to Status Bar
HANDLE mainthread; // Main Thread Handle
LPDWORD mainthreadid; // Main Thread ID
char comd[MAX_PATH]; // Command String
char sbbuf[MAX_PATH]; // Status Bar String Buffer
////////////////////////////////////////////////////////////////////////////////
// Preferences Dialog
BOOL CALLBACK BinaryLoadDialog( HWND hdwnd, UINT message,
WPARAM wParam, LPARAM lParam )
{
static HWND hwndCtrl; // Dialog Control Window Handle
static char buf[MAX_PATH]; // Temporary Buffer
switch( message )
{
case WM_COMMAND:
switch( LOWORD( wParam ) )
{
case IDOK: // Close Window - Save Changes
strcpy( comd, "rla " );
GetDlgItemText( hdwnd, IDC_ADDR, buf, MAX_PATH );
strcat( comd, buf );
strcat( comd, " " );
GetDlgItemText( hdwnd, IDC_FILE, buf, MAX_PATH );
strcat( comd, buf );
strcat( comd, "\0" );
EndDialog( hdwnd, 0 );
return( TRUE );
case IDCANCEL: // Close Window - Do Not Save Changes
EndDialog( hdwnd, 0 );
return( TRUE );
}
break;
case WM_INITDIALOG:
ShowWindow( hdwnd, SW_SHOW );
hwndCtrl = GetDlgItem( hdwnd, IDC_FILE );
SetFocus( hwndCtrl );
break;
}
return( FALSE );
}
////////////////////////////////////////////////////////////////////////////////
// Preferences Dialog
BOOL CALLBACK PreferencesDialog( HWND hdwnd, UINT message,
WPARAM wParam, LPARAM lParam )
{
static HWND hwndCtrl; // Dialog Control Window Handle
static char cfgpath[MAX_PATH]; // Config File Path
switch( message )
{
case WM_COMMAND:
switch( LOWORD( wParam ) )
{
case IDOK: // Close Window - Save Changes
strcpy( cfgpath, cfg.rootpath );
strcat( cfgpath, "jagulator.ini" );
GetDlgItemText( hdwnd, IDC_BOOTPATH, cfg.bootpath, MAX_PATH);
WritePrivateProfileString( "default", "bootpath",
cfg.bootpath, cfgpath );
GetDlgItemText( hdwnd, IDC_ROMPATH, cfg.rompath, MAX_PATH );
WritePrivateProfileString( "default", "rompath",
cfg.rompath, cfgpath );
EndDialog( hdwnd, 0 );
return( TRUE );
case IDCANCEL: // Close Window - Do Not Save Changes
EndDialog( hdwnd, 0 );
return( TRUE );
}
break;
case WM_INITDIALOG:
SetDlgItemText( hdwnd, IDC_BOOTPATH, cfg.bootpath );
SetDlgItemText( hdwnd, IDC_ROMPATH, cfg.rompath );
ShowWindow( hdwnd, SW_SHOW );
hwndCtrl = GetDlgItem( hdwnd, IDCANCEL );
SetFocus( hwndCtrl );
break;
}
return( FALSE );
}
////////////////////////////////////////////////////////////////////////////////
// Video Configuration Dialog
BOOL CALLBACK VideoConfigDialog( HWND hdwnd, UINT message,
WPARAM wParam, LPARAM lParam )
{
static HWND hwndCtrl; // Dialog Control Window Handle
FILE *glinfo; // GL Information File
fpos_t pos; // File Position Indicator
int i, j; // Iterator
char fsd[30]; // Frame Skip Description
static char buf[256]; // Temporary Buffer
static char cfgpath[MAX_PATH]; // Config File Path
char vm[5][12] = { "512 x 384", "640 x 480",
"800 x 600", "1024 x 768", "1280 x 1024" };
switch( message )
{
case WM_COMMAND:
switch( LOWORD( wParam ) )
{
case IDOK: // Close Window - Save Changes
strcpy( cfgpath, cfg.rootpath );
strcat( cfgpath, "jagulator.ini" );
cfg.graphics = SendDlgItemMessage( hdwnd, IDC_GFXENABLE,
BM_GETCHECK, 0, 0 );
itoa( cfg.graphics, buf, 10 );
WritePrivateProfileString( "video", "graphics",
buf, cfgpath );
cfg.fullscreen = SendDlgItemMessage( hdwnd, IDC_GLFULL,
BM_GETCHECK, 0, 0 );
itoa( cfg.fullscreen, buf, 10 );
WritePrivateProfileString( "video", "fullscreen",
buf, cfgpath );
i = SendDlgItemMessage( hdwnd, IDC_CD16, BM_GETCHECK, 0, 0 );
//cfg.cdepth = i ? 16 : 32;
//WritePrivateProfileString( "video", "cdepth",
// i ? "16" : "32", cfgpath );
i = SendDlgItemMessage( hdwnd, IDC_VMODE, CB_GETCURSEL, 0, 0);
switch( i )
{
case 0: strcpy( buf, "512\0" ); cfg.vres = 512;
strcpy( fsd, "384\0" ); cfg.hres = 384;
break;
case 1: strcpy( buf, "640\0" ); cfg.vres = 640;
strcpy( fsd, "480\0" ); cfg.hres = 480;
break;
case 2: strcpy( buf, "800\0" ); cfg.vres = 800;
strcpy( fsd, "600\0" ); cfg.hres = 600;
break;
case 3: strcpy( buf, "1024\0" ); cfg.vres = 1024;
strcpy( fsd, "768\0" ); cfg.hres = 768;
break;
case 4: strcpy( buf, "1280\0" ); cfg.vres = 1280;
strcpy( fsd, "1024\0" ); cfg.hres = 1024;
break;
}
WritePrivateProfileString( "video", "hres", buf, cfgpath );
WritePrivateProfileString( "video", "vres", fsd, cfgpath );
cfg.frameskip = SendDlgItemMessage( hdwnd, IDC_FSKIP,
CB_GETCURSEL, 0, 0 );
itoa( cfg.frameskip, buf, 10 );
WritePrivateProfileString( "video", "frameskip", buf,cfgpath);
EndDialog( hdwnd, 0 );
return( TRUE );
case IDCANCEL: // Close Window - Do Not Save Changes
EndDialog( hdwnd, 0 );
return( TRUE );
}
break;
case WM_INITDIALOG:
if( cfg.graphics )
SendDlgItemMessage( hdwnd, IDC_GFXENABLE,
BM_SETCHECK, BST_CHECKED, 0 );
else
SendDlgItemMessage( hdwnd, IDC_GFXENABLE,
BM_SETCHECK, BST_UNCHECKED, 0 );
if( cfg.fullscreen )
SendDlgItemMessage(hdwnd,IDC_GLFULL,BM_SETCHECK,BST_CHECKED,0);
else
SendDlgItemMessage(hdwnd,IDC_GLFULL,BM_SETCHECK,BST_UNCHECKED,0);
//if( cfg.cdepth == 32 )
// SendDlgItemMessage(hdwnd,IDC_CD32,BM_SETCHECK,BST_CHECKED,0);
//else
// SendDlgItemMessage(hdwnd,IDC_CD16,BM_SETCHECK,BST_CHECKED,0);
switch( cfg.vres )
{
case 1280: j = 4; break;
case 1024: j = 3; break;
case 800: j = 2; break;
case 640: j = 1; break;
case 512:
default: j = 0; break;
}
for( i = 0; i < 5; i++ )
SendDlgItemMessage(hdwnd,IDC_VMODE,CB_ADDSTRING,0,(LPARAM)vm[i]);
SendDlgItemMessage( hdwnd, IDC_VMODE, CB_SETCURSEL, j, 0 );
SendDlgItemMessage( hdwnd, IDC_FSKIP, CB_ADDSTRING, 0,
(LPARAM)"Display Every Frame");
for( i = 1; i < 10; i++)
{
wsprintf( fsd, "Skip %i of every 10 frames", i );
SendDlgItemMessage(hdwnd,IDC_FSKIP,CB_ADDSTRING,0,(LPARAM)fsd);
}
SendDlgItemMessage( hdwnd, IDC_FSKIP,
CB_SETCURSEL, cfg.frameskip, 0 );
GetTempPath( MAX_PATH, buf );
strcat( buf, "oglinfo" );
glinfo = fopen( buf, "r" );
pos = 0;
fgets( cfgpath, MAX_PATH, glinfo );
SetDlgItemText( hdwnd, IDC_GLVENDOR, cfgpath );
pos += strlen(cfgpath) + 1;
fsetpos( glinfo, &pos );
fgets( cfgpath, MAX_PATH, glinfo );
SetDlgItemText( hdwnd, IDC_GLRENDERER, cfgpath );
pos += strlen(cfgpath) + 1;
fsetpos( glinfo, &pos );
fgets( cfgpath, MAX_PATH, glinfo );
SetDlgItemText( hdwnd, IDC_GLVERSION, cfgpath );
pos += strlen(cfgpath) + 1;
fsetpos( glinfo, &pos );
fgets( cfgpath, MAX_PATH, glinfo );
SetDlgItemText( hdwnd, IDC_GLEXTENSION, cfgpath );
fclose( glinfo );
ShowWindow( hdwnd, SW_SHOW );
hwndCtrl = GetDlgItem( hdwnd, IDCANCEL );
SetFocus( hwndCtrl );
break;
}
return( FALSE );
}
////////////////////////////////////////////////////////////////////////////////
// About Jagulator Dialog
BOOL CALLBACK AboutDialog( HWND hdwnd, UINT message,
WPARAM wParam, LPARAM lParam )
{
static HWND hwndCtrl; // Dialog Control Window Handle
switch( message )
{
case WM_COMMAND:
switch( LOWORD( wParam ) )
{
case IDOK: // Close the Dialog Window
EndDialog( hdwnd, 0 );
return( TRUE );
}
break;
case WM_INITDIALOG:
ShowWindow( hdwnd, SW_SHOW );
hwndCtrl = GetDlgItem( hdwnd, IDOK );
SetFocus( hwndCtrl );
break;
}
return( FALSE );
}
////////////////////////////////////////////////////////////////////////////////
// Application Window Message Processing
LRESULT CALLBACK WindowFunc( HWND hwnd, // Handle to Application Window
UINT message, // Windows Message
WPARAM wParam, // Message Parameter
LPARAM lParam ) // Message Parameter
{
RECT rcl; // Window Size
HDWP hdwp; // Deferred Window Position
static char buf[256]; // Temporary Buffer
static char hlppath[MAX_PATH]; // Config File Path
const LPSTR HelpFile = "jagulator.hlp";
switch( message )
{
case WM_CREATE: // Do Application Initialisation
hwndMain = hwnd; // Set Main Window Handle
hwndStatus = CreateWindowEx( 0L, STATUSCLASSNAME, "", WS_CHILD |
WS_BORDER | WS_VISIBLE | SBS_SIZEGRIP,
0, 0, 0, 0, hwndMain,
(HMENU)ID_STATUSBAR, hInst, NULL );
wsprintf( sbbuf, "%s", COPYRIGHT );
v_getglinfo(); // Get OpenGL Information
break;
case WM_COMMAND: // Handle App Defined Windows Messages
switch( LOWORD( wParam ) )
{
case ID_ROM: // Load Jaguar Binary
boot_load();
break;
case ID_START: // Begin Emulation
wsprintf( sbbuf, "Emulating..." );
SendMessage( hwndStatus, SB_SETTEXT, 0, (LPARAM)sbbuf );
command( "go" );
break;
case ID_RESET: // Stop and Reset Emulator
v_deinit();
memset( &st, 0, sizeof( STATE ) );
memset( &gst, 0, sizeof( GPUSTATE ) );
memset( &dst, 0, sizeof( DSPSTATE ) );
memset( &blt, 0, sizeof( BLTSTATE ) );
wsprintf( sbbuf, "%s", COPYRIGHT );
SendMessage( hwndStatus, SB_SETTEXT, 0, (LPARAM)sbbuf );
break;
case ID_EXIT: // Exit Emulator Requested
SendMessage( hwndMain, WM_DESTROY, 0, 0L );
break;
case ID_VIDEO: // Video Configuration
DialogBox( hInst, MAKEINTRESOURCE( IDD_VIDEO ),
hwndMain, VideoConfigDialog );
break;
case ID_PREFS: // Preferences
DialogBox( hInst, MAKEINTRESOURCE( IDD_PREFS ),
hwndMain, PreferencesDialog );
break;
case ID_TOPICS: // Jagulator Help File
wsprintf( hlppath, "%s%s", cfg.rootpath, HelpFile );
WinHelp( hwndMain, hlppath, HELP_INDEX, 0 );
break;
case ID_ABOUT: // Display About Application Details
DialogBox( hInst, MAKEINTRESOURCE( IDD_ABOUT ),
hwndMain, AboutDialog );
break;
default: // Ignore any other App Defined Messages
break;
}
break;
case WM_DESTROY: // Terminate the Application
PostQuitMessage( 0 );
break;
case WM_SIZE: // Handle Window Resizing
GetClientRect( hwndMain, &rcl );
hdwp = BeginDeferWindowPos( 1 );
// Resize Status Bar
DeferWindowPos( hdwp, hwndStatus, NULL, 0, 0,
rcl.right - rcl.left, 20,
SWP_NOZORDER | SWP_NOMOVE );
EndDeferWindowPos( hdwp );
// Refresh Status Bar Elements
SendMessage( hwndStatus, SB_SETTEXT, 0, (LPARAM)sbbuf );
break;
default: // Handle any Unhandle Windows Messages
return( DefWindowProc( hwnd, message, wParam, lParam ) );
break;
}
return( 0L ); // Return from Main Win Msg Handling Proc
}
////////////////////////////////////////////////////////////////////////////////
// Emulator Thread - Basically Calls main.c which returns if the Debug
// User Interface is ever Exited.
int EmuThread( int value )
{
main_thread();
SendMessage( hwndMain, WM_CLOSE, 0, 0 );
return( 0 );
}
////////////////////////////////////////////////////////////////////////////////
// Main Application Code Starts Here
int WINAPI WinMain( HINSTANCE hThisInst, // Handle to this Program Instance
HINSTANCE hPrevInst, // Previous Instance (Obsolete)
LPSTR lpszArgs, // Passed Arguments
int nWinMode ) // Windows Display Mode
{
WNDCLASSEX wclex; // Pointer to Windows Class
HWND hwnd; // Window Handle
MSG msg; // Windows Message Pointer
static char buf[MAX_PATH]; // Temporary Buffer
// Store the Global Application Instance Handle
hInst = hThisInst;
// Define the Primary Windows Class
wclex.hInstance = hInst;
wclex.lpszClassName = APPNAME;
wclex.lpfnWndProc = WindowFunc;
wclex.style = CS_HREDRAW | CS_VREDRAW;
wclex.cbSize = sizeof( WNDCLASSEX );
wclex.hIcon = LoadIcon( hThisInst, MAKEINTRESOURCE(IDI_JAGEMU));
wclex.hIconSm = LoadIcon( hThisInst, MAKEINTRESOURCE(IDI_JAGEMU));
wclex.hCursor = LoadCursor( NULL, IDC_ARROW );
wclex.lpszMenuName = MAKEINTRESOURCE( IDR_MENU );
wclex.cbClsExtra = 0;
wclex.cbWndExtra = 0;
wclex.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
// Register the Window Class
if( !RegisterClassEx( &wclex ) ) return( 0 );
// Create the Main Application Window
wsprintf( buf, "%s - %s v%i.%i.%i",
APPNAME, TITLE, MAJORREV, MINORREV, PATCHLVL );
hwnd = CreateWindow( APPNAME, buf, WS_OVERLAPPEDWINDOW |
WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
50, 50, 600, 450, NULL, NULL, hInst, NULL );
// Initialise the Common Controls Library
InitCommonControls();
// Display and Update the Application Window
ShowWindow( hwnd, nWinMode );
UpdateWindow( hwnd );
// This is the Main Emulator Thread which will run in the background. By
// default it loads an empty 'dummy' cartridge and does nothing.
{
int mainthreadid;
mainthread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)EmuThread,
NULL, 0, &mainthreadid );
}
// Windows Message Processing Loop
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
GetTempPath( MAX_PATH, buf ); // Remove GL Information File
strcat( buf, "oglinfo" );
DeleteFile( buf );
return( msg.wParam ); // Exit the Application
}