Fixed a bug that caused pcsx2 to crash when loading/saving savestates using the "other..." menu option.

Added new command line options for running pcsx2 without a gui.  Using "pcsx2 [filename]" where filename is the name of a cd image, will run the game.  use "pcsx2 -nogui" to boot whatever you have configured in your CDVD.  Use -bootmode=1 to enable the quick boot method (same as RunCD) .. default boots through the BIOS.  [untested feature!  please report if it's broken]

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@752 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-03-12 12:44:22 +00:00
parent b894a7a217
commit b82d9a6541
5 changed files with 83 additions and 115 deletions

View File

@ -19,28 +19,34 @@
#pragma once
//////////////////////////////////////////////////////////////////////////////////////////
// TestRun Parameters.
// Startup Parameters.
struct TESTRUNARGS
enum StartupMode
{
u8 enabled;
u8 jpgcapture;
uint frame; // if == 0, frame is unlimited (run until crash).
int numimages;
int curimage;
u32 autopad; // mask for auto buttons
bool efile;
int snapdone;
const char* ptitle;
const char* pimagename;
const char* plogname;
const char* pgsdll, *pcdvddll, *pspudll;
const char* ppad1dll, *ppad2dll, *pdev9dll;
BootMode_Bios,
BootMode_Quick,
BootMode_Elf
};
extern TESTRUNARGS g_TestRun;
class StartupParams
{
public:
// Name of the CDVD or ELF image to load.
// if NULL, the CDVD configured settings are used.
const char* ImageName;
bool NoGui;
bool Enabled;
StartupMode BootMode;
// Plugin overrides
const char* gsdll, *cdvddll, *spudll;
const char* pad1dll, *pad2dll, *dev9dll;
StartupParams() { memzero_obj(*this); }
};
extern StartupParams g_Startup;
//////////////////////////////////////////////////////////////////////////////////////////
// Core Gui APIs (shared by all platforms)

View File

@ -22,8 +22,7 @@
#include "GS.h"
TESTRUNARGS g_TestRun;
StartupParams g_Startup;
//////////////////////////////////////////////////////////////////////////////////////////
// Save Slot Detection System
@ -63,11 +62,11 @@ void States_Load( const string& file )
try
{
_loadStateOrExcept( file );
HostGui::Notice( fmt_string(_("*PCSX2*: Loaded State %s"), file) );
HostGui::Notice( fmt_string(_("*PCSX2*: Loaded State %hs"), &file) );
}
catch( Exception::StateLoadError_Recoverable& ex)
{
Console::Notice( "Could not load savestate file: %s.\n\n%s", params file, ex.cMessage() );
Console::Notice( "Could not load savestate file: %hs.\n\n%s", params &file, ex.cMessage() );
// At this point the cpu hasn't been reset, so we can return
// control to the user safely... (that's why we use a console notice instead of a popup)
@ -79,7 +78,7 @@ void States_Load( const string& file )
// The emulation state is ruined. Might as well give them a popup and start the gui.
string message( fmt_string(
"Encountered an error while loading savestate from file: %s.\n", file ) );
"Encountered an error while loading savestate from file: %hs.\n", &file ) );
if( g_EmulationInProgress )
message += "Since the savestate load was incomplete, the emulator must reset.\n";
@ -145,12 +144,12 @@ void States_Save( const string& file )
try
{
StateRecovery::SaveToFile( file );
HostGui::Notice( fmt_string( _( "State saved to file: %s" ), file ) );
HostGui::Notice( fmt_string( _( "State saved to file: %hs" ), &file ) );
}
catch( Exception::BaseException& ex )
{
Console::Error( (fmt_string(
"An error occurred while trying to save to file %s\n", file ) +
"An error occurred while trying to save to file %hs\n", &file ) +
"Your emulation state has not been saved!\n\nError: " + ex.Message()).c_str()
);
}
@ -180,7 +179,7 @@ void States_Save(int num)
//
void vSyncDebugStuff( uint frame )
{
#ifdef PCSX2_DEVBUILD
#ifdef OLD_TESTBUILD_STUFF
if( g_TestRun.enabled && g_TestRun.frame > 0 ) {
if( frame > g_TestRun.frame ) {
// take a snapshot

View File

@ -391,7 +391,7 @@ void SysPrepareExecution( const char* elf_file, bool use_bios )
return;
}
if (OpenPlugins(g_TestRun.ptitle) == -1)
if (OpenPlugins(NULL) == -1)
return;
if( elf_file == NULL )
@ -401,9 +401,6 @@ void SysPrepareExecution( const char* elf_file, bool use_bios )
// Not recovering a state, so need to execute the bios and load the ELF information.
// (note: gsRecoveries are done from ExecuteCpu)
// if the elf_file is null we use the CDVD elf file.
// But if the elf_file is an empty string then we boot the bios instead.
char ename[g_MaxPath];
ename[0] = 0;
if( !use_bios )

View File

@ -55,36 +55,26 @@ void strcatz(char *dst, char *src)
strcpy(dst + len, src);
}
//2002-09-20 (Florin)
BOOL APIENTRY CmdlineProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);//forward def
//-------------------
static const char* phelpmsg =
"pcsx2 [options] [file]\n\n"
"-cfg [file] {configuration file}\n"
"-efile [efile] {0 - reset, 1 - runcd (default), 2 - loadelf}\n"
"-help {display this help file}\n"
"-nogui {Don't use gui when launching}\n"
"-loadgs [file] {Loads a gsstate}\n"
"pcsx2 [options] [cdimage/elf file]\n\n"
"\t-cfg [file] {configuration file}\n"
"\t-bootmode [mode] {0 - quick (default), 1 - bios, 2 - load elf}\n"
"\t-nogui {disables display of the gui - skips right to opening the GS window}"
"\t-help {display this help file}\n"
"\t-loadgs [file] {Loads a gsstate}\n\n"
"Run without GUI Options:\n"
"\n"
#ifdef PCSX2_DEVBUILD
"Testing Options: \n"
"\t-frame [frame] {game will run up to this frame before exiting}\n"
"\t-image [name] {path and base name of image (do not include the .ext)}\n"
"\t-jpg {save images to jpg format}\n"
"\t-log [name] {log path to save log file in}\n"
"\t-logopt [hex] {log options in hex (see debug.h) }\n"
"\t-numimages [num] {after hitting frame, this many images will be captures every 20 frames}\n"
"\t-test {Triggers testing mode (only for dev builds)}\n"
"\n"
#endif
"Plugin Overrides (specified dlls will be used in place of configured dlls):\n"
"\t-cdvd [dllpath] {specifies an override for the CDVD plugin}\n"
"\t-gs [dllpath] {specifies an override for the GS plugin}\n"
"\t-spu [dllpath] {specifies an override for the SPU2 plugin}\n"
"\t-pads [dllpath] {specifies an override for *both* pad plugins}\n"
"\t-pad [dllpath] {specifies an override for *both* pad plugins}\n"
"\t-pad1 [dllpath] {specifies an override for the PAD1 plugin only}\n"
"\t-pad2 [dllpath] {specifies an override for the PAD2 plugin only}\n"
"\t-dev9 [dllpath] {specifies an override for the DEV9 plugin}\n"
@ -189,21 +179,6 @@ void WinClose()
BOOL SysLoggedSetLockPagesPrivilege ( HANDLE hProcess, BOOL bEnable);
// Returns TRUE if the test run mode was activated (game was run and has been exited)
static bool TestRunMode()
{
if( IsDevBuild && (g_TestRun.enabled || g_TestRun.ptitle != NULL) )
{
// run without ui
UseGui = false;
PCSX2_MEM_PROTECT_BEGIN();
SysPrepareExecution( g_TestRun.efile ? g_TestRun.ptitle : NULL );
PCSX2_MEM_PROTECT_END();
return true;
}
return false;
}
static void _doPluginOverride( const char* name, const char* src, char (&dest)[g_MaxPath] )
{
if( src == NULL || src[0] == 0 ) return;
@ -219,12 +194,12 @@ void WinRun()
memcpy( &winConfig, &Config, sizeof( PcsxConfig ) );
_doPluginOverride( "GS", g_TestRun.pgsdll, Config.GS );
_doPluginOverride( "CDVD", g_TestRun.pcdvddll, Config.CDVD );
_doPluginOverride( "SPU2", g_TestRun.pspudll, Config.SPU2 );
_doPluginOverride( "PAD1", g_TestRun.ppad1dll, Config.PAD1 );
_doPluginOverride( "PAD2", g_TestRun.ppad2dll, Config.PAD2 );
_doPluginOverride( "DEV9", g_TestRun.pdev9dll, Config.DEV9 );
_doPluginOverride( "GS", g_Startup.gsdll, Config.GS );
_doPluginOverride( "CDVD", g_Startup.cdvddll, Config.CDVD );
_doPluginOverride( "SPU2", g_Startup.spudll, Config.SPU2 );
_doPluginOverride( "PAD1", g_Startup.pad1dll, Config.PAD1 );
_doPluginOverride( "PAD2", g_Startup.pad2dll, Config.PAD2 );
_doPluginOverride( "DEV9", g_Startup.dev9dll, Config.DEV9 );
#ifndef _DEBUG
@ -239,8 +214,6 @@ void WinRun()
if (Pcsx2Configure(NULL) == FALSE) return;
}
if( TestRunMode() ) return;
#ifdef PCSX2_DEVBUILD
if( g_pRunGSState ) {
LoadGSState(g_pRunGSState);
@ -294,8 +267,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
textdomain(PACKAGE);
#endif
memzero_obj(g_TestRun);
_getcwd( g_WorkingFolder, g_MaxPath );
int argc;
@ -303,7 +274,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
if( argv == NULL )
{
Msgbox::Alert( "A fatal error occured while attempting to parse the command line.\n" );
Msgbox::Alert( "A fatal error occurred while attempting to parse the command line.\n" );
return 2;
}
@ -396,6 +367,23 @@ void RunGui()
LoadPatch( str_Default );
if( g_Startup.NoGui || g_Startup.Enabled )
{
// Initially bypass GUI and start PCSX2 directly.
// Manually load plugins using the user's configured image (if non-elf).
if( g_Startup.Enabled && (g_Startup.BootMode != BootMode_Elf) )
{
if (OpenPlugins(g_Startup.ImageName) == -1)
return;
}
SysPrepareExecution(
(g_Startup.BootMode == BootMode_Elf) ? g_Startup.ImageName : NULL,
(g_Startup.BootMode == BootMode_Bios)
);
}
do
{
CreateMainWindow();

View File

@ -67,7 +67,7 @@ int SysPageFaultExceptionFilter( EXCEPTION_POINTERS* eps )
int ParseCommandLine( int tokenCount, TCHAR *const *const tokens )
{
int tidx = 0;
g_TestRun.efile = 0;
g_Startup.BootMode = BootMode_Bios;
while( tidx < tokenCount )
{
@ -75,8 +75,8 @@ int ParseCommandLine( int tokenCount, TCHAR *const *const tokens )
if( command[0] != '-' )
{
g_TestRun.ptitle = command;
printf("opening file %s\n", command);
g_Startup.ImageName = command;
g_Startup.Enabled = true;
continue;
}
@ -89,16 +89,11 @@ int ParseCommandLine( int tokenCount, TCHAR *const *const tokens )
return -1;
}
else if( CmdSwitchIs( "nogui" ) ) {
UseGui = false;
g_Startup.NoGui = true;
}
else if( CmdSwitchIs( "highpriority" ) ) {
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
}
#ifdef PCSX2_DEVBUILD
else if( CmdSwitchIs( "jpg" ) ) {
g_TestRun.jpgcapture = 1;
}
#endif
else
{
const TCHAR* param;
@ -112,9 +107,9 @@ int ParseCommandLine( int tokenCount, TCHAR *const *const tokens )
if( CmdSwitchIs( "cfg" ) ) {
g_CustomConfigFile = param;
}
else if( CmdSwitchIs( "efile" ) ) {
g_TestRun.efile = !!atoi( param );
else if( CmdSwitchIs( "bootmode" ) ) {
g_Startup.BootMode = (StartupMode)atoi( param );
g_Startup.Enabled = true;
}
else if( CmdSwitchIs( "loadgs" ) ) {
g_pRunGSState = param;
@ -123,46 +118,28 @@ int ParseCommandLine( int tokenCount, TCHAR *const *const tokens )
// Options to configure plugins:
else if( CmdSwitchIs( "gs" ) ) {
g_TestRun.pgsdll = param;
g_Startup.gsdll = param;
}
else if( CmdSwitchIs( "cdvd" ) ) {
g_TestRun.pcdvddll = param;
g_Startup.cdvddll = param;
}
else if( CmdSwitchIs( "spu" ) ) {
g_TestRun.pspudll = param;
g_Startup.spudll = param;
}
else if( CmdSwitchIs( "pads" ) ) {
g_TestRun.ppad1dll = param;
g_TestRun.ppad2dll = param;
else if( CmdSwitchIs( "pad" ) ) {
g_Startup.pad1dll = param;
g_Startup.pad2dll = param;
}
else if( CmdSwitchIs( "pad1" ) ) {
g_TestRun.ppad1dll = param;
g_Startup.pad1dll = param;
}
else if( CmdSwitchIs( "pad2" ) ) {
g_TestRun.ppad2dll = param;
g_Startup.pad2dll = param;
}
else if( CmdSwitchIs( "dev9" ) ) {
g_TestRun.pdev9dll = param;
g_Startup.dev9dll = param;
}
#ifdef PCSX2_DEVBUILD
else if( CmdSwitchIs( "image" ) ) {
g_TestRun.pimagename = param;
}
else if( CmdSwitchIs( "log" ) ) {
g_TestRun.plogname = param;
}
else if( CmdSwitchIs( "logopt" ) ) {
if( param[0] == '0' && param[1] == 'x' ) param += 2;
sscanf(param, "%x", &varLog);
}
else if( CmdSwitchIs( "frame" ) ) {
g_TestRun.frame = atoi( param );
}
else if( CmdSwitchIs( "numimages" ) ) {
g_TestRun.numimages = atoi( param );
}
#endif
}
}
return 0;
@ -259,9 +236,10 @@ bool HostGuiInit()
NTFS_CompressFile( MEMCARDS_DIR, Config.McdEnableNTFS );
#ifdef OLD_TESTBUILD_STUFF
if( IsDevBuild && emuLog == NULL && g_TestRun.plogname != NULL )
emuLog = fopen(g_TestRun.plogname, "w");
#endif
if( emuLog == NULL )
emuLog = fopen(LOGS_DIR "\\emuLog.txt","w");