all repos — mgba @ 9eb8faf1bab99e69e7c62fb8d7daa85a5cc07adf

mGBA Game Boy Advance Emulator

GUI: Add fast-forward key
Jeffrey Pfau jeffrey@endrift.com
Tue, 16 Aug 2016 23:24:07 -0700
commit

9eb8faf1bab99e69e7c62fb8d7daa85a5cc07adf

parent

400ac04d42bfa058e33f61176a53148a39b7ca34

M CHANGESCHANGES

@@ -7,6 +7,7 @@ - Tile viewer

- 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
M src/feature/gui/gui-runner.csrc/feature/gui/gui-runner.c

@@ -63,7 +63,9 @@ "Left",

"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 @@ break;

} #endif uint32_t guiKeys; - GUIPollInput(&runner->params, &guiKeys, 0); + uint32_t heldKeys; + GUIPollInput(&runner->params, &guiKeys, &heldKeys); if (guiKeys & (1 << GUI_INPUT_CANCEL)) { break; }

@@ -360,6 +363,14 @@ }

} 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) {
M src/feature/gui/gui-runner.hsrc/feature/gui/gui-runner.h

@@ -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 @@ void (*drawScreenshot)(struct mGUIRunner*, const uint32_t* pixels, unsigned width, unsigned height, bool faded);

void (*paused)(struct mGUIRunner*); void (*unpaused)(struct mGUIRunner*); void (*incrementScreenMode)(struct mGUIRunner*); + void (*setFrameLimiter)(struct mGUIRunner*, bool limit); uint16_t (*pollGameInput)(struct mGUIRunner*); };
M src/platform/3ds/main.csrc/platform/3ds/main.c

@@ -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 @@ ctrFinalize();

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 @@ unsigned mode;

if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode < SM_MAX) { screenMode = mode; } + frameLimiter = true; runner->core->setAudioBufferSize(runner->core, AUDIO_SAMPLES); }

@@ -300,6 +304,7 @@ CSND_SetPlayState(9, 0);

csndExecCmds(false); } osSetSpeedupEnable(false); + frameLimiter = true; switch (runner->core->platform(runner->core)) { #ifdef M_CORE_GBA

@@ -460,6 +465,11 @@ C3D_RenderBufClear(&bottomScreen);

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 @@ .drawScreenshot = _drawScreenshot,

.paused = _gameUnloaded, .unpaused = _gameLoaded, .incrementScreenMode = _incrementScreenMode, + .setFrameLimiter = _setFrameLimiter, .pollGameInput = _pollGameInput };
M src/platform/psp2/main.csrc/platform/psp2/main.c

@@ -31,10 +31,11 @@ }

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 @@ .drawScreenshot = mPSP2DrawScreenshot,

.paused = mPSP2Paused, .unpaused = mPSP2Unpaused, .incrementScreenMode = mPSP2IncrementScreenMode, + .setFrameLimiter = mPSP2SetFrameLimiter, .pollGameInput = mPSP2PollInput };
M src/platform/psp2/psp2-context.csrc/platform/psp2/psp2-context.c

@@ -58,11 +58,12 @@ struct mRumble d;

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 @@ }

struct GBAStereoSample* buffer = audio->buffer.readPtr; RingFIFORead(&audio->buffer, NULL, len * 4); audio->samples -= len; + ConditionWake(&audio->cond); MutexUnlock(&audio->mutex); sceAudioOutOutput(audioPort, buffer);

@@ -161,6 +163,11 @@ if (angles != GBA_KEY_NONE) {

activeKeys |= 1 << angles; } return activeKeys; +} + +void mPSP2SetFrameLimiter(struct mGUIRunner* runner, bool limit) { + UNUSED(runner); + frameLimiter = limit; } void mPSP2Setup(struct mGUIRunner* runner) {

@@ -200,6 +207,7 @@ rumble.d.setRumble = _setRumble;

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 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 @@ while (blip_samples_avail(runner->core->getAudioChannel(runner->core, 0)) >= PSP2_SAMPLES) {

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,8 +305,8 @@ 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;
M src/platform/psp2/psp2-context.hsrc/platform/psp2/psp2-context.h

@@ -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
M src/platform/wii/main.csrc/platform/wii/main.c

@@ -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 @@ .drawFrame = _drawFrame,

.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);

@@ -452,6 +457,11 @@ u32 level = 0;

_CPU_ISR_Disable(level); ++referenceRetraceCount; _CPU_ISR_Restore(level); +} + +static void _setFrameLimiter(struct mGUIRunner* runner, bool limit) { + UNUSED(runner); + frameLimiter = limit; } static uint32_t _pollInput(const struct mInputMap* map) {

@@ -585,11 +595,14 @@

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) {