SPU2: clang-format, spu close before cdvd and remove unused refs

This commit is contained in:
Gauvain 'GovanifY' Roussel-Tarbouriech 2020-10-01 08:04:10 +02:00 committed by refractionpcsx2
parent b11ad72473
commit 655748f2d9
9 changed files with 1504 additions and 1342 deletions

View File

@ -34,8 +34,8 @@
HBlank 15.73426573 KHz */
// Misc IOP Clocks
#define PSXPIXEL ((int)(PSXCLK / 13500000))
#define PSXSOUNDCLK ((int)(48000))
#define PSXPIXEL ((int)(PSXCLK / 13500000))
#define PSXSOUNDCLK ((int)(48000))
psxCounter psxCounters[NUM_COUNTERS];
s32 psxNextCounter;
@ -44,19 +44,19 @@ u8 psxhblankgate = 0;
u8 psxvblankgate = 0;
// flags when the gate is off or counter disabled. (do not count)
#define IOPCNT_STOPPED (0x10000000ul)
#define IOPCNT_STOPPED (0x10000000ul)
// used to disable targets until after an overflow
#define IOPCNT_FUTURE_TARGET (0x1000000000ULL)
#define IOPCNT_FUTURE_TARGET (0x1000000000ULL)
#define IOPCNT_ENABLE_GATE (1<<0) // enables gate-based counters
#define IOPCNT_MODE_GATE (3<<1) // 0x6 Gate mode (dependant on counter)
#define IOPCNT_MODE_RESET (1<<3) // 0x8 resets the counter on target (if interrupt only?)
#define IOPCNT_INT_TARGET (1<<4) // 0x10 triggers an interrupt on targets
#define IOPCNT_INT_OVERFLOW (1<<5) // 0x20 triggers an interrupt on overflows
#define IOPCNT_INT_TOGGLE (1<<7) // 0x80 0=Pulse (reset on read), 1=toggle each interrupt condition (in 1 shot not reset after fired)
#define IOPCNT_ALT_SOURCE (1<<8) // 0x100 uses hblank on counters 1 and 3, and PSXCLOCK on counter 0
#define IOPCNT_INT_REQ (1<<10) // 0x400 1=Can fire interrupt, 0=Interrupt Fired (reset on read if not 1 shot)
#define IOPCNT_ENABLE_GATE (1 << 0) // enables gate-based counters
#define IOPCNT_MODE_GATE (3 << 1) // 0x6 Gate mode (dependant on counter)
#define IOPCNT_MODE_RESET (1 << 3) // 0x8 resets the counter on target (if interrupt only?)
#define IOPCNT_INT_TARGET (1 << 4) // 0x10 triggers an interrupt on targets
#define IOPCNT_INT_OVERFLOW (1 << 5) // 0x20 triggers an interrupt on overflows
#define IOPCNT_INT_TOGGLE (1 << 7) // 0x80 0=Pulse (reset on read), 1=toggle each interrupt condition (in 1 shot not reset after fired)
#define IOPCNT_ALT_SOURCE (1 << 8) // 0x100 uses hblank on counters 1 and 3, and PSXCLOCK on counter 0
#define IOPCNT_INT_REQ (1 << 10) // 0x400 1=Can fire interrupt, 0=Interrupt Fired (reset on read if not 1 shot)
// Use an arbitrary value to flag HBLANK counters.
// These counters will be counted by the hblank gates coming from the EE,
@ -66,13 +66,13 @@ u8 psxvblankgate = 0;
static void psxRcntReset(int index)
{
psxCounters[index].count = 0;
psxCounters[index].mode&= ~0x18301C00;
psxCounters[index].mode &= ~0x18301C00;
psxCounters[index].sCycleT = psxRegs.cycle;
}
static void _rcntSet( int cntidx )
static void _rcntSet(int cntidx)
{
u64 overflowCap = (cntidx>=3) ? 0x100000000ULL : 0x10000;
u64 overflowCap = (cntidx >= 3) ? 0x100000000ULL : 0x10000;
u64 c;
const psxCounter& counter = psxCounters[cntidx];
@ -82,52 +82,57 @@ static void _rcntSet( int cntidx )
// that into account. Adding the difference from that cycle count to the current one
// will do the trick!
if( counter.mode & IOPCNT_STOPPED || counter.rate == PSXHBLANK) return;
if (counter.mode & IOPCNT_STOPPED || counter.rate == PSXHBLANK)
return;
// check for special cases where the overflow or target has just passed
// (we probably missed it because we're doing/checking other things)
if( counter.count > overflowCap || counter.count > counter.target )
if (counter.count > overflowCap || counter.count > counter.target)
{
psxNextCounter = 4;
return;
}
c = (u64)((overflowCap - counter.count) * counter.rate) - (psxRegs.cycle - counter.sCycleT);
c += psxRegs.cycle - psxNextsCounter; // adjust for time passed since last rcntUpdate();
c += psxRegs.cycle - psxNextsCounter; // adjust for time passed since last rcntUpdate();
if(c < (u64)psxNextCounter)
if (c < (u64)psxNextCounter)
{
psxNextCounter = (u32)c;
psxSetNextBranch( psxNextsCounter, psxNextCounter ); //Need to update on counter resets/target changes
psxSetNextBranch(psxNextsCounter, psxNextCounter); //Need to update on counter resets/target changes
}
//if((counter.mode & 0x10) == 0 || psxCounters[i].target > 0xffff) continue;
if( counter.target & IOPCNT_FUTURE_TARGET ) return;
if (counter.target & IOPCNT_FUTURE_TARGET)
return;
c = (s64)((counter.target - counter.count) * counter.rate) - (psxRegs.cycle - counter.sCycleT);
c += psxRegs.cycle - psxNextsCounter; // adjust for time passed since last rcntUpdate();
c = (s64)((counter.target - counter.count) * counter.rate) - (psxRegs.cycle - counter.sCycleT);
c += psxRegs.cycle - psxNextsCounter; // adjust for time passed since last rcntUpdate();
if(c < (u64)psxNextCounter)
if (c < (u64)psxNextCounter)
{
psxNextCounter = (u32)c;
psxSetNextBranch( psxNextsCounter, psxNextCounter ); //Need to update on counter resets/target changes
psxSetNextBranch(psxNextsCounter, psxNextCounter); //Need to update on counter resets/target changes
}
}
void psxRcntInit() {
void psxRcntInit()
{
int i;
memzero( psxCounters );
memzero(psxCounters);
for (i=0; i<3; i++) {
for (i = 0; i < 3; i++)
{
psxCounters[i].rate = 1;
psxCounters[i].mode|= 0x0400;
psxCounters[i].mode |= 0x0400;
psxCounters[i].target = IOPCNT_FUTURE_TARGET;
}
for (i=3; i<6; i++) {
for (i = 3; i < 6; i++)
{
psxCounters[i].rate = 1;
psxCounters[i].mode|= 0x0400;
psxCounters[i].mode |= 0x0400;
psxCounters[i].target = IOPCNT_FUTURE_TARGET;
}
@ -139,18 +144,18 @@ void psxRcntInit() {
psxCounters[4].interrupt = 0x08000;
psxCounters[5].interrupt = 0x10000;
psxCounters[6].rate = 768*12;
psxCounters[6].CycleT = psxCounters[6].rate;
psxCounters[6].mode = 0x8;
psxCounters[6].rate = 768 * 12;
psxCounters[6].CycleT = psxCounters[6].rate;
psxCounters[6].mode = 0x8;
if (USBasync != NULL)
{
psxCounters[7].rate = PSXCLK/1000;
psxCounters[7].rate = PSXCLK / 1000;
psxCounters[7].CycleT = psxCounters[7].rate;
psxCounters[7].mode = 0x8;
}
for (i=0; i<8; i++)
for (i = 0; i < 8; i++)
psxCounters[i].sCycleT = psxRegs.cycle;
// Tell the IOP to branch ASAP, so that timers can get
@ -159,16 +164,19 @@ void psxRcntInit() {
psxNextsCounter = psxRegs.cycle;
}
static bool __fastcall _rcntFireInterrupt(int i, bool isOverflow) {
static bool __fastcall _rcntFireInterrupt(int i, bool isOverflow)
{
bool ret;
if (psxCounters[i].mode & 0x400) { //IRQ fired
if (psxCounters[i].mode & 0x400)
{ //IRQ fired
//DevCon.Warning("Counter %d %s IRQ Fired count %x", i, isOverflow ? "Overflow" : "Target", psxCounters[i].count);
psxHu32(0x1070) |= psxCounters[i].interrupt;
iopTestIntc();
ret = true;
}
else {
else
{
//DevCon.Warning("Counter %d IRQ not fired count %x", i, psxCounters[i].count);
ret = false;
if (!(psxCounters[i].mode & 0x40)) //One shot
@ -178,27 +186,30 @@ static bool __fastcall _rcntFireInterrupt(int i, bool isOverflow) {
}
}
if (psxCounters[i].mode & 0x80) { //Toggle mode
if (psxCounters[i].mode & 0x80)
{ //Toggle mode
psxCounters[i].mode ^= 0x400; // Interrupt flag inverted
}
else {
else
{
psxCounters[i].mode &= ~0x0400; // Interrupt flag set low
}
return ret;
}
static void __fastcall _rcntTestTarget( int i )
static void __fastcall _rcntTestTarget(int i)
{
if( psxCounters[i].count < psxCounters[i].target ) return;
if (psxCounters[i].count < psxCounters[i].target)
return;
PSXCNT_LOG("IOP Counter[%d] target 0x%I64x >= 0x%I64x (mode: %x)",
i, psxCounters[i].count, psxCounters[i].target, psxCounters[i].mode);
i, psxCounters[i].count, psxCounters[i].target, psxCounters[i].mode);
if (psxCounters[i].mode & IOPCNT_INT_TARGET)
{
// Target interrupt
if(_rcntFireInterrupt(i, false))
if (_rcntFireInterrupt(i, false))
psxCounters[i].mode |= 0x0800; // Target flag
}
@ -209,37 +220,39 @@ static void __fastcall _rcntTestTarget( int i )
}
else
psxCounters[i].target |= IOPCNT_FUTURE_TARGET;
}
static __fi void _rcntTestOverflow( int i )
static __fi void _rcntTestOverflow(int i)
{
u64 maxTarget = ( i < 3 ) ? 0xffff : 0xfffffffful;
if( psxCounters[i].count <= maxTarget ) return;
u64 maxTarget = (i < 3) ? 0xffff : 0xfffffffful;
if (psxCounters[i].count <= maxTarget)
return;
PSXCNT_LOG("IOP Counter[%d] overflow 0x%I64x >= 0x%I64x (mode: %x)",
i, psxCounters[i].count, maxTarget, psxCounters[i].mode );
i, psxCounters[i].count, maxTarget, psxCounters[i].mode);
if (!(psxCounters[i].mode & 0x40)) //One shot, whichever condition is met first
{
if (psxCounters[i].target < IOPCNT_FUTURE_TARGET) { //Target didn't trigger so we can overflow
if (psxCounters[i].target < IOPCNT_FUTURE_TARGET)
{ //Target didn't trigger so we can overflow
// Overflow interrupt
if ((psxCounters[i].mode & IOPCNT_INT_OVERFLOW)) {
if ((psxCounters[i].mode & IOPCNT_INT_OVERFLOW))
{
if (_rcntFireInterrupt(i, true))
psxCounters[i].mode |= 0x1000; // Overflow flag
psxCounters[i].mode |= 0x1000; // Overflow flag
}
}
psxCounters[i].target |= IOPCNT_FUTURE_TARGET;
}
else
{
// Overflow interrupt
if ((psxCounters[i].mode & IOPCNT_INT_OVERFLOW)) {
if ((psxCounters[i].mode & IOPCNT_INT_OVERFLOW))
{
if (_rcntFireInterrupt(i, true))
psxCounters[i].mode |= 0x1000; // Overflow flag
}
psxCounters[i].target &= maxTarget;
psxCounters[i].target &= maxTarget;
}
// Update count.
@ -248,9 +261,6 @@ static __fi void _rcntTestOverflow( int i )
// the counter value, and thus should not be flagged until after an overflow)
psxCounters[i].count -= maxTarget;
}
/*
@ -286,121 +296,125 @@ Gate:
<---->0==========================>============
*/
static void _psxCheckStartGate( int i )
static void _psxCheckStartGate(int i)
{
if(!(psxCounters[i].mode & IOPCNT_ENABLE_GATE)) return; //Ignore Gate
if (!(psxCounters[i].mode & IOPCNT_ENABLE_GATE))
return; //Ignore Gate
switch((psxCounters[i].mode & 0x6) >> 1)
switch ((psxCounters[i].mode & 0x6) >> 1)
{
case 0x0: //GATE_ON_count - stop count on gate start:
// get the current count at the time of stoppage:
psxCounters[i].count = ( i < 3 ) ?
psxRcntRcount16( i ) : psxRcntRcount32( i );
psxCounters[i].count = (i < 3) ?
psxRcntRcount16(i) :
psxRcntRcount32(i);
psxCounters[i].mode |= IOPCNT_STOPPED;
return;
return;
case 0x1: //GATE_ON_ClearStart - count normally with resets after every end gate
// do nothing - All counting will be done on a need-to-count basis.
return;
// do nothing - All counting will be done on a need-to-count basis.
return;
case 0x2: //GATE_ON_Clear_OFF_Start - start counting on gate start, stop on gate end
psxCounters[i].count = 0;
psxCounters[i].sCycleT = psxRegs.cycle;
psxCounters[i].mode &= ~IOPCNT_STOPPED;
break;
break;
case 0x3: //GATE_ON_Start - start and count normally on gate end (no restarts or stops or clears)
// do nothing!
return;
// do nothing!
return;
}
_rcntSet( i );
_rcntSet(i);
}
static void _psxCheckEndGate(int i)
{
if(!(psxCounters[i].mode & IOPCNT_ENABLE_GATE)) return; //Ignore Gate
if (!(psxCounters[i].mode & IOPCNT_ENABLE_GATE))
return; //Ignore Gate
switch((psxCounters[i].mode & 0x6) >> 1)
switch ((psxCounters[i].mode & 0x6) >> 1)
{
case 0x0: //GATE_ON_count - reset and start counting
case 0x1: //GATE_ON_ClearStart - count normally with resets after every end gate
psxCounters[i].count = 0;
psxCounters[i].sCycleT = psxRegs.cycle;
psxCounters[i].mode &= ~IOPCNT_STOPPED;
break;
break;
case 0x2: //GATE_ON_Clear_OFF_Start - start counting on gate start, stop on gate end
psxCounters[i].count = ( i < 3 ) ?
psxRcntRcount16( i ) : psxRcntRcount32( i );
psxCounters[i].count = (i < 3) ?
psxRcntRcount16(i) :
psxRcntRcount32(i);
psxCounters[i].mode |= IOPCNT_STOPPED;
return; // do not set the counter
return; // do not set the counter
case 0x3: //GATE_ON_Start - start and count normally (no restarts or stops or clears)
if( psxCounters[i].mode & IOPCNT_STOPPED )
if (psxCounters[i].mode & IOPCNT_STOPPED)
{
psxCounters[i].count = 0;
psxCounters[i].sCycleT = psxRegs.cycle;
psxCounters[i].mode &= ~IOPCNT_STOPPED;
}
break;
break;
}
_rcntSet( i );
_rcntSet(i);
}
void psxCheckStartGate16(int i)
{
pxAssert( i < 3 );
pxAssert(i < 3);
if(i == 0) // hSync counting...
if (i == 0) // hSync counting...
{
// AlternateSource/scanline counters for Gates 1 and 3.
// We count them here so that they stay nicely synced with the EE's hsync.
const u32 altSourceCheck = IOPCNT_ALT_SOURCE | IOPCNT_ENABLE_GATE;
const u32 stoppedGateCheck = (IOPCNT_STOPPED | altSourceCheck );
const u32 stoppedGateCheck = (IOPCNT_STOPPED | altSourceCheck);
// count if alt source is enabled and either:
// * the gate is enabled and not stopped.
// * the gate is disabled.
if( (psxCounters[1].mode & altSourceCheck) == IOPCNT_ALT_SOURCE ||
(psxCounters[1].mode & stoppedGateCheck ) == altSourceCheck )
if ((psxCounters[1].mode & altSourceCheck) == IOPCNT_ALT_SOURCE ||
(psxCounters[1].mode & stoppedGateCheck) == altSourceCheck)
{
psxCounters[1].count++;
_rcntTestTarget( 1 );
_rcntTestOverflow( 1 );
_rcntTestTarget(1);
_rcntTestOverflow(1);
}
if( (psxCounters[3].mode & altSourceCheck) == IOPCNT_ALT_SOURCE ||
(psxCounters[3].mode & stoppedGateCheck ) == altSourceCheck )
if ((psxCounters[3].mode & altSourceCheck) == IOPCNT_ALT_SOURCE ||
(psxCounters[3].mode & stoppedGateCheck) == altSourceCheck)
{
psxCounters[3].count++;
_rcntTestTarget( 3 );
_rcntTestOverflow( 3 );
_rcntTestTarget(3);
_rcntTestOverflow(3);
}
}
_psxCheckStartGate( i );
_psxCheckStartGate(i);
}
void psxCheckEndGate16(int i)
{
pxAssert(i < 3);
_psxCheckEndGate( i );
_psxCheckEndGate(i);
}
static void psxCheckStartGate32(int i)
{
// 32 bit gate is called for gate 3 only. Ever.
pxAssert(i == 3);
_psxCheckStartGate( i );
_psxCheckStartGate(i);
}
static void psxCheckEndGate32(int i)
{
pxAssert(i == 3);
_psxCheckEndGate( i );
_psxCheckEndGate(i);
}
@ -408,15 +422,19 @@ void psxVBlankStart()
{
cdvdVsync();
iopIntcIrq(0);
if(psxvblankgate & (1 << 1)) psxCheckStartGate16(1);
if(psxvblankgate & (1 << 3)) psxCheckStartGate32(3);
if (psxvblankgate & (1 << 1))
psxCheckStartGate16(1);
if (psxvblankgate & (1 << 3))
psxCheckStartGate32(3);
}
void psxVBlankEnd()
{
iopIntcIrq(11);
if(psxvblankgate & (1 << 1)) psxCheckEndGate16(1);
if(psxvblankgate & (1 << 3)) psxCheckEndGate32(3);
if (psxvblankgate & (1 << 1))
psxCheckEndGate16(1);
if (psxvblankgate & (1 << 3))
psxCheckEndGate32(3);
}
void psxRcntUpdate()
@ -429,26 +447,30 @@ void psxRcntUpdate()
psxNextCounter = 0x7fffffff;
psxNextsCounter = psxRegs.cycle;
for (i=0; i<=5; i++)
for (i = 0; i <= 5; i++)
{
s32 change = psxRegs.cycle - psxCounters[i].sCycleT;
// don't count disabled or hblank counters...
// We can't check the ALTSOURCE flag because the PSXCLOCK source *should*
// be counted here.
if( psxCounters[i].mode & IOPCNT_STOPPED ) continue;
if ((psxCounters[i].mode & 0x40) && !(psxCounters[i].mode & 0x80)) { //Repeat IRQ mode Pulsed, resets a few cycles after the interrupt, this should do.
if (psxCounters[i].mode & IOPCNT_STOPPED)
continue;
if ((psxCounters[i].mode & 0x40) && !(psxCounters[i].mode & 0x80))
{ //Repeat IRQ mode Pulsed, resets a few cycles after the interrupt, this should do.
psxCounters[i].mode |= 0x400;
}
if( psxCounters[i].rate == PSXHBLANK ) continue;
if( change <= 0 ) continue;
if (psxCounters[i].rate == PSXHBLANK)
continue;
if (change <= 0)
continue;
psxCounters[i].count += change / psxCounters[i].rate;
if(psxCounters[i].rate != 1)
if (psxCounters[i].rate != 1)
{
change -= (change / psxCounters[i].rate) * psxCounters[i].rate;
psxCounters[i].sCycleT = psxRegs.cycle - change;
@ -461,15 +483,17 @@ void psxRcntUpdate()
// Optimization Note: This approach is very sound. Please do not try to unroll it
// as the size of the Test functions will cause code cache clutter and slowness.
for( i=0; i<6; i++ )
for (i = 0; i < 6; i++)
{
// don't do target/oveflow checks for hblankers. Those
// checks are done when the counters are updated.
if( psxCounters[i].rate == PSXHBLANK ) continue;
if( psxCounters[i].mode & IOPCNT_STOPPED ) continue;
if (psxCounters[i].rate == PSXHBLANK)
continue;
if (psxCounters[i].mode & IOPCNT_STOPPED)
continue;
_rcntTestTarget( i );
_rcntTestOverflow( i );
_rcntTestTarget(i);
_rcntTestOverflow(i);
// perform second target test because if we overflowed above it's possible we
// already shot past our target if it was very near zero.
@ -478,37 +502,41 @@ void psxRcntUpdate()
}
const s32 difference = psxRegs.cycle - psxCounters[6].sCycleT;
s32 c = psxCounters[6].CycleT;
const s32 difference = psxRegs.cycle - psxCounters[6].sCycleT;
s32 c = psxCounters[6].CycleT;
if(difference >= psxCounters[6].CycleT)
{
SPU2async(difference);
psxCounters[6].sCycleT = psxRegs.cycle;
psxCounters[6].CycleT = psxCounters[6].rate;
}
else c -= difference;
psxNextCounter = c;
if (difference >= psxCounters[6].CycleT)
{
SPU2async(difference);
psxCounters[6].sCycleT = psxRegs.cycle;
psxCounters[6].CycleT = psxCounters[6].rate;
}
else
c -= difference;
psxNextCounter = c;
if (DEV9async)
{
DEV9async(1);
}
if(USBasync)
if (USBasync)
{
const s32 difference = psxRegs.cycle - psxCounters[7].sCycleT;
s32 c = psxCounters[7].CycleT;
if(difference >= psxCounters[7].CycleT)
if (difference >= psxCounters[7].CycleT)
{
USBasync(difference);
psxCounters[7].sCycleT = psxRegs.cycle;
psxCounters[7].CycleT = psxCounters[7].rate;
}
else c -= difference;
if (c < psxNextCounter) psxNextCounter = c;
else
c -= difference;
if (c < psxNextCounter)
psxNextCounter = c;
}
for (i=0; i<6; i++) _rcntSet( i );
for (i = 0; i < 6; i++)
_rcntSet(i);
}
//////////////////////////////////////////////////////////////////////////////////////////
@ -517,10 +545,10 @@ void psxRcntWcount16(int index, u16 value)
{
u32 change;
pxAssert( index < 3 );
pxAssert(index < 3);
//DevCon.Warning("16bit IOP Counter[%d] writeCount16 = %x", index, value);
if(psxCounters[index].rate != PSXHBLANK)
if (psxCounters[index].rate != PSXHBLANK)
{
// Re-adjust the sCycleT to match where the counter is currently
// (remainder of the rate divided into the time passed will do the trick)
@ -530,14 +558,16 @@ void psxRcntWcount16(int index, u16 value)
}
psxCounters[index].count = value & 0xffff;
if ((psxCounters[index].mode & 0x400) || (psxCounters[index].mode & 0x40)) {
if ((psxCounters[index].mode & 0x400) || (psxCounters[index].mode & 0x40))
{
psxCounters[index].target &= 0xffff;
}
if (value > psxCounters[index].target) {//Count already higher than Target
// DevCon.Warning("16bit Count already higher than target");
if (value > psxCounters[index].target)
{ //Count already higher than Target
// DevCon.Warning("16bit Count already higher than target");
psxCounters[index].target |= IOPCNT_FUTURE_TARGET;
}
_rcntSet( index );
_rcntSet(index);
}
//////////////////////////////////////////////////////////////////////////////////////////
@ -546,10 +576,10 @@ void psxRcntWcount32(int index, u32 value)
{
u32 change;
pxAssert( index >= 3 && index < 6 );
pxAssert(index >= 3 && index < 6);
PSXCNT_LOG("32bit IOP Counter[%d] writeCount32 = %x", index, value);
if(psxCounters[index].rate != PSXHBLANK)
if (psxCounters[index].rate != PSXHBLANK)
{
// Re-adjust the sCycleT to match where the counter is currently
// (remainder of the rate divided into the time passed will do the trick)
@ -559,14 +589,16 @@ void psxRcntWcount32(int index, u32 value)
}
psxCounters[index].count = value;
if ((psxCounters[index].mode & 0x400) || (psxCounters[index].mode & 0x40)) { //IRQ not triggered (one shot) or toggle
if ((psxCounters[index].mode & 0x400) || (psxCounters[index].mode & 0x40))
{ //IRQ not triggered (one shot) or toggle
psxCounters[index].target &= 0xffffffff;
}
if (value > psxCounters[index].target) {//Count already higher than Target
if (value > psxCounters[index].target)
{ //Count already higher than Target
//DevCon.Warning("32bit Count already higher than target");
psxCounters[index].target |= IOPCNT_FUTURE_TARGET;
}
_rcntSet( index );
_rcntSet(index);
}
//////////////////////////////////////////////////////////////////////////////////////////
@ -582,35 +614,44 @@ __fi void psxRcntWmode16(int index, u32 value)
counter.mode = value;
counter.mode |= 0x0400; //IRQ Enable
if (value & (1 << 4)) {
if (value & (1 << 4))
{
irqmode += 1;
}
if (value & (1 << 5)) {
if (value & (1 << 5))
{
irqmode += 2;
}
if (value & (1 << 7)) {
if (value & (1 << 7))
{
PSXCNT_LOG("16 Counter %d Toggle IRQ on %s", index, (irqmode & 3) == 1 ? "Target" : ((irqmode & 3) == 2 ? "Overflow" : "Target and Overflow"));
}
else
{
PSXCNT_LOG("16 Counter %d Pulsed IRQ on %s", index, (irqmode & 3) == 1 ? "Target" : ((irqmode & 3) == 2 ? "Overflow" : "Target and Overflow"));
}
if (!(value & (1 << 6))) {
if (!(value & (1 << 6)))
{
PSXCNT_LOG("16 Counter %d One Shot", index);
}
else {
else
{
PSXCNT_LOG("16 Counter %d Repeat", index);
}
if( index == 2 )
if (index == 2)
{
switch(value & 0x200)
switch (value & 0x200)
{
case 0x000: psxCounters[2].rate = 1; break;
case 0x200: psxCounters[2].rate = 8; break;
jNO_DEFAULT;
case 0x000:
psxCounters[2].rate = 1;
break;
case 0x200:
psxCounters[2].rate = 8;
break;
jNO_DEFAULT;
}
if((counter.mode & 0x7) == 0x7 || (counter.mode & 0x7) == 0x1)
if ((counter.mode & 0x7) == 0x7 || (counter.mode & 0x7) == 0x1)
{
counter.mode |= IOPCNT_STOPPED;
}
@ -620,26 +661,26 @@ __fi void psxRcntWmode16(int index, u32 value)
// Counters 0 and 1 can select PIXEL or HSYNC as an alternate source:
counter.rate = 1;
if(value & IOPCNT_ALT_SOURCE)
counter.rate = (index==0) ? PSXPIXEL : PSXHBLANK;
if (value & IOPCNT_ALT_SOURCE)
counter.rate = (index == 0) ? PSXPIXEL : PSXHBLANK;
if(counter.mode & IOPCNT_ENABLE_GATE)
if (counter.mode & IOPCNT_ENABLE_GATE)
{
// gated counters are added up as per the h/vblank timers.
// (the PIXEL alt source becomes a vsync gate)
counter.mode |= IOPCNT_STOPPED;
PSXCNT_LOG( "IOP Counter[%d] Gate Check set, value = 0x%04X", index, value );
if( index == 0 )
psxhblankgate |= 1; // fixme: these gate flags should be one var >_<
PSXCNT_LOG("IOP Counter[%d] Gate Check set, value = 0x%04X", index, value);
if (index == 0)
psxhblankgate |= 1; // fixme: these gate flags should be one var >_<
else
psxvblankgate |= 1<<1;
psxvblankgate |= 1 << 1;
}
else
{
if( index == 0 )
if (index == 0)
psxhblankgate &= ~1;
else
psxvblankgate &= ~(1<<1);
psxvblankgate &= ~(1 << 1);
}
}
@ -647,70 +688,84 @@ __fi void psxRcntWmode16(int index, u32 value)
counter.sCycleT = psxRegs.cycle;
counter.target &= 0xffff;
_rcntSet( index );
_rcntSet(index);
}
//////////////////////////////////////////////////////////////////////////////////////////
//
__fi void psxRcntWmode32( int index, u32 value )
__fi void psxRcntWmode32(int index, u32 value)
{
PSXCNT_LOG("32bit IOP Counter[%d] writeMode = 0x%04x", index, value );
PSXCNT_LOG("32bit IOP Counter[%d] writeMode = 0x%04x", index, value);
int irqmode = 0;
pxAssume( index >= 3 && index < 6 );
pxAssume(index >= 3 && index < 6);
psxCounter& counter = psxCounters[index];
counter.mode = value;
counter.mode = value;
counter.mode |= 0x0400; //IRQ enable
if (value & (1 << 4)) {
if (value & (1 << 4))
{
irqmode += 1;
}
if (value & (1 << 5)) {
if (value & (1 << 5))
{
irqmode += 2;
}
if (value & (1 << 7)) {
if (value & (1 << 7))
{
PSXCNT_LOG("32 Counter %d Toggle IRQ on %s", index, (irqmode & 3) == 1 ? "Target" : ((irqmode & 3) == 2 ? "Overflow" : "Target and Overflow"));
}
else
{
PSXCNT_LOG("32 Counter %d Pulsed IRQ on %s", index, (irqmode & 3) == 1 ? "Target" : ((irqmode & 3) == 2 ? "Overflow" : "Target and Overflow"));
}
if (!(value & (1 << 6))) {
PSXCNT_LOG("32 Counter %d One Shot", index);
}
else {
PSXCNT_LOG("32 Counter %d Repeat", index);
}
if( index == 3 )
if (!(value & (1 << 6)))
{
// Counter 3 has the HBlank as an alternate source.
counter.rate = 1;
if(value & IOPCNT_ALT_SOURCE)
counter.rate = PSXHBLANK;
if(counter.mode & IOPCNT_ENABLE_GATE)
{
PSXCNT_LOG("IOP Counter[3] Gate Check set, value = %x", value);
counter.mode |= IOPCNT_STOPPED;
psxvblankgate |= 1<<3;
}
else psxvblankgate &= ~(1<<3);
PSXCNT_LOG("32 Counter %d One Shot", index);
}
else
{
switch(value & 0x6000)
PSXCNT_LOG("32 Counter %d Repeat", index);
}
if (index == 3)
{
// Counter 3 has the HBlank as an alternate source.
counter.rate = 1;
if (value & IOPCNT_ALT_SOURCE)
counter.rate = PSXHBLANK;
if (counter.mode & IOPCNT_ENABLE_GATE)
{
case 0x0000: counter.rate = 1; break;
case 0x2000: counter.rate = 8; break;
case 0x4000: counter.rate = 16; break;
case 0x6000: counter.rate = 256; break;
PSXCNT_LOG("IOP Counter[3] Gate Check set, value = %x", value);
counter.mode |= IOPCNT_STOPPED;
psxvblankgate |= 1 << 3;
}
else
psxvblankgate &= ~(1 << 3);
}
else
{
switch (value & 0x6000)
{
case 0x0000:
counter.rate = 1;
break;
case 0x2000:
counter.rate = 8;
break;
case 0x4000:
counter.rate = 16;
break;
case 0x6000:
counter.rate = 256;
break;
}
// Need to set a rate and target
if((counter.mode & 0x7) == 0x7 || (counter.mode & 0x7) == 0x1)
if ((counter.mode & 0x7) == 0x7 || (counter.mode & 0x7) == 0x1)
{
Console.WriteLn( "Gate set on IOP Counter %d, disabling", index );
Console.WriteLn("Gate set on IOP Counter %d, disabling", index);
counter.mode |= IOPCNT_STOPPED;
}
}
@ -718,14 +773,14 @@ __fi void psxRcntWmode32( int index, u32 value )
counter.count = 0;
counter.sCycleT = psxRegs.cycle;
counter.target &= 0xffffffff;
_rcntSet( index );
_rcntSet(index);
}
//////////////////////////////////////////////////////////////////////////////////////////
//
void psxRcntWtarget16(int index, u32 value)
{
pxAssert( index < 3 );
pxAssert(index < 3);
//DevCon.Warning("IOP Counter[%d] writeTarget16 = %lx", index, value);
psxCounters[index].target = value & 0xffff;
@ -733,19 +788,20 @@ void psxRcntWtarget16(int index, u32 value)
// if the target is behind the current count, then set the target overflow
// flag, so that the target won't be active until after the next overflow.
if(psxCounters[index].target <= psxRcntCycles(index) || ((psxCounters[index].mode & 0x400) == 0 && !(psxCounters[index].mode & 0x40)))
if (psxCounters[index].target <= psxRcntCycles(index) || ((psxCounters[index].mode & 0x400) == 0 && !(psxCounters[index].mode & 0x40)))
psxCounters[index].target |= IOPCNT_FUTURE_TARGET;
_rcntSet( index );
_rcntSet(index);
}
void psxRcntWtarget32(int index, u32 value)
{
pxAssert( index >= 3 && index < 6);
pxAssert(index >= 3 && index < 6);
//DevCon.Warning("IOP Counter[%d] writeTarget32 = %lx mode %x", index, value, psxCounters[index].mode);
psxCounters[index].target = value;
if (!(psxCounters[index].mode & 0x80)) { //Toggle mode
if (!(psxCounters[index].mode & 0x80))
{ //Toggle mode
psxCounters[index].mode |= 0x0400; // Interrupt flag set low
}
// protect the target from an early arrival.
@ -755,26 +811,26 @@ void psxRcntWtarget32(int index, u32 value)
if (psxCounters[index].target <= psxRcntCycles(index) || ((psxCounters[index].mode & 0x400) == 0 && !(psxCounters[index].mode & 0x40)))
psxCounters[index].target |= IOPCNT_FUTURE_TARGET;
_rcntSet( index );
_rcntSet(index);
}
u16 psxRcntRcount16(int index)
{
u32 retval = (u32)psxCounters[index].count;
pxAssert( index < 3 );
pxAssert(index < 3);
PSXCNT_LOG("IOP Counter[%d] readCount16 = %lx", index, (u16)retval );
PSXCNT_LOG("IOP Counter[%d] readCount16 = %lx", index, (u16)retval);
// Don't count HBLANK timers
// Don't count stopped gates either.
if( !( psxCounters[index].mode & IOPCNT_STOPPED ) &&
( psxCounters[index].rate != PSXHBLANK ) )
if (!(psxCounters[index].mode & IOPCNT_STOPPED) &&
(psxCounters[index].rate != PSXHBLANK))
{
u32 delta = (u32)((psxRegs.cycle - psxCounters[index].sCycleT) / psxCounters[index].rate);
retval += delta;
PSXCNT_LOG(" (delta = %lx)", delta );
PSXCNT_LOG(" (delta = %lx)", delta);
}
return (u16)retval;
@ -784,16 +840,16 @@ u32 psxRcntRcount32(int index)
{
u32 retval = (u32)psxCounters[index].count;
pxAssert( index >= 3 && index < 6 );
pxAssert(index >= 3 && index < 6);
PSXCNT_LOG("IOP Counter[%d] readCount32 = %lx", index, retval );
PSXCNT_LOG("IOP Counter[%d] readCount32 = %lx", index, retval);
if( !( psxCounters[index].mode & IOPCNT_STOPPED ) &&
( psxCounters[index].rate != PSXHBLANK ) )
if (!(psxCounters[index].mode & IOPCNT_STOPPED) &&
(psxCounters[index].rate != PSXHBLANK))
{
u32 delta = (u32)((psxRegs.cycle - psxCounters[index].sCycleT) / psxCounters[index].rate);
retval += delta;
PSXCNT_LOG(" (delta = %lx)", delta );
PSXCNT_LOG(" (delta = %lx)", delta);
}
return retval;
@ -801,36 +857,37 @@ u32 psxRcntRcount32(int index)
u64 psxRcntCycles(int index)
{
if(psxCounters[index].mode & IOPCNT_STOPPED || psxCounters[index].rate == PSXHBLANK ) return psxCounters[index].count;
if (psxCounters[index].mode & IOPCNT_STOPPED || psxCounters[index].rate == PSXHBLANK)
return psxCounters[index].count;
return (u64)(psxCounters[index].count + (u32)((psxRegs.cycle - psxCounters[index].sCycleT) / psxCounters[index].rate));
}
void psxRcntSetGates()
{
if(psxCounters[0].mode & IOPCNT_ENABLE_GATE)
if (psxCounters[0].mode & IOPCNT_ENABLE_GATE)
psxhblankgate |= 1;
else
psxhblankgate &= ~1;
if(psxCounters[1].mode & IOPCNT_ENABLE_GATE)
psxvblankgate |= 1<<1;
if (psxCounters[1].mode & IOPCNT_ENABLE_GATE)
psxvblankgate |= 1 << 1;
else
psxvblankgate &= ~(1<<1);
psxvblankgate &= ~(1 << 1);
if(psxCounters[3].mode & IOPCNT_ENABLE_GATE)
psxvblankgate |= 1<<3;
if (psxCounters[3].mode & IOPCNT_ENABLE_GATE)
psxvblankgate |= 1 << 3;
else
psxvblankgate &= ~(1<<3);
psxvblankgate &= ~(1 << 3);
}
void SaveStateBase::psxRcntFreeze()
{
FreezeTag( "iopCounters" );
FreezeTag("iopCounters");
Freeze(psxCounters);
Freeze(psxCounters);
Freeze(psxNextCounter);
Freeze(psxNextsCounter);
if( IsLoading() )
if (IsLoading())
psxRcntSetGates();
}

View File

@ -43,12 +43,6 @@ namespace soundtouch
#include "Pcsx2Defs.h"
#include "Pcsx2Types.h"
namespace VersionInfo
{
static const u8 Release = 2;
static const u8 Revision = 0; // increase that with each version
} // namespace VersionInfo
//////////////////////////////////////////////////////////////////////////
// Override Win32 min/max macros with the STL's type safe and macro
// free varieties (much safer!)

View File

@ -37,7 +37,7 @@
#include "IopBios.h"
#ifdef __WXMSW__
# include <wx/msw/wrapwin.h>
#include <wx/msw/wrapwin.h>
#endif
#include "x86emitter/x86_intrin.h"
@ -49,35 +49,36 @@
SysCoreThread::SysCoreThread()
{
m_name = L"EE Core";
m_resetRecompilers = true;
m_resetProfilers = true;
m_resetVsyncTimers = true;
m_resetVirtualMachine = true;
m_name = L"EE Core";
m_resetRecompilers = true;
m_resetProfilers = true;
m_resetVsyncTimers = true;
m_resetVirtualMachine = true;
m_hasActiveMachine = false;
m_hasActiveMachine = false;
}
SysCoreThread::~SysCoreThread()
{
try {
try
{
SysCoreThread::Cancel();
}
DESTRUCTOR_CATCHALL
}
void SysCoreThread::Cancel( bool isBlocking )
void SysCoreThread::Cancel(bool isBlocking)
{
m_hasActiveMachine = false;
R3000A::ioman::reset();
_parent::Cancel();
}
bool SysCoreThread::Cancel( const wxTimeSpan& span )
bool SysCoreThread::Cancel(const wxTimeSpan& span)
{
m_hasActiveMachine = false;
R3000A::ioman::reset();
return _parent::Cancel( span );
return _parent::Cancel(span);
}
void SysCoreThread::OnStart()
@ -87,9 +88,10 @@ void SysCoreThread::OnStart()
void SysCoreThread::Start()
{
if( !GetCorePlugins().AreLoaded() ) return;
if (!GetCorePlugins().AreLoaded())
return;
GetCorePlugins().Init();
SPU2init();
SPU2init();
_parent::Start();
}
@ -104,17 +106,17 @@ void SysCoreThread::Start()
//
void SysCoreThread::OnResumeReady()
{
if( m_resetVirtualMachine )
if (m_resetVirtualMachine)
m_hasActiveMachine = false;
if( !m_hasActiveMachine )
if (!m_hasActiveMachine)
m_resetRecompilers = true;
}
// This function *will* reset the emulator in order to allow the specified elf file to
// take effect. This is because it really doesn't make sense to change the elf file outside
// the context of a reset/restart.
void SysCoreThread::SetElfOverride( const wxString& elf )
void SysCoreThread::SetElfOverride(const wxString& elf)
{
//pxAssertDev( !m_hasValidMachine, "Thread synchronization error while assigning ELF override." );
m_elf_override = elf;
@ -129,8 +131,8 @@ void SysCoreThread::ResetQuick()
{
Suspend();
m_resetVirtualMachine = true;
m_hasActiveMachine = false;
m_resetVirtualMachine = true;
m_hasActiveMachine = false;
R3000A::ioman::reset();
}
@ -139,7 +141,7 @@ void SysCoreThread::Reset()
ResetQuick();
GetVmMemory().DecommitAll();
SysClearExecutionCache();
sApp.PostAppMethod( &Pcsx2App::leaveDebugMode );
sApp.PostAppMethod(&Pcsx2App::leaveDebugMode);
g_FrameCount = 0;
}
@ -148,24 +150,27 @@ void SysCoreThread::Reset()
// resets of the core and components (including plugins, if needed). The scope of resetting
// is determined by comparing the current settings against the new settings, so that only
// real differences are applied.
void SysCoreThread::ApplySettings( const Pcsx2Config& src )
void SysCoreThread::ApplySettings(const Pcsx2Config& src)
{
if( src == EmuConfig ) return;
if (src == EmuConfig)
return;
if( !pxAssertDev( IsPaused(), "CoreThread is not paused; settings cannot be applied." ) ) return;
if (!pxAssertDev(IsPaused(), "CoreThread is not paused; settings cannot be applied."))
return;
m_resetRecompilers = ( src.Cpu != EmuConfig.Cpu ) || ( src.Gamefixes != EmuConfig.Gamefixes ) || ( src.Speedhacks != EmuConfig.Speedhacks );
m_resetProfilers = ( src.Profiler != EmuConfig.Profiler );
m_resetVsyncTimers = ( src.GS != EmuConfig.GS );
m_resetRecompilers = (src.Cpu != EmuConfig.Cpu) || (src.Gamefixes != EmuConfig.Gamefixes) || (src.Speedhacks != EmuConfig.Speedhacks);
m_resetProfilers = (src.Profiler != EmuConfig.Profiler);
m_resetVsyncTimers = (src.GS != EmuConfig.GS);
const_cast<Pcsx2Config&>(EmuConfig) = src;
}
void SysCoreThread::UploadStateCopy( const VmStateBuffer& copy )
void SysCoreThread::UploadStateCopy(const VmStateBuffer& copy)
{
if( !pxAssertDev( IsPaused(), "CoreThread is not paused; new VM state cannot be uploaded." ) ) return;
if (!pxAssertDev(IsPaused(), "CoreThread is not paused; new VM state cannot be uploaded."))
return;
memLoadingState loadme( copy );
memLoadingState loadme(copy);
loadme.FreezeAll();
m_resetVirtualMachine = false;
}
@ -187,38 +192,38 @@ void SysCoreThread::_reset_stuff_as_needed()
GetVmMemory().CommitAll();
if( m_resetVirtualMachine || m_resetRecompilers || m_resetProfilers )
if (m_resetVirtualMachine || m_resetRecompilers || m_resetProfilers)
{
SysClearExecutionCache();
memBindConditionalHandlers();
SetCPUState( EmuConfig.Cpu.sseMXCSR, EmuConfig.Cpu.sseVUMXCSR );
SetCPUState(EmuConfig.Cpu.sseMXCSR, EmuConfig.Cpu.sseVUMXCSR);
m_resetRecompilers = false;
m_resetProfilers = false;
m_resetRecompilers = false;
m_resetProfilers = false;
}
if( m_resetVirtualMachine )
if (m_resetVirtualMachine)
{
DoCpuReset();
m_resetVirtualMachine = false;
m_resetVsyncTimers = false;
m_resetVirtualMachine = false;
m_resetVsyncTimers = false;
ForgetLoadedPatches();
}
if( m_resetVsyncTimers )
if (m_resetVsyncTimers)
{
UpdateVSyncRate();
frameLimitReset();
m_resetVsyncTimers = false;
m_resetVsyncTimers = false;
}
}
void SysCoreThread::DoCpuReset()
{
AffinityAssert_AllowFromSelf( pxDiagSpot );
AffinityAssert_AllowFromSelf(pxDiagSpot);
cpuReset();
}
@ -240,7 +245,7 @@ void SysCoreThread::GameStartingInThread()
{
GetMTGS().SendGameCRC(ElfCRC);
MIPSAnalyst::ScanForFunctions(ElfTextRange.first,ElfTextRange.first+ElfTextRange.second,true);
MIPSAnalyst::ScanForFunctions(ElfTextRange.first, ElfTextRange.first + ElfTextRange.second, true);
symbolMap.UpdateActiveSymbols();
sApp.PostAppMethod(&Pcsx2App::resetDebugger);
@ -280,12 +285,15 @@ void SysCoreThread::ExecuteTaskInThread()
m_mxcsr_saved.bitmask = _mm_getcsr();
PCSX2_PAGEFAULT_PROTECT {
while(true) {
PCSX2_PAGEFAULT_PROTECT
{
while (true)
{
StateCheckInThread();
DoCpuExecute();
}
} PCSX2_PAGEFAULT_EXCEPT;
}
PCSX2_PAGEFAULT_EXCEPT;
}
void SysCoreThread::OnSuspendInThread()
@ -293,41 +301,40 @@ void SysCoreThread::OnSuspendInThread()
GetCorePlugins().Close();
DoCDVDclose();
FWclose();
SPU2close();
SPU2close();
}
void SysCoreThread::OnResumeInThread( bool isSuspended )
void SysCoreThread::OnResumeInThread(bool isSuspended)
{
GetCorePlugins().Open();
if (isSuspended || !g_GameStarted)
DoCDVDopen();
FWopen();
SPU2open((void*)pDsp);
SPU2open((void*)pDsp);
}
// Invoked by the pthread_exit or pthread_cancel.
void SysCoreThread::OnCleanupInThread()
{
m_ExecMode = ExecMode_Closing;
m_ExecMode = ExecMode_Closing;
m_hasActiveMachine = false;
m_resetVirtualMachine = true;
m_hasActiveMachine = false;
m_resetVirtualMachine = true;
R3000A::ioman::reset();
// FIXME: temporary workaround for deadlock on exit, which actually should be a crash
vu1Thread.WaitVU();
SPU2close();
DoCDVDclose();
FWclose();
SPU2close();
GetCorePlugins().Close();
GetCorePlugins().Shutdown();
SPU2shutdown();
SPU2shutdown();
_mm_setcsr( m_mxcsr_saved.bitmask );
_mm_setcsr(m_mxcsr_saved.bitmask);
Threading::DisableHiresScheduler();
_parent::OnCleanupInThread();
m_ExecMode = ExecMode_NoThreadYet;
m_ExecMode = ExecMode_NoThreadYet;
}

View File

@ -45,8 +45,8 @@ typedef void (AppCoreThread::*FnPtr_CoreThreadMethod)();
class SysExecEvent_InvokeCoreThreadMethod : public SysExecEvent
{
protected:
FnPtr_CoreThreadMethod m_method;
bool m_IsCritical;
FnPtr_CoreThreadMethod m_method;
bool m_IsCritical;
public:
wxString GetEventName() const { return L"CoreThreadMethod"; }
@ -56,7 +56,7 @@ public:
bool AllowCancelOnExit() const { return false; }
bool IsCriticalEvent() const { return m_IsCritical; }
SysExecEvent_InvokeCoreThreadMethod( FnPtr_CoreThreadMethod method, bool critical=false )
SysExecEvent_InvokeCoreThreadMethod(FnPtr_CoreThreadMethod method, bool critical = false)
{
m_method = method;
m_IsCritical = critical;
@ -71,27 +71,30 @@ public:
protected:
void InvokeEvent()
{
if( m_method ) (CoreThread.*m_method)();
if (m_method)
(CoreThread.*m_method)();
}
};
static void PostCoreStatus( CoreThreadStatus pevt )
static void PostCoreStatus(CoreThreadStatus pevt)
{
sApp.PostAction( CoreThreadStatusEvent( pevt ) );
sApp.PostAction(CoreThreadStatusEvent(pevt));
}
// --------------------------------------------------------------------------------------
// AppCoreThread Implementations
// --------------------------------------------------------------------------------------
AppCoreThread::AppCoreThread() : SysCoreThread()
AppCoreThread::AppCoreThread()
: SysCoreThread()
{
m_resetCdvd = false;
}
AppCoreThread::~AppCoreThread()
{
try {
_parent::Cancel(); // use parent's, skips thread affinity check.
try
{
_parent::Cancel(); // use parent's, skips thread affinity check.
}
DESTRUCTOR_CATCHALL
}
@ -101,17 +104,17 @@ static void _Cancel()
GetCoreThread().Cancel();
}
void AppCoreThread::Cancel( bool isBlocking )
void AppCoreThread::Cancel(bool isBlocking)
{
if (GetSysExecutorThread().IsRunning() && !GetSysExecutorThread().Rpc_TryInvoke( _Cancel, L"AppCoreThread::Cancel" ))
_parent::Cancel( wxTimeSpan(0, 0, 4, 0) );
if (GetSysExecutorThread().IsRunning() && !GetSysExecutorThread().Rpc_TryInvoke(_Cancel, L"AppCoreThread::Cancel"))
_parent::Cancel(wxTimeSpan(0, 0, 4, 0));
}
void AppCoreThread::Reset()
{
if( !GetSysExecutorThread().IsSelf() )
if (!GetSysExecutorThread().IsSelf())
{
GetSysExecutorThread().PostEvent( SysExecEvent_InvokeCoreThreadMethod(&AppCoreThread::Reset) );
GetSysExecutorThread().PostEvent(SysExecEvent_InvokeCoreThreadMethod(&AppCoreThread::Reset));
return;
}
@ -120,9 +123,9 @@ void AppCoreThread::Reset()
void AppCoreThread::ResetQuick()
{
if( !GetSysExecutorThread().IsSelf() )
if (!GetSysExecutorThread().IsSelf())
{
GetSysExecutorThread().PostEvent( SysExecEvent_InvokeCoreThreadMethod(&AppCoreThread::ResetQuick) );
GetSysExecutorThread().PostEvent(SysExecEvent_InvokeCoreThreadMethod(&AppCoreThread::ResetQuick));
return;
}
@ -139,48 +142,50 @@ static void _Suspend()
GetCoreThread().Suspend(true);
}
void AppCoreThread::Suspend( bool isBlocking )
void AppCoreThread::Suspend(bool isBlocking)
{
if (IsClosed()) return;
if (IsClosed())
return;
if (IsSelf())
{
// this should never fail...
bool result = GetSysExecutorThread().Rpc_TryInvokeAsync( _Suspend, L"AppCoreThread::Suspend" );
bool result = GetSysExecutorThread().Rpc_TryInvokeAsync(_Suspend, L"AppCoreThread::Suspend");
pxAssert(result);
}
else if (!GetSysExecutorThread().Rpc_TryInvoke( _Suspend, L"AppCoreThread::Suspend" ))
else if (!GetSysExecutorThread().Rpc_TryInvoke(_Suspend, L"AppCoreThread::Suspend"))
_parent::Suspend(true);
}
void AppCoreThread::Resume()
{
if( !GetSysExecutorThread().IsSelf() )
if (!GetSysExecutorThread().IsSelf())
{
GetSysExecutorThread().PostEvent( SysExecEvent_InvokeCoreThreadMethod(&AppCoreThread::Resume) );
GetSysExecutorThread().PostEvent(SysExecEvent_InvokeCoreThreadMethod(&AppCoreThread::Resume));
return;
}
GetCorePlugins().Init();
SPU2init();
SPU2init();
_parent::Resume();
}
void AppCoreThread::ChangeCdvdSource()
{
if( !GetSysExecutorThread().IsSelf() )
if (!GetSysExecutorThread().IsSelf())
{
GetSysExecutorThread().PostEvent( new SysExecEvent_InvokeCoreThreadMethod(&AppCoreThread::ChangeCdvdSource) );
GetSysExecutorThread().PostEvent(new SysExecEvent_InvokeCoreThreadMethod(&AppCoreThread::ChangeCdvdSource));
return;
}
CDVD_SourceType cdvdsrc( g_Conf->CdvdSource );
if( cdvdsrc == CDVDsys_GetSourceType() ) return;
CDVD_SourceType cdvdsrc(g_Conf->CdvdSource);
if (cdvdsrc == CDVDsys_GetSourceType())
return;
// Fast change of the CDVD source only -- a Pause will suffice.
ScopedCoreThreadPause paused_core;
CDVDsys_ChangeSource( cdvdsrc );
CDVDsys_ChangeSource(cdvdsrc);
paused_core.AllowResume();
// TODO: Add a listener for CDVDsource changes? Or should we bother?
@ -188,24 +193,25 @@ void AppCoreThread::ChangeCdvdSource()
void Pcsx2App::SysApplySettings()
{
if( AppRpc_TryInvoke(&Pcsx2App::SysApplySettings) ) return;
CoreThread.ApplySettings( g_Conf->EmuOptions );
if (AppRpc_TryInvoke(&Pcsx2App::SysApplySettings))
return;
CoreThread.ApplySettings(g_Conf->EmuOptions);
CDVD_SourceType cdvdsrc( g_Conf->CdvdSource );
if( cdvdsrc != CDVDsys_GetSourceType() || (cdvdsrc == CDVD_SourceType::Iso && (CDVDsys_GetFile(cdvdsrc) != g_Conf->CurrentIso)) )
CDVD_SourceType cdvdsrc(g_Conf->CdvdSource);
if (cdvdsrc != CDVDsys_GetSourceType() || (cdvdsrc == CDVD_SourceType::Iso && (CDVDsys_GetFile(cdvdsrc) != g_Conf->CurrentIso)))
{
CoreThread.ResetCdvd();
}
CDVDsys_SetFile(CDVD_SourceType::Iso, g_Conf->CurrentIso );
CDVDsys_SetFile(CDVD_SourceType::Iso, g_Conf->CurrentIso);
}
void AppCoreThread::OnResumeReady()
{
wxGetApp().SysApplySettings();
wxGetApp().PostMethod( AppSaveSettings );
wxGetApp().PostMethod(AppSaveSettings);
sApp.PostAppMethod( &Pcsx2App::leaveDebugMode );
sApp.PostAppMethod(&Pcsx2App::leaveDebugMode);
_parent::OnResumeReady();
}
@ -224,10 +230,12 @@ void AppCoreThread::OnPauseDebug()
// Load Game Settings found in database
// (game fixes, round modes, clamp modes, etc...)
// Returns number of gamefixes set
static int loadGameSettings(Pcsx2Config& dest, const Game_Data& game) {
if( !game.IsOk() ) return 0;
static int loadGameSettings(Pcsx2Config& dest, const Game_Data& game)
{
if (!game.IsOk())
return 0;
int gf = 0;
int gf = 0;
if (game.keyExists("eeRoundMode"))
{
@ -251,35 +259,38 @@ static int loadGameSettings(Pcsx2Config& dest, const Game_Data& game) {
}
}
if (game.keyExists("eeClampMode")) {
if (game.keyExists("eeClampMode"))
{
int clampMode = game.getInt("eeClampMode");
PatchesCon->WriteLn("(GameDB) Changing EE/FPU clamp mode [mode=%d]", clampMode);
dest.Cpu.Recompiler.fpuOverflow = (clampMode >= 1);
dest.Cpu.Recompiler.fpuExtraOverflow = (clampMode >= 2);
dest.Cpu.Recompiler.fpuFullMode = (clampMode >= 3);
dest.Cpu.Recompiler.fpuOverflow = (clampMode >= 1);
dest.Cpu.Recompiler.fpuExtraOverflow = (clampMode >= 2);
dest.Cpu.Recompiler.fpuFullMode = (clampMode >= 3);
gf++;
}
if (game.keyExists("vuClampMode")) {
if (game.keyExists("vuClampMode"))
{
int clampMode = game.getInt("vuClampMode");
PatchesCon->WriteLn("(GameDB) Changing VU0/VU1 clamp mode [mode=%d]", clampMode);
dest.Cpu.Recompiler.vuOverflow = (clampMode >= 1);
dest.Cpu.Recompiler.vuExtraOverflow = (clampMode >= 2);
dest.Cpu.Recompiler.vuSignOverflow = (clampMode >= 3);
dest.Cpu.Recompiler.vuOverflow = (clampMode >= 1);
dest.Cpu.Recompiler.vuExtraOverflow = (clampMode >= 2);
dest.Cpu.Recompiler.vuSignOverflow = (clampMode >= 3);
gf++;
}
if (game.keyExists("mvuFlagSpeedHack")) {
if (game.keyExists("mvuFlagSpeedHack"))
{
bool vuFlagHack = game.getInt("mvuFlagSpeedHack") ? 1 : 0;
PatchesCon->WriteLn("(GameDB) Changing mVU flag speed hack [mode=%d]", vuFlagHack);
dest.Speedhacks.vuFlagHack = vuFlagHack;
gf++;
}
for( GamefixId id=GamefixId_FIRST; id<pxEnumEnd; ++id )
for (GamefixId id = GamefixId_FIRST; id < pxEnumEnd; ++id)
{
wxString key( EnumToString(id) );
wxString key(EnumToString(id));
key += L"Hack";
if (game.keyExists(key))
@ -313,7 +324,7 @@ void PatchesVerboseReset()
// PatchesCon points to either Console or ConsoleWriter_Null, such that if we're in Devel mode
// or the user enabled the devel/verbose console it prints all patching info whenever it's applied,
// else it prints the patching info only once - right after boot.
const IConsoleWriter *PatchesCon = &Console;
const IConsoleWriter* PatchesCon = &Console;
static void SetupPatchesCon(bool verbose)
{
@ -335,7 +346,7 @@ static void SetupPatchesCon(bool verbose)
// It doesn't require that the emulation is paused, and console writes/title should
// be thread safe, but it's best if things don't move around much while it runs.
static Threading::Mutex mtx__ApplySettings;
static void _ApplySettings( const Pcsx2Config& src, Pcsx2Config& fixup )
static void _ApplySettings(const Pcsx2Config& src, Pcsx2Config& fixup)
{
Threading::ScopedLock lock(mtx__ApplySettings);
// 'fixup' is the EmuConfig we're going to upload to the emulator, which very well may
@ -348,19 +359,19 @@ static void _ApplySettings( const Pcsx2Config& src, Pcsx2Config& fixup )
fixup = src;
const CommandlineOverrides& overrides( wxGetApp().Overrides );
if( overrides.DisableSpeedhacks || !g_Conf->EnableSpeedHacks )
const CommandlineOverrides& overrides(wxGetApp().Overrides);
if (overrides.DisableSpeedhacks || !g_Conf->EnableSpeedHacks)
fixup.Speedhacks.DisableAll();
if( overrides.ApplyCustomGamefixes )
if (overrides.ApplyCustomGamefixes)
{
for (GamefixId id=GamefixId_FIRST; id < pxEnumEnd; ++id)
fixup.Gamefixes.Set( id, overrides.Gamefixes.Get(id) );
for (GamefixId id = GamefixId_FIRST; id < pxEnumEnd; ++id)
fixup.Gamefixes.Set(id, overrides.Gamefixes.Get(id));
}
else if( !g_Conf->EnableGameFixes )
else if (!g_Conf->EnableGameFixes)
fixup.Gamefixes.DisableAll();
if( overrides.ProfilingMode )
if (overrides.ProfilingMode)
{
fixup.GS.FrameLimitEnable = false;
fixup.GS.VsyncEnable = VsyncMode::Off;
@ -383,11 +394,12 @@ static void _ApplySettings( const Pcsx2Config& src, Pcsx2Config& fixup )
// settings as if the game is already running (title, loadeding patches, etc).
bool ingame = (ElfCRC && (g_GameLoading || g_GameStarted));
if (ingame)
gameCRC.Printf( L"%8.8x", ElfCRC );
if (ingame && !DiscSerial.IsEmpty()) gameSerial = L" [" + DiscSerial + L"]";
gameCRC.Printf(L"%8.8x", ElfCRC);
if (ingame && !DiscSerial.IsEmpty())
gameSerial = L" [" + DiscSerial + L"]";
const wxString newGameKey(ingame ? SysGetDiscID() : SysGetBiosDiscID());
const bool verbose( newGameKey != curGameKey && ingame );
const bool verbose(newGameKey != curGameKey && ingame);
//Console.WriteLn(L"------> patches verbose: %d prev: '%s' new: '%s'", (int)verbose, WX_STR(curGameKey), WX_STR(newGameKey));
SetupPatchesCon(verbose);
@ -397,15 +409,15 @@ static void _ApplySettings( const Pcsx2Config& src, Pcsx2Config& fixup )
if (!curGameKey.IsEmpty())
{
if (IGameDatabase* GameDB = AppHost_GetGameDatabase() )
if (IGameDatabase* GameDB = AppHost_GetGameDatabase())
{
Game_Data game;
if (GameDB->findGame(game, curGameKey))
{
int compat = game.getInt("Compat");
gameName = game.getString("Name");
gameName += L" (" + game.getString("Region") + L")";
gameCompat = L" [Status = "+compatToStringWX(compat)+L"]";
gameName = game.getString("Name");
gameName += L" (" + game.getString("Region") + L")";
gameCompat = L" [Status = " + compatToStringWX(compat) + L"]";
gameMemCardFilter = game.getString("MemCardFilter");
}
@ -499,7 +511,7 @@ void LoadAllPatchesAndStuff(const Pcsx2Config& cfg)
#endif
}
void AppCoreThread::ApplySettings( const Pcsx2Config& src )
void AppCoreThread::ApplySettings(const Pcsx2Config& src)
{
// Re-entry guard protects against cases where code wants to manually set core settings
// which are not part of g_Conf. The subsequent call to apply g_Conf settings (which is
@ -508,19 +520,21 @@ void AppCoreThread::ApplySettings( const Pcsx2Config& src )
_ApplySettings(src, fixup);
static int localc = 0;
RecursionGuard guard( localc );
if( guard.IsReentrant() ) return;
if( fixup == EmuConfig ) return;
RecursionGuard guard(localc);
if (guard.IsReentrant())
return;
if (fixup == EmuConfig)
return;
if( m_ExecMode >= ExecMode_Opened )
if (m_ExecMode >= ExecMode_Opened)
{
ScopedCoreThreadPause paused_core;
_parent::ApplySettings( fixup );
_parent::ApplySettings(fixup);
paused_core.AllowResume();
}
else
{
_parent::ApplySettings( fixup );
_parent::ApplySettings(fixup);
}
if (m_ExecMode >= ExecMode_Paused)
@ -534,27 +548,27 @@ void AppCoreThread::ApplySettings( const Pcsx2Config& src )
void AppCoreThread::DoCpuReset()
{
PostCoreStatus( CoreThread_Reset );
PostCoreStatus(CoreThread_Reset);
_parent::DoCpuReset();
}
void AppCoreThread::OnResumeInThread( bool isSuspended )
void AppCoreThread::OnResumeInThread(bool isSuspended)
{
if( m_resetCdvd )
if (m_resetCdvd)
{
CDVDsys_ChangeSource( g_Conf->CdvdSource );
CDVDsys_ChangeSource(g_Conf->CdvdSource);
cdvdCtrlTrayOpen();
m_resetCdvd = false;
}
_parent::OnResumeInThread( isSuspended );
PostCoreStatus( CoreThread_Resumed );
_parent::OnResumeInThread(isSuspended);
PostCoreStatus(CoreThread_Resumed);
}
void AppCoreThread::OnSuspendInThread()
{
_parent::OnSuspendInThread();
PostCoreStatus( CoreThread_Suspended );
PostCoreStatus(CoreThread_Suspended);
}
// Called whenever the thread has terminated, for either regular or irregular reasons.
@ -564,7 +578,7 @@ void AppCoreThread::OnSuspendInThread()
void AppCoreThread::OnCleanupInThread()
{
m_ExecMode = ExecMode_Closing;
PostCoreStatus( CoreThread_Stopped );
PostCoreStatus(CoreThread_Stopped);
_parent::OnCleanupInThread();
}
@ -593,10 +607,10 @@ bool AppCoreThread::StateCheckInThread()
return _parent::StateCheckInThread();
}
void AppCoreThread::UploadStateCopy( const VmStateBuffer& copy )
void AppCoreThread::UploadStateCopy(const VmStateBuffer& copy)
{
ScopedCoreThreadPause paused_core;
_parent::UploadStateCopy( copy );
_parent::UploadStateCopy(copy);
paused_core.AllowResume();
}
@ -604,23 +618,24 @@ static uint m_except_threshold = 0;
void AppCoreThread::ExecuteTaskInThread()
{
PostCoreStatus( CoreThread_Started );
PostCoreStatus(CoreThread_Started);
m_except_threshold = 0;
_parent::ExecuteTaskInThread();
}
void AppCoreThread::DoCpuExecute()
{
try {
try
{
_parent::DoCpuExecute();
}
catch (BaseR5900Exception& ex)
{
Console.Error( ex.FormatMessage() );
Console.Error(ex.FormatMessage());
// [TODO] : Debugger Hook!
if( ++m_except_threshold > 6 )
if (++m_except_threshold > 6)
{
// If too many TLB Misses occur, we're probably going to crash and
// the game is probably running miserably.
@ -629,7 +644,7 @@ void AppCoreThread::DoCpuExecute()
//Suspend();
// [TODO] Issue error dialog to the user here...
Console.Error( "Too many execution errors. VM execution has been suspended!" );
Console.Error("Too many execution errors. VM execution has been suspended!");
// Hack: this keeps the EE thread from running more code while the SysExecutor
// thread catches up and signals it for suspension.
@ -641,33 +656,34 @@ void AppCoreThread::DoCpuExecute()
// --------------------------------------------------------------------------------------
// BaseSysExecEvent_ScopedCore / SysExecEvent_CoreThreadClose / SysExecEvent_CoreThreadPause
// --------------------------------------------------------------------------------------
void BaseSysExecEvent_ScopedCore::_post_and_wait( IScopedCoreThread& core )
void BaseSysExecEvent_ScopedCore::_post_and_wait(IScopedCoreThread& core)
{
DoScopedTask();
ScopedLock lock( m_mtx_resume );
ScopedLock lock(m_mtx_resume);
PostResult();
if( m_resume )
if (m_resume)
{
// If the sender of the message requests a non-blocking resume, then we need
// to deallocate the m_sync object, since the sender will likely leave scope and
// invalidate it.
switch( m_resume->WaitForResult() )
switch (m_resume->WaitForResult())
{
case ScopedCore_BlockingResume:
if( m_sync ) m_sync->ClearResult();
if (m_sync)
m_sync->ClearResult();
core.AllowResume();
break;
break;
case ScopedCore_NonblockingResume:
m_sync = NULL;
core.AllowResume();
break;
break;
case ScopedCore_SkipResume:
m_sync = NULL;
break;
break;
}
}
}
@ -691,10 +707,10 @@ void SysExecEvent_CoreThreadPause::InvokeEvent()
// All plugins should be initialized and opened upon resuming from
// a paused state. If the thread that puased us changed plugin status, it should
// have used Close instead.
if( CorePluginsAreOpen )
if (CorePluginsAreOpen)
{
CorePluginsAreOpen = GetCorePlugins().AreOpen();
pxAssertDev( CorePluginsAreOpen, "Invalid plugin close/shutdown detected during paused CoreThread; please Stop/Suspend the core instead." );
pxAssertDev(CorePluginsAreOpen, "Invalid plugin close/shutdown detected during paused CoreThread; please Stop/Suspend the core instead.");
}
paused_core.AllowResume();
@ -712,16 +728,16 @@ void SysExecEvent_CoreThreadPause::InvokeEvent()
// ScopedCoreThreadClose / ScopedCoreThreadPause
// --------------------------------------------------------------------------------------
static DeclareTls(bool) ScopedCore_IsPaused = false;
static DeclareTls(bool) ScopedCore_IsFullyClosed = false;
static DeclareTls(bool) ScopedCore_IsPaused = false;
static DeclareTls(bool) ScopedCore_IsFullyClosed = false;
BaseScopedCoreThread::BaseScopedCoreThread()
{
//AffinityAssert_AllowFrom_MainUI();
m_allowResume = false;
m_alreadyStopped = false;
m_alreadyScoped = false;
m_allowResume = false;
m_alreadyStopped = false;
m_alreadyScoped = false;
}
BaseScopedCoreThread::~BaseScopedCoreThread() = default;
@ -741,11 +757,12 @@ void BaseScopedCoreThread::DisallowResume()
void BaseScopedCoreThread::DoResume()
{
if( m_alreadyStopped ) return;
if( !GetSysExecutorThread().IsSelf() )
if (m_alreadyStopped)
return;
if (!GetSysExecutorThread().IsSelf())
{
//DbgCon.WriteLn("(ScopedCoreThreadPause) Threaded Scope Created!");
m_sync_resume.PostResult( m_allowResume ? ScopedCore_NonblockingResume : ScopedCore_SkipResume );
m_sync_resume.PostResult(m_allowResume ? ScopedCore_NonblockingResume : ScopedCore_SkipResume);
m_mtx_resume.Wait();
}
else
@ -755,15 +772,16 @@ void BaseScopedCoreThread::DoResume()
// Returns TRUE if the event is posted to the SysExecutor.
// Returns FALSE if the thread *is* the SysExecutor (no message is posted, calling code should
// handle the code directly).
bool BaseScopedCoreThread::PostToSysExec( BaseSysExecEvent_ScopedCore* msg )
bool BaseScopedCoreThread::PostToSysExec(BaseSysExecEvent_ScopedCore* msg)
{
std::unique_ptr<BaseSysExecEvent_ScopedCore> smsg( msg );
if( !smsg || GetSysExecutorThread().IsSelf()) return false;
std::unique_ptr<BaseSysExecEvent_ScopedCore> smsg(msg);
if (!smsg || GetSysExecutorThread().IsSelf())
return false;
msg->SetSyncState(m_sync);
msg->SetResumeStates(m_sync_resume, m_mtx_resume);
GetSysExecutorThread().PostEvent( smsg.release() );
GetSysExecutorThread().PostEvent(smsg.release());
m_sync.WaitForResult();
m_sync.RethrowException();
@ -772,17 +790,17 @@ bool BaseScopedCoreThread::PostToSysExec( BaseSysExecEvent_ScopedCore* msg )
ScopedCoreThreadClose::ScopedCoreThreadClose()
{
if( ScopedCore_IsFullyClosed )
if (ScopedCore_IsFullyClosed)
{
// tracks if we're already in scope or not.
m_alreadyScoped = true;
return;
}
if( !PostToSysExec(new SysExecEvent_CoreThreadClose()) )
if (!PostToSysExec(new SysExecEvent_CoreThreadClose()))
{
m_alreadyStopped = CoreThread.IsClosed();
if ( !m_alreadyStopped )
if (!m_alreadyStopped)
CoreThread.Suspend();
}
@ -791,28 +809,31 @@ ScopedCoreThreadClose::ScopedCoreThreadClose()
ScopedCoreThreadClose::~ScopedCoreThreadClose()
{
if( m_alreadyScoped ) return;
try {
if (m_alreadyScoped)
return;
try
{
_parent::DoResume();
ScopedCore_IsFullyClosed = false;
}
DESTRUCTOR_CATCHALL
}
ScopedCoreThreadPause::ScopedCoreThreadPause( BaseSysExecEvent_ScopedCore* abuse_me )
ScopedCoreThreadPause::ScopedCoreThreadPause(BaseSysExecEvent_ScopedCore* abuse_me)
{
if( ScopedCore_IsFullyClosed || ScopedCore_IsPaused )
if (ScopedCore_IsFullyClosed || ScopedCore_IsPaused)
{
// tracks if we're already in scope or not.
m_alreadyScoped = true;
return;
}
if( !abuse_me ) abuse_me = new SysExecEvent_CoreThreadPause();
if( !PostToSysExec( abuse_me ) )
if (!abuse_me)
abuse_me = new SysExecEvent_CoreThreadPause();
if (!PostToSysExec(abuse_me))
{
m_alreadyStopped = CoreThread.IsPaused();
if( !m_alreadyStopped )
if (!m_alreadyStopped)
CoreThread.Pause();
}
@ -821,8 +842,10 @@ ScopedCoreThreadPause::ScopedCoreThreadPause( BaseSysExecEvent_ScopedCore* abuse
ScopedCoreThreadPause::~ScopedCoreThreadPause()
{
if( m_alreadyScoped ) return;
try {
if (m_alreadyScoped)
return;
try
{
_parent::DoResume();
ScopedCore_IsPaused = false;
}
@ -835,7 +858,7 @@ ScopedCoreThreadPopup::ScopedCoreThreadPopup()
// ensure that the GS window isn't blocking the popup, and to avoid crashes if the GS window
// is maximized or fullscreen.
if( !GSopen2 )
if (!GSopen2)
m_scoped_core = std::unique_ptr<BaseScopedCoreThread>(new ScopedCoreThreadClose());
else
m_scoped_core = std::unique_ptr<BaseScopedCoreThread>(new ScopedCoreThreadPause());
@ -843,10 +866,12 @@ ScopedCoreThreadPopup::ScopedCoreThreadPopup()
void ScopedCoreThreadPopup::AllowResume()
{
if( m_scoped_core ) m_scoped_core->AllowResume();
if (m_scoped_core)
m_scoped_core->AllowResume();
}
void ScopedCoreThreadPopup::DisallowResume()
{
if( m_scoped_core ) m_scoped_core->DisallowResume();
if (m_scoped_core)
m_scoped_core->DisallowResume();
}

View File

@ -23,8 +23,8 @@
#include "AppSaveStates.h"
#ifndef DISABLE_RECORDING
# include "Recording/InputRecordingControls.h"
# include "Recording/InputRecording.h"
#include "Recording/InputRecordingControls.h"
#include "Recording/InputRecording.h"
#endif
// Various includes needed for dumping...
@ -43,15 +43,18 @@ extern bool switchAR;
static int g_Pcsx2Recording = 0; // true 1 if recording video and sound
KeyAcceleratorCode::KeyAcceleratorCode( const wxKeyEvent& evt )
KeyAcceleratorCode::KeyAcceleratorCode(const wxKeyEvent& evt)
{
val32 = 0;
keycode = evt.GetKeyCode();
if( evt.AltDown() ) Alt();
if( evt.CmdDown() ) Cmd();
if( evt.ShiftDown() ) Shift();
if (evt.AltDown())
Alt();
if (evt.CmdDown())
Cmd();
if (evt.ShiftDown())
Shift();
}
wxString KeyAcceleratorCode::ToString() const
@ -59,11 +62,11 @@ wxString KeyAcceleratorCode::ToString() const
// Let's use wx's string formatter:
return wxAcceleratorEntry(
(cmd ? wxACCEL_CMD : 0) |
(shift ? wxACCEL_SHIFT : 0) |
(alt ? wxACCEL_ALT : 0),
keycode
).ToString();
(cmd ? wxACCEL_CMD : 0) |
(shift ? wxACCEL_SHIFT : 0) |
(alt ? wxACCEL_ALT : 0),
keycode)
.ToString();
}
LimiterModeType g_LimiterMode = Limit_Nominal;
@ -75,11 +78,14 @@ namespace Implementations
g_Conf->EmuOptions.GS.FrameSkipEnable = !g_Conf->EmuOptions.GS.FrameSkipEnable;
SetGSConfig().FrameSkipEnable = g_Conf->EmuOptions.GS.FrameSkipEnable;
if( EmuConfig.GS.FrameSkipEnable ) {
OSDlog( Color_StrongRed, true, "(FrameSkipping) Enabled." );
OSDlog( Color_StrongRed, true, " FrameDraws=%d, FrameSkips=%d", g_Conf->EmuOptions.GS.FramesToDraw, g_Conf->EmuOptions.GS.FramesToSkip );
} else {
OSDlog( Color_StrongRed, true, "(FrameSkipping) Disabled." );
if (EmuConfig.GS.FrameSkipEnable)
{
OSDlog(Color_StrongRed, true, "(FrameSkipping) Enabled.");
OSDlog(Color_StrongRed, true, " FrameDraws=%d, FrameSkips=%d", g_Conf->EmuOptions.GS.FramesToDraw, g_Conf->EmuOptions.GS.FramesToSkip);
}
else
{
OSDlog(Color_StrongRed, true, "(FrameSkipping) Disabled.");
}
}
@ -87,25 +93,25 @@ namespace Implementations
{
ScopedCoreThreadPause pauser;
if( !g_Conf->EmuOptions.GS.FrameLimitEnable )
if (!g_Conf->EmuOptions.GS.FrameLimitEnable)
{
g_Conf->EmuOptions.GS.FrameLimitEnable = true;
g_LimiterMode = Limit_Turbo;
OSDlog( Color_StrongRed, true, "(FrameLimiter) Turbo + FrameLimit ENABLED." );
OSDlog(Color_StrongRed, true, "(FrameLimiter) Turbo + FrameLimit ENABLED.");
g_Conf->EmuOptions.GS.FrameSkipEnable = !!g_Conf->Framerate.SkipOnTurbo;
}
else if( g_LimiterMode == Limit_Turbo )
else if (g_LimiterMode == Limit_Turbo)
{
g_LimiterMode = Limit_Nominal;
if ( g_Conf->Framerate.SkipOnLimit)
if (g_Conf->Framerate.SkipOnLimit)
{
OSDlog( Color_StrongRed, true, "(FrameLimiter) Turbo DISABLED. Frameskip ENABLED" );
OSDlog(Color_StrongRed, true, "(FrameLimiter) Turbo DISABLED. Frameskip ENABLED");
g_Conf->EmuOptions.GS.FrameSkipEnable = true;
}
else
{
OSDlog( Color_StrongRed, true, "(FrameLimiter) Turbo DISABLED." );
OSDlog(Color_StrongRed, true, "(FrameLimiter) Turbo DISABLED.");
g_Conf->EmuOptions.GS.FrameSkipEnable = false;
}
}
@ -113,14 +119,14 @@ namespace Implementations
{
g_LimiterMode = Limit_Turbo;
if ( g_Conf->Framerate.SkipOnTurbo)
if (g_Conf->Framerate.SkipOnTurbo)
{
OSDlog( Color_StrongRed, true, "(FrameLimiter) Turbo + Frameskip ENABLED." );
OSDlog(Color_StrongRed, true, "(FrameLimiter) Turbo + Frameskip ENABLED.");
g_Conf->EmuOptions.GS.FrameSkipEnable = true;
}
else
{
OSDlog( Color_StrongRed, true, "(FrameLimiter) Turbo ENABLED." );
OSDlog(Color_StrongRed, true, "(FrameLimiter) Turbo ENABLED.");
g_Conf->EmuOptions.GS.FrameSkipEnable = false;
}
}
@ -139,15 +145,15 @@ namespace Implementations
// out a better consistency approach... -air
ScopedCoreThreadPause pauser;
if( g_LimiterMode == Limit_Slomo )
if (g_LimiterMode == Limit_Slomo)
{
g_LimiterMode = Limit_Nominal;
OSDlog( Color_StrongRed, true, "(FrameLimiter) SlowMotion DISABLED." );
OSDlog(Color_StrongRed, true, "(FrameLimiter) SlowMotion DISABLED.");
}
else
{
g_LimiterMode = Limit_Slomo;
OSDlog( Color_StrongRed, true, "(FrameLimiter) SlowMotion ENABLED." );
OSDlog(Color_StrongRed, true, "(FrameLimiter) SlowMotion ENABLED.");
g_Conf->EmuOptions.GS.FrameLimitEnable = true;
}
@ -160,7 +166,7 @@ namespace Implementations
{
ScopedCoreThreadPause pauser;
g_Conf->EmuOptions.GS.FrameLimitEnable = !g_Conf->EmuOptions.GS.FrameLimitEnable;
OSDlog( Color_StrongRed, true, "(FrameLimiter) %s.", g_Conf->EmuOptions.GS.FrameLimitEnable ? "ENABLED" : "DISABLED" );
OSDlog(Color_StrongRed, true, "(FrameLimiter) %s.", g_Conf->EmuOptions.GS.FrameLimitEnable ? "ENABLED" : "DISABLED");
// Turbo/Slowmo don't make sense when framelimiter is toggled
g_LimiterMode = Limit_Nominal;
@ -181,15 +187,25 @@ namespace Implementations
void GSwindow_CycleAspectRatio()
{
AspectRatioType& art = g_Conf->GSWindow.AspectRatio;
const char *arts = "Not modified";
const char* arts = "Not modified";
if (art == AspectRatio_Stretch && switchAR) //avoids a double 4:3 when coming from FMV aspect ratio switch
art = AspectRatio_4_3;
switch( art )
switch (art)
{
case AspectRatio_Stretch: art = AspectRatio_4_3; arts = "4:3"; break;
case AspectRatio_4_3: art = AspectRatio_16_9; arts = "16:9"; break;
case AspectRatio_16_9: art = AspectRatio_Stretch; arts = "Stretch"; break;
default: break;
case AspectRatio_Stretch:
art = AspectRatio_4_3;
arts = "4:3";
break;
case AspectRatio_4_3:
art = AspectRatio_16_9;
arts = "16:9";
break;
case AspectRatio_16_9:
art = AspectRatio_Stretch;
arts = "Stretch";
break;
default:
break;
}
OSDlog(Color_StrongBlue, true, "(GSwindow) Aspect ratio: %s", arts);
@ -200,66 +216,70 @@ namespace Implementations
{
g_Conf->GSWindow.OffsetX = x;
g_Conf->GSWindow.OffsetY = y;
OSDlog( Color_StrongBlue, true, "(GSwindow) Offset: x=%f, y=%f", x,y);
OSDlog(Color_StrongBlue, true, "(GSwindow) Offset: x=%f, y=%f", x, y);
UpdateImagePosition();
}
void GSwindow_OffsetYplus(){
SetOffset(g_Conf->GSWindow.OffsetX.ToFloat(), g_Conf->GSWindow.OffsetY.ToFloat()+1);
void GSwindow_OffsetYplus()
{
SetOffset(g_Conf->GSWindow.OffsetX.ToFloat(), g_Conf->GSWindow.OffsetY.ToFloat() + 1);
}
void GSwindow_OffsetYminus(){
SetOffset(g_Conf->GSWindow.OffsetX.ToFloat(), g_Conf->GSWindow.OffsetY.ToFloat()-1);
void GSwindow_OffsetYminus()
{
SetOffset(g_Conf->GSWindow.OffsetX.ToFloat(), g_Conf->GSWindow.OffsetY.ToFloat() - 1);
}
void GSwindow_OffsetXplus(){
SetOffset(g_Conf->GSWindow.OffsetX.ToFloat()+1, g_Conf->GSWindow.OffsetY.ToFloat());
void GSwindow_OffsetXplus()
{
SetOffset(g_Conf->GSWindow.OffsetX.ToFloat() + 1, g_Conf->GSWindow.OffsetY.ToFloat());
}
void GSwindow_OffsetXminus(){
SetOffset(g_Conf->GSWindow.OffsetX.ToFloat()-1, g_Conf->GSWindow.OffsetY.ToFloat());
void GSwindow_OffsetXminus()
{
SetOffset(g_Conf->GSWindow.OffsetX.ToFloat() - 1, g_Conf->GSWindow.OffsetY.ToFloat());
}
void GSwindow_OffsetReset(){
SetOffset(0,0);
void GSwindow_OffsetReset()
{
SetOffset(0, 0);
}
void SetZoomY(float zoom)
{
if( zoom <= 0 )
if (zoom <= 0)
return;
g_Conf->GSWindow.StretchY = zoom;
OSDlog( Color_StrongBlue, true, "(GSwindow) Vertical stretch: %f", zoom);
OSDlog(Color_StrongBlue, true, "(GSwindow) Vertical stretch: %f", zoom);
UpdateImagePosition();
}
void GSwindow_ZoomInY()
{
SetZoomY( g_Conf->GSWindow.StretchY.ToFloat()+1 );
SetZoomY(g_Conf->GSWindow.StretchY.ToFloat() + 1);
}
void GSwindow_ZoomOutY()
{
SetZoomY( g_Conf->GSWindow.StretchY.ToFloat()-1 );
SetZoomY(g_Conf->GSWindow.StretchY.ToFloat() - 1);
}
void GSwindow_ZoomResetY()
{
SetZoomY( 100 );
SetZoomY(100);
}
void SetZoom(float zoom)
{
if( zoom < 0 )
if (zoom < 0)
return;
g_Conf->GSWindow.Zoom = zoom;
if ( zoom == 0 )
OSDlog( Color_StrongBlue, true, "(GSwindow) Zoom: 0 (auto, no black bars)");
if (zoom == 0)
OSDlog(Color_StrongBlue, true, "(GSwindow) Zoom: 0 (auto, no black bars)");
else
OSDlog( Color_StrongBlue, true, "(GSwindow) Zoom: %f", zoom);
OSDlog(Color_StrongBlue, true, "(GSwindow) Zoom: %f", zoom);
UpdateImagePosition();
}
@ -267,31 +287,36 @@ namespace Implementations
void GSwindow_ZoomIn()
{
float z = g_Conf->GSWindow.Zoom.ToFloat();
if( z==0 ) z = 100;
if (z == 0)
z = 100;
z++;
SetZoom( z );
SetZoom(z);
}
void GSwindow_ZoomOut()
{
float z = g_Conf->GSWindow.Zoom.ToFloat();
if( z==0 ) z = 100;
if (z == 0)
z = 100;
z--;
SetZoom( z );
SetZoom(z);
}
void GSwindow_ZoomToggle()
{
float z = g_Conf->GSWindow.Zoom.ToFloat();
if( z==100 ) z = 0;
else z = 100;
if (z == 100)
z = 0;
else
z = 100;
SetZoom( z );
SetZoom(z);
}
void Sys_Suspend()
{
GSFrame* gsframe = wxGetApp().GetGsFramePtr();
if (gsframe && gsframe->IsShown() && gsframe->IsFullScreen()) {
if (gsframe && gsframe->IsShown() && gsframe->IsFullScreen())
{
// On some cases, probably due to driver bugs, if we don't exit fullscreen then
// the content stays on screen. Try to prevent that by first exiting fullscreen,
// but don't update the internal PCSX2 state/config, and PCSX2 will restore
@ -304,7 +329,8 @@ namespace Implementations
CoreThread.Suspend();
gsframe = wxGetApp().GetGsFramePtr(); // just in case suspend removes this window
if (gsframe && !wxGetApp().HasGUI() && g_Conf->GSWindow.CloseOnEsc) {
if (gsframe && !wxGetApp().HasGUI() && g_Conf->GSWindow.CloseOnEsc)
{
// When we run with --nogui, PCSX2 only knows to exit when the gs window closes.
// However, by default suspend just hides the gs window, so PCSX2 will not exit
// and there will also be no way to exit it even if no windows are left.
@ -313,7 +339,7 @@ namespace Implementations
// So if we're set to close on esc and nogui:
// If the user didn't specify --noguiprompt - exit immediately.
// else prompt to either exit or abort the suspend.
if (!wxGetApp().ExitPromptWithNoGUI() // configured to exit without a dialog
if (!wxGetApp().ExitPromptWithNoGUI() // configured to exit without a dialog
|| (wxOK == wxMessageBox(_("Exit PCSX2?"), // or confirmed exit at the dialog
L"PCSX2",
wxICON_WARNING | wxOK | wxCANCEL)))
@ -358,14 +384,14 @@ namespace Implementations
void Sys_TakeSnapshot()
{
GSmakeSnapshot( g_Conf->Folders.Snapshots.ToUTF8() );
GSmakeSnapshot(g_Conf->Folders.Snapshots.ToUTF8());
}
void Sys_RenderToggle()
{
if(renderswitch_delay == 0)
if (renderswitch_delay == 0)
{
ScopedCoreThreadPause paused_core( new SysExecEvent_SaveSinglePlugin(PluginId_GS) );
ScopedCoreThreadPause paused_core(new SysExecEvent_SaveSinglePlugin(PluginId_GS));
renderswitch = !renderswitch;
paused_core.AllowResume();
renderswitch_delay = -1;
@ -379,7 +405,7 @@ namespace Implementations
// --arcum42
// FIXME: Some of the trace logs will require recompiler resets to be activated properly.
#ifdef PCSX2_DEVBUILD
#ifdef PCSX2_DEVBUILD
SetTraceConfig().Enabled = !EmuConfig.Trace.Enabled;
Console.WriteLn(EmuConfig.Trace.Enabled ? "Logging Enabled." : "Logging Disabled.");
#endif
@ -390,28 +416,27 @@ namespace Implementations
// fixme : fix up gsstate mess and make it mtgs compatible -- air
#ifdef _STGS_GSSTATE_CODE
wxString Text;
if( strgametitle[0] != 0 )
if (strgametitle[0] != 0)
{
// only take the first two words
wxString gsText;
wxStringTokenizer parts( strgametitle, L" " );
wxStringTokenizer parts(strgametitle, L" ");
wxString name( parts.GetNextToken() ); // first part
wxString part2( parts.GetNextToken() );
wxString name(parts.GetNextToken()); // first part
wxString part2(parts.GetNextToken());
if( !!part2 )
if (!!part2)
name += L"_" + part2;
gsText.Printf( L"%s.%d.gs", WX_STR(name), StatesC );
Text = Path::Combine( g_Conf->Folders.Savestates, gsText );
gsText.Printf(L"%s.%d.gs", WX_STR(name), StatesC);
Text = Path::Combine(g_Conf->Folders.Savestates, gsText);
}
else
{
Text = GetGSStateFilename();
}
#endif
}
void Sys_RecordingToggle()
@ -421,7 +446,7 @@ namespace Implementations
g_Pcsx2Recording ^= 1;
GetMTGS().WaitGS(); // make sure GS is in sync with the audio stream when we start.
GetMTGS().WaitGS(); // make sure GS is in sync with the audio stream when we start.
if (g_Pcsx2Recording)
{
// start recording
@ -478,8 +503,8 @@ namespace Implementations
void FullscreenToggle()
{
if( GSFrame* gsframe = wxGetApp().GetGsFramePtr() )
gsframe->ShowFullScreen( !gsframe->IsFullScreen() );
if (GSFrame* gsframe = wxGetApp().GetGsFramePtr())
gsframe->ShowFullScreen(!gsframe->IsFullScreen());
}
#ifndef DISABLE_RECORDING
void FrameAdvance()
@ -618,7 +643,7 @@ namespace Implementations
States_LoadSlot(9);
}
#endif
}
} // namespace Implementations
// --------------------------------------------------------------------------------------
// CommandDeclarations table
@ -629,201 +654,221 @@ namespace Implementations
// goold old fashioned way! :)
static const GlobalCommandDescriptor CommandDeclarations[] =
{
{ "States_FreezeCurrentSlot",
States_FreezeCurrentSlot,
pxL( "Save state" ),
pxL( "Saves the virtual machine state to the current slot." ),
false,
},
{
{
"States_FreezeCurrentSlot",
States_FreezeCurrentSlot,
pxL("Save state"),
pxL("Saves the virtual machine state to the current slot."),
false,
},
{ "States_DefrostCurrentSlot",
States_DefrostCurrentSlot,
pxL( "Load state" ),
pxL( "Loads a virtual machine state from the current slot." ),
false,
},
{
"States_DefrostCurrentSlot",
States_DefrostCurrentSlot,
pxL("Load state"),
pxL("Loads a virtual machine state from the current slot."),
false,
},
{ "States_DefrostCurrentSlotBackup",
States_DefrostCurrentSlotBackup,
pxL( "Load State Backup" ),
pxL( "Loads virtual machine state backup for current slot." ),
false,
},
{
"States_DefrostCurrentSlotBackup",
States_DefrostCurrentSlotBackup,
pxL("Load State Backup"),
pxL("Loads virtual machine state backup for current slot."),
false,
},
{ "States_CycleSlotForward",
States_CycleSlotForward,
pxL( "Cycle to next slot" ),
pxL( "Cycles the current save slot in +1 fashion!" ),
false,
},
{
"States_CycleSlotForward",
States_CycleSlotForward,
pxL("Cycle to next slot"),
pxL("Cycles the current save slot in +1 fashion!"),
false,
},
{ "States_CycleSlotBackward",
States_CycleSlotBackward,
pxL( "Cycle to prev slot" ),
pxL( "Cycles the current save slot in -1 fashion!" ),
false,
},
{
"States_CycleSlotBackward",
States_CycleSlotBackward,
pxL("Cycle to prev slot"),
pxL("Cycles the current save slot in -1 fashion!"),
false,
},
{ "Frameskip_Toggle",
Implementations::Frameskip_Toggle,
NULL,
NULL,
false,
},
{
"Frameskip_Toggle",
Implementations::Frameskip_Toggle,
NULL,
NULL,
false,
},
{ "Framelimiter_TurboToggle",
Implementations::Framelimiter_TurboToggle,
NULL,
NULL,
false,
},
{
"Framelimiter_TurboToggle",
Implementations::Framelimiter_TurboToggle,
NULL,
NULL,
false,
},
{ "Framelimiter_SlomoToggle",
Implementations::Framelimiter_SlomoToggle,
NULL,
NULL,
false,
},
{
"Framelimiter_SlomoToggle",
Implementations::Framelimiter_SlomoToggle,
NULL,
NULL,
false,
},
{ "Framelimiter_MasterToggle",
Implementations::Framelimiter_MasterToggle,
NULL,
NULL,
false,
},
{
"Framelimiter_MasterToggle",
Implementations::Framelimiter_MasterToggle,
NULL,
NULL,
false,
},
{ "GSwindow_CycleAspectRatio",
Implementations::GSwindow_CycleAspectRatio,
NULL,
NULL,
true,
},
{
"GSwindow_CycleAspectRatio",
Implementations::GSwindow_CycleAspectRatio,
NULL,
NULL,
true,
},
{ "GSwindow_ZoomIn",
Implementations::GSwindow_ZoomIn,
NULL,
NULL,
false,
},
{
"GSwindow_ZoomIn",
Implementations::GSwindow_ZoomIn,
NULL,
NULL,
false,
},
{ "GSwindow_ZoomOut",
Implementations::GSwindow_ZoomOut,
NULL,
NULL,
false,
},
{
"GSwindow_ZoomOut",
Implementations::GSwindow_ZoomOut,
NULL,
NULL,
false,
},
{ "GSwindow_ZoomToggle",
Implementations::GSwindow_ZoomToggle,
NULL,
NULL,
false,
},
{
"GSwindow_ZoomToggle",
Implementations::GSwindow_ZoomToggle,
NULL,
NULL,
false,
},
{ "GSwindow_ZoomInY" , Implementations::GSwindow_ZoomInY , NULL, NULL, false},
{ "GSwindow_ZoomOutY" , Implementations::GSwindow_ZoomOutY , NULL, NULL, false},
{ "GSwindow_ZoomResetY" , Implementations::GSwindow_ZoomResetY , NULL, NULL, false},
{"GSwindow_ZoomInY", Implementations::GSwindow_ZoomInY, NULL, NULL, false},
{"GSwindow_ZoomOutY", Implementations::GSwindow_ZoomOutY, NULL, NULL, false},
{"GSwindow_ZoomResetY", Implementations::GSwindow_ZoomResetY, NULL, NULL, false},
{ "GSwindow_OffsetYminus", Implementations::GSwindow_OffsetYminus, NULL, NULL, false},
{ "GSwindow_OffsetYplus" , Implementations::GSwindow_OffsetYplus , NULL, NULL, false},
{ "GSwindow_OffsetXminus", Implementations::GSwindow_OffsetXminus, NULL, NULL, false},
{ "GSwindow_OffsetXplus" , Implementations::GSwindow_OffsetXplus , NULL, NULL, false},
{ "GSwindow_OffsetReset" , Implementations::GSwindow_OffsetReset , NULL, NULL, false},
{"GSwindow_OffsetYminus", Implementations::GSwindow_OffsetYminus, NULL, NULL, false},
{"GSwindow_OffsetYplus", Implementations::GSwindow_OffsetYplus, NULL, NULL, false},
{"GSwindow_OffsetXminus", Implementations::GSwindow_OffsetXminus, NULL, NULL, false},
{"GSwindow_OffsetXplus", Implementations::GSwindow_OffsetXplus, NULL, NULL, false},
{"GSwindow_OffsetReset", Implementations::GSwindow_OffsetReset, NULL, NULL, false},
{ "Sys_SuspendResume",
Implementations::Sys_SuspendResume,
NULL,
NULL,
false,
},
{
"Sys_SuspendResume",
Implementations::Sys_SuspendResume,
NULL,
NULL,
false,
},
{ "Sys_TakeSnapshot",
Implementations::Sys_TakeSnapshot,
NULL,
NULL,
false,
},
{
"Sys_TakeSnapshot",
Implementations::Sys_TakeSnapshot,
NULL,
NULL,
false,
},
{ "Sys_RenderswitchToggle",
Implementations::Sys_RenderToggle,
NULL,
NULL,
false,
},
{
"Sys_RenderswitchToggle",
Implementations::Sys_RenderToggle,
NULL,
NULL,
false,
},
{ "Sys_LoggingToggle",
Implementations::Sys_LoggingToggle,
NULL,
NULL,
false,
},
{
"Sys_LoggingToggle",
Implementations::Sys_LoggingToggle,
NULL,
NULL,
false,
},
{ "Sys_FreezeGS",
Implementations::Sys_FreezeGS,
NULL,
NULL,
false,
},
{ "Sys_RecordingToggle",
Implementations::Sys_RecordingToggle,
NULL,
NULL,
false,
},
{
"Sys_FreezeGS",
Implementations::Sys_FreezeGS,
NULL,
NULL,
false,
},
{
"Sys_RecordingToggle",
Implementations::Sys_RecordingToggle,
NULL,
NULL,
false,
},
{ "FullscreenToggle",
Implementations::FullscreenToggle,
NULL,
NULL,
false,
},
{
"FullscreenToggle",
Implementations::FullscreenToggle,
NULL,
NULL,
false,
},
#ifndef DISABLE_RECORDING
{ "FrameAdvance" , Implementations::FrameAdvance, NULL, NULL, false },
{ "TogglePause" , Implementations::TogglePause, NULL, NULL, false },
{ "InputRecordingModeToggle" , Implementations::InputRecordingModeToggle, NULL, NULL, false },
{ "States_SaveSlot0" , Implementations::States_SaveSlot0, NULL, NULL, false },
{ "States_SaveSlot1" , Implementations::States_SaveSlot1, NULL, NULL, false },
{ "States_SaveSlot2" , Implementations::States_SaveSlot2, NULL, NULL, false },
{ "States_SaveSlot3" , Implementations::States_SaveSlot3, NULL, NULL, false },
{ "States_SaveSlot4" , Implementations::States_SaveSlot4, NULL, NULL, false },
{ "States_SaveSlot5" , Implementations::States_SaveSlot5, NULL, NULL, false },
{ "States_SaveSlot6" , Implementations::States_SaveSlot6, NULL, NULL, false },
{ "States_SaveSlot7" , Implementations::States_SaveSlot7, NULL, NULL, false },
{ "States_SaveSlot8" , Implementations::States_SaveSlot8, NULL, NULL, false },
{ "States_SaveSlot9" , Implementations::States_SaveSlot9, NULL, NULL, false },
{ "States_LoadSlot0" , Implementations::States_LoadSlot0, NULL, NULL, false },
{ "States_LoadSlot1" , Implementations::States_LoadSlot1, NULL, NULL, false },
{ "States_LoadSlot2" , Implementations::States_LoadSlot2, NULL, NULL, false },
{ "States_LoadSlot3" , Implementations::States_LoadSlot3, NULL, NULL, false },
{ "States_LoadSlot4" , Implementations::States_LoadSlot4, NULL, NULL, false },
{ "States_LoadSlot5" , Implementations::States_LoadSlot5, NULL, NULL, false },
{ "States_LoadSlot6" , Implementations::States_LoadSlot6, NULL, NULL, false },
{ "States_LoadSlot7" , Implementations::States_LoadSlot7, NULL, NULL, false },
{ "States_LoadSlot8" , Implementations::States_LoadSlot8, NULL, NULL, false },
{ "States_LoadSlot9" , Implementations::States_LoadSlot9, NULL, NULL, false },
{"FrameAdvance", Implementations::FrameAdvance, NULL, NULL, false},
{"TogglePause", Implementations::TogglePause, NULL, NULL, false},
{"InputRecordingModeToggle", Implementations::InputRecordingModeToggle, NULL, NULL, false},
{"States_SaveSlot0", Implementations::States_SaveSlot0, NULL, NULL, false},
{"States_SaveSlot1", Implementations::States_SaveSlot1, NULL, NULL, false},
{"States_SaveSlot2", Implementations::States_SaveSlot2, NULL, NULL, false},
{"States_SaveSlot3", Implementations::States_SaveSlot3, NULL, NULL, false},
{"States_SaveSlot4", Implementations::States_SaveSlot4, NULL, NULL, false},
{"States_SaveSlot5", Implementations::States_SaveSlot5, NULL, NULL, false},
{"States_SaveSlot6", Implementations::States_SaveSlot6, NULL, NULL, false},
{"States_SaveSlot7", Implementations::States_SaveSlot7, NULL, NULL, false},
{"States_SaveSlot8", Implementations::States_SaveSlot8, NULL, NULL, false},
{"States_SaveSlot9", Implementations::States_SaveSlot9, NULL, NULL, false},
{"States_LoadSlot0", Implementations::States_LoadSlot0, NULL, NULL, false},
{"States_LoadSlot1", Implementations::States_LoadSlot1, NULL, NULL, false},
{"States_LoadSlot2", Implementations::States_LoadSlot2, NULL, NULL, false},
{"States_LoadSlot3", Implementations::States_LoadSlot3, NULL, NULL, false},
{"States_LoadSlot4", Implementations::States_LoadSlot4, NULL, NULL, false},
{"States_LoadSlot5", Implementations::States_LoadSlot5, NULL, NULL, false},
{"States_LoadSlot6", Implementations::States_LoadSlot6, NULL, NULL, false},
{"States_LoadSlot7", Implementations::States_LoadSlot7, NULL, NULL, false},
{"States_LoadSlot8", Implementations::States_LoadSlot8, NULL, NULL, false},
{"States_LoadSlot9", Implementations::States_LoadSlot9, NULL, NULL, false},
#endif
// Command Declarations terminator:
// (must always be last in list!!)
{ NULL }
};
// Command Declarations terminator:
// (must always be last in list!!)
{NULL}};
void AcceleratorDictionary::Map( const KeyAcceleratorCode& _acode, const char *searchfor )
void AcceleratorDictionary::Map(const KeyAcceleratorCode& _acode, const char* searchfor)
{
// Search override mapping at ini file
KeyAcceleratorCode acode = _acode;
wxString overrideStr;
wxAcceleratorEntry codeParser; //Provides string parsing capabilities
wxFileConfig cfg(L"", L"", L"" , GetUiKeysFilename(), wxCONFIG_USE_GLOBAL_FILE );
if( cfg.Read( wxString::FromUTF8(searchfor), &overrideStr) )
wxAcceleratorEntry codeParser; //Provides string parsing capabilities
wxFileConfig cfg(L"", L"", L"", GetUiKeysFilename(), wxCONFIG_USE_GLOBAL_FILE);
if (cfg.Read(wxString::FromUTF8(searchfor), &overrideStr))
{
// needs a '\t' prefix (originally used for wxMenu accelerators parsing)...
if (codeParser.FromString(wxString(L"\t") + overrideStr))
{
// ini file contains alternative parsable key combination for current 'searchfor'.
acode = codeParser;
if (acode.keycode >= 'A' && acode.keycode <= 'Z') {
if (acode.keycode >= 'A' && acode.keycode <= 'Z')
{
// Note that this needs to match the key event codes at Pcsx2App::PadKeyDispatch
// Our canonical representation is the char code (at lower case if
// applicable) with a separate modifier indicator, including shift.
@ -833,9 +878,10 @@ void AcceleratorDictionary::Map( const KeyAcceleratorCode& _acode, const char *s
// So we only need to change upper case letters to lower case.
acode.keycode += 'a' - 'A';
}
if (_acode.ToString() != acode.ToString()) {
if (_acode.ToString() != acode.ToString())
{
Console.WriteLn(Color_StrongGreen, L"Overriding '%s': assigning %s (instead of %s)",
WX_STR(fromUTF8(searchfor)), WX_STR(acode.ToString()), WX_STR(_acode.ToString()));
WX_STR(fromUTF8(searchfor)), WX_STR(acode.ToString()), WX_STR(_acode.ToString()));
}
}
else
@ -852,13 +898,12 @@ void AcceleratorDictionary::Map( const KeyAcceleratorCode& _acode, const char *s
if (iter != end())
result = iter->second;
if( result != NULL )
if (result != NULL)
{
Console.Warning(
L"Kbd Accelerator '%s' is mapped multiple times.\n"
L"\t'Command %s' is being replaced by '%s'",
WX_STR(acode.ToString()), WX_STR(fromUTF8( result->Id )), WX_STR(fromUTF8( searchfor ))
);
WX_STR(acode.ToString()), WX_STR(fromUTF8(result->Id)), WX_STR(fromUTF8(searchfor)));
}
std::unordered_map<std::string, const GlobalCommandDescriptor*>::const_iterator acceleratorIter(wxGetApp().GlobalCommands->find(searchfor));
@ -866,15 +911,15 @@ void AcceleratorDictionary::Map( const KeyAcceleratorCode& _acode, const char *s
if (acceleratorIter != wxGetApp().GlobalCommands->end())
result = acceleratorIter->second;
if( result == NULL )
if (result == NULL)
{
Console.Warning( L"Kbd Accelerator '%s' is mapped to unknown command '%s'",
WX_STR(acode.ToString()), WX_STR(fromUTF8( searchfor ))
);
Console.Warning(L"Kbd Accelerator '%s' is mapped to unknown command '%s'",
WX_STR(acode.ToString()), WX_STR(fromUTF8(searchfor)));
}
else
{
if (!strcmp("Sys_TakeSnapshot", searchfor)) {
if (!strcmp("Sys_TakeSnapshot", searchfor))
{
// Sys_TakeSnapshot is special in a bad way. On its own it creates a screenshot
// but GSdx also checks whether shift or ctrl are held down, and for each of
// them it does a different thing (gs dumps). So we need to map a shortcut and
@ -885,26 +930,31 @@ void AcceleratorDictionary::Map( const KeyAcceleratorCode& _acode, const char *s
// and ctrl held together, but PCSX2 traditionally mapped f8, shift-f8 and ctrl-shift-f8
// to Sys_TakeSnapshot, so let's not change it - we'll keep adding only shift and
// ctrl-shift to the base shortcut.
if (acode.cmd || acode.shift) {
if (acode.cmd || acode.shift)
{
Console.Error(L"Cannot map %s to Sys_TakeSnapshot - must not include Shift or Ctrl - these modifiers will be added automatically.",
WX_STR(acode.ToString()));
WX_STR(acode.ToString()));
}
else {
KeyAcceleratorCode shifted(acode); shifted.Shift();
KeyAcceleratorCode controlledShifted(shifted); controlledShifted.Cmd();
else
{
KeyAcceleratorCode shifted(acode);
shifted.Shift();
KeyAcceleratorCode controlledShifted(shifted);
controlledShifted.Cmd();
operator[](acode.val32) = result;
operator[](shifted.val32) = result;
operator[](controlledShifted.val32) = result;
if (_acode.val32 != acode.val32) { // overriding default
if (_acode.val32 != acode.val32)
{ // overriding default
Console.WriteLn(Color_Green, L"Sys_TakeSnapshot: automatically mapping also %s and %s",
WX_STR(shifted.ToString()),
WX_STR(controlledShifted.ToString())
);
WX_STR(shifted.ToString()),
WX_STR(controlledShifted.ToString()));
}
}
}
else {
else
{
operator[](acode.val32) = result;
}
}
@ -925,10 +975,11 @@ KeyAcceleratorCode AcceleratorDictionary::findKeycodeWithCommandId(const char* c
void Pcsx2App::BuildCommandHash()
{
if( !GlobalCommands ) GlobalCommands = std::unique_ptr<CommandDictionary>(new CommandDictionary);
if (!GlobalCommands)
GlobalCommands = std::unique_ptr<CommandDictionary>(new CommandDictionary);
const GlobalCommandDescriptor* curcmd = CommandDeclarations;
while( curcmd->Invoke != NULL )
while (curcmd->Invoke != NULL)
{
(*GlobalCommands)[curcmd->Id] = curcmd;
curcmd++;
@ -939,20 +990,21 @@ void Pcsx2App::InitDefaultGlobalAccelerators()
{
typedef KeyAcceleratorCode AAC;
if( !GlobalAccels ) GlobalAccels = std::unique_ptr<AcceleratorDictionary>(new AcceleratorDictionary);
if (!GlobalAccels)
GlobalAccels = std::unique_ptr<AcceleratorDictionary>(new AcceleratorDictionary);
// Why do we even have those here? all of them seem to be overridden
// by GSPanel::m_Accels ( GSPanel::InitDefaultAccelerators() )
// - One reason is because this is used to initialize shortcuts in the MainFrame's UI (see - MainFrame::AppendShortcutToMenuOption)
// this is before the GS Window has been initialized.
GlobalAccels->Map( AAC( WXK_F1 ), "States_FreezeCurrentSlot" );
GlobalAccels->Map( AAC( WXK_F3 ), "States_DefrostCurrentSlot" );
GlobalAccels->Map( AAC( WXK_F2 ), "States_CycleSlotForward" );
GlobalAccels->Map( AAC( WXK_F2 ).Shift(), "States_CycleSlotBackward" );
GlobalAccels->Map(AAC(WXK_F1), "States_FreezeCurrentSlot");
GlobalAccels->Map(AAC(WXK_F3), "States_DefrostCurrentSlot");
GlobalAccels->Map(AAC(WXK_F2), "States_CycleSlotForward");
GlobalAccels->Map(AAC(WXK_F2).Shift(), "States_CycleSlotBackward");
GlobalAccels->Map( AAC( WXK_F4 ), "Framelimiter_MasterToggle");
GlobalAccels->Map( AAC( WXK_F4 ).Shift(), "Frameskip_Toggle");
GlobalAccels->Map(AAC(WXK_F4), "Framelimiter_MasterToggle");
GlobalAccels->Map(AAC(WXK_F4).Shift(), "Frameskip_Toggle");
/*GlobalAccels->Map( AAC( WXK_ESCAPE ), "Sys_Suspend");
GlobalAccels->Map( AAC( WXK_F8 ), "Sys_TakeSnapshot");

View File

@ -31,7 +31,7 @@
#include "Saveslots.h"
// ------------------------------------------------------------------------
wxMenu* MainEmuFrame::MakeStatesSubMenu( int baseid, int loadBackupId ) const
wxMenu* MainEmuFrame::MakeStatesSubMenu(int baseid, int loadBackupId) const
{
wxMenu* mnuSubstates = new wxMenu();
@ -46,10 +46,10 @@ wxMenu* MainEmuFrame::MakeStatesSubMenu( int baseid, int loadBackupId ) const
mnuSubstates->AppendSeparator();
wxMenuItem* m = mnuSubstates->Append(loadBackupId, _("Backup"));
m->Enable( false );
m->Enable(false);
}
mnuSubstates->Append( baseid - 1, _("File...") );
mnuSubstates->Append(baseid - 1, _("File..."));
return mnuSubstates;
}
@ -61,7 +61,7 @@ void MainEmuFrame::UpdateStatusBar()
temp += "Fast Boot - ";
if (g_Conf->CdvdSource == CDVD_SourceType::Iso)
temp += "Load: '" + wxFileName(g_Conf->CurrentIso).GetFullName() +"' ";
temp += "Load: '" + wxFileName(g_Conf->CurrentIso).GetFullName() + "' ";
m_statusbar.SetStatusText(temp, 0);
m_statusbar.SetStatusText(CDVD_SourceLabels[enum_cast(g_Conf->CdvdSource)], 1);
@ -77,15 +77,21 @@ void MainEmuFrame::UpdateCdvdSrcSelection()
{
MenuIdentifiers cdsrc = MenuId_Src_Iso;
switch( g_Conf->CdvdSource )
switch (g_Conf->CdvdSource)
{
case CDVD_SourceType::Iso: cdsrc = MenuId_Src_Iso; break;
case CDVD_SourceType::Disc: cdsrc = MenuId_Src_Disc; break;
case CDVD_SourceType::NoDisc: cdsrc = MenuId_Src_NoDisc; break;
case CDVD_SourceType::Iso:
cdsrc = MenuId_Src_Iso;
break;
case CDVD_SourceType::Disc:
cdsrc = MenuId_Src_Disc;
break;
case CDVD_SourceType::NoDisc:
cdsrc = MenuId_Src_NoDisc;
break;
jNO_DEFAULT
jNO_DEFAULT
}
sMenuBar.Check( cdsrc, true );
sMenuBar.Check(cdsrc, true);
UpdateStatusBar();
}
@ -97,18 +103,19 @@ bool MainEmuFrame::Destroy()
for (
wxWindowList::const_iterator
i = wxTopLevelWindows.begin(),
i = wxTopLevelWindows.begin(),
end = wxTopLevelWindows.end();
i != end; ++i
)
i != end; ++i)
{
wxTopLevelWindow * const win = wx_static_cast(wxTopLevelWindow *, *i);
if (win == this) continue;
if (win->GetParent() != this) continue;
wxTopLevelWindow* const win = wx_static_cast(wxTopLevelWindow*, *i);
if (win == this)
continue;
if (win->GetParent() != this)
continue;
win->Destroy();
}
return _parent::Destroy();
}
@ -122,13 +129,14 @@ bool MainEmuFrame::Destroy()
//
void MainEmuFrame::OnCloseWindow(wxCloseEvent& evt)
{
if( IsBeingDeleted() ) return;
if (IsBeingDeleted())
return;
CoreThread.Suspend();
//bool isClosing = false;
if( !evt.CanVeto() )
if (!evt.CanVeto())
{
// Mandatory destruction...
//isClosing = true;
@ -142,28 +150,28 @@ void MainEmuFrame::OnCloseWindow(wxCloseEvent& evt)
// however. --air
//evt.Veto( true );
}
sApp.OnMainFrameClosed( GetId() );
sApp.OnMainFrameClosed(GetId());
RemoveCdvdMenu();
RemoveEventHandler( &wxGetApp().GetRecentIsoManager() );
wxGetApp().PostIdleAppMethod( &Pcsx2App::PrepForExit );
RemoveEventHandler(&wxGetApp().GetRecentIsoManager());
wxGetApp().PostIdleAppMethod(&Pcsx2App::PrepForExit);
evt.Skip();
}
void MainEmuFrame::OnMoveAround( wxMoveEvent& evt )
void MainEmuFrame::OnMoveAround(wxMoveEvent& evt)
{
if( IsBeingDeleted() || !IsVisible() || IsIconized() ) return;
if (IsBeingDeleted() || !IsVisible() || IsIconized())
return;
// Uncomment this when doing logger stress testing (and then move the window around
// while the logger spams itself)
// ... makes for a good test of the message pump's responsiveness.
if( EnableThreadedLoggingTest )
Console.Warning( "Threaded Logging Test! (a window move event)" );
if (EnableThreadedLoggingTest)
Console.Warning("Threaded Logging Test! (a window move event)");
// evt.GetPosition() returns the client area position, not the window frame position.
// So read the window's screen-relative position directly.
@ -173,11 +181,12 @@ void MainEmuFrame::OnMoveAround( wxMoveEvent& evt )
// like selecting or deselecting a window, which muck up docking logic. We filter them
// out using 'lastpos' here. :)
static wxPoint lastpos( wxDefaultCoord, wxDefaultCoord );
if( lastpos == evt.GetPosition() ) return;
static wxPoint lastpos(wxDefaultCoord, wxDefaultCoord);
if (lastpos == evt.GetPosition())
return;
lastpos = evt.GetPosition();
if( g_Conf->ProgLogBox.AutoDock )
if (g_Conf->ProgLogBox.AutoDock)
{
if (ConsoleLogFrame* proglog = wxGetApp().GetProgramLog())
{
@ -195,7 +204,7 @@ void MainEmuFrame::OnMoveAround( wxMoveEvent& evt )
void MainEmuFrame::OnLogBoxHidden()
{
g_Conf->ProgLogBox.Visible = false;
m_MenuItem_Console.Check( false );
m_MenuItem_Console.Check(false);
}
// ------------------------------------------------------------------------
@ -285,45 +294,46 @@ void MainEmuFrame::ConnectMenus()
#endif
}
void MainEmuFrame::InitLogBoxPosition( AppConfig::ConsoleLogOptions& conf )
void MainEmuFrame::InitLogBoxPosition(AppConfig::ConsoleLogOptions& conf)
{
conf.DisplaySize.Set(
std::min( std::max( conf.DisplaySize.GetWidth(), 160 ), wxGetDisplayArea().GetWidth() ),
std::min( std::max( conf.DisplaySize.GetHeight(), 160 ), wxGetDisplayArea().GetHeight() )
);
std::min(std::max(conf.DisplaySize.GetWidth(), 160), wxGetDisplayArea().GetWidth()),
std::min(std::max(conf.DisplaySize.GetHeight(), 160), wxGetDisplayArea().GetHeight()));
if( conf.AutoDock )
if (conf.AutoDock)
{
conf.DisplayPosition = GetScreenPosition() + wxSize( GetSize().x, 0 );
conf.DisplayPosition = GetScreenPosition() + wxSize(GetSize().x, 0);
}
else if( conf.DisplayPosition != wxDefaultPosition )
else if (conf.DisplayPosition != wxDefaultPosition)
{
if( !wxGetDisplayArea().Contains( wxRect( conf.DisplayPosition, conf.DisplaySize ) ) )
if (!wxGetDisplayArea().Contains(wxRect(conf.DisplayPosition, conf.DisplaySize)))
conf.DisplayPosition = wxDefaultPosition;
}
}
void MainEmuFrame::DispatchEvent( const PluginEventType& plugin_evt )
void MainEmuFrame::DispatchEvent(const PluginEventType& plugin_evt)
{
if( !pxAssertMsg( GetMenuBar()!=NULL, "Mainframe menu bar is NULL!" ) ) return;
if (!pxAssertMsg(GetMenuBar() != NULL, "Mainframe menu bar is NULL!"))
return;
//ApplyCoreStatus();
if( plugin_evt == CorePlugins_Unloaded )
if (plugin_evt == CorePlugins_Unloaded)
{
for( int i=0; i<PluginId_Count; ++i )
for (int i = 0; i < PluginId_Count; ++i)
m_PluginMenuPacks[i].OnUnloaded();
}
else if( plugin_evt == CorePlugins_Loaded )
else if (plugin_evt == CorePlugins_Loaded)
{
for( int i=0; i<PluginId_Count; ++i )
for (int i = 0; i < PluginId_Count; ++i)
m_PluginMenuPacks[i].OnLoaded();
}
}
void MainEmuFrame::DispatchEvent( const CoreThreadStatus& status )
void MainEmuFrame::DispatchEvent(const CoreThreadStatus& status)
{
if( !pxAssertMsg( GetMenuBar()!=NULL, "Mainframe menu bar is NULL!" ) ) return;
if (!pxAssertMsg(GetMenuBar() != NULL, "Mainframe menu bar is NULL!"))
return;
ApplyCoreStatus();
}
@ -332,12 +342,12 @@ void MainEmuFrame::AppStatusEvent_OnSettingsApplied()
ApplySettings();
}
int GetPluginMenuId_Settings( PluginsEnum_t pid )
int GetPluginMenuId_Settings(PluginsEnum_t pid)
{
return MenuId_PluginBase_Settings + ((int)pid * PluginMenuId_Interval);
}
static int GetPluginMenuId_Name( PluginsEnum_t pid )
static int GetPluginMenuId_Name(PluginsEnum_t pid)
{
return MenuId_PluginBase_Name + ((int)pid * PluginMenuId_Interval);
}
@ -347,74 +357,73 @@ void MainEmuFrame::CreatePcsx2Menu()
// ------------------------------------------------------------------------
// Some of the items in the System menu are configured by the UpdateCoreStatus() method.
m_menuSys.Append(MenuId_Boot_CDVD, _("Initializing..."));
m_menuSys.Append(MenuId_Boot_CDVD, _("Initializing..."));
m_menuSys.Append(MenuId_Sys_SuspendResume, _("Initializing..."));
m_menuSys.Append(MenuId_Sys_SuspendResume, _("Initializing..."));
m_menuSys.Append(MenuId_Sys_Shutdown, _("Shut&down"),
_("Wipes all internal VM states and shuts down plugins."));
m_menuSys.Append(MenuId_Sys_Shutdown, _("Shut&down"),
_("Wipes all internal VM states and shuts down plugins."));
m_menuSys.FindItem(MenuId_Sys_Shutdown)->Enable(false);
m_menuSys.Append(MenuId_Boot_ELF, _("&Run ELF..."),
_("For running raw PS2 binaries directly"));
m_menuSys.Append(MenuId_Boot_ELF, _("&Run ELF..."),
_("For running raw PS2 binaries directly"));
m_menuSys.AppendSeparator();
m_menuSys.Append( MenuId_Config_FastBoot,_("Fast Boot"),
_("Skips PS2 splash screens when booting from ISO or DVD media"), wxITEM_CHECK );
m_menuSys.Append(MenuId_Config_FastBoot, _("Fast Boot"),
_("Skips PS2 splash screens when booting from ISO or DVD media"), wxITEM_CHECK);
m_menuSys.AppendCheckItem(MenuId_Debug_CreateBlockdump, _("Create &Blockdump"), _("Creates a block dump for debugging purposes."));
m_menuSys.Append(MenuId_GameSettingsSubMenu, _("&Game Settings"), &m_GameSettingsSubmenu);
m_menuSys.Append(MenuId_GameSettingsSubMenu, _("&Game Settings"), &m_GameSettingsSubmenu);
m_GameSettingsSubmenu.Append(MenuId_EnablePatches, _("Automatic &Gamefixes"),
_("Automatically applies needed Gamefixes to known problematic games"), wxITEM_CHECK);
m_GameSettingsSubmenu.Append(MenuId_EnablePatches, _("Automatic &Gamefixes"),
_("Automatically applies needed Gamefixes to known problematic games"), wxITEM_CHECK);
m_GameSettingsSubmenu.Append(MenuId_EnableCheats, _("Enable &Cheats"),
wxEmptyString, wxITEM_CHECK);
m_GameSettingsSubmenu.Append(MenuId_EnableCheats, _("Enable &Cheats"),
wxEmptyString, wxITEM_CHECK);
m_GameSettingsSubmenu.Append(MenuId_EnableIPC, _("Enable &IPC"),
wxEmptyString, wxITEM_CHECK);
m_GameSettingsSubmenu.Append(MenuId_EnableIPC, _("Enable &IPC"),
wxEmptyString, wxITEM_CHECK);
m_GameSettingsSubmenu.Append(MenuId_EnableWideScreenPatches, _("Enable &Widescreen Patches"),
_("Enabling Widescreen Patches may occasionally cause issues."), wxITEM_CHECK);
m_GameSettingsSubmenu.Append(MenuId_EnableWideScreenPatches, _("Enable &Widescreen Patches"),
_("Enabling Widescreen Patches may occasionally cause issues."), wxITEM_CHECK);
#ifndef DISABLE_RECORDING
m_GameSettingsSubmenu.Append(MenuId_EnableInputRecording, _("Enable &Input Recording"),
wxEmptyString, wxITEM_CHECK);
wxEmptyString, wxITEM_CHECK);
#endif
if(IsDebugBuild || IsDevBuild)
m_GameSettingsSubmenu.Append(MenuId_EnableHostFs, _("Enable &Host Filesystem"),
wxEmptyString, wxITEM_CHECK);
if (IsDebugBuild || IsDevBuild)
m_GameSettingsSubmenu.Append(MenuId_EnableHostFs, _("Enable &Host Filesystem"),
wxEmptyString, wxITEM_CHECK);
m_menuSys.AppendSeparator();
m_menuSys.Append(MenuId_Sys_LoadStates, _("&Load state"), &m_LoadStatesSubmenu);
m_menuSys.Append(MenuId_Sys_SaveStates, _("&Save state"), &m_SaveStatesSubmenu);
m_menuSys.Append(MenuId_Sys_LoadStates, _("&Load state"), &m_LoadStatesSubmenu);
m_menuSys.Append(MenuId_Sys_SaveStates, _("&Save state"), &m_SaveStatesSubmenu);
m_menuSys.Append(MenuId_EnableBackupStates, _("&Backup before save"), wxEmptyString, wxITEM_CHECK);
m_menuSys.Append(MenuId_EnableBackupStates, _("&Backup before save"), wxEmptyString, wxITEM_CHECK);
m_menuSys.AppendSeparator();
m_menuSys.Append(MenuId_Exit, _("E&xit"),
AddAppName(_("Closing %s may be hazardous to your health")));
m_menuSys.Append(MenuId_Exit, _("E&xit"),
AddAppName(_("Closing %s may be hazardous to your health")));
}
void MainEmuFrame::CreateCdvdMenu()
{
// ------------------------------------------------------------------------
wxMenu& isoRecents( wxGetApp().GetRecentIsoMenu() );
wxMenu& driveList ( wxGetApp().GetDriveListMenu() );
wxMenu& isoRecents(wxGetApp().GetRecentIsoMenu());
wxMenu& driveList(wxGetApp().GetDriveListMenu());
m_menuItem_RecentIsoMenu = m_menuCDVD.AppendSubMenu(&isoRecents, _("ISO &Selector"));
m_menuItem_DriveListMenu = m_menuCDVD.AppendSubMenu(&driveList, _("D&rive Selector"));
m_menuItem_DriveListMenu = m_menuCDVD.AppendSubMenu(&driveList, _("D&rive Selector"));
m_menuCDVD.AppendSeparator();
m_menuCDVD.Append( MenuId_Src_Iso, _("&ISO"), _("Makes the specified ISO image the CDVD source."), wxITEM_RADIO );
m_menuCDVD.Append( MenuId_Src_Disc, _("&Disc"), _("Uses a disc drive as the CDVD source."), wxITEM_RADIO );
m_menuCDVD.Append( MenuId_Src_NoDisc, _("&No disc"), _("Use this to boot into your virtual PS2's BIOS configuration."), wxITEM_RADIO );
m_menuCDVD.Append(MenuId_Src_Iso, _("&ISO"), _("Makes the specified ISO image the CDVD source."), wxITEM_RADIO);
m_menuCDVD.Append(MenuId_Src_Disc, _("&Disc"), _("Uses a disc drive as the CDVD source."), wxITEM_RADIO);
m_menuCDVD.Append(MenuId_Src_NoDisc, _("&No disc"), _("Use this to boot into your virtual PS2's BIOS configuration."), wxITEM_RADIO);
#if defined(__FREEBSD__) || defined(__APPLE__)
m_menuItem_DriveListMenu->Enable(false);
@ -425,37 +434,37 @@ void MainEmuFrame::CreateCdvdMenu()
void MainEmuFrame::CreateConfigMenu()
{
m_menuConfig.Append(MenuId_Config_SysSettings, _("Emulation &Settings...") );
m_menuConfig.Append(MenuId_Config_McdSettings, _("&Memory Cards...") );
m_menuConfig.Append(MenuId_Config_BIOS, _("&Plugin/BIOS Selector...") );
m_menuConfig.Append(MenuId_Config_SPU2, _("&Audio Settings...") );
m_menuConfig.Append(MenuId_Config_SysSettings, _("Emulation &Settings..."));
m_menuConfig.Append(MenuId_Config_McdSettings, _("&Memory Cards..."));
m_menuConfig.Append(MenuId_Config_BIOS, _("&Plugin/BIOS Selector..."));
m_menuConfig.Append(MenuId_Config_SPU2, _("&Audio Settings..."));
m_menuConfig.AppendSeparator();
m_menuConfig.Append(MenuId_Config_GS, _("&Video (GS)"), m_PluginMenuPacks[PluginId_GS]);
m_menuConfig.Append(MenuId_Config_PAD, _("&Controllers (PAD)"),m_PluginMenuPacks[PluginId_PAD]);
m_menuConfig.Append(MenuId_Config_DEV9, _("&Dev9"), m_PluginMenuPacks[PluginId_DEV9]);
m_menuConfig.Append(MenuId_Config_USB, _("&USB"), m_PluginMenuPacks[PluginId_USB]);
m_menuConfig.Append(MenuId_Config_GS, _("&Video (GS)"), m_PluginMenuPacks[PluginId_GS]);
m_menuConfig.Append(MenuId_Config_PAD, _("&Controllers (PAD)"), m_PluginMenuPacks[PluginId_PAD]);
m_menuConfig.Append(MenuId_Config_DEV9, _("&Dev9"), m_PluginMenuPacks[PluginId_DEV9]);
m_menuConfig.Append(MenuId_Config_USB, _("&USB"), m_PluginMenuPacks[PluginId_USB]);
m_menuConfig.AppendSeparator();
m_menuConfig.Append(MenuId_Config_Multitap0Toggle, _("Multitap &1"), wxEmptyString, wxITEM_CHECK );
m_menuConfig.Append(MenuId_Config_Multitap1Toggle, _("Multitap &2"), wxEmptyString, wxITEM_CHECK );
m_menuConfig.Append(MenuId_Config_Multitap0Toggle, _("Multitap &1"), wxEmptyString, wxITEM_CHECK);
m_menuConfig.Append(MenuId_Config_Multitap1Toggle, _("Multitap &2"), wxEmptyString, wxITEM_CHECK);
m_menuConfig.AppendSeparator();
m_menuConfig.Append(MenuId_ChangeLang, L"Change &Language..." ); // Always in English
m_menuConfig.Append(MenuId_Config_ResetAll, _("C&lear All Settings..."),
AddAppName(_("Clears all %s settings and re-runs the startup wizard.")));
m_menuConfig.Append(MenuId_ChangeLang, L"Change &Language..."); // Always in English
m_menuConfig.Append(MenuId_Config_ResetAll, _("C&lear All Settings..."),
AddAppName(_("Clears all %s settings and re-runs the startup wizard.")));
}
void MainEmuFrame::CreateWindowsMenu()
{
m_menuWindow.Append(MenuId_Debug_Open, _("&Show Debug"), wxEmptyString, wxITEM_CHECK );
m_menuWindow.Append(MenuId_Debug_Open, _("&Show Debug"), wxEmptyString, wxITEM_CHECK);
m_menuWindow.Append( &m_MenuItem_Console );
m_menuWindow.Append(&m_MenuItem_Console);
#if defined(__unix__)
m_menuWindow.AppendSeparator();
m_menuWindow.Append( &m_MenuItem_Console_Stdio );
m_menuWindow.Append(&m_MenuItem_Console_Stdio);
#endif
}
@ -486,64 +495,64 @@ void MainEmuFrame::CreateRecordMenu()
void MainEmuFrame::CreateHelpMenu()
{
m_menuHelp.Append(MenuId_Help_GetStarted, _("&Getting Started"));
m_menuHelp.Append(MenuId_Help_Compatibility, _("&Compatibility"));
m_menuHelp.Append(MenuId_Help_GetStarted, _("&Getting Started"));
m_menuHelp.Append(MenuId_Help_Compatibility, _("&Compatibility"));
m_menuHelp.AppendSeparator();
m_menuHelp.Append(MenuId_Help_Website, _("&Website"));
m_menuHelp.Append(MenuId_Help_Wiki, _("&Wiki"));
m_menuHelp.Append(MenuId_Help_Forums, _("&Support Forums"));
m_menuHelp.Append(MenuId_Help_Github, _("&Github Repository"));
m_menuHelp.Append(MenuId_Help_Website, _("&Website"));
m_menuHelp.Append(MenuId_Help_Wiki, _("&Wiki"));
m_menuHelp.Append(MenuId_Help_Forums, _("&Support Forums"));
m_menuHelp.Append(MenuId_Help_Github, _("&Github Repository"));
m_menuHelp.AppendSeparator();
m_menuHelp.Append(MenuId_About, _("&About..."));
m_menuHelp.Append(MenuId_About, _("&About..."));
}
// ------------------------------------------------------------------------
MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title)
: wxFrame(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE & ~(wxMAXIMIZE_BOX | wxRESIZE_BORDER) )
: wxFrame(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE & ~(wxMAXIMIZE_BOX | wxRESIZE_BORDER))
, m_statusbar( *CreateStatusBar(2, 0) )
, m_background( new wxStaticBitmap(this, wxID_ANY, wxGetApp().GetLogoBitmap()) )
, m_statusbar(*CreateStatusBar(2, 0))
, m_background(new wxStaticBitmap(this, wxID_ANY, wxGetApp().GetLogoBitmap()))
// All menu components must be created on the heap!
, m_menubar( *new wxMenuBar() )
, m_menubar(*new wxMenuBar())
, m_menuCDVD ( *new wxMenu() )
, m_menuSys ( *new wxMenu() )
, m_menuConfig ( *new wxMenu() )
, m_menuWindow ( *new wxMenu() )
, m_menuCapture ( *new wxMenu() )
, m_submenuVideoCapture ( *new wxMenu() )
, m_menuCDVD(*new wxMenu())
, m_menuSys(*new wxMenu())
, m_menuConfig(*new wxMenu())
, m_menuWindow(*new wxMenu())
, m_menuCapture(*new wxMenu())
, m_submenuVideoCapture(*new wxMenu())
#ifndef DISABLE_RECORDING
, m_menuRecording(*new wxMenu())
#endif
, m_menuHelp(*new wxMenu())
, m_LoadStatesSubmenu( *MakeStatesSubMenu( MenuId_State_Load01, MenuId_State_LoadBackup ) )
, m_SaveStatesSubmenu( *MakeStatesSubMenu( MenuId_State_Save01 ) )
, m_GameSettingsSubmenu( *new wxMenu() )
, m_LoadStatesSubmenu(*MakeStatesSubMenu(MenuId_State_Load01, MenuId_State_LoadBackup))
, m_SaveStatesSubmenu(*MakeStatesSubMenu(MenuId_State_Save01))
, m_GameSettingsSubmenu(*new wxMenu())
, m_MenuItem_Console( *new wxMenuItem( &m_menuWindow, MenuId_Console, _("&Show Console"), wxEmptyString, wxITEM_CHECK ) )
, m_MenuItem_Console(*new wxMenuItem(&m_menuWindow, MenuId_Console, _("&Show Console"), wxEmptyString, wxITEM_CHECK))
#if defined(__unix__)
, m_MenuItem_Console_Stdio( *new wxMenuItem( &m_menuWindow, MenuId_Console_Stdio, _("&Console to Stdio"), wxEmptyString, wxITEM_CHECK ) )
, m_MenuItem_Console_Stdio(*new wxMenuItem(&m_menuWindow, MenuId_Console_Stdio, _("&Console to Stdio"), wxEmptyString, wxITEM_CHECK))
#endif
{
m_RestartEmuOnDelete = false;
for( int i=0; i<PluginId_Count; ++i )
m_PluginMenuPacks[i].Populate( (PluginsEnum_t)i );
for (int i = 0; i < PluginId_Count; ++i)
m_PluginMenuPacks[i].Populate((PluginsEnum_t)i);
// ------------------------------------------------------------------------
// Initial menubar setup. This needs to be done first so that the menu bar's visible size
// can be factored into the window size (which ends up being background+status+menus)
m_menubar.Append( &m_menuSys, _("&PCSX2") );
m_menubar.Append( &m_menuCDVD, _("CD&VD") );
m_menubar.Append( &m_menuConfig, _("&Config") );
m_menubar.Append( &m_menuWindow, _("&Window") );
m_menubar.Append( &m_menuCapture, _("&Capture") );
m_menubar.Append(&m_menuSys, _("&PCSX2"));
m_menubar.Append(&m_menuCDVD, _("CD&VD"));
m_menubar.Append(&m_menuConfig, _("&Config"));
m_menubar.Append(&m_menuWindow, _("&Window"));
m_menubar.Append(&m_menuCapture, _("&Capture"));
SetMenuBar( &m_menubar );
SetMenuBar(&m_menubar);
#ifndef DISABLE_RECORDING
// Append the Recording options if previously enabled and setting has been picked up from ini
@ -552,7 +561,7 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title)
m_menubar.Append(&m_menuRecording, _("&Input Record"));
}
#endif
m_menubar.Append( &m_menuHelp, _("&Help") );
m_menubar.Append(&m_menuHelp, _("&Help"));
// ------------------------------------------------------------------------
@ -561,37 +570,40 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title)
wxSize backsize(m_background->GetBitmap().GetWidth(), m_background->GetBitmap().GetHeight());
wxString wintitle;
if( PCSX2_isReleaseVersion )
if (PCSX2_isReleaseVersion)
{
// stable releases, with a simple title.
wintitle.Printf( L"%s %d.%d.%d", pxGetAppName().c_str(), PCSX2_VersionHi, PCSX2_VersionMid, PCSX2_VersionLo );
wintitle.Printf(L"%s %d.%d.%d", pxGetAppName().c_str(), PCSX2_VersionHi, PCSX2_VersionMid, PCSX2_VersionLo);
}
else
{
// beta / development editions, which feature revision number and compile date.
if (strlen(GIT_REV) > 5) {
wintitle.Printf( L"%s %s", pxGetAppName().c_str(), GIT_REV);
} else {
wintitle.Printf( L"%s %d.%d.%d-%lld%s (git)", pxGetAppName().c_str(), PCSX2_VersionHi, PCSX2_VersionMid,
PCSX2_VersionLo, SVN_REV, SVN_MODS ? L"m" : wxEmptyString );
if (strlen(GIT_REV) > 5)
{
wintitle.Printf(L"%s %s", pxGetAppName().c_str(), GIT_REV);
}
else
{
wintitle.Printf(L"%s %d.%d.%d-%lld%s (git)", pxGetAppName().c_str(), PCSX2_VersionHi, PCSX2_VersionMid,
PCSX2_VersionLo, SVN_REV, SVN_MODS ? L"m" : wxEmptyString);
}
}
SetTitle( wintitle );
SetTitle(wintitle);
// Ideally the __WXMSW__ port should use the embedded IDI_ICON2 icon, because wxWidgets sucks and
// loses the transparency information when loading bitmaps into icons. But for some reason
// I cannot get it to work despite following various examples to the letter.
SetIcons( wxGetApp().GetIconBundle() );
SetIcons(wxGetApp().GetIconBundle());
int m_statusbar_widths[] = { (int)-20, (int)-3, (int) -2 };
int m_statusbar_widths[] = {(int)-20, (int)-3, (int)-2};
m_statusbar.SetFieldsCount(3);
m_statusbar.SetStatusWidths(3, m_statusbar_widths);
m_statusbar.SetStatusText( wxEmptyString, 0);
m_statusbar.SetStatusText(wxEmptyString, 0);
wxBoxSizer& joe( *new wxBoxSizer( wxVERTICAL ) );
joe.Add( m_background );
SetSizerAndFit( &joe );
wxBoxSizer& joe(*new wxBoxSizer(wxVERTICAL));
joe.Add(m_background);
SetSizerAndFit(&joe);
// Makes no sense, but this is needed for the window size to be correct for
// 200% DPI on Windows. The SetSizerAndFit is supposed to be doing the exact
@ -599,16 +611,16 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title)
GetSizer()->SetSizeHints(this);
// Use default window position if the configured windowpos is invalid (partially offscreen)
if( g_Conf->MainGuiPosition == wxDefaultPosition || !pxIsValidWindowPosition( *this, g_Conf->MainGuiPosition) )
if (g_Conf->MainGuiPosition == wxDefaultPosition || !pxIsValidWindowPosition(*this, g_Conf->MainGuiPosition))
g_Conf->MainGuiPosition = GetScreenPosition();
else
SetPosition( g_Conf->MainGuiPosition );
SetPosition(g_Conf->MainGuiPosition);
// Updating console log positions after the main window has been fitted to its sizer ensures
// proper docked positioning, since the main window's size is invalid until after the sizer
// has been set/fit.
InitLogBoxPosition( g_Conf->ProgLogBox );
InitLogBoxPosition(g_Conf->ProgLogBox);
CreatePcsx2Menu();
CreateCdvdMenu();
CreateConfigMenu();
@ -619,7 +631,7 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title)
#endif
CreateHelpMenu();
m_MenuItem_Console.Check( g_Conf->ProgLogBox.Visible );
m_MenuItem_Console.Check(g_Conf->ProgLogBox.Visible);
ConnectMenus();
Bind(wxEVT_MOVE, &MainEmuFrame::OnMoveAround, this);
@ -627,8 +639,8 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title)
Bind(wxEVT_SET_FOCUS, &MainEmuFrame::OnFocus, this);
Bind(wxEVT_ACTIVATE, &MainEmuFrame::OnActivate, this);
PushEventHandler( &wxGetApp().GetRecentIsoManager() );
SetDropTarget( new IsoDropTarget( this ) );
PushEventHandler(&wxGetApp().GetRecentIsoManager());
SetDropTarget(new IsoDropTarget(this));
ApplyCoreStatus();
ApplySettings();
@ -637,11 +649,12 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title)
MainEmuFrame::~MainEmuFrame()
{
try {
if( m_RestartEmuOnDelete )
try
{
if (m_RestartEmuOnDelete)
{
sApp.SetExitOnFrameDelete( false );
sApp.PostAppMethod( &Pcsx2App::DetectCpuAndUserMode );
sApp.SetExitOnFrameDelete(false);
sApp.PostAppMethod(&Pcsx2App::DetectCpuAndUserMode);
sApp.WipeUserModeSettings();
}
}
@ -662,18 +675,18 @@ void MainEmuFrame::DoGiveHelp(const wxString& text, bool show)
// not propagate up the window hierarchy, and on Activate events don't always get sent
// on the first focusing event after PCSX2 starts.
void MainEmuFrame::OnFocus( wxFocusEvent& evt )
void MainEmuFrame::OnFocus(wxFocusEvent& evt)
{
if( ConsoleLogFrame* logframe = wxGetApp().GetProgramLog() )
MSW_SetWindowAfter( logframe->GetHandle(), GetHandle() );
if (ConsoleLogFrame* logframe = wxGetApp().GetProgramLog())
MSW_SetWindowAfter(logframe->GetHandle(), GetHandle());
evt.Skip();
}
void MainEmuFrame::OnActivate( wxActivateEvent& evt )
void MainEmuFrame::OnActivate(wxActivateEvent& evt)
{
if( ConsoleLogFrame* logframe = wxGetApp().GetProgramLog() )
MSW_SetWindowAfter( logframe->GetHandle(), GetHandle() );
if (ConsoleLogFrame* logframe = wxGetApp().GetProgramLog())
MSW_SetWindowAfter(logframe->GetHandle(), GetHandle());
evt.Skip();
}
@ -681,14 +694,14 @@ void MainEmuFrame::OnActivate( wxActivateEvent& evt )
void MainEmuFrame::ApplyCoreStatus()
{
wxMenuBar& menubar( *GetMenuBar() );
wxMenuBar& menubar(*GetMenuBar());
// [TODO] : Ideally each of these items would bind a listener instance to the AppCoreThread
// dispatcher, and modify their states accordingly. This is just a hack (for now) -- air
if (wxMenuItem* susres = menubar.FindItem(MenuId_Sys_SuspendResume))
{
if( !CoreThread.IsClosing() )
if (!CoreThread.IsClosing())
{
susres->Enable();
susres->SetItemLabel(_("Paus&e"));
@ -698,7 +711,7 @@ void MainEmuFrame::ApplyCoreStatus()
{
bool ActiveVM = SysHasValidState();
susres->Enable(ActiveVM);
if( ActiveVM )
if (ActiveVM)
{
susres->SetItemLabel(_("R&esume"));
susres->SetHelp(_("Resumes the suspended emulation state."));
@ -713,25 +726,25 @@ void MainEmuFrame::ApplyCoreStatus()
const CDVD_SourceType Source = g_Conf->CdvdSource;
wxMenuItem *cdvd_menu = menubar.FindItem(MenuId_Boot_CDVD);
wxMenuItem* cdvd_menu = menubar.FindItem(MenuId_Boot_CDVD);
wxString label;
wxString help_text = _("Use fast boot to skip PS2 startup and splash screens");
switch (Source)
{
case CDVD_SourceType::Iso:
label = _("Boot ISO");
break;
case CDVD_SourceType::Disc:
label = _("Boot CDVD");
break;
case CDVD_SourceType::NoDisc:
label = _("Boot Bios");
break;
default:
label = _("Boot Bios");
break;
case CDVD_SourceType::Iso:
label = _("Boot ISO");
break;
case CDVD_SourceType::Disc:
label = _("Boot CDVD");
break;
case CDVD_SourceType::NoDisc:
label = _("Boot Bios");
break;
default:
label = _("Boot Bios");
break;
}
cdvd_menu->SetItemLabel(label);
@ -748,52 +761,54 @@ void MainEmuFrame::ApplySettings()
//currently only EnablePatches is affected when the settings come from a preset.
void MainEmuFrame::ApplyConfigToGui(AppConfig& configToApply, int flags)
{
wxMenuBar& menubar( *GetMenuBar() );
wxMenuBar& menubar(*GetMenuBar());
menubar.Check( MenuId_EnablePatches, configToApply.EmuOptions.EnablePatches );
menubar.Enable( MenuId_EnablePatches, !configToApply.EnablePresets );
menubar.Check(MenuId_EnablePatches, configToApply.EmuOptions.EnablePatches);
menubar.Enable(MenuId_EnablePatches, !configToApply.EnablePresets);
if ( !(flags & AppConfig::APPLY_FLAG_FROM_PRESET) )
{//these should not be affected by presets
menubar.Check( MenuId_EnableBackupStates, configToApply.EmuOptions.BackupSavestate );
menubar.Check( MenuId_EnableCheats, configToApply.EmuOptions.EnableCheats );
menubar.Check( MenuId_EnableIPC, configToApply.EmuOptions.EnableIPC );
menubar.Check( MenuId_EnableWideScreenPatches, configToApply.EmuOptions.EnableWideScreenPatches );
if (!(flags & AppConfig::APPLY_FLAG_FROM_PRESET))
{ //these should not be affected by presets
menubar.Check(MenuId_EnableBackupStates, configToApply.EmuOptions.BackupSavestate);
menubar.Check(MenuId_EnableCheats, configToApply.EmuOptions.EnableCheats);
menubar.Check(MenuId_EnableIPC, configToApply.EmuOptions.EnableIPC);
menubar.Check(MenuId_EnableWideScreenPatches, configToApply.EmuOptions.EnableWideScreenPatches);
#ifndef DISABLE_RECORDING
menubar.Check( MenuId_EnableInputRecording, configToApply.EmuOptions.EnableRecordingTools);
menubar.Check(MenuId_EnableInputRecording, configToApply.EmuOptions.EnableRecordingTools);
#endif
menubar.Check( MenuId_EnableHostFs, configToApply.EmuOptions.HostFs );
menubar.Check( MenuId_Debug_CreateBlockdump, configToApply.EmuOptions.CdvdDumpBlocks );
menubar.Check(MenuId_EnableHostFs, configToApply.EmuOptions.HostFs);
menubar.Check(MenuId_Debug_CreateBlockdump, configToApply.EmuOptions.CdvdDumpBlocks);
#if defined(__unix__)
menubar.Check( MenuId_Console_Stdio, configToApply.EmuOptions.ConsoleToStdio );
menubar.Check(MenuId_Console_Stdio, configToApply.EmuOptions.ConsoleToStdio);
#endif
menubar.Check( MenuId_Config_Multitap0Toggle, configToApply.EmuOptions.MultitapPort0_Enabled );
menubar.Check( MenuId_Config_Multitap1Toggle, configToApply.EmuOptions.MultitapPort1_Enabled );
menubar.Check( MenuId_Config_FastBoot, configToApply.EnableFastBoot );
menubar.Check(MenuId_Config_Multitap0Toggle, configToApply.EmuOptions.MultitapPort0_Enabled);
menubar.Check(MenuId_Config_Multitap1Toggle, configToApply.EmuOptions.MultitapPort1_Enabled);
menubar.Check(MenuId_Config_FastBoot, configToApply.EnableFastBoot);
}
UpdateCdvdSrcSelection(); //shouldn't be affected by presets but updates from g_Conf anyway and not from configToApply, so no problem here.
UpdateCdvdSrcSelection(); //shouldn't be affected by presets but updates from g_Conf anyway and not from configToApply, so no problem here.
}
//write pending preset settings from the gui to g_Conf,
// without triggering an overall "settingsApplied" event.
void MainEmuFrame::CommitPreset_noTrigger()
{
wxMenuBar& menubar( *GetMenuBar() );
g_Conf->EmuOptions.EnablePatches = menubar.IsChecked( MenuId_EnablePatches );
wxMenuBar& menubar(*GetMenuBar());
g_Conf->EmuOptions.EnablePatches = menubar.IsChecked(MenuId_EnablePatches);
}
static void AppendShortcutToMenuOption( wxMenuItem& item, wxString keyCodeStr ) {
static void AppendShortcutToMenuOption(wxMenuItem& item, wxString keyCodeStr)
{
wxString text = item.GetItemLabel();
const size_t tabPos = text.rfind(L'\t');
item.SetItemLabel(text.Mid(0, tabPos ) + L"\t" + keyCodeStr);
item.SetItemLabel(text.Mid(0, tabPos) + L"\t" + keyCodeStr);
}
void MainEmuFrame::AppendKeycodeNamesToMenuOptions() {
AppendShortcutToMenuOption(*m_menuSys.FindChildItem( MenuId_Sys_LoadStates ), wxGetApp().GlobalAccels->findKeycodeWithCommandId("States_DefrostCurrentSlot").toTitleizedString());
AppendShortcutToMenuOption(*m_menuSys.FindChildItem( MenuId_Sys_SaveStates ), wxGetApp().GlobalAccels->findKeycodeWithCommandId("States_FreezeCurrentSlot").toTitleizedString());
void MainEmuFrame::AppendKeycodeNamesToMenuOptions()
{
AppendShortcutToMenuOption(*m_menuSys.FindChildItem(MenuId_Sys_LoadStates), wxGetApp().GlobalAccels->findKeycodeWithCommandId("States_DefrostCurrentSlot").toTitleizedString());
AppendShortcutToMenuOption(*m_menuSys.FindChildItem(MenuId_Sys_SaveStates), wxGetApp().GlobalAccels->findKeycodeWithCommandId("States_FreezeCurrentSlot").toTitleizedString());
}
#ifndef DISABLE_RECORDING
@ -817,31 +832,31 @@ void MainEmuFrame::enableRecordingMenuItem(MenuIdentifiers menuId, bool enable)
// "Extensible" Plugin Menus
// ------------------------------------------------------------------------
void PerPluginMenuInfo::Populate( PluginsEnum_t pid )
void PerPluginMenuInfo::Populate(PluginsEnum_t pid)
{
if( !pxAssert(pid < PluginId_Count) ) return;
if (!pxAssert(pid < PluginId_Count))
return;
PluginId = pid;
MyMenu.Append( GetPluginMenuId_Name(PluginId), _("No plugin loaded") )->Enable( false );
MyMenu.Append(GetPluginMenuId_Name(PluginId), _("No plugin loaded"))->Enable(false);
MyMenu.AppendSeparator();
if( PluginId == PluginId_GS )
if (PluginId == PluginId_GS)
{
MyMenu.Append( MenuId_Video_CoreSettings, _("&Core GS Settings..."),
_("Modify hardware emulation settings regulated by the PCSX2 core virtual machine.") );
MyMenu.Append(MenuId_Video_CoreSettings, _("&Core GS Settings..."),
_("Modify hardware emulation settings regulated by the PCSX2 core virtual machine."));
MyMenu.Append( MenuId_Video_WindowSettings, _("&Window Settings..."),
_("Modify window and appearance options, including aspect ratio.") );
MyMenu.Append(MenuId_Video_WindowSettings, _("&Window Settings..."),
_("Modify window and appearance options, including aspect ratio."));
MyMenu.AppendSeparator();
}
// Populate options from the plugin here.
MyMenu.Append( GetPluginMenuId_Settings(PluginId), _("&Plugin Settings..."),
wxsFormat( _("Opens the %s plugin's advanced settings dialog."), tbl_PluginInfo[pid].GetShortname().c_str() )
);
MyMenu.Append(GetPluginMenuId_Settings(PluginId), _("&Plugin Settings..."),
wxsFormat(_("Opens the %s plugin's advanced settings dialog."), tbl_PluginInfo[pid].GetShortname().c_str()));
}
// deletes menu items belonging to (created by) the plugin. Leaves menu items created
@ -852,21 +867,21 @@ void PerPluginMenuInfo::OnUnloaded()
// done its own proper cleanup when the plugin was shutdown or unloaded, but lets
// not trust them, shall we?)
MenuItemAddonList& curlist( m_PluginMenuItems );
for( uint mx=0; mx<curlist.size(); ++mx )
MyMenu.Delete( curlist[mx].Item );
MenuItemAddonList& curlist(m_PluginMenuItems);
for (uint mx = 0; mx < curlist.size(); ++mx)
MyMenu.Delete(curlist[mx].Item);
curlist.clear();
MyMenu.SetLabel( GetPluginMenuId_Name(PluginId), _("No plugin loaded") );
MyMenu.Enable( GetPluginMenuId_Settings(PluginId), false );
MyMenu.SetLabel(GetPluginMenuId_Name(PluginId), _("No plugin loaded"));
MyMenu.Enable(GetPluginMenuId_Settings(PluginId), false);
}
void PerPluginMenuInfo::OnLoaded()
{
if( !CorePlugins.IsLoaded(PluginId) ) return;
MyMenu.SetLabel( GetPluginMenuId_Name(PluginId),
CorePlugins.GetName( PluginId ) + L" " + CorePlugins.GetVersion( PluginId )
);
MyMenu.Enable( GetPluginMenuId_Settings(PluginId), true );
if (!CorePlugins.IsLoaded(PluginId))
return;
MyMenu.SetLabel(GetPluginMenuId_Name(PluginId),
CorePlugins.GetName(PluginId) + L" " + CorePlugins.GetVersion(PluginId));
MyMenu.Enable(GetPluginMenuId_Settings(PluginId), true);
}

View File

@ -13,7 +13,7 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#pragma once
#include "App.h"
#include "AppSaveStates.h"
@ -23,17 +23,17 @@
struct PluginMenuAddition
{
wxString Text;
wxString HelpText;
PS2E_MenuItemStyle Flags;
wxString Text;
wxString HelpText;
PS2E_MenuItemStyle Flags;
wxMenuItem* Item;
int ItemId;
wxMenuItem* Item;
int ItemId;
// Optional user data pointer (or typecast integer value)
void* UserPtr;
void* UserPtr;
void (PS2E_CALLBACK *OnClicked)( PS2E_THISPTR* thisptr, void* userptr );
void(PS2E_CALLBACK* OnClicked)(PS2E_THISPTR* thisptr, void* userptr);
};
// --------------------------------------------------------------------------------------
@ -45,18 +45,22 @@ protected:
typedef std::vector<PluginMenuAddition> MenuItemAddonList;
// A list of menu items belonging to this plugin's menu.
MenuItemAddonList m_PluginMenuItems;
MenuItemAddonList m_PluginMenuItems;
public:
wxMenu& MyMenu;
PluginsEnum_t PluginId;
wxMenu& MyMenu;
PluginsEnum_t PluginId;
public:
PerPluginMenuInfo() : MyMenu(*new wxMenu()), PluginId (PluginId_Count) {}
PerPluginMenuInfo()
: MyMenu(*new wxMenu())
, PluginId(PluginId_Count)
{
}
virtual ~PerPluginMenuInfo() = default;
void Populate( PluginsEnum_t pid );
void Populate(PluginsEnum_t pid);
void OnUnloaded();
void OnLoaded();
@ -68,23 +72,23 @@ public:
// InvokeMenuCommand_OnSysStateUnlocked
// --------------------------------------------------------------------------------------
class InvokeMenuCommand_OnSysStateUnlocked
: public IEventListener_SysState
, public BaseDeletableObject
: public IEventListener_SysState,
public BaseDeletableObject
{
protected:
MenuIdentifiers m_menu_cmd;
MenuIdentifiers m_menu_cmd;
public:
InvokeMenuCommand_OnSysStateUnlocked( MenuIdentifiers menu_command )
InvokeMenuCommand_OnSysStateUnlocked(MenuIdentifiers menu_command)
{
m_menu_cmd = menu_command;
}
virtual ~InvokeMenuCommand_OnSysStateUnlocked() = default;
virtual void SaveStateAction_OnCreateFinished()
{
wxGetApp().PostMenuAction( m_menu_cmd );
wxGetApp().PostMenuAction(m_menu_cmd);
}
};
@ -92,50 +96,50 @@ public:
// MainEmuFrame
// --------------------------------------------------------------------------------------
class MainEmuFrame : public wxFrame,
public EventListener_Plugins,
public EventListener_CoreThread,
public EventListener_AppStatus
public EventListener_Plugins,
public EventListener_CoreThread,
public EventListener_AppStatus
{
typedef wxFrame _parent;
protected:
bool m_RestartEmuOnDelete;
bool m_RestartEmuOnDelete;
wxStatusBar& m_statusbar;
wxStaticBitmap* m_background;
wxStatusBar& m_statusbar;
wxStaticBitmap* m_background;
wxMenuBar& m_menubar;
wxMenuBar& m_menubar;
wxMenu& m_menuCDVD;
wxMenu& m_menuSys;
wxMenu& m_menuConfig;
wxMenu& m_menuWindow;
wxMenu& m_menuCDVD;
wxMenu& m_menuSys;
wxMenu& m_menuConfig;
wxMenu& m_menuWindow;
wxMenu& m_menuCapture;
wxMenu& m_submenuVideoCapture;
wxMenu& m_menuCapture;
wxMenu& m_submenuVideoCapture;
#ifndef DISABLE_RECORDING
wxMenu& m_menuRecording;
wxMenu& m_menuRecording;
#endif
wxMenu& m_menuHelp;
wxMenu& m_menuHelp;
wxMenu& m_LoadStatesSubmenu;
wxMenu& m_SaveStatesSubmenu;
wxMenu& m_GameSettingsSubmenu;
wxMenu& m_LoadStatesSubmenu;
wxMenu& m_SaveStatesSubmenu;
wxMenu& m_GameSettingsSubmenu;
wxMenuItem* m_menuItem_RecentIsoMenu;
wxMenuItem* m_menuItem_DriveListMenu;
wxMenuItem& m_MenuItem_Console;
wxMenuItem* m_menuItem_RecentIsoMenu;
wxMenuItem* m_menuItem_DriveListMenu;
wxMenuItem& m_MenuItem_Console;
#if defined(__unix__)
wxMenuItem& m_MenuItem_Console_Stdio;
wxMenuItem& m_MenuItem_Console_Stdio;
#endif
PerPluginMenuInfo m_PluginMenuPacks[PluginId_Count];
PerPluginMenuInfo m_PluginMenuPacks[PluginId_Count];
bool m_capturingVideo;
bool m_capturingVideo;
virtual void DispatchEvent( const PluginEventType& plugin_evt );
virtual void DispatchEvent( const CoreThreadStatus& status );
virtual void DispatchEvent(const PluginEventType& plugin_evt);
virtual void DispatchEvent(const CoreThreadStatus& status);
virtual void AppStatusEvent_OnSettingsApplied();
public:
@ -144,10 +148,10 @@ public:
void OnLogBoxHidden();
bool IsPaused() const { return GetMenuBar()->IsChecked( MenuId_Sys_SuspendResume ); }
bool IsPaused() const { return GetMenuBar()->IsChecked(MenuId_Sys_SuspendResume); }
void UpdateCdvdSrcSelection();
void RemoveCdvdMenu();
void EnableMenuItem( int id, bool enable );
void EnableMenuItem(int id, bool enable);
void CheckMenuItem(int id, bool checked);
void SetMenuItemLabel(int id, wxString str);
void EnableCdvdPluginSubmenu(bool isEnable = true);
@ -159,7 +163,7 @@ public:
void CreateCaptureMenu();
void CreateRecordMenu();
void CreateHelpMenu();
bool Destroy();
void ApplyConfigToGui(AppConfig& configToApply, int flags = 0);
@ -178,77 +182,77 @@ protected:
void ApplySettings();
void ApplyCoreStatus();
void InitLogBoxPosition( AppConfig::ConsoleLogOptions& conf );
void InitLogBoxPosition(AppConfig::ConsoleLogOptions& conf);
void OnCloseWindow( wxCloseEvent& evt );
void OnMoveAround( wxMoveEvent& evt );
void OnFocus( wxFocusEvent& evt );
void OnActivate( wxActivateEvent& evt );
void OnCloseWindow(wxCloseEvent& evt);
void OnMoveAround(wxMoveEvent& evt);
void OnFocus(wxFocusEvent& evt);
void OnActivate(wxActivateEvent& evt);
void Menu_SysSettings_Click(wxCommandEvent &event);
void Menu_AudioSettings_Click(wxCommandEvent &event);
void Menu_McdSettings_Click(wxCommandEvent &event);
void Menu_WindowSettings_Click(wxCommandEvent &event);
void Menu_GSSettings_Click(wxCommandEvent &event);
void Menu_SelectPluginsBios_Click(wxCommandEvent &event);
void Menu_ResetAllSettings_Click(wxCommandEvent &event);
void Menu_SysSettings_Click(wxCommandEvent& event);
void Menu_AudioSettings_Click(wxCommandEvent& event);
void Menu_McdSettings_Click(wxCommandEvent& event);
void Menu_WindowSettings_Click(wxCommandEvent& event);
void Menu_GSSettings_Click(wxCommandEvent& event);
void Menu_SelectPluginsBios_Click(wxCommandEvent& event);
void Menu_ResetAllSettings_Click(wxCommandEvent& event);
void Menu_IsoBrowse_Click(wxCommandEvent &event);
void Menu_IsoClear_Click(wxCommandEvent &event);
void Menu_EnableBackupStates_Click(wxCommandEvent &event);
void Menu_EnablePatches_Click(wxCommandEvent &event);
void Menu_EnableCheats_Click(wxCommandEvent &event);
void Menu_EnableIPC_Click(wxCommandEvent &event);
void Menu_EnableWideScreenPatches_Click(wxCommandEvent &event);
void Menu_IsoBrowse_Click(wxCommandEvent& event);
void Menu_IsoClear_Click(wxCommandEvent& event);
void Menu_EnableBackupStates_Click(wxCommandEvent& event);
void Menu_EnablePatches_Click(wxCommandEvent& event);
void Menu_EnableCheats_Click(wxCommandEvent& event);
void Menu_EnableIPC_Click(wxCommandEvent& event);
void Menu_EnableWideScreenPatches_Click(wxCommandEvent& event);
#ifndef DISABLE_RECORDING
void Menu_EnableRecordingTools_Click(wxCommandEvent &event);
void Menu_EnableRecordingTools_Click(wxCommandEvent& event);
#endif
void Menu_EnableHostFs_Click(wxCommandEvent &event);
void Menu_EnableHostFs_Click(wxCommandEvent& event);
void Menu_BootCdvd_Click(wxCommandEvent &event);
void Menu_FastBoot_Click(wxCommandEvent &event);
void Menu_BootCdvd_Click(wxCommandEvent& event);
void Menu_FastBoot_Click(wxCommandEvent& event);
void Menu_OpenELF_Click(wxCommandEvent &event);
void Menu_CdvdSource_Click(wxCommandEvent &event);
void Menu_LoadStates_Click(wxCommandEvent &event);
void Menu_SaveStates_Click(wxCommandEvent &event);
void Menu_LoadStateFromFile_Click(wxCommandEvent &event);
void Menu_SaveStateToFile_Click(wxCommandEvent &event);
void Menu_Exit_Click(wxCommandEvent &event);
void Menu_OpenELF_Click(wxCommandEvent& event);
void Menu_CdvdSource_Click(wxCommandEvent& event);
void Menu_LoadStates_Click(wxCommandEvent& event);
void Menu_SaveStates_Click(wxCommandEvent& event);
void Menu_LoadStateFromFile_Click(wxCommandEvent& event);
void Menu_SaveStateToFile_Click(wxCommandEvent& event);
void Menu_Exit_Click(wxCommandEvent& event);
void Menu_SuspendResume_Click(wxCommandEvent &event);
void Menu_SysShutdown_Click(wxCommandEvent &event);
void Menu_SuspendResume_Click(wxCommandEvent& event);
void Menu_SysShutdown_Click(wxCommandEvent& event);
void Menu_ConfigPlugin_Click(wxCommandEvent &event);
void Menu_ConfigPlugin_Click(wxCommandEvent& event);
void Menu_MultitapToggle_Click(wxCommandEvent &event);
void Menu_MultitapToggle_Click(wxCommandEvent& event);
void Menu_Debug_Open_Click(wxCommandEvent &event);
void Menu_Debug_MemoryDump_Click(wxCommandEvent &event);
void Menu_Debug_CreateBlockdump_Click(wxCommandEvent &event);
void Menu_Ask_On_Boot_Click(wxCommandEvent &event);
void Menu_Debug_Open_Click(wxCommandEvent& event);
void Menu_Debug_MemoryDump_Click(wxCommandEvent& event);
void Menu_Debug_CreateBlockdump_Click(wxCommandEvent& event);
void Menu_Ask_On_Boot_Click(wxCommandEvent& event);
void Menu_ShowConsole(wxCommandEvent &event);
void Menu_ChangeLang(wxCommandEvent &event);
void Menu_ShowConsole_Stdio(wxCommandEvent &event);
void Menu_ShowConsole(wxCommandEvent& event);
void Menu_ChangeLang(wxCommandEvent& event);
void Menu_ShowConsole_Stdio(wxCommandEvent& event);
void Menu_GetStarted(wxCommandEvent &event);
void Menu_Compatibility(wxCommandEvent &event);
void Menu_Forums(wxCommandEvent &event);
void Menu_Website(wxCommandEvent &event);
void Menu_Github(wxCommandEvent &event);
void Menu_Wiki(wxCommandEvent &event);
void Menu_ShowAboutBox(wxCommandEvent &event);
void Menu_GetStarted(wxCommandEvent& event);
void Menu_Compatibility(wxCommandEvent& event);
void Menu_Forums(wxCommandEvent& event);
void Menu_Website(wxCommandEvent& event);
void Menu_Github(wxCommandEvent& event);
void Menu_Wiki(wxCommandEvent& event);
void Menu_ShowAboutBox(wxCommandEvent& event);
void Menu_Capture_Video_Record_Click(wxCommandEvent &event);
void Menu_Capture_Video_Stop_Click(wxCommandEvent &event);
void Menu_Capture_Video_Record_Click(wxCommandEvent& event);
void Menu_Capture_Video_Stop_Click(wxCommandEvent& event);
void VideoCaptureUpdate();
void Menu_Capture_Screenshot_Screenshot_Click(wxCommandEvent &event);
void Menu_Capture_Screenshot_Screenshot_Click(wxCommandEvent& event);
#ifndef DISABLE_RECORDING
void Menu_Recording_New_Click(wxCommandEvent &event);
void Menu_Recording_Play_Click(wxCommandEvent &event);
void Menu_Recording_Stop_Click(wxCommandEvent &event);
void Menu_Recording_New_Click(wxCommandEvent& event);
void Menu_Recording_Play_Click(wxCommandEvent& event);
void Menu_Recording_Stop_Click(wxCommandEvent& event);
void Menu_Recording_TogglePause_Click(wxCommandEvent &event);
void Menu_Recording_FrameAdvance_Click(wxCommandEvent &event);
void Menu_Recording_ToggleRecordingMode_Click(wxCommandEvent &event);
@ -256,18 +260,18 @@ protected:
#endif
void _DoBootCdvd();
bool _DoSelectIsoBrowser( wxString& dest );
bool _DoSelectIsoBrowser(wxString& dest);
bool _DoSelectELFBrowser();
// ------------------------------------------------------------------------
// MainEmuFram Internal API for Populating Main Menu Contents
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// MainEmuFram Internal API for Populating Main Menu Contents
// ------------------------------------------------------------------------
wxMenu* MakeStatesSubMenu( int baseid, int loadBackupId=-1 ) const;
wxMenu* MakeStatesSubMenu(int baseid, int loadBackupId = -1) const;
void ConnectMenus();
friend class Pcsx2App;
};
extern int GetPluginMenuId_Settings( PluginsEnum_t pid );
extern int GetPluginMenuId_Settings(PluginsEnum_t pid);

View File

@ -32,51 +32,51 @@
#include "Utilities/IniInterface.h"
#ifndef DISABLE_RECORDING
# include "Recording/InputRecording.h"
# include "Recording/InputRecordingControls.h"
# include "Recording/VirtualPad/VirtualPad.h"
#include "Recording/InputRecording.h"
#include "Recording/InputRecordingControls.h"
#include "Recording/VirtualPad/VirtualPad.h"
#endif
using namespace Dialogs;
void MainEmuFrame::Menu_SysSettings_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_SysSettings_Click(wxCommandEvent& event)
{
AppOpenDialog<SysConfigDialog>( this );
AppOpenDialog<SysConfigDialog>(this);
}
void MainEmuFrame::Menu_AudioSettings_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_AudioSettings_Click(wxCommandEvent& event)
{
SPU2configure();
SPU2configure();
}
void MainEmuFrame::Menu_McdSettings_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_McdSettings_Click(wxCommandEvent& event)
{
ScopedCoreThreadClose closed_core;
closed_core.AllowResume();
AppOpenModalDialog<McdConfigDialog>(wxEmptyString, this);
}
void MainEmuFrame::Menu_WindowSettings_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_WindowSettings_Click(wxCommandEvent& event)
{
wxCommandEvent evt( pxEvt_SetSettingsPage );
evt.SetString( L"GS Window" );
AppOpenDialog<SysConfigDialog>( this )->GetEventHandler()->ProcessEvent( evt );
wxCommandEvent evt(pxEvt_SetSettingsPage);
evt.SetString(L"GS Window");
AppOpenDialog<SysConfigDialog>(this)->GetEventHandler()->ProcessEvent(evt);
}
void MainEmuFrame::Menu_GSSettings_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_GSSettings_Click(wxCommandEvent& event)
{
wxCommandEvent evt( pxEvt_SetSettingsPage );
evt.SetString( L"GS" );
AppOpenDialog<SysConfigDialog>( this )->GetEventHandler()->ProcessEvent( evt );
wxCommandEvent evt(pxEvt_SetSettingsPage);
evt.SetString(L"GS");
AppOpenDialog<SysConfigDialog>(this)->GetEventHandler()->ProcessEvent(evt);
}
void MainEmuFrame::Menu_SelectPluginsBios_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_SelectPluginsBios_Click(wxCommandEvent& event)
{
AppOpenDialog<ComponentsConfigDialog>( this );
AppOpenDialog<ComponentsConfigDialog>(this);
}
void MainEmuFrame::Menu_ChangeLang(wxCommandEvent &event) // Always in English
void MainEmuFrame::Menu_ChangeLang(wxCommandEvent& event) // Always in English
{
AppOpenDialog<InterfaceLanguageDialog>(this);
}
@ -86,8 +86,8 @@ static void WipeSettings()
wxGetApp().CleanupRestartable();
wxGetApp().CleanupResources();
wxRemoveFile( GetUiSettingsFilename() );
wxRemoveFile( GetVmSettingsFilename() );
wxRemoveFile(GetUiSettingsFilename());
wxRemoveFile(GetVmSettingsFilename());
// FIXME: wxRmdir doesn't seem to work here for some reason (possible file sharing issue
// with a plugin that leaves a file handle dangling maybe?). But deleting the inis folder
@ -111,16 +111,16 @@ void MainEmuFrame::RemoveCdvdMenu()
m_menuItem_RecentIsoMenu = nullptr;
}
void MainEmuFrame::Menu_ResetAllSettings_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_ResetAllSettings_Click(wxCommandEvent& event)
{
if( IsBeingDeleted() || m_RestartEmuOnDelete ) return;
if (IsBeingDeleted() || m_RestartEmuOnDelete)
return;
{
ScopedCoreThreadPopup suspender;
if( !Msgbox::OkCancel( pxsFmt(
pxE( L"This command clears %s settings and allows you to re-run the First-Time Wizard. You will need to manually restart %s after this operation.\n\nWARNING!! Click OK to delete *ALL* settings for %s and force-close the app, losing any current emulation progress. Are you absolutely sure?\n\n(note: settings for plugins are unaffected)"
), WX_STR(pxGetAppName()), WX_STR(pxGetAppName()), WX_STR(pxGetAppName()) ),
_("Reset all settings?") ) )
if (!Msgbox::OkCancel(pxsFmt(
pxE(L"This command clears %s settings and allows you to re-run the First-Time Wizard. You will need to manually restart %s after this operation.\n\nWARNING!! Click OK to delete *ALL* settings for %s and force-close the app, losing any current emulation progress. Are you absolutely sure?\n\n(note: settings for plugins are unaffected)"), WX_STR(pxGetAppName()), WX_STR(pxGetAppName()), WX_STR(pxGetAppName())),
_("Reset all settings?")))
{
suspender.AllowResume();
return;
@ -128,27 +128,27 @@ void MainEmuFrame::Menu_ResetAllSettings_Click(wxCommandEvent &event)
}
WipeSettings();
wxGetApp().PostMenuAction( MenuId_Exit );
wxGetApp().PostMenuAction(MenuId_Exit);
}
// Return values:
// wxID_CANCEL - User canceled the action outright.
// wxID_RESET - User wants to reset the emu in addition to swap discs
// (anything else) - Standard swap, no reset. (hotswap!)
wxWindowID SwapOrReset_Iso( wxWindow* owner, IScopedCoreThread& core_control, const wxString& isoFilename, const wxString& descpart1 )
wxWindowID SwapOrReset_Iso(wxWindow* owner, IScopedCoreThread& core_control, const wxString& isoFilename, const wxString& descpart1)
{
wxWindowID result = wxID_CANCEL;
if( (g_Conf->CdvdSource == CDVD_SourceType::Iso) && (isoFilename == g_Conf->CurrentIso) )
if ((g_Conf->CdvdSource == CDVD_SourceType::Iso) && (isoFilename == g_Conf->CurrentIso))
{
core_control.AllowResume();
return result;
}
if( SysHasValidState() )
if (SysHasValidState())
{
core_control.DisallowResume();
wxDialogWithHelpers dialog( owner, _("Confirm ISO image change") );
wxDialogWithHelpers dialog(owner, _("Confirm ISO image change"));
dialog += dialog.Heading(descpart1);
dialog += dialog.GetCharHeight();
@ -156,8 +156,8 @@ wxWindowID SwapOrReset_Iso( wxWindow* owner, IScopedCoreThread& core_control, co
dialog += dialog.GetCharHeight();
dialog += dialog.Heading(_("Do you want to swap discs or boot the new image (via system reset)?"));
result = pxIssueConfirmation( dialog, MsgButtons().Reset().Cancel().Custom(_("Swap Disc"), "swap"));
if( result == wxID_CANCEL )
result = pxIssueConfirmation(dialog, MsgButtons().Reset().Cancel().Custom(_("Swap Disc"), "swap"));
if (result == wxID_CANCEL)
{
core_control.AllowResume();
return result;
@ -165,16 +165,16 @@ wxWindowID SwapOrReset_Iso( wxWindow* owner, IScopedCoreThread& core_control, co
}
g_Conf->CdvdSource = CDVD_SourceType::Iso;
SysUpdateIsoSrcFile( isoFilename );
SysUpdateIsoSrcFile(isoFilename);
if( result == wxID_RESET )
if (result == wxID_RESET)
{
core_control.DisallowResume();
sApp.SysExecute(CDVD_SourceType::Iso);
}
else
{
Console.Indent().WriteLn( "HotSwapping to new ISO src image!" );
Console.Indent().WriteLn("HotSwapping to new ISO src image!");
//g_Conf->CdvdSource = CDVDsrc_Iso;
//CoreThread.ChangeCdvdSource();
core_control.AllowResume();
@ -187,7 +187,7 @@ wxWindowID SwapOrReset_Iso( wxWindow* owner, IScopedCoreThread& core_control, co
// wxID_CANCEL - User canceled the action outright.
// wxID_RESET - User wants to reset the emu in addition to swap discs
// (anything else) - Standard swap, no reset. (hotswap!)
wxWindowID SwapOrReset_Disc( wxWindow* owner, IScopedCoreThread& core, const wxString driveLetter)
wxWindowID SwapOrReset_Disc(wxWindow* owner, IScopedCoreThread& core, const wxString driveLetter)
{
wxWindowID result = wxID_CANCEL;
@ -230,27 +230,27 @@ wxWindowID SwapOrReset_Disc( wxWindow* owner, IScopedCoreThread& core, const wxS
return result;
}
wxWindowID SwapOrReset_CdvdSrc( wxWindow* owner, CDVD_SourceType newsrc )
wxWindowID SwapOrReset_CdvdSrc(wxWindow* owner, CDVD_SourceType newsrc)
{
if(newsrc == g_Conf->CdvdSource) return wxID_CANCEL;
if (newsrc == g_Conf->CdvdSource)
return wxID_CANCEL;
wxWindowID result = wxID_CANCEL;
ScopedCoreThreadPopup core;
if( SysHasValidState() )
if (SysHasValidState())
{
wxDialogWithHelpers dialog( owner, _("Confirm CDVD source change") );
wxDialogWithHelpers dialog(owner, _("Confirm CDVD source change"));
wxString changeMsg;
changeMsg.Printf(_("You've selected to switch the CDVD source from %s to %s."),
CDVD_SourceLabels[enum_cast(g_Conf->CdvdSource)], CDVD_SourceLabels[enum_cast(newsrc)] );
CDVD_SourceLabels[enum_cast(g_Conf->CdvdSource)], CDVD_SourceLabels[enum_cast(newsrc)]);
dialog += dialog.Heading(changeMsg + L"\n\n" +
_("Do you want to swap discs or boot the new image (system reset)?")
);
_("Do you want to swap discs or boot the new image (system reset)?"));
result = pxIssueConfirmation( dialog, MsgButtons().Reset().Cancel().Custom(_("Swap Disc"), "swap"));
result = pxIssueConfirmation(dialog, MsgButtons().Reset().Cancel().Custom(_("Swap Disc"), "swap"));
if( result == wxID_CANCEL )
if (result == wxID_CANCEL)
{
core.AllowResume();
sMainFrame.UpdateCdvdSrcSelection();
@ -261,11 +261,11 @@ wxWindowID SwapOrReset_CdvdSrc( wxWindow* owner, CDVD_SourceType newsrc )
CDVD_SourceType oldsrc = g_Conf->CdvdSource;
g_Conf->CdvdSource = newsrc;
if( result != wxID_RESET )
if (result != wxID_RESET)
{
Console.Indent().WriteLn(L"(CdvdSource) HotSwapping CDVD source types from %s to %s.",
WX_STR(wxString(CDVD_SourceLabels[enum_cast(oldsrc)])),
WX_STR(wxString(CDVD_SourceLabels[enum_cast(newsrc)])));
WX_STR(wxString(CDVD_SourceLabels[enum_cast(oldsrc)])),
WX_STR(wxString(CDVD_SourceLabels[enum_cast(newsrc)])));
//CoreThread.ChangeCdvdSource();
sMainFrame.UpdateCdvdSrcSelection();
core.AllowResume();
@ -273,19 +273,20 @@ wxWindowID SwapOrReset_CdvdSrc( wxWindow* owner, CDVD_SourceType newsrc )
else
{
core.DisallowResume();
sApp.SysExecute( g_Conf->CdvdSource );
sApp.SysExecute(g_Conf->CdvdSource);
}
return result;
}
static wxString JoinFiletypes( const wxChar** src )
static wxString JoinFiletypes(const wxChar** src)
{
wxString dest;
while( *src != NULL )
while (*src != NULL)
{
if( *src[0] == 0 ) continue;
if( !dest.IsEmpty() )
if (*src[0] == 0)
continue;
if (!dest.IsEmpty())
dest += L";";
dest += pxsFmt(L"*.%ls", *src);
@ -298,30 +299,29 @@ static wxString JoinFiletypes( const wxChar** src )
++src;
}
return dest;
}
// Returns FALSE if the user canceled the action.
bool MainEmuFrame::_DoSelectIsoBrowser( wxString& result )
bool MainEmuFrame::_DoSelectIsoBrowser(wxString& result)
{
static const wxChar* isoSupportedTypes[] =
{
L"iso", L"mdf", L"nrg", L"bin", L"img", NULL
};
{
L"iso", L"mdf", L"nrg", L"bin", L"img", NULL};
const wxString isoSupportedLabel(JoinString(isoSupportedTypes, L" "));
const wxString isoSupportedList(JoinFiletypes(isoSupportedTypes));
const wxString isoSupportedLabel( JoinString(isoSupportedTypes, L" ") );
const wxString isoSupportedList( JoinFiletypes(isoSupportedTypes) );
wxArrayString isoFilterTypes;
isoFilterTypes.Add(pxsFmt(_("All Supported (%s)"), WX_STR((isoSupportedLabel + L" .dump" + L" .gz" + L" .cso"))));
isoFilterTypes.Add(isoSupportedList + L";*.dump" + L";*.gz" + L";*.cso");
isoFilterTypes.Add(pxsFmt(_("Disc Images (%s)"), WX_STR(isoSupportedLabel) ));
isoFilterTypes.Add(pxsFmt(_("Disc Images (%s)"), WX_STR(isoSupportedLabel)));
isoFilterTypes.Add(isoSupportedList);
isoFilterTypes.Add(pxsFmt(_("Blockdumps (%s)"), L".dump" ));
isoFilterTypes.Add(pxsFmt(_("Blockdumps (%s)"), L".dump"));
isoFilterTypes.Add(L"*.dump");
isoFilterTypes.Add(pxsFmt(_("Compressed (%s)"), L".gz .cso"));
@ -329,14 +329,14 @@ bool MainEmuFrame::_DoSelectIsoBrowser( wxString& result )
isoFilterTypes.Add(_("All Files (*.*)"));
isoFilterTypes.Add(L"*.*");
wxFileDialog ctrl( this, _("Select disc image, compressed disc image, or block-dump..."), g_Conf->Folders.RunIso.ToString(), wxEmptyString,
JoinString(isoFilterTypes, L"|"), wxFD_OPEN | wxFD_FILE_MUST_EXIST );
if( ctrl.ShowModal() != wxID_CANCEL )
wxFileDialog ctrl(this, _("Select disc image, compressed disc image, or block-dump..."), g_Conf->Folders.RunIso.ToString(), wxEmptyString,
JoinString(isoFilterTypes, L"|"), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (ctrl.ShowModal() != wxID_CANCEL)
{
result = ctrl.GetPath();
g_Conf->Folders.RunIso = wxFileName( result ).GetPath();
g_Conf->Folders.RunIso = wxFileName(result).GetPath();
return true;
}
@ -347,12 +347,12 @@ bool MainEmuFrame::_DoSelectELFBrowser()
{
static const wxChar* elfFilterType = L"ELF Files (.elf)|*.elf;*.ELF";
wxFileDialog ctrl( this, _("Select ELF file..."), g_Conf->Folders.RunELF.ToString(), wxEmptyString,
(wxString)elfFilterType + L"|" + _("All Files (*.*)") + L"|*.*", wxFD_OPEN | wxFD_FILE_MUST_EXIST );
wxFileDialog ctrl(this, _("Select ELF file..."), g_Conf->Folders.RunELF.ToString(), wxEmptyString,
(wxString)elfFilterType + L"|" + _("All Files (*.*)") + L"|*.*", wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if( ctrl.ShowModal() != wxID_CANCEL )
if (ctrl.ShowModal() != wxID_CANCEL)
{
g_Conf->Folders.RunELF = wxFileName( ctrl.GetPath() ).GetPath();
g_Conf->Folders.RunELF = wxFileName(ctrl.GetPath()).GetPath();
g_Conf->CurrentELF = ctrl.GetPath();
return true;
}
@ -364,79 +364,84 @@ void MainEmuFrame::_DoBootCdvd()
{
ScopedCoreThreadPause paused_core;
if( g_Conf->CdvdSource == CDVD_SourceType::Iso )
if (g_Conf->CdvdSource == CDVD_SourceType::Iso)
{
bool selector = g_Conf->CurrentIso.IsEmpty();
if( !selector && !wxFileExists(g_Conf->CurrentIso) )
if (!selector && !wxFileExists(g_Conf->CurrentIso))
{
// User has an iso selected from a previous run, but it doesn't exist anymore.
// Issue a courtesy popup and then an Iso Selector to choose a new one.
wxDialogWithHelpers dialog( this, _("ISO file not found!") );
wxDialogWithHelpers dialog(this, _("ISO file not found!"));
dialog += dialog.Heading(
_("An error occurred while trying to open the file:") + wxString(L"\n\n") + g_Conf->CurrentIso + L"\n\n" +
_("Error: The configured ISO file does not exist. Click OK to select a new ISO source for CDVD.")
);
_("Error: The configured ISO file does not exist. Click OK to select a new ISO source for CDVD."));
pxIssueConfirmation( dialog, MsgButtons().OK() );
pxIssueConfirmation(dialog, MsgButtons().OK());
selector = true;
}
if( selector || g_Conf->AskOnBoot)
if (selector || g_Conf->AskOnBoot)
{
wxString result;
if( !_DoSelectIsoBrowser( result ) )
if (!_DoSelectIsoBrowser(result))
{
paused_core.AllowResume();
return;
}
SysUpdateIsoSrcFile( result );
SysUpdateIsoSrcFile(result);
}
}
if( SysHasValidState() )
if (SysHasValidState())
{
wxDialogWithHelpers dialog( this, _("Confirm PS2 Reset") );
dialog += dialog.Heading( GetMsg_ConfirmSysReset() );
bool confirmed = (pxIssueConfirmation( dialog, MsgButtons().Yes().Cancel(), L"BootCdvd.ConfirmReset" ) != wxID_CANCEL);
wxDialogWithHelpers dialog(this, _("Confirm PS2 Reset"));
dialog += dialog.Heading(GetMsg_ConfirmSysReset());
bool confirmed = (pxIssueConfirmation(dialog, MsgButtons().Yes().Cancel(), L"BootCdvd.ConfirmReset") != wxID_CANCEL);
if( !confirmed )
if (!confirmed)
{
paused_core.AllowResume();
return;
}
}
sApp.SysExecute( g_Conf->CdvdSource );
sApp.SysExecute(g_Conf->CdvdSource);
}
void MainEmuFrame::Menu_CdvdSource_Click( wxCommandEvent &event )
void MainEmuFrame::Menu_CdvdSource_Click(wxCommandEvent& event)
{
CDVD_SourceType newsrc = CDVD_SourceType::NoDisc;
switch( event.GetId() )
switch (event.GetId())
{
case MenuId_Src_Iso: newsrc = CDVD_SourceType::Iso; break;
case MenuId_Src_Disc: newsrc = CDVD_SourceType::Disc; break;
case MenuId_Src_NoDisc: newsrc = CDVD_SourceType::NoDisc; break;
jNO_DEFAULT
case MenuId_Src_Iso:
newsrc = CDVD_SourceType::Iso;
break;
case MenuId_Src_Disc:
newsrc = CDVD_SourceType::Disc;
break;
case MenuId_Src_NoDisc:
newsrc = CDVD_SourceType::NoDisc;
break;
jNO_DEFAULT
}
SwapOrReset_CdvdSrc(this, newsrc);
}
void MainEmuFrame::Menu_BootCdvd_Click( wxCommandEvent &event )
void MainEmuFrame::Menu_BootCdvd_Click(wxCommandEvent& event)
{
g_Conf->EmuOptions.UseBOOT2Injection = g_Conf->EnableFastBoot;
_DoBootCdvd();
}
void MainEmuFrame::Menu_FastBoot_Click( wxCommandEvent &event )
void MainEmuFrame::Menu_FastBoot_Click(wxCommandEvent& event)
{
g_Conf->EnableFastBoot = GetMenuBar()->IsChecked( MenuId_Config_FastBoot );
g_Conf->EnableFastBoot = GetMenuBar()->IsChecked(MenuId_Config_FastBoot);
AppApplySettings();
AppSaveSettings();
UpdateStatusBar();
@ -447,22 +452,22 @@ wxString GetMsg_IsoImageChanged()
return _("You have selected the following ISO image into PCSX2:\n\n");
}
void MainEmuFrame::Menu_IsoBrowse_Click( wxCommandEvent &event )
void MainEmuFrame::Menu_IsoBrowse_Click(wxCommandEvent& event)
{
ScopedCoreThreadPopup core;
wxString isofile;
if( !_DoSelectIsoBrowser(isofile) )
if (!_DoSelectIsoBrowser(isofile))
{
core.AllowResume();
return;
}
SwapOrReset_Iso(this, core, isofile, GetMsg_IsoImageChanged());
AppSaveSettings(); // save the new iso selection; update menus!
AppSaveSettings(); // save the new iso selection; update menus!
}
void MainEmuFrame::Menu_IsoClear_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_IsoClear_Click(wxCommandEvent& event)
{
wxDialogWithHelpers dialog(this, _("Confirm clearing ISO list"));
dialog += dialog.Heading(_("This will clear the ISO list. If an ISO is running it will remain in the list. Continue?"));
@ -479,7 +484,7 @@ void MainEmuFrame::Menu_IsoClear_Click(wxCommandEvent &event)
}
}
void MainEmuFrame::Menu_Ask_On_Boot_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_Ask_On_Boot_Click(wxCommandEvent& event)
{
g_Conf->AskOnBoot = event.IsChecked();
@ -490,7 +495,7 @@ void MainEmuFrame::Menu_Ask_On_Boot_Click(wxCommandEvent &event)
FindItemInMenuBar(MenuId_IsoBrowse)->Enable(!event.IsChecked());
}
void MainEmuFrame::Menu_Debug_CreateBlockdump_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_Debug_CreateBlockdump_Click(wxCommandEvent& event)
{
g_Conf->EmuOptions.CdvdDumpBlocks = event.IsChecked();
if (g_Conf->EmuOptions.CdvdDumpBlocks && SysHasValidState())
@ -499,20 +504,20 @@ void MainEmuFrame::Menu_Debug_CreateBlockdump_Click(wxCommandEvent &event)
AppSaveSettings();
}
void MainEmuFrame::Menu_MultitapToggle_Click( wxCommandEvent& )
void MainEmuFrame::Menu_MultitapToggle_Click(wxCommandEvent&)
{
g_Conf->EmuOptions.MultitapPort0_Enabled = GetMenuBar()->IsChecked( MenuId_Config_Multitap0Toggle );
g_Conf->EmuOptions.MultitapPort1_Enabled = GetMenuBar()->IsChecked( MenuId_Config_Multitap1Toggle );
g_Conf->EmuOptions.MultitapPort0_Enabled = GetMenuBar()->IsChecked(MenuId_Config_Multitap0Toggle);
g_Conf->EmuOptions.MultitapPort1_Enabled = GetMenuBar()->IsChecked(MenuId_Config_Multitap1Toggle);
AppApplySettings();
AppSaveSettings();
//evt.Skip();
}
void MainEmuFrame::Menu_EnableBackupStates_Click( wxCommandEvent& )
void MainEmuFrame::Menu_EnableBackupStates_Click(wxCommandEvent&)
{
g_Conf->EmuOptions.BackupSavestate = GetMenuBar()->IsChecked( MenuId_EnableBackupStates );
g_Conf->EmuOptions.BackupSavestate = GetMenuBar()->IsChecked(MenuId_EnableBackupStates);
//without the next line, after toggling this menu-checkbox, the change only applies from the 2nd save and onwards
// (1st save after the toggle keeps the old pre-toggle value)..
// wonder what that means for all the other menu checkboxes which only use AppSaveSettings... (avih)
@ -520,30 +525,30 @@ void MainEmuFrame::Menu_EnableBackupStates_Click( wxCommandEvent& )
AppSaveSettings();
}
void MainEmuFrame::Menu_EnablePatches_Click( wxCommandEvent& )
void MainEmuFrame::Menu_EnablePatches_Click(wxCommandEvent&)
{
g_Conf->EmuOptions.EnablePatches = GetMenuBar()->IsChecked( MenuId_EnablePatches );
g_Conf->EmuOptions.EnablePatches = GetMenuBar()->IsChecked(MenuId_EnablePatches);
AppApplySettings();
AppSaveSettings();
}
void MainEmuFrame::Menu_EnableCheats_Click( wxCommandEvent& )
void MainEmuFrame::Menu_EnableCheats_Click(wxCommandEvent&)
{
g_Conf->EmuOptions.EnableCheats = GetMenuBar()->IsChecked( MenuId_EnableCheats );
g_Conf->EmuOptions.EnableCheats = GetMenuBar()->IsChecked(MenuId_EnableCheats);
AppApplySettings();
AppSaveSettings();
}
void MainEmuFrame::Menu_EnableIPC_Click( wxCommandEvent& )
void MainEmuFrame::Menu_EnableIPC_Click(wxCommandEvent&)
{
g_Conf->EmuOptions.EnableIPC = GetMenuBar()->IsChecked( MenuId_EnableIPC );
g_Conf->EmuOptions.EnableIPC = GetMenuBar()->IsChecked(MenuId_EnableIPC);
AppApplySettings();
AppSaveSettings();
}
void MainEmuFrame::Menu_EnableWideScreenPatches_Click( wxCommandEvent& )
void MainEmuFrame::Menu_EnableWideScreenPatches_Click(wxCommandEvent&)
{
g_Conf->EmuOptions.EnableWideScreenPatches = GetMenuBar()->IsChecked( MenuId_EnableWideScreenPatches );
g_Conf->EmuOptions.EnableWideScreenPatches = GetMenuBar()->IsChecked(MenuId_EnableWideScreenPatches);
AppApplySettings();
AppSaveSettings();
}
@ -556,8 +561,9 @@ void MainEmuFrame::Menu_EnableRecordingTools_Click(wxCommandEvent& event)
if (checked)
{
if (!Msgbox::OkCancel(_("Please be aware that PCSX2's input recording features are still very much a work-in-progress.\n"
"As a result, there may be unforeseen bugs, performance implications and instability with certain games.\n\n"
"These tools are provided as-is and should be enabled under your own discretion."), "Enabling Input Recording"))
"As a result, there may be unforeseen bugs, performance implications and instability with certain games.\n\n"
"These tools are provided as-is and should be enabled under your own discretion."),
"Enabling Input Recording"))
{
checked = false;
m_GameSettingsSubmenu.FindChildItem(MenuId_EnableInputRecording)->Check(false);
@ -608,46 +614,46 @@ void MainEmuFrame::Menu_EnableRecordingTools_Click(wxCommandEvent& event)
}
#endif
void MainEmuFrame::Menu_EnableHostFs_Click( wxCommandEvent& )
void MainEmuFrame::Menu_EnableHostFs_Click(wxCommandEvent&)
{
g_Conf->EmuOptions.HostFs = GetMenuBar()->IsChecked( MenuId_EnableHostFs );
g_Conf->EmuOptions.HostFs = GetMenuBar()->IsChecked(MenuId_EnableHostFs);
AppSaveSettings();
}
void MainEmuFrame::Menu_OpenELF_Click(wxCommandEvent&)
{
ScopedCoreThreadClose stopped_core;
if( _DoSelectELFBrowser() )
if (_DoSelectELFBrowser())
{
g_Conf->EmuOptions.UseBOOT2Injection = true;
sApp.SysExecute( g_Conf->CdvdSource, g_Conf->CurrentELF );
sApp.SysExecute(g_Conf->CdvdSource, g_Conf->CurrentELF);
}
stopped_core.AllowResume();
}
void MainEmuFrame::Menu_LoadStates_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_LoadStates_Click(wxCommandEvent& event)
{
if( event.GetId() == MenuId_State_LoadBackup )
if (event.GetId() == MenuId_State_LoadBackup)
{
States_DefrostCurrentSlotBackup();
return;
}
States_SetCurrentSlot( event.GetId() - MenuId_State_Load01 - 1 );
States_SetCurrentSlot(event.GetId() - MenuId_State_Load01 - 1);
States_DefrostCurrentSlot();
}
void MainEmuFrame::Menu_SaveStates_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_SaveStates_Click(wxCommandEvent& event)
{
States_SetCurrentSlot( event.GetId() - MenuId_State_Save01 - 1 );
States_SetCurrentSlot(event.GetId() - MenuId_State_Save01 - 1);
States_FreezeCurrentSlot();
}
void MainEmuFrame::Menu_LoadStateFromFile_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_LoadStateFromFile_Click(wxCommandEvent& event)
{
wxFileDialog loadStateDialog(this, _("Load State"), L"", L"",
L"Savestate files (*.p2s)|*.p2s", wxFD_OPEN);
L"Savestate files (*.p2s)|*.p2s", wxFD_OPEN);
if (loadStateDialog.ShowModal() == wxID_CANCEL)
{
@ -658,10 +664,10 @@ void MainEmuFrame::Menu_LoadStateFromFile_Click(wxCommandEvent &event)
StateCopy_LoadFromFile(path);
}
void MainEmuFrame::Menu_SaveStateToFile_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_SaveStateToFile_Click(wxCommandEvent& event)
{
wxFileDialog saveStateDialog(this, _("Save State"), L"", L"",
L"Savestate files (*.p2s)|*.p2s", wxFD_OPEN);
L"Savestate files (*.p2s)|*.p2s", wxFD_OPEN);
if (saveStateDialog.ShowModal() == wxID_CANCEL)
{
@ -672,7 +678,7 @@ void MainEmuFrame::Menu_SaveStateToFile_Click(wxCommandEvent &event)
StateCopy_SaveToFile(path);
}
void MainEmuFrame::Menu_Exit_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_Exit_Click(wxCommandEvent& event)
{
Close();
}
@ -687,26 +693,27 @@ public:
protected:
void InvokeEvent()
{
if( CoreThread.IsOpen() )
if (CoreThread.IsOpen())
CoreThread.Suspend();
else
CoreThread.Resume();
}
};
void MainEmuFrame::Menu_SuspendResume_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_SuspendResume_Click(wxCommandEvent& event)
{
if( !SysHasValidState() ) return;
if (!SysHasValidState())
return;
// Disable the menu item. The state of the menu is indeterminate until the core thread
// has responded (it updates status after the plugins are loaded and emulation has
// engaged successfully).
EnableMenuItem( MenuId_Sys_SuspendResume, false );
GetSysExecutorThread().PostEvent( new SysExecEvent_ToggleSuspend() );
EnableMenuItem(MenuId_Sys_SuspendResume, false);
GetSysExecutorThread().PostEvent(new SysExecEvent_ToggleSuspend());
}
void MainEmuFrame::Menu_SysShutdown_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_SysShutdown_Click(wxCommandEvent& event)
{
UI_DisableSysShutdown();
Console.SetTitle("PCSX2 Program Log");
@ -737,8 +744,8 @@ void MainEmuFrame::Menu_ConfigPlugin_Click(wxCommandEvent& event)
// However, since the PAD plugin is used to do so, if it's closed then there is nothing to read
// the keybind resulting producing an unrecovable state.
//
// If the CoreThread is paused prior to opening the PAD plugin settings then when the settings
// are closed the PAD will not re-open. To avoid this, we resume emulation prior to the plugins
// If the CoreThread is paused prior to opening the PAD plugin settings then when the settings
// are closed the PAD will not re-open. To avoid this, we resume emulation prior to the plugins
// configuration handler doing so.
if (g_Conf->EmuOptions.EnableRecordingTools && g_InputRecordingControls.IsPaused())
{
@ -756,7 +763,7 @@ void MainEmuFrame::Menu_ConfigPlugin_Click(wxCommandEvent& event)
#endif
}
void MainEmuFrame::Menu_Debug_Open_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_Debug_Open_Click(wxCommandEvent& event)
{
DisassemblyDialog* dlg = wxGetApp().GetDisassemblyPtr();
if (dlg)
@ -768,61 +775,61 @@ void MainEmuFrame::Menu_Debug_Open_Click(wxCommandEvent &event)
}
}
void MainEmuFrame::Menu_Debug_MemoryDump_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_Debug_MemoryDump_Click(wxCommandEvent& event)
{
}
void MainEmuFrame::Menu_ShowConsole(wxCommandEvent &event)
void MainEmuFrame::Menu_ShowConsole(wxCommandEvent& event)
{
// Use messages to relay open/close commands (thread-safe)
g_Conf->ProgLogBox.Visible = event.IsChecked();
wxCommandEvent evt( wxEVT_MENU, g_Conf->ProgLogBox.Visible ? wxID_OPEN : wxID_CLOSE );
wxGetApp().ProgramLog_PostEvent( evt );
wxCommandEvent evt(wxEVT_MENU, g_Conf->ProgLogBox.Visible ? wxID_OPEN : wxID_CLOSE);
wxGetApp().ProgramLog_PostEvent(evt);
}
void MainEmuFrame::Menu_ShowConsole_Stdio(wxCommandEvent &event)
void MainEmuFrame::Menu_ShowConsole_Stdio(wxCommandEvent& event)
{
g_Conf->EmuOptions.ConsoleToStdio = GetMenuBar()->IsChecked( MenuId_Console_Stdio );
g_Conf->EmuOptions.ConsoleToStdio = GetMenuBar()->IsChecked(MenuId_Console_Stdio);
AppSaveSettings();
}
void MainEmuFrame::Menu_GetStarted(wxCommandEvent &event)
void MainEmuFrame::Menu_GetStarted(wxCommandEvent& event)
{
wxLaunchDefaultBrowser("https://pcsx2.net/getting-started.html");
}
void MainEmuFrame::Menu_Compatibility(wxCommandEvent &event)
void MainEmuFrame::Menu_Compatibility(wxCommandEvent& event)
{
wxLaunchDefaultBrowser("https://pcsx2.net/compatibility-list.html");
}
void MainEmuFrame::Menu_Forums(wxCommandEvent &event)
void MainEmuFrame::Menu_Forums(wxCommandEvent& event)
{
wxLaunchDefaultBrowser("https://forums.pcsx2.net/");
}
void MainEmuFrame::Menu_Website(wxCommandEvent &event)
void MainEmuFrame::Menu_Website(wxCommandEvent& event)
{
wxLaunchDefaultBrowser("https://pcsx2.net/");
}
void MainEmuFrame::Menu_Github(wxCommandEvent &event)
void MainEmuFrame::Menu_Github(wxCommandEvent& event)
{
wxLaunchDefaultBrowser("https://github.com/PCSX2/pcsx2");
}
void MainEmuFrame::Menu_Wiki(wxCommandEvent &event)
void MainEmuFrame::Menu_Wiki(wxCommandEvent& event)
{
wxLaunchDefaultBrowser("https://wiki.pcsx2.net/Main_Page");
}
void MainEmuFrame::Menu_ShowAboutBox(wxCommandEvent &event)
void MainEmuFrame::Menu_ShowAboutBox(wxCommandEvent& event)
{
AppOpenDialog<AboutBoxDialog>( this );
AppOpenDialog<AboutBoxDialog>(this);
}
void MainEmuFrame::Menu_Capture_Video_Record_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_Capture_Video_Record_Click(wxCommandEvent& event)
{
ScopedCoreThreadPause paused_core;
paused_core.AllowResume();
@ -831,7 +838,7 @@ void MainEmuFrame::Menu_Capture_Video_Record_Click(wxCommandEvent &event)
VideoCaptureUpdate();
}
void MainEmuFrame::Menu_Capture_Video_Stop_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_Capture_Video_Stop_Click(wxCommandEvent& event)
{
ScopedCoreThreadPause paused_core;
paused_core.AllowResume();
@ -842,7 +849,7 @@ void MainEmuFrame::Menu_Capture_Video_Stop_Click(wxCommandEvent &event)
void MainEmuFrame::VideoCaptureUpdate()
{
GetMTGS().WaitGS(); // make sure GS is in sync with the audio stream when we start.
GetMTGS().WaitGS(); // make sure GS is in sync with the audio stream when we start.
if (m_capturingVideo)
{
// start recording
@ -879,7 +886,6 @@ void MainEmuFrame::VideoCaptureUpdate()
if (GetMainFramePtr() && needsMainFrameEnable)
GetMainFramePtr()->Enable();
}
else
{
@ -901,7 +907,7 @@ void MainEmuFrame::VideoCaptureUpdate()
}
}
void MainEmuFrame::Menu_Capture_Screenshot_Screenshot_Click(wxCommandEvent & event)
void MainEmuFrame::Menu_Capture_Screenshot_Screenshot_Click(wxCommandEvent& event)
{
if (!CoreThread.IsOpen())
{
@ -911,7 +917,7 @@ void MainEmuFrame::Menu_Capture_Screenshot_Screenshot_Click(wxCommandEvent & eve
}
#ifndef DISABLE_RECORDING
void MainEmuFrame::Menu_Recording_New_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_Recording_New_Click(wxCommandEvent& event)
{
const bool initiallyPaused = g_InputRecordingControls.IsPaused();
if (!initiallyPaused)
@ -937,13 +943,13 @@ void MainEmuFrame::Menu_Recording_New_Click(wxCommandEvent &event)
sMainFrame.enableRecordingMenuItem(MenuId_Recording_ToggleRecordingMode, g_InputRecording.IsActive());
}
void MainEmuFrame::Menu_Recording_Play_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_Recording_Play_Click(wxCommandEvent& event)
{
const bool initiallyPaused = g_InputRecordingControls.IsPaused();
if (!initiallyPaused)
g_InputRecordingControls.PauseImmediately();
wxFileDialog openFileDialog(this, _("Select P2M2 record file."), L"", L"",
L"p2m2 file(*.p2m2)|*.p2m2", wxFD_OPEN);
L"p2m2 file(*.p2m2)|*.p2m2", wxFD_OPEN);
if (openFileDialog.ShowModal() == wxID_CANCEL)
{
if (!initiallyPaused)
@ -969,7 +975,7 @@ void MainEmuFrame::Menu_Recording_Play_Click(wxCommandEvent &event)
sMainFrame.enableRecordingMenuItem(MenuId_Recording_ToggleRecordingMode, g_InputRecording.IsActive());
}
void MainEmuFrame::Menu_Recording_Stop_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_Recording_Stop_Click(wxCommandEvent& event)
{
g_InputRecording.Stop();
m_menuRecording.FindChildItem(MenuId_Recording_New)->Enable(true);

View File

@ -35,9 +35,9 @@
// Used to hold the current state backup (fullcopy of PS2 memory and plugin states).
//static VmStateBuffer state_buffer( L"Public Savestate Buffer" );
static const wxChar* EntryFilename_StateVersion = L"PCSX2 Savestate Version.id";
static const wxChar* EntryFilename_Screenshot = L"Screenshot.jpg";
static const wxChar* EntryFilename_InternalStructures = L"PCSX2 Internal Structures.dat";
static const wxChar* EntryFilename_StateVersion = L"PCSX2 Savestate Version.id";
static const wxChar* EntryFilename_Screenshot = L"Screenshot.jpg";
static const wxChar* EntryFilename_InternalStructures = L"PCSX2 Internal Structures.dat";
// --------------------------------------------------------------------------------------
@ -51,10 +51,10 @@ protected:
public:
virtual ~BaseSavestateEntry() = default;
virtual wxString GetFilename() const=0;
virtual void FreezeIn( pxInputStream& reader ) const=0;
virtual void FreezeOut( SaveStateBase& writer ) const=0;
virtual bool IsRequired() const=0;
virtual wxString GetFilename() const = 0;
virtual void FreezeIn(pxInputStream& reader) const = 0;
virtual void FreezeOut(SaveStateBase& writer) const = 0;
virtual bool IsRequired() const = 0;
};
class MemorySavestateEntry : public BaseSavestateEntry
@ -64,13 +64,13 @@ protected:
virtual ~MemorySavestateEntry() = default;
public:
virtual void FreezeIn( pxInputStream& reader ) const;
virtual void FreezeOut( SaveStateBase& writer ) const;
virtual void FreezeIn(pxInputStream& reader) const;
virtual void FreezeOut(SaveStateBase& writer) const;
virtual bool IsRequired() const { return true; }
protected:
virtual u8* GetDataPtr() const=0;
virtual uint GetDataSize() const=0;
virtual u8* GetDataPtr() const = 0;
virtual uint GetDataSize() const = 0;
};
class PluginSavestateEntry : public BaseSavestateEntry
@ -79,7 +79,7 @@ protected:
PluginsEnum_t m_pid;
public:
PluginSavestateEntry( PluginsEnum_t pid )
PluginSavestateEntry(PluginsEnum_t pid)
{
m_pid = pid;
}
@ -87,8 +87,8 @@ public:
virtual ~PluginSavestateEntry() = default;
virtual wxString GetFilename() const;
virtual void FreezeIn( pxInputStream& reader ) const;
virtual void FreezeOut( SaveStateBase& writer ) const;
virtual void FreezeIn(pxInputStream& reader) const;
virtual void FreezeOut(SaveStateBase& writer) const;
virtual bool IsRequired() const { return false; }
@ -96,43 +96,43 @@ protected:
virtual PluginsEnum_t GetPluginId() const { return m_pid; }
};
void MemorySavestateEntry::FreezeIn( pxInputStream& reader ) const
void MemorySavestateEntry::FreezeIn(pxInputStream& reader) const
{
const uint entrySize = reader.Length();
const uint expectedSize = GetDataSize();
const uint entrySize = reader.Length();
const uint expectedSize = GetDataSize();
if (entrySize < expectedSize)
{
Console.WriteLn( Color_Yellow, " '%s' is incomplete (expected 0x%x bytes, loading only 0x%x bytes)",
WX_STR(GetFilename()), expectedSize, entrySize );
Console.WriteLn(Color_Yellow, " '%s' is incomplete (expected 0x%x bytes, loading only 0x%x bytes)",
WX_STR(GetFilename()), expectedSize, entrySize);
}
uint copylen = std::min(entrySize, expectedSize);
reader.Read( GetDataPtr(), copylen );
reader.Read(GetDataPtr(), copylen);
}
void MemorySavestateEntry::FreezeOut( SaveStateBase& writer ) const
void MemorySavestateEntry::FreezeOut(SaveStateBase& writer) const
{
writer.FreezeMem( GetDataPtr(), GetDataSize() );
writer.FreezeMem(GetDataPtr(), GetDataSize());
}
wxString PluginSavestateEntry::GetFilename() const
{
return pxsFmt( "Plugin %s.dat", tbl_PluginInfo[m_pid].shortname );
return pxsFmt("Plugin %s.dat", tbl_PluginInfo[m_pid].shortname);
}
void PluginSavestateEntry::FreezeIn( pxInputStream& reader ) const
void PluginSavestateEntry::FreezeIn(pxInputStream& reader) const
{
GetCorePlugins().FreezeIn( GetPluginId(), reader );
GetCorePlugins().FreezeIn(GetPluginId(), reader);
}
void PluginSavestateEntry::FreezeOut( SaveStateBase& writer ) const
void PluginSavestateEntry::FreezeOut(SaveStateBase& writer) const
{
if (uint size = GetCorePlugins().GetFreezeSize( GetPluginId() ))
if (uint size = GetCorePlugins().GetFreezeSize(GetPluginId()))
{
writer.PrepBlock( size );
GetCorePlugins().FreezeOut( GetPluginId(), writer.GetBlockPtr() );
writer.CommitBlock( size );
writer.PrepBlock(size);
GetCorePlugins().FreezeOut(GetPluginId(), writer.GetBlockPtr());
writer.CommitBlock(size);
}
}
@ -150,14 +150,14 @@ class SavestateEntry_EmotionMemory : public MemorySavestateEntry
public:
virtual ~SavestateEntry_EmotionMemory() = default;
wxString GetFilename() const { return L"eeMemory.bin"; }
u8* GetDataPtr() const { return eeMem->Main; }
uint GetDataSize() const { return sizeof(eeMem->Main); }
wxString GetFilename() const { return L"eeMemory.bin"; }
u8* GetDataPtr() const { return eeMem->Main; }
uint GetDataSize() const { return sizeof(eeMem->Main); }
virtual void FreezeIn( pxInputStream& reader ) const
virtual void FreezeIn(pxInputStream& reader) const
{
SysClearExecutionCache();
MemorySavestateEntry::FreezeIn( reader );
MemorySavestateEntry::FreezeIn(reader);
}
};
@ -166,9 +166,9 @@ class SavestateEntry_IopMemory : public MemorySavestateEntry
public:
virtual ~SavestateEntry_IopMemory() = default;
wxString GetFilename() const { return L"iopMemory.bin"; }
u8* GetDataPtr() const { return iopMem->Main; }
uint GetDataSize() const { return sizeof(iopMem->Main); }
wxString GetFilename() const { return L"iopMemory.bin"; }
u8* GetDataPtr() const { return iopMem->Main; }
uint GetDataSize() const { return sizeof(iopMem->Main); }
};
class SavestateEntry_HwRegs : public MemorySavestateEntry
@ -176,9 +176,9 @@ class SavestateEntry_HwRegs : public MemorySavestateEntry
public:
virtual ~SavestateEntry_HwRegs() = default;
wxString GetFilename() const { return L"eeHwRegs.bin"; }
u8* GetDataPtr() const { return eeHw; }
uint GetDataSize() const { return sizeof(eeHw); }
wxString GetFilename() const { return L"eeHwRegs.bin"; }
u8* GetDataPtr() const { return eeHw; }
uint GetDataSize() const { return sizeof(eeHw); }
};
class SavestateEntry_IopHwRegs : public MemorySavestateEntry
@ -186,9 +186,9 @@ class SavestateEntry_IopHwRegs : public MemorySavestateEntry
public:
virtual ~SavestateEntry_IopHwRegs() = default;
wxString GetFilename() const { return L"iopHwRegs.bin"; }
u8* GetDataPtr() const { return iopHw; }
uint GetDataSize() const { return sizeof(iopHw); }
wxString GetFilename() const { return L"iopHwRegs.bin"; }
u8* GetDataPtr() const { return iopHw; }
uint GetDataSize() const { return sizeof(iopHw); }
};
class SavestateEntry_Scratchpad : public MemorySavestateEntry
@ -196,9 +196,9 @@ class SavestateEntry_Scratchpad : public MemorySavestateEntry
public:
virtual ~SavestateEntry_Scratchpad() = default;
wxString GetFilename() const { return L"Scratchpad.bin"; }
u8* GetDataPtr() const { return eeMem->Scratch; }
uint GetDataSize() const { return sizeof(eeMem->Scratch); }
wxString GetFilename() const { return L"Scratchpad.bin"; }
u8* GetDataPtr() const { return eeMem->Scratch; }
uint GetDataSize() const { return sizeof(eeMem->Scratch); }
};
class SavestateEntry_VU0mem : public MemorySavestateEntry
@ -206,9 +206,9 @@ class SavestateEntry_VU0mem : public MemorySavestateEntry
public:
virtual ~SavestateEntry_VU0mem() = default;
wxString GetFilename() const { return L"vu0Memory.bin"; }
u8* GetDataPtr() const { return vuRegs[0].Mem; }
uint GetDataSize() const { return VU0_MEMSIZE; }
wxString GetFilename() const { return L"vu0Memory.bin"; }
u8* GetDataPtr() const { return vuRegs[0].Mem; }
uint GetDataSize() const { return VU0_MEMSIZE; }
};
class SavestateEntry_VU1mem : public MemorySavestateEntry
@ -216,9 +216,9 @@ class SavestateEntry_VU1mem : public MemorySavestateEntry
public:
virtual ~SavestateEntry_VU1mem() = default;
wxString GetFilename() const { return L"vu1Memory.bin"; }
u8* GetDataPtr() const { return vuRegs[1].Mem; }
uint GetDataSize() const { return VU1_MEMSIZE; }
wxString GetFilename() const { return L"vu1Memory.bin"; }
u8* GetDataPtr() const { return vuRegs[1].Mem; }
uint GetDataSize() const { return VU1_MEMSIZE; }
};
class SavestateEntry_VU0prog : public MemorySavestateEntry
@ -226,9 +226,9 @@ class SavestateEntry_VU0prog : public MemorySavestateEntry
public:
virtual ~SavestateEntry_VU0prog() = default;
wxString GetFilename() const { return L"vu0MicroMem.bin"; }
u8* GetDataPtr() const { return vuRegs[0].Micro; }
uint GetDataSize() const { return VU0_PROGSIZE; }
wxString GetFilename() const { return L"vu0MicroMem.bin"; }
u8* GetDataPtr() const { return vuRegs[0].Micro; }
uint GetDataSize() const { return VU0_PROGSIZE; }
};
class SavestateEntry_VU1prog : public MemorySavestateEntry
@ -236,9 +236,9 @@ class SavestateEntry_VU1prog : public MemorySavestateEntry
public:
virtual ~SavestateEntry_VU1prog() = default;
wxString GetFilename() const { return L"vu1MicroMem.bin"; }
u8* GetDataPtr() const { return vuRegs[1].Micro; }
uint GetDataSize() const { return VU1_PROGSIZE; }
wxString GetFilename() const { return L"vu1MicroMem.bin"; }
u8* GetDataPtr() const { return vuRegs[1].Micro; }
uint GetDataSize() const { return VU1_PROGSIZE; }
};
class SavestateEntry_SPU2 : public BaseSavestateEntry
@ -246,20 +246,21 @@ class SavestateEntry_SPU2 : public BaseSavestateEntry
public:
virtual ~SavestateEntry_SPU2() = default;
wxString GetFilename() const { return L"SPU2.bin"; }
void FreezeIn( pxInputStream& reader ) const { return SPU2DoFreezeIn(reader); }
void FreezeOut( SaveStateBase& writer ) const
{
int size = 0;
freezeData fP = { 0, NULL };
if(SPU2freeze( FREEZE_SIZE, &fP)==0) {
size = fP.size;
writer.PrepBlock( size );
SPU2DoFreezeOut(writer.GetBlockPtr());
writer.CommitBlock( size );
}
return;
}
wxString GetFilename() const { return L"SPU2.bin"; }
void FreezeIn(pxInputStream& reader) const { return SPU2DoFreezeIn(reader); }
void FreezeOut(SaveStateBase& writer) const
{
int size = 0;
freezeData fP = {0, NULL};
if (SPU2freeze(FREEZE_SIZE, &fP) == 0)
{
size = fP.size;
writer.PrepBlock(size);
SPU2DoFreezeOut(writer.GetBlockPtr());
writer.CommitBlock(size);
}
return;
}
bool IsRequired() const { return true; }
};
@ -286,11 +287,10 @@ static const std::unique_ptr<BaseSavestateEntry> SavestateEntries[] = {
std::unique_ptr<BaseSavestateEntry>(new SavestateEntry_VU1prog),
std::unique_ptr<BaseSavestateEntry>(new SavestateEntry_SPU2),
std::unique_ptr<BaseSavestateEntry>(new PluginSavestateEntry( PluginId_GS )),
std::unique_ptr<BaseSavestateEntry>(new PluginSavestateEntry( PluginId_PAD )),
std::unique_ptr<BaseSavestateEntry>(new PluginSavestateEntry( PluginId_USB )),
std::unique_ptr<BaseSavestateEntry>(new PluginSavestateEntry( PluginId_DEV9 ))
};
std::unique_ptr<BaseSavestateEntry>(new PluginSavestateEntry(PluginId_GS)),
std::unique_ptr<BaseSavestateEntry>(new PluginSavestateEntry(PluginId_PAD)),
std::unique_ptr<BaseSavestateEntry>(new PluginSavestateEntry(PluginId_USB)),
std::unique_ptr<BaseSavestateEntry>(new PluginSavestateEntry(PluginId_DEV9))};
// It's bad mojo to have savestates trying to read and write from the same file at the
// same time. To prevent that we use this mutex lock, which is used by both the
@ -300,23 +300,23 @@ static const std::unique_ptr<BaseSavestateEntry> SavestateEntries[] = {
//
static Mutex mtx_CompressToDisk;
static void CheckVersion( pxInputStream& thr )
static void CheckVersion(pxInputStream& thr)
{
u32 savever;
thr.Read( savever );
thr.Read(savever);
// Major version mismatch. Means we can't load this savestate at all. Support for it
// was removed entirely.
if( savever > g_SaveVersion )
throw Exception::SaveStateLoadError( thr.GetStreamName() )
.SetDiagMsg(pxsFmt( L"Savestate uses an unsupported or unknown savestate version.\n(PCSX2 ver=%x, state ver=%x)", g_SaveVersion, savever ))
if (savever > g_SaveVersion)
throw Exception::SaveStateLoadError(thr.GetStreamName())
.SetDiagMsg(pxsFmt(L"Savestate uses an unsupported or unknown savestate version.\n(PCSX2 ver=%x, state ver=%x)", g_SaveVersion, savever))
.SetUserMsg(_("Cannot load this savestate. The state is an unsupported version."));
// check for a "minor" version incompatibility; which happens if the savestate being loaded is a newer version
// than the emulator recognizes. 99% chance that trying to load it will just corrupt emulation or crash.
if( (savever >> 16) != (g_SaveVersion >> 16) )
throw Exception::SaveStateLoadError( thr.GetStreamName() )
.SetDiagMsg(pxsFmt( L"Savestate uses an unknown savestate version.\n(PCSX2 ver=%x, state ver=%x)", g_SaveVersion, savever ))
if ((savever >> 16) != (g_SaveVersion >> 16))
throw Exception::SaveStateLoadError(thr.GetStreamName())
.SetDiagMsg(pxsFmt(L"Savestate uses an unknown savestate version.\n(PCSX2 ver=%x, state ver=%x)", g_SaveVersion, savever))
.SetUserMsg(_("Cannot load this savestate. The state is an unsupported version."));
};
@ -330,14 +330,14 @@ static void CheckVersion( pxInputStream& thr )
class SysExecEvent_DownloadState : public SysExecEvent
{
protected:
ArchiveEntryList* m_dest_list;
ArchiveEntryList* m_dest_list;
public:
wxString GetEventName() const { return L"VM_Download"; }
virtual ~SysExecEvent_DownloadState() = default;
SysExecEvent_DownloadState* Clone() const { return new SysExecEvent_DownloadState( *this ); }
SysExecEvent_DownloadState( ArchiveEntryList* dest_list=NULL )
SysExecEvent_DownloadState* Clone() const { return new SysExecEvent_DownloadState(*this); }
SysExecEvent_DownloadState(ArchiveEntryList* dest_list = NULL)
{
m_dest_list = dest_list;
}
@ -350,29 +350,28 @@ protected:
{
ScopedCoreThreadPause paused_core;
if( !SysHasValidState() )
if (!SysHasValidState())
throw Exception::RuntimeError()
.SetDiagMsg(L"SysExecEvent_DownloadState: Cannot freeze/download an invalid VM state!")
.SetUserMsg(_("There is no active virtual machine state to download or save." ));
.SetUserMsg(_("There is no active virtual machine state to download or save."));
memSavingState saveme( m_dest_list->GetBuffer() );
ArchiveEntry internals( EntryFilename_InternalStructures );
internals.SetDataIndex( saveme.GetCurrentPos() );
memSavingState saveme(m_dest_list->GetBuffer());
ArchiveEntry internals(EntryFilename_InternalStructures);
internals.SetDataIndex(saveme.GetCurrentPos());
saveme.FreezeBios();
saveme.FreezeInternals();
internals.SetDataSize( saveme.GetCurrentPos() - internals.GetDataIndex() );
m_dest_list->Add( internals );
internals.SetDataSize(saveme.GetCurrentPos() - internals.GetDataIndex());
m_dest_list->Add(internals);
for (uint i=0; i<ArraySize(SavestateEntries); ++i)
for (uint i = 0; i < ArraySize(SavestateEntries); ++i)
{
uint startpos = saveme.GetCurrentPos();
SavestateEntries[i]->FreezeOut( saveme );
m_dest_list->Add( ArchiveEntry( SavestateEntries[i]->GetFilename() )
.SetDataIndex( startpos )
.SetDataSize( saveme.GetCurrentPos() - startpos )
);
SavestateEntries[i]->FreezeOut(saveme);
m_dest_list->Add(ArchiveEntry(SavestateEntries[i]->GetFilename())
.SetDataIndex(startpos)
.SetDataSize(saveme.GetCurrentPos() - startpos));
}
UI_EnableStateActions();
@ -389,7 +388,7 @@ class VmStateCompressThread : public BaseCompressThread
typedef BaseCompressThread _parent;
protected:
ScopedLock m_lock_Compress;
ScopedLock m_lock_Compress;
public:
VmStateCompressThread()
@ -419,24 +418,24 @@ protected:
class SysExecEvent_ZipToDisk : public SysExecEvent
{
protected:
ArchiveEntryList* m_src_list;
wxString m_filename;
ArchiveEntryList* m_src_list;
wxString m_filename;
public:
wxString GetEventName() const { return L"VM_ZipToDisk"; }
virtual ~SysExecEvent_ZipToDisk() = default;
SysExecEvent_ZipToDisk* Clone() const { return new SysExecEvent_ZipToDisk( *this ); }
SysExecEvent_ZipToDisk* Clone() const { return new SysExecEvent_ZipToDisk(*this); }
SysExecEvent_ZipToDisk( ArchiveEntryList& srclist, const wxString& filename )
: m_filename( filename )
SysExecEvent_ZipToDisk(ArchiveEntryList& srclist, const wxString& filename)
: m_filename(filename)
{
m_src_list = &srclist;
}
SysExecEvent_ZipToDisk( ArchiveEntryList* srclist, const wxString& filename )
: m_filename( filename )
SysExecEvent_ZipToDisk(ArchiveEntryList* srclist, const wxString& filename)
: m_filename(filename)
{
m_src_list = srclist;
}
@ -450,7 +449,7 @@ protected:
// Provisionals for scoped cleanup, in case of exception:
std::unique_ptr<ArchiveEntryList> elist(m_src_list);
wxString tempfile( m_filename + L".tmp" );
wxString tempfile(m_filename + L".tmp");
wxFFileOutputStream* woot = new wxFFileOutputStream(tempfile);
if (!woot->IsOk())
@ -468,8 +467,8 @@ protected:
{
wxZipEntry* vent = new wxZipEntry(EntryFilename_StateVersion);
vent->SetMethod( wxZIP_METHOD_STORE );
gzfp->PutNextEntry( vent );
vent->SetMethod(wxZIP_METHOD_STORE);
gzfp->PutNextEntry(vent);
out->Write(g_SaveVersion);
gzfp->CloseEntry();
}
@ -479,9 +478,9 @@ protected:
if (m_screenshot)
{
wxZipEntry* vent = new wxZipEntry(EntryFilename_Screenshot);
vent->SetMethod( wxZIP_METHOD_STORE );
gzfp->PutNextEntry( vent );
m_screenshot->SaveFile( *gzfp, wxBITMAP_TYPE_JPEG );
vent->SetMethod(wxZIP_METHOD_STORE);
gzfp->PutNextEntry(vent);
m_screenshot->SaveFile(*gzfp, wxBITMAP_TYPE_JPEG);
gzfp->CloseEntry();
}
@ -511,15 +510,15 @@ protected:
class SysExecEvent_UnzipFromDisk : public SysExecEvent
{
protected:
wxString m_filename;
wxString m_filename;
public:
wxString GetEventName() const { return L"VM_UnzipFromDisk"; }
virtual ~SysExecEvent_UnzipFromDisk() = default;
SysExecEvent_UnzipFromDisk* Clone() const { return new SysExecEvent_UnzipFromDisk( *this ); }
SysExecEvent_UnzipFromDisk( const wxString& filename )
: m_filename( filename )
SysExecEvent_UnzipFromDisk* Clone() const { return new SysExecEvent_UnzipFromDisk(*this); }
SysExecEvent_UnzipFromDisk(const wxString& filename)
: m_filename(filename)
{
}
@ -528,21 +527,21 @@ public:
protected:
void InvokeEvent()
{
ScopedLock lock( mtx_CompressToDisk );
ScopedLock lock(mtx_CompressToDisk);
// Ugh. Exception handling made crappy because wxWidgets classes don't support scoped pointers yet.
std::unique_ptr<wxFFileInputStream> woot(new wxFFileInputStream(m_filename));
if (!woot->IsOk())
throw Exception::CannotCreateStream( m_filename ).SetDiagMsg(L"Cannot open file for reading.");
throw Exception::CannotCreateStream(m_filename).SetDiagMsg(L"Cannot open file for reading.");
std::unique_ptr<pxInputStream> reader(new pxInputStream(m_filename, new wxZipInputStream(woot.get())));
woot.release();
if (!reader->IsOk())
{
throw Exception::SaveStateLoadError( m_filename )
.SetDiagMsg( L"Savestate file is not a valid gzip archive." )
throw Exception::SaveStateLoadError(m_filename)
.SetDiagMsg(L"Savestate file is not a valid gzip archive.")
.SetUserMsg(_("This savestate cannot be loaded because it is not a valid gzip archive. It may have been created by an older unsupported version of PCSX2, or it may be corrupted."));
}
@ -557,16 +556,17 @@ protected:
std::unique_ptr<wxZipEntry> foundInternal;
std::unique_ptr<wxZipEntry> foundEntry[ArraySize(SavestateEntries)];
while(true)
while (true)
{
Threading::pxTestCancel();
std::unique_ptr<wxZipEntry> entry(gzreader->GetNextEntry());
if (!entry) break;
if (!entry)
break;
if (entry->GetName().CmpNoCase(EntryFilename_StateVersion) == 0)
{
DevCon.WriteLn( Color_Green, L" ... found '%s'", EntryFilename_StateVersion);
DevCon.WriteLn(Color_Green, L" ... found '%s'", EntryFilename_StateVersion);
foundVersion = true;
CheckVersion(*reader);
continue;
@ -574,7 +574,7 @@ protected:
if (entry->GetName().CmpNoCase(EntryFilename_InternalStructures) == 0)
{
DevCon.WriteLn( Color_Green, L" ... found '%s'", EntryFilename_InternalStructures);
DevCon.WriteLn(Color_Green, L" ... found '%s'", EntryFilename_InternalStructures);
foundInternal = std::move(entry);
continue;
}
@ -586,11 +586,11 @@ protected:
foundScreenshot = true;
}*/
for (uint i=0; i<ArraySize(SavestateEntries); ++i)
for (uint i = 0; i < ArraySize(SavestateEntries); ++i)
{
if (entry->GetName().CmpNoCase(SavestateEntries[i]->GetFilename()) == 0)
{
DevCon.WriteLn( Color_Green, L" ... found '%s'", WX_STR(SavestateEntries[i]->GetFilename()) );
DevCon.WriteLn(Color_Green, L" ... found '%s'", WX_STR(SavestateEntries[i]->GetFilename()));
foundEntry[i] = std::move(entry);
break;
}
@ -599,28 +599,29 @@ protected:
if (!foundVersion || !foundInternal)
{
throw Exception::SaveStateLoadError( m_filename )
.SetDiagMsg( pxsFmt(L"Savestate file does not contain '%s'",
!foundVersion ? EntryFilename_StateVersion : EntryFilename_InternalStructures) )
throw Exception::SaveStateLoadError(m_filename)
.SetDiagMsg(pxsFmt(L"Savestate file does not contain '%s'",
!foundVersion ? EntryFilename_StateVersion : EntryFilename_InternalStructures))
.SetUserMsg(_("This file is not a valid PCSX2 savestate. See the logfile for details."));
}
// Log any parts and pieces that are missing, and then generate an exception.
bool throwIt = false;
for (uint i=0; i<ArraySize(SavestateEntries); ++i)
for (uint i = 0; i < ArraySize(SavestateEntries); ++i)
{
if (foundEntry[i]) continue;
if (foundEntry[i])
continue;
if (SavestateEntries[i]->IsRequired())
{
throwIt = true;
Console.WriteLn( Color_Red, " ... not found '%s'!", WX_STR(SavestateEntries[i]->GetFilename()) );
Console.WriteLn(Color_Red, " ... not found '%s'!", WX_STR(SavestateEntries[i]->GetFilename()));
}
}
if (throwIt)
throw Exception::SaveStateLoadError( m_filename )
.SetDiagMsg( L"Savestate cannot be loaded: some required components were not found or are incomplete." )
throw Exception::SaveStateLoadError(m_filename)
.SetDiagMsg(L"Savestate cannot be loaded: some required components were not found or are incomplete.")
.SetUserMsg(_("This savestate cannot be loaded due to missing critical components. See the log file for details."));
// We use direct Suspend/Resume control here, since it's desirable that emulation
@ -631,25 +632,26 @@ protected:
GetCoreThread().Pause();
SysClearExecutionCache();
for (uint i=0; i<ArraySize(SavestateEntries); ++i)
for (uint i = 0; i < ArraySize(SavestateEntries); ++i)
{
if (!foundEntry[i]) continue;
if (!foundEntry[i])
continue;
Threading::pxTestCancel();
gzreader->OpenEntry( *foundEntry[i] );
SavestateEntries[i]->FreezeIn( *reader );
gzreader->OpenEntry(*foundEntry[i]);
SavestateEntries[i]->FreezeIn(*reader);
}
// Load all the internal data
gzreader->OpenEntry( *foundInternal );
gzreader->OpenEntry(*foundInternal);
VmStateBuffer buffer( foundInternal->GetSize(), L"StateBuffer_UnzipFromDisk" ); // start with an 8 meg buffer to avoid frequent reallocation.
reader->Read( buffer.GetPtr(), foundInternal->GetSize() );
VmStateBuffer buffer(foundInternal->GetSize(), L"StateBuffer_UnzipFromDisk"); // start with an 8 meg buffer to avoid frequent reallocation.
reader->Read(buffer.GetPtr(), foundInternal->GetSize());
memLoadingState( buffer ).FreezeBios().FreezeInternals();
GetCoreThread().Resume(); // force resume regardless of emulation state earlier.
memLoadingState(buffer).FreezeBios().FreezeInternals();
GetCoreThread().Resume(); // force resume regardless of emulation state earlier.
}
};
@ -657,7 +659,7 @@ protected:
// StateCopy Public Interface
// =====================================================================================================
void StateCopy_SaveToFile( const wxString& file )
void StateCopy_SaveToFile(const wxString& file)
{
UI_DisableStateActions();
@ -669,52 +671,52 @@ void StateCopy_SaveToFile( const wxString& file )
ziplist.release();
}
void StateCopy_LoadFromFile( const wxString& file )
void StateCopy_LoadFromFile(const wxString& file)
{
UI_DisableSysActions();
GetSysExecutorThread().PostEvent(new SysExecEvent_UnzipFromDisk( file ));
GetSysExecutorThread().PostEvent(new SysExecEvent_UnzipFromDisk(file));
}
// Saves recovery state info to the given saveslot, or saves the active emulation state
// (if one exists) and no recovery data was found. This is needed because when a recovery
// state is made, the emulation state is usually reset so the only persisting state is
// the one in the memory save. :)
void StateCopy_SaveToSlot( uint num )
void StateCopy_SaveToSlot(uint num)
{
const wxString file( SaveStateBase::GetFilename( num ) );
const wxString file(SaveStateBase::GetFilename(num));
// Backup old Savestate if one exists.
if( wxFileExists( file ) && EmuConfig.BackupSavestate )
if (wxFileExists(file) && EmuConfig.BackupSavestate)
{
const wxString copy( SaveStateBase::GetFilename( num ) + pxsFmt( L".backup") );
const wxString copy(SaveStateBase::GetFilename(num) + pxsFmt(L".backup"));
Console.Indent().WriteLn( Color_StrongGreen, L"Backing up existing state in slot %d.", num);
wxRenameFile( file, copy );
Console.Indent().WriteLn(Color_StrongGreen, L"Backing up existing state in slot %d.", num);
wxRenameFile(file, copy);
}
OSDlog( Color_StrongGreen, true, "Saving savestate to slot %d...", num );
Console.Indent().WriteLn( Color_StrongGreen, L"filename: %s", WX_STR(file) );
OSDlog(Color_StrongGreen, true, "Saving savestate to slot %d...", num);
Console.Indent().WriteLn(Color_StrongGreen, L"filename: %s", WX_STR(file));
StateCopy_SaveToFile( file );
StateCopy_SaveToFile(file);
#ifdef USE_NEW_SAVESLOTS_UI
UI_UpdateSysControls();
#endif
}
void StateCopy_LoadFromSlot( uint slot, bool isFromBackup )
void StateCopy_LoadFromSlot(uint slot, bool isFromBackup)
{
wxString file( SaveStateBase::GetFilename( slot ) + wxString( isFromBackup?L".backup":L"" ) );
wxString file(SaveStateBase::GetFilename(slot) + wxString(isFromBackup ? L".backup" : L""));
if( !wxFileExists( file ) )
if (!wxFileExists(file))
{
OSDlog(Color_StrongGreen, true, "Savestate slot %d%s is empty.", slot, isFromBackup ? " (backup)" : "");
return;
}
OSDlog( Color_StrongGreen, true, "Loading savestate from slot %d...%s", slot, isFromBackup?" (backup)":"" );
Console.Indent().WriteLn( Color_StrongGreen, L"filename: %s", WX_STR(file) );
OSDlog(Color_StrongGreen, true, "Loading savestate from slot %d...%s", slot, isFromBackup ? " (backup)" : "");
Console.Indent().WriteLn(Color_StrongGreen, L"filename: %s", WX_STR(file));
StateCopy_LoadFromFile( file );
StateCopy_LoadFromFile(file);
#ifdef USE_NEW_SAVESLOTS_UI
UI_UpdateSysControls();
#endif