GUI: Add fast-forward key

This commit is contained in:
Jeffrey Pfau 2016-08-16 23:24:07 -07:00
parent 400ac04d42
commit 9eb8faf1ba
8 changed files with 62 additions and 10 deletions

View File

@ -7,6 +7,7 @@ Features:
- Threaded rendering mode
- Libretro: Memory map and achievement support (leiradel)
- GUI: Add UI control remapping
- GUI: Add fast-forward
Bugfixes:
- SDL: Fix axes being mapped wrong
- GBA Memory: Fix mirror on non-overdumped Classic NES games

View File

@ -63,7 +63,9 @@ static const struct mInputPlatformInfo _mGUIKeyInfo = {
"Right",
[mGUI_INPUT_INCREASE_BRIGHTNESS] = "Increase solar brightness",
[mGUI_INPUT_DECREASE_BRIGHTNESS] = "Decrease solar brightness",
[mGUI_INPUT_SCREEN_MODE] = "Screen mode"
[mGUI_INPUT_SCREEN_MODE] = "Screen mode",
[mGUI_INPUT_SCREENSHOT] = "Take screenshot",
[mGUI_INPUT_FAST_FORWARD] = "Fast forward",
},
.nKeys = GUI_INPUT_MAX
};
@ -344,7 +346,8 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) {
}
#endif
uint32_t guiKeys;
GUIPollInput(&runner->params, &guiKeys, 0);
uint32_t heldKeys;
GUIPollInput(&runner->params, &guiKeys, &heldKeys);
if (guiKeys & (1 << GUI_INPUT_CANCEL)) {
break;
}
@ -361,6 +364,14 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) {
if (guiKeys & (1 << mGUI_INPUT_SCREEN_MODE) && runner->incrementScreenMode) {
runner->incrementScreenMode(runner);
}
if (guiKeys & (1 << mGUI_INPUT_SCREENSHOT)) {
mCoreTakeScreenshot(runner->core);
}
if (heldKeys & (1 << mGUI_INPUT_FAST_FORWARD)) {
runner->setFrameLimiter(runner, false);
} else {
runner->setFrameLimiter(runner, true);
}
uint16_t keys = runner->pollGameInput(runner);
if (runner->prepareForFrame) {
runner->prepareForFrame(runner);

View File

@ -18,6 +18,8 @@ enum mGUIInput {
mGUI_INPUT_INCREASE_BRIGHTNESS = GUI_INPUT_USER_START,
mGUI_INPUT_DECREASE_BRIGHTNESS,
mGUI_INPUT_SCREEN_MODE,
mGUI_INPUT_SCREENSHOT,
mGUI_INPUT_FAST_FORWARD,
};
struct mGUIBackground {
@ -64,6 +66,7 @@ struct mGUIRunner {
void (*paused)(struct mGUIRunner*);
void (*unpaused)(struct mGUIRunner*);
void (*incrementScreenMode)(struct mGUIRunner*);
void (*setFrameLimiter)(struct mGUIRunner*, bool limit);
uint16_t (*pollGameInput)(struct mGUIRunner*);
};

View File

@ -64,6 +64,7 @@ static size_t audioPos = 0;
static C3D_Tex outputTexture;
static ndspWaveBuf dspBuffer[DSP_BUFFERS];
static int bufferId = 0;
static bool frameLimiter = true;
static C3D_RenderBuf bottomScreen;
static C3D_RenderBuf topScreen;
@ -182,7 +183,9 @@ static void _drawEnd(void) {
C3D_RenderBufTransfer(&topScreen, (u32*) gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8));
C3D_RenderBufTransfer(&bottomScreen, (u32*) gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL), GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8));
gfxSwapBuffersGpu();
gspWaitForEvent(GSPGPU_EVENT_VBlank0, false);
if (frameLimiter) {
gspWaitForEvent(GSPGPU_EVENT_VBlank0, false);
}
}
static int _batteryState(void) {
@ -245,6 +248,7 @@ static void _setup(struct mGUIRunner* runner) {
if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode < SM_MAX) {
screenMode = mode;
}
frameLimiter = true;
runner->core->setAudioBufferSize(runner->core, AUDIO_SAMPLES);
}
@ -300,6 +304,7 @@ static void _gameUnloaded(struct mGUIRunner* runner) {
csndExecCmds(false);
}
osSetSpeedupEnable(false);
frameLimiter = true;
switch (runner->core->platform(runner->core)) {
#ifdef M_CORE_GBA
@ -460,6 +465,11 @@ static void _incrementScreenMode(struct mGUIRunner* runner) {
C3D_RenderBufClear(&topScreen);
}
static void _setFrameLimiter(struct mGUIRunner* runner, bool limit) {
UNUSED(runner);
frameLimiter = limit;
}
static uint32_t _pollInput(const struct mInputMap* map) {
hidScanInput();
int activeKeys = hidKeysHeld();
@ -689,6 +699,7 @@ int main() {
.paused = _gameUnloaded,
.unpaused = _gameLoaded,
.incrementScreenMode = _incrementScreenMode,
.setFrameLimiter = _setFrameLimiter,
.pollGameInput = _pollGameInput
};

View File

@ -31,10 +31,11 @@ static void _drawStart(void) {
static void _drawEnd(void) {
static int oldVCount = 0;
extern bool frameLimiter;
int vcount = oldVCount;
vita2d_end_drawing();
oldVCount = sceDisplayGetVcount();
vita2d_set_vblank_wait(oldVCount + 1 >= vcount);
vita2d_set_vblank_wait(frameLimiter && oldVCount + 1 >= vcount);
vita2d_swap_buffers();
}
@ -146,6 +147,7 @@ int main() {
.paused = mPSP2Paused,
.unpaused = mPSP2Unpaused,
.incrementScreenMode = mPSP2IncrementScreenMode,
.setFrameLimiter = mPSP2SetFrameLimiter,
.pollGameInput = mPSP2PollInput
};

View File

@ -58,11 +58,12 @@ static struct mSceRumble {
struct CircleBuffer history;
int current;
} rumble;
bool frameLimiter = true;
extern const uint8_t _binary_backdrop_png_start[];
static vita2d_texture* backdrop = 0;
#define PSP2_SAMPLES 64
#define PSP2_SAMPLES 128
#define PSP2_AUDIO_BUFFER_SIZE (PSP2_SAMPLES * 40)
static struct mPSP2AudioContext {
@ -89,6 +90,7 @@ static THREAD_ENTRY _audioThread(void* context) {
struct GBAStereoSample* buffer = audio->buffer.readPtr;
RingFIFORead(&audio->buffer, NULL, len * 4);
audio->samples -= len;
ConditionWake(&audio->cond);
MutexUnlock(&audio->mutex);
sceAudioOutOutput(audioPort, buffer);
@ -163,6 +165,11 @@ uint16_t mPSP2PollInput(struct mGUIRunner* runner) {
return activeKeys;
}
void mPSP2SetFrameLimiter(struct mGUIRunner* runner, bool limit) {
UNUSED(runner);
frameLimiter = limit;
}
void mPSP2Setup(struct mGUIRunner* runner) {
mCoreConfigSetDefaultIntValue(&runner->config, "threadedVideo", 1);
mCoreLoadForeignConfig(runner->core, &runner->config);
@ -200,6 +207,7 @@ void mPSP2Setup(struct mGUIRunner* runner) {
CircleBufferInit(&rumble.history, RUMBLE_PWM);
runner->core->setRumble(runner->core, &rumble.d);
frameLimiter = true;
backdrop = vita2d_load_PNG_buffer(_binary_backdrop_png_start);
unsigned mode;
@ -210,7 +218,7 @@ void mPSP2Setup(struct mGUIRunner* runner) {
void mPSP2LoadROM(struct mGUIRunner* runner) {
scePowerSetArmClockFrequency(444);
double ratio = GBAAudioCalculateRatio(1, 60, 1);
double ratio = GBAAudioCalculateRatio(1, 60.0 / 1.001, 1);
blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 48000 * ratio);
blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 48000 * ratio);
@ -246,7 +254,9 @@ void mPSP2PrepareForFrame(struct mGUIRunner* runner) {
struct GBAStereoSample* samples = audioContext.buffer.writePtr;
blip_read_samples(runner->core->getAudioChannel(runner->core, 0), &samples[0].left, PSP2_SAMPLES, true);
blip_read_samples(runner->core->getAudioChannel(runner->core, 1), &samples[0].right, PSP2_SAMPLES, true);
RingFIFOWrite(&audioContext.buffer, NULL, PSP2_SAMPLES * 4);
if (!RingFIFOWrite(&audioContext.buffer, NULL, PSP2_SAMPLES * 4)) {
break;
}
audioContext.samples += PSP2_SAMPLES;
}
ConditionWake(&audioContext.cond);
@ -295,9 +305,9 @@ void mPSP2Teardown(struct mGUIRunner* runner) {
CircleBufferDeinit(&rumble.history);
vita2d_free_texture(tex);
vita2d_free_texture(screenshot);
frameLimiter = true;
}
void _drawTex(vita2d_texture* t, unsigned width, unsigned height, bool faded) {
unsigned w = width;
unsigned h = height;

View File

@ -22,6 +22,7 @@ void mPSP2Unpaused(struct mGUIRunner* runner);
void mPSP2Draw(struct mGUIRunner* runner, bool faded);
void mPSP2DrawScreenshot(struct mGUIRunner* runner, const uint32_t* pixels, unsigned width, unsigned height, bool faded);
void mPSP2IncrementScreenMode(struct mGUIRunner* runner);
void mPSP2SetFrameLimiter(struct mGUIRunner* runner, bool limit);
uint16_t mPSP2PollInput(struct mGUIRunner* runner);
#endif

View File

@ -71,6 +71,7 @@ static void _gameUnloaded(struct mGUIRunner* runner);
static void _unpaused(struct mGUIRunner* runner);
static void _drawFrame(struct mGUIRunner* runner, bool faded);
static uint16_t _pollGameInput(struct mGUIRunner* runner);
static void _setFrameLimiter(struct mGUIRunner* runner, bool limit);
static void _incrementScreenMode(struct mGUIRunner* runner);
static s8 WPAD_StickX(u8 chan, u8 right);
@ -88,6 +89,7 @@ static int32_t tiltY;
static int32_t gyroZ;
static uint32_t retraceCount;
static uint32_t referenceRetraceCount;
static bool frameLimiter = true;
static int scaleFactor;
static unsigned corew, coreh;
@ -363,6 +365,7 @@ int main(int argc, char* argv[]) {
.paused = _gameUnloaded,
.unpaused = _unpaused,
.incrementScreenMode = _incrementScreenMode,
.setFrameLimiter = _setFrameLimiter,
.pollGameInput = _pollGameInput
};
mGUIInit(&runner, "wii");
@ -429,9 +432,11 @@ static void _drawStart(void) {
u32 level = 0;
_CPU_ISR_Disable(level);
if (referenceRetraceCount >= retraceCount) {
VIDEO_WaitVSync();
if (frameLimiter) {
VIDEO_WaitVSync();
}
referenceRetraceCount = retraceCount;
}
referenceRetraceCount = retraceCount;
_CPU_ISR_Restore(level);
GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
@ -454,6 +459,11 @@ static void _drawEnd(void) {
_CPU_ISR_Restore(level);
}
static void _setFrameLimiter(struct mGUIRunner* runner, bool limit) {
UNUSED(runner);
frameLimiter = limit;
}
static uint32_t _pollInput(const struct mInputMap* map) {
PAD_ScanPads();
u16 padkeys = PAD_ButtonsHeld(0);
@ -585,11 +595,14 @@ void _setup(struct mGUIRunner* runner) {
double ratio = GBAAudioCalculateRatio(1, 60 / 1.001, 1);
blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 48000 * ratio);
blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 48000 * ratio);
frameLimiter = true;
}
void _gameUnloaded(struct mGUIRunner* runner) {
UNUSED(runner);
AUDIO_StopDMA();
frameLimiter = true;
}
void _gameLoaded(struct mGUIRunner* runner) {