(new/changed functionality is mostly described in the new file doc/ReadMe.SDL.txt)
Reworked rewinds More schemes for save/load keybindings Savestate backups Per-gamepad autofire (binds to a button on the real pad/keyboard) Allow adding cheat codes from commandline Allow adding IPS patch files from commandline Fix bug in configuration for pad 4 Configurable default scaling of window size for openGL (when filter=0) Assorted code cleanups (using DEFINEs instead of literals, factored-out chunks of code from the big switch to functions, ...) New switches for muting sound (CTRL+S), toggling cheats (CTRL-E) Added timestamp to console messages All messages go to console, even if they go to screen Some messages no longer go to screen git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@506 a31d4220-a93d-0410-bf67-fe4944624d44
This commit is contained in:
parent
8d47c2aae4
commit
d2bd65709b
625
src/sdl/SDL.cpp
625
src/sdl/SDL.cpp
|
@ -31,6 +31,8 @@
|
||||||
#include <GL/glext.h>
|
#include <GL/glext.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include "../AutoBuild.h"
|
#include "../AutoBuild.h"
|
||||||
|
|
||||||
#include <SDL/SDL.h>
|
#include <SDL/SDL.h>
|
||||||
|
@ -43,6 +45,7 @@
|
||||||
#include "../Util.h"
|
#include "../Util.h"
|
||||||
#include "../dmg/gb.h"
|
#include "../dmg/gb.h"
|
||||||
#include "../dmg/gbGlobals.h"
|
#include "../dmg/gbGlobals.h"
|
||||||
|
#include "../Cheats.h"
|
||||||
|
|
||||||
#include "debugger.h"
|
#include "debugger.h"
|
||||||
#include "filters.h"
|
#include "filters.h"
|
||||||
|
@ -158,27 +161,59 @@ char* homeDir = NULL;
|
||||||
#define DOT_DIR ".vbam"
|
#define DOT_DIR ".vbam"
|
||||||
|
|
||||||
static char *rewindMemory = NULL;
|
static char *rewindMemory = NULL;
|
||||||
|
static int *rewindSerials = NULL;
|
||||||
static int rewindPos = 0;
|
static int rewindPos = 0;
|
||||||
|
static int rewindSerial = 0;
|
||||||
static int rewindTopPos = 0;
|
static int rewindTopPos = 0;
|
||||||
static int rewindCounter = 0;
|
static int rewindCounter = 0;
|
||||||
static int rewindCount = 0;
|
static int rewindCount = 0;
|
||||||
static bool rewindSaveNeeded = false;
|
static bool rewindSaveNeeded = false;
|
||||||
static int rewindTimer = 0;
|
static int rewindTimer = 0;
|
||||||
|
|
||||||
|
static int sdlSaveKeysSwitch = 0;
|
||||||
|
// if 0, then SHIFT+F# saves, F# loads (old VBA, ...)
|
||||||
|
// if 1, then SHIFT+F# loads, F# saves (linux snes9x, ...)
|
||||||
|
// if 2, then F5 decreases slot number, F6 increases, F7 saves, F8 loads
|
||||||
|
|
||||||
|
static int saveSlotPosition = 0; // default is the slot from normal F1
|
||||||
|
// internal slot number for undoing the last load
|
||||||
|
#define SLOT_POS_LOAD_BACKUP 8
|
||||||
|
// internal slot number for undoing the last save
|
||||||
|
#define SLOT_POS_SAVE_BACKUP 9
|
||||||
|
|
||||||
|
static int sdlOpenglScale = 1;
|
||||||
|
// will scale window on init by this much
|
||||||
|
static int sdlSoundToggledOff = 0;
|
||||||
|
// allow up to 100 IPS patches given on commandline
|
||||||
|
#define IPS_MAX_NUM 100
|
||||||
|
int sdl_ips_num = 0;
|
||||||
|
char * (sdl_ips_names[IPS_MAX_NUM]) = { NULL }; // and so on
|
||||||
|
|
||||||
|
#define REWIND_NUM 8
|
||||||
#define REWIND_SIZE 400000
|
#define REWIND_SIZE 400000
|
||||||
#define SYSMSG_BUFFER_SIZE 1024
|
#define SYSMSG_BUFFER_SIZE 1024
|
||||||
|
|
||||||
#define _stricmp strcasecmp
|
#define _stricmp strcasecmp
|
||||||
|
|
||||||
bool sdlButtons[4][12] = {
|
#define SDLBUTTONS_NUM 14
|
||||||
|
|
||||||
|
bool sdlButtons[4][SDLBUTTONS_NUM] = {
|
||||||
{ false, false, false, false, false, false,
|
{ false, false, false, false, false, false,
|
||||||
false, false, false, false, false, false },
|
false, false, false, false, false, false,
|
||||||
|
false, false
|
||||||
|
},
|
||||||
{ false, false, false, false, false, false,
|
{ false, false, false, false, false, false,
|
||||||
false, false, false, false, false, false },
|
false, false, false, false, false, false,
|
||||||
|
false, false
|
||||||
|
},
|
||||||
{ false, false, false, false, false, false,
|
{ false, false, false, false, false, false,
|
||||||
false, false, false, false, false, false },
|
false, false, false, false, false, false,
|
||||||
|
false, false
|
||||||
|
},
|
||||||
{ false, false, false, false, false, false,
|
{ false, false, false, false, false, false,
|
||||||
false, false, false, false, false, false }
|
false, false, false, false, false, false,
|
||||||
|
false, false
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool sdlMotionButtons[4] = { false, false, false, false };
|
bool sdlMotionButtons[4] = { false, false, false, false };
|
||||||
|
@ -211,6 +246,11 @@ int sdlMirroringEnable = 0;
|
||||||
|
|
||||||
int sdlDefaultJoypad = 0;
|
int sdlDefaultJoypad = 0;
|
||||||
|
|
||||||
|
static int ignore_first_resize_event = 0;
|
||||||
|
|
||||||
|
/* forward */
|
||||||
|
void systemConsoleMessage(const char*);
|
||||||
|
|
||||||
void (*dbgMain)() = debuggerMain;
|
void (*dbgMain)() = debuggerMain;
|
||||||
void (*dbgSignal)(int,int) = debuggerSignal;
|
void (*dbgSignal)(int,int) = debuggerSignal;
|
||||||
void (*dbgOutput)(const char *, u32) = debuggerOutput;
|
void (*dbgOutput)(const char *, u32) = debuggerOutput;
|
||||||
|
@ -231,29 +271,32 @@ enum {
|
||||||
KEY_BUTTON_A, KEY_BUTTON_B,
|
KEY_BUTTON_A, KEY_BUTTON_B,
|
||||||
KEY_BUTTON_START, KEY_BUTTON_SELECT,
|
KEY_BUTTON_START, KEY_BUTTON_SELECT,
|
||||||
KEY_BUTTON_L, KEY_BUTTON_R,
|
KEY_BUTTON_L, KEY_BUTTON_R,
|
||||||
KEY_BUTTON_SPEED, KEY_BUTTON_CAPTURE
|
KEY_BUTTON_SPEED, KEY_BUTTON_CAPTURE,
|
||||||
|
KEY_BUTTON_AUTO_A, KEY_BUTTON_AUTO_B
|
||||||
};
|
};
|
||||||
|
|
||||||
u16 joypad[4][12] = {
|
u16 joypad[4][SDLBUTTONS_NUM] = {
|
||||||
{ SDLK_LEFT, SDLK_RIGHT,
|
{ SDLK_LEFT, SDLK_RIGHT,
|
||||||
SDLK_UP, SDLK_DOWN,
|
SDLK_UP, SDLK_DOWN,
|
||||||
SDLK_z, SDLK_x,
|
SDLK_z, SDLK_x,
|
||||||
SDLK_RETURN,SDLK_BACKSPACE,
|
SDLK_RETURN,SDLK_BACKSPACE,
|
||||||
SDLK_a, SDLK_s,
|
SDLK_a, SDLK_s,
|
||||||
SDLK_SPACE, SDLK_F12
|
SDLK_SPACE, SDLK_F12,
|
||||||
|
SDLK_q, SDLK_w,
|
||||||
},
|
},
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
u16 defaultJoypad[12] = {
|
u16 defaultJoypad[SDLBUTTONS_NUM] = {
|
||||||
SDLK_LEFT, SDLK_RIGHT,
|
SDLK_LEFT, SDLK_RIGHT,
|
||||||
SDLK_UP, SDLK_DOWN,
|
SDLK_UP, SDLK_DOWN,
|
||||||
SDLK_z, SDLK_x,
|
SDLK_z, SDLK_x,
|
||||||
SDLK_RETURN,SDLK_BACKSPACE,
|
SDLK_RETURN,SDLK_BACKSPACE,
|
||||||
SDLK_a, SDLK_s,
|
SDLK_a, SDLK_s,
|
||||||
SDLK_SPACE, SDLK_F12
|
SDLK_SPACE, SDLK_F12,
|
||||||
|
SDLK_q, SDLK_w
|
||||||
};
|
};
|
||||||
|
|
||||||
u16 motion[4] = {
|
u16 motion[4] = {
|
||||||
|
@ -264,6 +307,10 @@ u16 defaultMotion[4] = {
|
||||||
SDLK_KP4, SDLK_KP6, SDLK_KP8, SDLK_KP2
|
SDLK_KP4, SDLK_KP6, SDLK_KP8, SDLK_KP2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int sdlPreparedCheats = 0;
|
||||||
|
#define MAX_CHEATS 100
|
||||||
|
const char * sdlPreparedCheatCodes[MAX_CHEATS];
|
||||||
|
|
||||||
struct option sdlOptions[] = {
|
struct option sdlOptions[] = {
|
||||||
{ "agb-print", no_argument, &sdlAgbPrint, 1 },
|
{ "agb-print", no_argument, &sdlAgbPrint, 1 },
|
||||||
{ "auto-frameskip", no_argument, &autoFrameSkip, 1 },
|
{ "auto-frameskip", no_argument, &autoFrameSkip, 1 },
|
||||||
|
@ -306,6 +353,7 @@ struct option sdlOptions[] = {
|
||||||
{ "show-speed-detailed", no_argument, &showSpeed, 2 },
|
{ "show-speed-detailed", no_argument, &showSpeed, 2 },
|
||||||
{ "throttle", required_argument, 0, 'T' },
|
{ "throttle", required_argument, 0, 'T' },
|
||||||
{ "verbose", required_argument, 0, 'v' },
|
{ "verbose", required_argument, 0, 'v' },
|
||||||
|
{ "cheat", required_argument, 0, 1000 },
|
||||||
{ NULL, no_argument, NULL, 0 }
|
{ NULL, no_argument, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -567,30 +615,46 @@ void sdlReadPreferences(FILE *f)
|
||||||
joypad[2][KEY_BUTTON_SPEED] = sdlFromHex(value);
|
joypad[2][KEY_BUTTON_SPEED] = sdlFromHex(value);
|
||||||
} else if(!strcmp(key, "Joy2_Capture")) {
|
} else if(!strcmp(key, "Joy2_Capture")) {
|
||||||
joypad[2][KEY_BUTTON_CAPTURE] = sdlFromHex(value);
|
joypad[2][KEY_BUTTON_CAPTURE] = sdlFromHex(value);
|
||||||
} else if(!strcmp(key,"Joy4_Left")) {
|
} else if(!strcmp(key,"Joy3_Left")) {
|
||||||
joypad[4][KEY_LEFT] = sdlFromHex(value);
|
joypad[3][KEY_LEFT] = sdlFromHex(value);
|
||||||
} else if(!strcmp(key, "Joy4_Right")) {
|
} else if(!strcmp(key, "Joy3_Right")) {
|
||||||
joypad[4][KEY_RIGHT] = sdlFromHex(value);
|
joypad[3][KEY_RIGHT] = sdlFromHex(value);
|
||||||
} else if(!strcmp(key, "Joy4_Up")) {
|
} else if(!strcmp(key, "Joy3_Up")) {
|
||||||
joypad[4][KEY_UP] = sdlFromHex(value);
|
joypad[3][KEY_UP] = sdlFromHex(value);
|
||||||
} else if(!strcmp(key, "Joy4_Down")) {
|
} else if(!strcmp(key, "Joy3_Down")) {
|
||||||
joypad[4][KEY_DOWN] = sdlFromHex(value);
|
joypad[3][KEY_DOWN] = sdlFromHex(value);
|
||||||
} else if(!strcmp(key, "Joy4_A")) {
|
} else if(!strcmp(key, "Joy3_A")) {
|
||||||
joypad[4][KEY_BUTTON_A] = sdlFromHex(value);
|
joypad[3][KEY_BUTTON_A] = sdlFromHex(value);
|
||||||
} else if(!strcmp(key, "Joy4_B")) {
|
} else if(!strcmp(key, "Joy3_B")) {
|
||||||
joypad[4][KEY_BUTTON_B] = sdlFromHex(value);
|
joypad[3][KEY_BUTTON_B] = sdlFromHex(value);
|
||||||
} else if(!strcmp(key, "Joy4_L")) {
|
} else if(!strcmp(key, "Joy3_L")) {
|
||||||
joypad[4][KEY_BUTTON_L] = sdlFromHex(value);
|
joypad[3][KEY_BUTTON_L] = sdlFromHex(value);
|
||||||
} else if(!strcmp(key, "Joy4_R")) {
|
} else if(!strcmp(key, "Joy3_R")) {
|
||||||
joypad[4][KEY_BUTTON_R] = sdlFromHex(value);
|
joypad[3][KEY_BUTTON_R] = sdlFromHex(value);
|
||||||
} else if(!strcmp(key, "Joy4_Start")) {
|
} else if(!strcmp(key, "Joy3_Start")) {
|
||||||
joypad[4][KEY_BUTTON_START] = sdlFromHex(value);
|
joypad[3][KEY_BUTTON_START] = sdlFromHex(value);
|
||||||
} else if(!strcmp(key, "Joy4_Select")) {
|
} else if(!strcmp(key, "Joy3_Select")) {
|
||||||
joypad[4][KEY_BUTTON_SELECT] = sdlFromHex(value);
|
joypad[3][KEY_BUTTON_SELECT] = sdlFromHex(value);
|
||||||
} else if(!strcmp(key, "Joy4_Speed")) {
|
} else if(!strcmp(key, "Joy3_Speed")) {
|
||||||
joypad[4][KEY_BUTTON_SPEED] = sdlFromHex(value);
|
joypad[3][KEY_BUTTON_SPEED] = sdlFromHex(value);
|
||||||
} else if(!strcmp(key, "Joy4_Capture")) {
|
} else if(!strcmp(key, "Joy3_Capture")) {
|
||||||
joypad[4][KEY_BUTTON_CAPTURE] = sdlFromHex(value);
|
joypad[3][KEY_BUTTON_CAPTURE] = sdlFromHex(value);
|
||||||
|
} else if(!strcmp(key, "Joy0_AutoA")) {
|
||||||
|
joypad[0][KEY_BUTTON_AUTO_A] = sdlFromHex(value);
|
||||||
|
} else if(!strcmp(key, "Joy0_AutoB")) {
|
||||||
|
joypad[0][KEY_BUTTON_AUTO_B] = sdlFromHex(value);
|
||||||
|
} else if(!strcmp(key, "Joy1_AutoA")) {
|
||||||
|
joypad[1][KEY_BUTTON_AUTO_A] = sdlFromHex(value);
|
||||||
|
} else if(!strcmp(key, "Joy1_AutoB")) {
|
||||||
|
joypad[1][KEY_BUTTON_AUTO_B] = sdlFromHex(value);
|
||||||
|
} else if(!strcmp(key, "Joy2_AutoA")) {
|
||||||
|
joypad[2][KEY_BUTTON_AUTO_A] = sdlFromHex(value);
|
||||||
|
} else if(!strcmp(key, "Joy2_AutoB")) {
|
||||||
|
joypad[2][KEY_BUTTON_AUTO_B] = sdlFromHex(value);
|
||||||
|
} else if(!strcmp(key, "Joy3_AutoA")) {
|
||||||
|
joypad[3][KEY_BUTTON_AUTO_A] = sdlFromHex(value);
|
||||||
|
} else if(!strcmp(key, "Joy3_AutoB")) {
|
||||||
|
joypad[3][KEY_BUTTON_AUTO_B] = sdlFromHex(value);
|
||||||
} else if(!strcmp(key, "openGL")) {
|
} else if(!strcmp(key, "openGL")) {
|
||||||
openGL = sdlFromHex(value);
|
openGL = sdlFromHex(value);
|
||||||
} else if(!strcmp(key, "Motion_Left")) {
|
} else if(!strcmp(key, "Motion_Left")) {
|
||||||
|
@ -710,6 +774,10 @@ void sdlReadPreferences(FILE *f)
|
||||||
if(rewindTimer < 0 || rewindTimer > 600)
|
if(rewindTimer < 0 || rewindTimer > 600)
|
||||||
rewindTimer = 0;
|
rewindTimer = 0;
|
||||||
rewindTimer *= 6; // convert value to 10 frames multiple
|
rewindTimer *= 6; // convert value to 10 frames multiple
|
||||||
|
} else if(!strcmp(key, "saveKeysSwitch")) {
|
||||||
|
sdlSaveKeysSwitch = sdlFromHex(value);
|
||||||
|
} else if(!strcmp(key, "openGLscale")) {
|
||||||
|
sdlOpenglScale = sdlFromHex(value);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Unknown configuration key %s\n", key);
|
fprintf(stderr, "Unknown configuration key %s\n", key);
|
||||||
}
|
}
|
||||||
|
@ -885,9 +953,13 @@ static int sdlCalculateShift(u32 mask)
|
||||||
return m-5;
|
return m-5;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sdlWriteState(int num)
|
/* returns filename of savestate num, in static buffer (not reentrant, no need to free,
|
||||||
|
* but value won't survive much - so if you want to remember it, dup it)
|
||||||
|
* You may use the buffer for something else though - until you call sdlStateName again
|
||||||
|
*/
|
||||||
|
static char * sdlStateName(int num)
|
||||||
{
|
{
|
||||||
char stateName[2048];
|
static char stateName[2048];
|
||||||
|
|
||||||
if(saveDir[0])
|
if(saveDir[0])
|
||||||
sprintf(stateName, "%s/%s%d.sgm", saveDir, sdlGetFilename(filename),
|
sprintf(stateName, "%s/%s%d.sgm", saveDir, sdlGetFilename(filename),
|
||||||
|
@ -897,36 +969,98 @@ void sdlWriteState(int num)
|
||||||
else
|
else
|
||||||
sprintf(stateName,"%s%d.sgm", filename, num+1);
|
sprintf(stateName,"%s%d.sgm", filename, num+1);
|
||||||
|
|
||||||
|
return stateName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sdlWriteState(int num)
|
||||||
|
{
|
||||||
|
char * stateName;
|
||||||
|
|
||||||
|
stateName = sdlStateName(num);
|
||||||
|
|
||||||
if(emulator.emuWriteState)
|
if(emulator.emuWriteState)
|
||||||
emulator.emuWriteState(stateName);
|
emulator.emuWriteState(stateName);
|
||||||
|
|
||||||
|
// now we reuse the stateName buffer - 2048 bytes fit in a lot
|
||||||
|
if (num == SLOT_POS_LOAD_BACKUP)
|
||||||
|
{
|
||||||
|
sprintf(stateName, "Current state backed up to %d", num+1);
|
||||||
|
systemScreenMessage(stateName);
|
||||||
|
}
|
||||||
|
else if (num>=0)
|
||||||
|
{
|
||||||
sprintf(stateName, "Wrote state %d", num+1);
|
sprintf(stateName, "Wrote state %d", num+1);
|
||||||
systemScreenMessage(stateName);
|
systemScreenMessage(stateName);
|
||||||
|
}
|
||||||
|
|
||||||
systemDrawScreen();
|
systemDrawScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sdlReadState(int num)
|
void sdlReadState(int num)
|
||||||
{
|
{
|
||||||
char stateName[2048];
|
char * stateName;
|
||||||
|
|
||||||
if(saveDir[0])
|
|
||||||
sprintf(stateName, "%s/%s%d.sgm", saveDir, sdlGetFilename(filename),
|
|
||||||
num+1);
|
|
||||||
else if (homeDir)
|
|
||||||
sprintf(stateName, "%s/%s/%s%d.sgm", homeDir, DOT_DIR, sdlGetFilename(filename), num + 1);
|
|
||||||
else
|
|
||||||
sprintf(stateName,"%s%d.sgm", filename, num+1);
|
|
||||||
|
|
||||||
|
stateName = sdlStateName(num);
|
||||||
if(emulator.emuReadState)
|
if(emulator.emuReadState)
|
||||||
emulator.emuReadState(stateName);
|
emulator.emuReadState(stateName);
|
||||||
|
|
||||||
|
if (num == SLOT_POS_LOAD_BACKUP)
|
||||||
|
{
|
||||||
|
sprintf(stateName, "Last load UNDONE");
|
||||||
|
} else
|
||||||
|
if (num == SLOT_POS_SAVE_BACKUP)
|
||||||
|
{
|
||||||
|
sprintf(stateName, "Last save UNDONE");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
sprintf(stateName, "Loaded state %d", num+1);
|
sprintf(stateName, "Loaded state %d", num+1);
|
||||||
|
}
|
||||||
systemScreenMessage(stateName);
|
systemScreenMessage(stateName);
|
||||||
|
|
||||||
systemDrawScreen();
|
systemDrawScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* perform savestate exchange
|
||||||
|
* - put the savestate in slot "to" to slot "backup" (unless backup == to)
|
||||||
|
* - put the savestate in slot "from" to slot "to" (unless from == to)
|
||||||
|
*/
|
||||||
|
void sdlWriteBackupStateExchange(int from, int to, int backup)
|
||||||
|
{
|
||||||
|
char * dmp;
|
||||||
|
char * stateNameOrig = NULL;
|
||||||
|
char * stateNameDest = NULL;
|
||||||
|
char * stateNameBack = NULL;
|
||||||
|
|
||||||
|
dmp = sdlStateName(from);
|
||||||
|
stateNameOrig = (char*)realloc(stateNameOrig, strlen(dmp) + 1);
|
||||||
|
strcpy(stateNameOrig, dmp);
|
||||||
|
dmp = sdlStateName(to);
|
||||||
|
stateNameDest = (char*)realloc(stateNameDest, strlen(dmp) + 1);
|
||||||
|
strcpy(stateNameDest, dmp);
|
||||||
|
dmp = sdlStateName(backup);
|
||||||
|
stateNameBack = (char*)realloc(stateNameBack, strlen(dmp) + 1);
|
||||||
|
strcpy(stateNameBack, dmp);
|
||||||
|
|
||||||
|
/* on POSIX, rename would not do anything anyway for identical names, but let's check it ourselves anyway */
|
||||||
|
if (to != backup) {
|
||||||
|
if (-1 == rename(stateNameDest, stateNameBack)) {
|
||||||
|
fprintf(stderr, "savestate backup: can't backup old state %s to %s", stateNameDest, stateNameBack );
|
||||||
|
perror(": ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (to != from) {
|
||||||
|
if (-1 == rename(stateNameOrig, stateNameDest)) {
|
||||||
|
fprintf(stderr, "savestate backup: can't move new state %s to %s", stateNameOrig, stateNameDest );
|
||||||
|
perror(": ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
systemConsoleMessage("Savestate store and backup committed"); // with timestamp and newline
|
||||||
|
fprintf(stderr, "to slot %d, backup in %d, using temporary slot %d\n", to+1, backup+1, from+1);
|
||||||
|
}
|
||||||
|
|
||||||
void sdlWriteBattery()
|
void sdlWriteBattery()
|
||||||
{
|
{
|
||||||
char buffer[1048];
|
char buffer[1048];
|
||||||
|
@ -974,6 +1108,7 @@ void sdlInitVideo() {
|
||||||
int screenHeight;
|
int screenHeight;
|
||||||
|
|
||||||
filter_enlarge = getFilterEnlargeFactor(filter);
|
filter_enlarge = getFilterEnlargeFactor(filter);
|
||||||
|
|
||||||
destWidth = filter_enlarge * srcWidth;
|
destWidth = filter_enlarge * srcWidth;
|
||||||
destHeight = filter_enlarge * srcHeight;
|
destHeight = filter_enlarge * srcHeight;
|
||||||
|
|
||||||
|
@ -1016,9 +1151,27 @@ void sdlInitVideo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(openGL) {
|
if(openGL) {
|
||||||
|
int scaledWidth = screenWidth * sdlOpenglScale;
|
||||||
|
int scaledHeight = screenHeight * sdlOpenglScale;
|
||||||
|
|
||||||
free(filterPix);
|
free(filterPix);
|
||||||
filterPix = (u8 *)calloc(1, (systemColorDepth >> 3) * destWidth * destHeight);
|
filterPix = (u8 *)calloc(1, (systemColorDepth >> 3) * destWidth * destHeight);
|
||||||
sdlOpenGLInit(screenWidth, screenHeight);
|
sdlOpenGLInit(screenWidth, screenHeight);
|
||||||
|
|
||||||
|
if ( (!fullscreen)
|
||||||
|
&& sdlOpenglScale > 1
|
||||||
|
&& scaledWidth < desktopWidth
|
||||||
|
&& scaledHeight < desktopHeight
|
||||||
|
) {
|
||||||
|
SDL_SetVideoMode(scaledWidth, scaledHeight, 0,
|
||||||
|
SDL_OPENGL | SDL_RESIZABLE |
|
||||||
|
(fullscreen ? SDL_FULLSCREEN : 0));
|
||||||
|
sdlOpenGLInit(scaledWidth, scaledHeight);
|
||||||
|
/* xKiv: it would seem that SDL_RESIZABLE causes the *previous* dimensions to be immediately
|
||||||
|
* reported back via the SDL_VIDEORESIZE event
|
||||||
|
*/
|
||||||
|
ignore_first_resize_event = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1032,7 +1185,7 @@ void sdlUpdateKey(int key, bool down)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(int j = 0; j < 4; j++) {
|
for(int j = 0; j < 4; j++) {
|
||||||
for(i = 0 ; i < 12; i++) {
|
for(i = 0 ; i < SDLBUTTONS_NUM; i++) {
|
||||||
if((joypad[j][i] & 0xf000) == 0) {
|
if((joypad[j][i] & 0xf000) == 0) {
|
||||||
if(key == joypad[j][i])
|
if(key == joypad[j][i])
|
||||||
sdlButtons[j][i] = down;
|
sdlButtons[j][i] = down;
|
||||||
|
@ -1053,7 +1206,7 @@ void sdlUpdateJoyButton(int which,
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(int j = 0; j < 4; j++) {
|
for(int j = 0; j < 4; j++) {
|
||||||
for(i = 0; i < 12; i++) {
|
for(i = 0; i < SDLBUTTONS_NUM; i++) {
|
||||||
int dev = (joypad[j][i] >> 12);
|
int dev = (joypad[j][i] >> 12);
|
||||||
int b = joypad[j][i] & 0xfff;
|
int b = joypad[j][i] & 0xfff;
|
||||||
if(dev) {
|
if(dev) {
|
||||||
|
@ -1084,7 +1237,7 @@ void sdlUpdateJoyHat(int which,
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(int j = 0; j < 4; j++) {
|
for(int j = 0; j < 4; j++) {
|
||||||
for(i = 0; i < 12; i++) {
|
for(i = 0; i < SDLBUTTONS_NUM; i++) {
|
||||||
int dev = (joypad[j][i] >> 12);
|
int dev = (joypad[j][i] >> 12);
|
||||||
int a = joypad[j][i] & 0xfff;
|
int a = joypad[j][i] & 0xfff;
|
||||||
if(dev) {
|
if(dev) {
|
||||||
|
@ -1147,7 +1300,7 @@ void sdlUpdateJoyAxis(int which,
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(int j = 0; j < 4; j++) {
|
for(int j = 0; j < 4; j++) {
|
||||||
for(i = 0; i < 12; i++) {
|
for(i = 0; i < SDLBUTTONS_NUM; i++) {
|
||||||
int dev = (joypad[j][i] >> 12);
|
int dev = (joypad[j][i] >> 12);
|
||||||
int a = joypad[j][i] & 0xfff;
|
int a = joypad[j][i] & 0xfff;
|
||||||
if(dev) {
|
if(dev) {
|
||||||
|
@ -1212,7 +1365,7 @@ void sdlCheckKeys()
|
||||||
bool usesJoy = false;
|
bool usesJoy = false;
|
||||||
|
|
||||||
for(int j = 0; j < 4; j++) {
|
for(int j = 0; j < 4; j++) {
|
||||||
for(i = 0; i < 12; i++) {
|
for(i = 0; i < SDLBUTTONS_NUM; i++) {
|
||||||
int dev = joypad[j][i] >> 12;
|
int dev = joypad[j][i] >> 12;
|
||||||
if(dev) {
|
if(dev) {
|
||||||
dev--;
|
dev--;
|
||||||
|
@ -1265,6 +1418,130 @@ void sdlCheckKeys()
|
||||||
SDL_JoystickEventState(SDL_ENABLE);
|
SDL_JoystickEventState(SDL_ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 04.02.2008 (xKiv): factored out from sdlPollEvents
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void change_rewind(int howmuch)
|
||||||
|
{
|
||||||
|
if( emulating && emulator.emuReadMemState && rewindMemory
|
||||||
|
&& rewindCount
|
||||||
|
) {
|
||||||
|
rewindPos = (rewindPos + rewindCount + howmuch) % rewindCount;
|
||||||
|
emulator.emuReadMemState(
|
||||||
|
&rewindMemory[REWIND_SIZE*rewindPos],
|
||||||
|
REWIND_SIZE
|
||||||
|
);
|
||||||
|
rewindCounter = 0;
|
||||||
|
{
|
||||||
|
char rewindMsgBuffer[50];
|
||||||
|
snprintf(rewindMsgBuffer, 50, "Rewind to %1d [%d]", rewindPos+1, rewindSerials[rewindPos]);
|
||||||
|
rewindMsgBuffer[49] = 0;
|
||||||
|
systemConsoleMessage(rewindMsgBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* handle the F* keys (for savestates)
|
||||||
|
* given the slot number and state of the SHIFT modifier, save or restore
|
||||||
|
* (in savemode 3, saveslot is stored in saveSlotPosition and num means:
|
||||||
|
* 4 .. F5: decrease slot number (down to 0)
|
||||||
|
* 5 .. F6: increase slot number (up to 7, because 8 and 9 are reserved for backups)
|
||||||
|
* 6 .. F7: save state
|
||||||
|
* 7 .. F8: load state
|
||||||
|
* (these *should* be configurable)
|
||||||
|
* other keys are ignored
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
static void sdlHandleSavestateKey(int num, int shifted)
|
||||||
|
{
|
||||||
|
int action = -1;
|
||||||
|
// 0: load
|
||||||
|
// 1: save
|
||||||
|
int backuping = 1; // controls whether we are doing savestate backups
|
||||||
|
|
||||||
|
if ( sdlSaveKeysSwitch == 2 )
|
||||||
|
{
|
||||||
|
// ignore "shifted"
|
||||||
|
switch (num)
|
||||||
|
{
|
||||||
|
// nb.: saveSlotPosition is base 0, but to the user, we show base 1 indexes (F## numbers)!
|
||||||
|
case 4:
|
||||||
|
if (saveSlotPosition > 0)
|
||||||
|
{
|
||||||
|
saveSlotPosition--;
|
||||||
|
fprintf(stderr, "Changed savestate slot to %d.\n", saveSlotPosition + 1);
|
||||||
|
} else
|
||||||
|
fprintf(stderr, "Can't decrease slotnumber below 1.\n");
|
||||||
|
return; // handled
|
||||||
|
case 5:
|
||||||
|
if (saveSlotPosition < 7)
|
||||||
|
{
|
||||||
|
saveSlotPosition++;
|
||||||
|
fprintf(stderr, "Changed savestate slot to %d.\n", saveSlotPosition + 1);
|
||||||
|
} else
|
||||||
|
fprintf(stderr, "Can't increase slotnumber above 8.\n");
|
||||||
|
return; // handled
|
||||||
|
case 6:
|
||||||
|
action = 1; // save
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
action = 0; // load
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// explicitly ignore
|
||||||
|
return; // handled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sdlSaveKeysSwitch == 0 ) /* "classic" VBA: shifted is save */
|
||||||
|
{
|
||||||
|
if (shifted)
|
||||||
|
action = 1; // save
|
||||||
|
else action = 0; // load
|
||||||
|
saveSlotPosition = num;
|
||||||
|
}
|
||||||
|
if (sdlSaveKeysSwitch == 1 ) /* "xKiv" VBA: shifted is load */
|
||||||
|
{
|
||||||
|
if (!shifted)
|
||||||
|
action = 1; // save
|
||||||
|
else action = 0; // load
|
||||||
|
saveSlotPosition = num;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action < 0 || action > 1)
|
||||||
|
{
|
||||||
|
fprintf(
|
||||||
|
stderr,
|
||||||
|
"sdlHandleSavestateKey(%d,%d), mode %d: unexpected action %d.\n",
|
||||||
|
num,
|
||||||
|
shifted,
|
||||||
|
sdlSaveKeysSwitch,
|
||||||
|
action
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action)
|
||||||
|
{ /* save */
|
||||||
|
if (backuping)
|
||||||
|
{
|
||||||
|
sdlWriteState(-1); // save to a special slot
|
||||||
|
sdlWriteBackupStateExchange(-1, saveSlotPosition, SLOT_POS_SAVE_BACKUP); // F10
|
||||||
|
} else {
|
||||||
|
sdlWriteState(saveSlotPosition);
|
||||||
|
}
|
||||||
|
} else { /* load */
|
||||||
|
if (backuping)
|
||||||
|
{
|
||||||
|
/* first back up where we are now */
|
||||||
|
sdlWriteState(SLOT_POS_LOAD_BACKUP); // F9
|
||||||
|
}
|
||||||
|
sdlReadState(saveSlotPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // sdlHandleSavestateKey
|
||||||
|
|
||||||
void sdlPollEvents()
|
void sdlPollEvents()
|
||||||
{
|
{
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
@ -1274,6 +1551,11 @@ void sdlPollEvents()
|
||||||
emulating = 0;
|
emulating = 0;
|
||||||
break;
|
break;
|
||||||
case SDL_VIDEORESIZE:
|
case SDL_VIDEORESIZE:
|
||||||
|
if (ignore_first_resize_event)
|
||||||
|
{
|
||||||
|
ignore_first_resize_event = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (openGL)
|
if (openGL)
|
||||||
{
|
{
|
||||||
SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
|
SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
|
||||||
|
@ -1341,19 +1623,57 @@ void sdlPollEvents()
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDLK_b:
|
case SDLK_b:
|
||||||
|
if(!(event.key.keysym.mod & MOD_NOCTRL) &&
|
||||||
|
(event.key.keysym.mod & KMOD_CTRL))
|
||||||
|
change_rewind(-1);
|
||||||
|
break;
|
||||||
|
case SDLK_v:
|
||||||
|
if(!(event.key.keysym.mod & MOD_NOCTRL) &&
|
||||||
|
(event.key.keysym.mod & KMOD_CTRL))
|
||||||
|
change_rewind(+1);
|
||||||
|
break;
|
||||||
|
case SDLK_h:
|
||||||
|
if(!(event.key.keysym.mod & MOD_NOCTRL) &&
|
||||||
|
(event.key.keysym.mod & KMOD_CTRL))
|
||||||
|
change_rewind(0);
|
||||||
|
break;
|
||||||
|
case SDLK_j:
|
||||||
|
if(!(event.key.keysym.mod & MOD_NOCTRL) &&
|
||||||
|
(event.key.keysym.mod & KMOD_CTRL))
|
||||||
|
change_rewind( (rewindTopPos - rewindPos) * ((rewindTopPos>rewindPos) ? +1:-1) );
|
||||||
|
break;
|
||||||
|
case SDLK_e:
|
||||||
if(!(event.key.keysym.mod & MOD_NOCTRL) &&
|
if(!(event.key.keysym.mod & MOD_NOCTRL) &&
|
||||||
(event.key.keysym.mod & KMOD_CTRL)) {
|
(event.key.keysym.mod & KMOD_CTRL)) {
|
||||||
if(emulating && emulator.emuReadMemState && rewindMemory
|
cheatsEnabled = !cheatsEnabled;
|
||||||
&& rewindCount) {
|
systemConsoleMessage(cheatsEnabled?"Cheats on":"Cheats off");
|
||||||
rewindPos = (rewindPos - 1) & 7;
|
}
|
||||||
emulator.emuReadMemState(&rewindMemory[REWIND_SIZE*rewindPos],
|
break;
|
||||||
REWIND_SIZE);
|
|
||||||
rewindCount--;
|
case SDLK_s:
|
||||||
rewindCounter = 0;
|
if(!(event.key.keysym.mod & MOD_NOCTRL) &&
|
||||||
systemScreenMessage("Rewind");
|
(event.key.keysym.mod & KMOD_CTRL)
|
||||||
|
) {
|
||||||
|
if (sdlSoundToggledOff) { // was off
|
||||||
|
// restore saved state
|
||||||
|
soundEnable(sdlSoundToggledOff);
|
||||||
|
soundDisable(~sdlSoundToggledOff);
|
||||||
|
sdlSoundToggledOff = 0;
|
||||||
|
systemConsoleMessage("Sound toggled on");
|
||||||
|
} else { // was on
|
||||||
|
sdlSoundToggledOff = soundGetEnable();
|
||||||
|
soundEnable(0);
|
||||||
|
soundDisable(sdlSoundToggledOff);
|
||||||
|
systemConsoleMessage("Sound toggled off");
|
||||||
|
if (!sdlSoundToggledOff) {
|
||||||
|
// if ON actually meant "all channels off" for some reason,
|
||||||
|
// remember that on "toggle to ON" we should unmute everything
|
||||||
|
sdlSoundToggledOff = 0x3ff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_p:
|
case SDLK_p:
|
||||||
if(!(event.key.keysym.mod & MOD_NOCTRL) &&
|
if(!(event.key.keysym.mod & MOD_NOCTRL) &&
|
||||||
(event.key.keysym.mod & KMOD_CTRL)) {
|
(event.key.keysym.mod & KMOD_CTRL)) {
|
||||||
|
@ -1361,6 +1681,7 @@ void sdlPollEvents()
|
||||||
SDL_PauseAudio(paused);
|
SDL_PauseAudio(paused);
|
||||||
if(paused)
|
if(paused)
|
||||||
wasPaused = true;
|
wasPaused = true;
|
||||||
|
systemConsoleMessage(paused?"Pause on":"Pause off");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDLK_ESCAPE:
|
case SDLK_ESCAPE:
|
||||||
|
@ -1408,13 +1729,26 @@ void sdlPollEvents()
|
||||||
case SDLK_F6:
|
case SDLK_F6:
|
||||||
case SDLK_F7:
|
case SDLK_F7:
|
||||||
case SDLK_F8:
|
case SDLK_F8:
|
||||||
case SDLK_F9:
|
|
||||||
case SDLK_F10:
|
|
||||||
if(!(event.key.keysym.mod & MOD_NOSHIFT) &&
|
if(!(event.key.keysym.mod & MOD_NOSHIFT) &&
|
||||||
(event.key.keysym.mod & KMOD_SHIFT)) {
|
(event.key.keysym.mod & KMOD_SHIFT)) {
|
||||||
sdlWriteState(event.key.keysym.sym-SDLK_F1);
|
sdlHandleSavestateKey( event.key.keysym.sym - SDLK_F1, 1); // with SHIFT
|
||||||
} else if(!(event.key.keysym.mod & MOD_KEYS)) {
|
} else if(!(event.key.keysym.mod & MOD_KEYS)) {
|
||||||
sdlReadState(event.key.keysym.sym-SDLK_F1);
|
sdlHandleSavestateKey( event.key.keysym.sym - SDLK_F1, 0); // without SHIFT
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
/* backups - only load */
|
||||||
|
case SDLK_F9:
|
||||||
|
/* F9 is "load backup" - saved state from *just before* the last restore */
|
||||||
|
if ( ! (event.key.keysym.mod & MOD_NOSHIFT) ) /* must work with or without shift, but only without other modifiers*/
|
||||||
|
{
|
||||||
|
sdlReadState(SLOT_POS_LOAD_BACKUP);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDLK_F10:
|
||||||
|
/* F10 is "save backup" - what was in the last overwritten savestate before we overwrote it*/
|
||||||
|
if ( ! (event.key.keysym.mod & MOD_NOSHIFT) ) /* must work with or without shift, but only without other modifiers*/
|
||||||
|
{
|
||||||
|
sdlReadState(SLOT_POS_SAVE_BACKUP);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDLK_1:
|
case SDLK_1:
|
||||||
|
@ -1549,9 +1883,49 @@ Long options only:\n\
|
||||||
--rtc Enable RTC support\n\
|
--rtc Enable RTC support\n\
|
||||||
--show-speed-normal Show emulation speed\n\
|
--show-speed-normal Show emulation speed\n\
|
||||||
--show-speed-detailed Show detailed speed data\n\
|
--show-speed-detailed Show detailed speed data\n\
|
||||||
|
--cheat 'CHEAT' add a cheat\n\
|
||||||
");
|
");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 04.02.2008 (xKiv) factored out, reformatted, more usefuler rewinds browsing scheme
|
||||||
|
*/
|
||||||
|
void handleRewinds()
|
||||||
|
{
|
||||||
|
int curSavePos; // where we are saving today [1]
|
||||||
|
|
||||||
|
rewindCount++; // how many rewinds will be stored after this store
|
||||||
|
if(rewindCount > REWIND_NUM)
|
||||||
|
rewindCount = REWIND_NUM;
|
||||||
|
|
||||||
|
curSavePos = (rewindTopPos + 1) % rewindCount; // [1] depends on previous
|
||||||
|
|
||||||
|
if(
|
||||||
|
emulator.emuWriteMemState
|
||||||
|
&&
|
||||||
|
emulator.emuWriteMemState(
|
||||||
|
&rewindMemory[curSavePos*REWIND_SIZE],
|
||||||
|
REWIND_SIZE
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
char rewMsgBuf[100];
|
||||||
|
snprintf(rewMsgBuf, 100, "Remembered rewind %1d (of %1d), serial %d.", curSavePos+1, rewindCount, rewindSerial);
|
||||||
|
rewMsgBuf[99] = 0;
|
||||||
|
systemConsoleMessage(rewMsgBuf);
|
||||||
|
rewindSerials[curSavePos] = rewindSerial;
|
||||||
|
|
||||||
|
// set up next rewind save
|
||||||
|
// - don't clobber the current rewind position, unless it is the original top
|
||||||
|
if (rewindPos == rewindTopPos) {
|
||||||
|
rewindPos = curSavePos;
|
||||||
|
}
|
||||||
|
// - new identification and top
|
||||||
|
rewindSerial++;
|
||||||
|
rewindTopPos = curSavePos;
|
||||||
|
// for the rest of the code, rewindTopPos will be where the newest rewind got stored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "VBA-M version %s [SDL]\n", VERSION);
|
fprintf(stderr, "VBA-M version %s [SDL]\n", VERSION);
|
||||||
|
@ -1597,6 +1971,19 @@ int main(int argc, char **argv)
|
||||||
case 0:
|
case 0:
|
||||||
// long option already processed by getopt_long
|
// long option already processed by getopt_long
|
||||||
break;
|
break;
|
||||||
|
case 1000:
|
||||||
|
// --cheat
|
||||||
|
if (sdlPreparedCheats >= MAX_CHEATS) {
|
||||||
|
fprintf(stderr, "Warning: cannot add more than %d cheats.\n", MAX_CHEATS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
char * cpy;
|
||||||
|
cpy = (char *)malloc(1 + strlen(optarg));
|
||||||
|
strcpy(cpy, optarg);
|
||||||
|
sdlPreparedCheatCodes[sdlPreparedCheats++] = cpy;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
useBios = true;
|
useBios = true;
|
||||||
if(optarg == NULL) {
|
if(optarg == NULL) {
|
||||||
|
@ -1630,7 +2017,14 @@ int main(int argc, char **argv)
|
||||||
if(optarg == NULL) {
|
if(optarg == NULL) {
|
||||||
fprintf(stderr, "Missing IPS name\n");
|
fprintf(stderr, "Missing IPS name\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
strcpy(ipsname, optarg);
|
}
|
||||||
|
// strcpy(ipsname, optarg);
|
||||||
|
if (sdl_ips_num >= IPS_MAX_NUM) {
|
||||||
|
fprintf(stderr, "Too many IPS patches given at %s (max is %d). Ignoring.\n", optarg, IPS_MAX_NUM);
|
||||||
|
} else {
|
||||||
|
sdl_ips_names[sdl_ips_num] = (char *)malloc(1 + strlen(optarg));
|
||||||
|
strcpy(sdl_ips_names[sdl_ips_num], optarg);
|
||||||
|
sdl_ips_num++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
|
@ -1753,8 +2147,10 @@ int main(int argc, char **argv)
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rewindTimer)
|
if(rewindTimer) {
|
||||||
rewindMemory = (char *)malloc(8*REWIND_SIZE);
|
rewindMemory = (char *)malloc(REWIND_NUM*REWIND_SIZE);
|
||||||
|
rewindSerials = (int *)calloc(REWIND_NUM, sizeof(int)); // init to zeroes
|
||||||
|
}
|
||||||
|
|
||||||
if(sdlFlashSize == 0)
|
if(sdlFlashSize == 0)
|
||||||
flashSetSize(0x10000);
|
flashSetSize(0x10000);
|
||||||
|
@ -1796,8 +2192,15 @@ int main(int argc, char **argv)
|
||||||
if(p)
|
if(p)
|
||||||
*p = 0;
|
*p = 0;
|
||||||
|
|
||||||
if(ipsname[0] == 0)
|
// if(ipsname[0] == 0)
|
||||||
|
// sprintf(ipsname, "%s.ips", filename);
|
||||||
|
if (sdl_ips_num == 0)
|
||||||
|
{
|
||||||
|
// no patch given yet - look for ROMBASENAME.ips
|
||||||
sprintf(ipsname, "%s.ips", filename);
|
sprintf(ipsname, "%s.ips", filename);
|
||||||
|
sdl_ips_names[0] = ipsname;
|
||||||
|
sdl_ips_num++;
|
||||||
|
}
|
||||||
|
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
|
|
||||||
|
@ -1822,8 +2225,12 @@ int main(int argc, char **argv)
|
||||||
cartridgeType = IMAGE_GB;
|
cartridgeType = IMAGE_GB;
|
||||||
emulator = GBSystem;
|
emulator = GBSystem;
|
||||||
if(sdlAutoIPS) {
|
if(sdlAutoIPS) {
|
||||||
int size = gbRomSize;
|
int size = gbRomSize, patchnum;
|
||||||
utilApplyIPS(ipsname, &gbRom, &size);
|
// utilApplyIPS(ipsname, &gbRom, &size);
|
||||||
|
for (patchnum = 0; patchnum < sdl_ips_num; patchnum++) {
|
||||||
|
fprintf(stderr, "Trying IPS patch %s.\n", sdl_ips_names[patchnum]);
|
||||||
|
utilApplyIPS(sdl_ips_names[patchnum], &gbRom, &size);
|
||||||
|
}
|
||||||
if(size != gbRomSize) {
|
if(size != gbRomSize) {
|
||||||
extern bool gbUpdateSizes();
|
extern bool gbUpdateSizes();
|
||||||
gbUpdateSizes();
|
gbUpdateSizes();
|
||||||
|
@ -1845,8 +2252,12 @@ int main(int argc, char **argv)
|
||||||
CPUInit(biosFileName, useBios);
|
CPUInit(biosFileName, useBios);
|
||||||
CPUReset();
|
CPUReset();
|
||||||
if(sdlAutoIPS) {
|
if(sdlAutoIPS) {
|
||||||
int size = 0x2000000;
|
int size = 0x2000000, patchnum;
|
||||||
utilApplyIPS(ipsname, &rom, &size);
|
// utilApplyIPS(ipsname, &rom, &size);
|
||||||
|
for (patchnum = 0; patchnum < sdl_ips_num; patchnum++) {
|
||||||
|
fprintf(stderr, "Trying IPS patch %s.\n", sdl_ips_names[patchnum]);
|
||||||
|
utilApplyIPS(sdl_ips_names[patchnum], &rom, &size);
|
||||||
|
}
|
||||||
if(size != 0x2000000) {
|
if(size != 0x2000000) {
|
||||||
CPUReset();
|
CPUReset();
|
||||||
}
|
}
|
||||||
|
@ -1963,6 +2374,27 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
SDL_WM_SetCaption("VisualBoyAdvance", NULL);
|
SDL_WM_SetCaption("VisualBoyAdvance", NULL);
|
||||||
|
|
||||||
|
// now we can enable cheats?
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0; i<sdlPreparedCheats; i++) {
|
||||||
|
const char * p;
|
||||||
|
int l;
|
||||||
|
p = sdlPreparedCheatCodes[i];
|
||||||
|
l = strlen(p);
|
||||||
|
if (l == 17 && p[8] == ':') {
|
||||||
|
fprintf(stderr,"Adding cheat code %s\n", p);
|
||||||
|
cheatsAddCheatCode(p, p);
|
||||||
|
} else if (l == 13 && p[8] == ' ') {
|
||||||
|
fprintf(stderr,"Adding CBA cheat code %s\n", p);
|
||||||
|
cheatsAddCBACode(p, p);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,"Unknown format for cheat code %s\n", p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
while(emulating) {
|
while(emulating) {
|
||||||
if(!paused && active) {
|
if(!paused && active) {
|
||||||
if(debugger && emulator.emuHasDebugger)
|
if(debugger && emulator.emuHasDebugger)
|
||||||
|
@ -1970,16 +2402,7 @@ int main(int argc, char **argv)
|
||||||
else {
|
else {
|
||||||
emulator.emuMain(emulator.emuCount);
|
emulator.emuMain(emulator.emuCount);
|
||||||
if(rewindSaveNeeded && rewindMemory && emulator.emuWriteMemState) {
|
if(rewindSaveNeeded && rewindMemory && emulator.emuWriteMemState) {
|
||||||
rewindCount++;
|
handleRewinds();
|
||||||
if(rewindCount > 8)
|
|
||||||
rewindCount = 8;
|
|
||||||
if(emulator.emuWriteMemState &&
|
|
||||||
emulator.emuWriteMemState(&rewindMemory[rewindPos*REWIND_SIZE],
|
|
||||||
REWIND_SIZE)) {
|
|
||||||
rewindPos = (rewindPos + 1) & 7;
|
|
||||||
if(rewindCount == 8)
|
|
||||||
rewindTopPos = (rewindTopPos + 1) & 7;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rewindSaveNeeded = false;
|
rewindSaveNeeded = false;
|
||||||
|
@ -2134,6 +2557,8 @@ bool systemReadJoypads()
|
||||||
|
|
||||||
u32 systemReadJoypad(int which)
|
u32 systemReadJoypad(int which)
|
||||||
{
|
{
|
||||||
|
int realAutoFire = autoFire;
|
||||||
|
|
||||||
if(which < 0 || which > 3)
|
if(which < 0 || which > 3)
|
||||||
which = sdlDefaultJoypad;
|
which = sdlDefaultJoypad;
|
||||||
|
|
||||||
|
@ -2159,6 +2584,10 @@ u32 systemReadJoypad(int which)
|
||||||
res |= 256;
|
res |= 256;
|
||||||
if(sdlButtons[which][KEY_BUTTON_L])
|
if(sdlButtons[which][KEY_BUTTON_L])
|
||||||
res |= 512;
|
res |= 512;
|
||||||
|
if(sdlButtons[which][KEY_BUTTON_AUTO_A])
|
||||||
|
realAutoFire ^= 1;
|
||||||
|
if(sdlButtons[which][KEY_BUTTON_AUTO_B])
|
||||||
|
realAutoFire ^= 2;
|
||||||
|
|
||||||
// disallow L+R or U+D of being pressed at the same time
|
// disallow L+R or U+D of being pressed at the same time
|
||||||
if((res & 48) == 48)
|
if((res & 48) == 48)
|
||||||
|
@ -2171,10 +2600,10 @@ u32 systemReadJoypad(int which)
|
||||||
if(sdlButtons[which][KEY_BUTTON_CAPTURE])
|
if(sdlButtons[which][KEY_BUTTON_CAPTURE])
|
||||||
res |= 2048;
|
res |= 2048;
|
||||||
|
|
||||||
if(autoFire) {
|
if(realAutoFire) {
|
||||||
res &= (~autoFire);
|
res &= (~realAutoFire);
|
||||||
if(autoFireToggle)
|
if(autoFireToggle)
|
||||||
res |= autoFire;
|
res |= realAutoFire;
|
||||||
autoFireToggle = !autoFireToggle;
|
autoFireToggle = !autoFireToggle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2364,8 +2793,30 @@ void systemGbPrint(u8 *data,int pages,int feed,int palette, int contrast)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* xKiv: added timestamp */
|
||||||
|
void systemConsoleMessage(const char *msg)
|
||||||
|
{
|
||||||
|
time_t now_time;
|
||||||
|
struct tm now_time_broken;
|
||||||
|
|
||||||
|
now_time = time(NULL);
|
||||||
|
now_time_broken = *(localtime( &now_time ));
|
||||||
|
fprintf(
|
||||||
|
stderr,
|
||||||
|
"%02d:%02d:%02d %02d.%02d.%4d: %s\n",
|
||||||
|
now_time_broken.tm_hour,
|
||||||
|
now_time_broken.tm_min,
|
||||||
|
now_time_broken.tm_sec,
|
||||||
|
now_time_broken.tm_mday,
|
||||||
|
now_time_broken.tm_mon + 1,
|
||||||
|
now_time_broken.tm_year + 1900,
|
||||||
|
msg
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void systemScreenMessage(const char *msg)
|
void systemScreenMessage(const char *msg)
|
||||||
{
|
{
|
||||||
|
|
||||||
screenMessage = true;
|
screenMessage = true;
|
||||||
screenMessageTime = systemGetClock();
|
screenMessageTime = systemGetClock();
|
||||||
if(strlen(msg) > 20) {
|
if(strlen(msg) > 20) {
|
||||||
|
@ -2373,6 +2824,8 @@ void systemScreenMessage(const char *msg)
|
||||||
screenMessageBuffer[20] = 0;
|
screenMessageBuffer[20] = 0;
|
||||||
} else
|
} else
|
||||||
strcpy(screenMessageBuffer, msg);
|
strcpy(screenMessageBuffer, msg);
|
||||||
|
|
||||||
|
systemConsoleMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool systemCanChangeSoundQuality()
|
bool systemCanChangeSoundQuality()
|
||||||
|
|
Loading…
Reference in New Issue