GUI: Add UI control remapping
jump to
@@ -6,6 +6,7 @@ - Emulation of Vast Fame protected GBA carts (taizou)
- Tile viewer - Threaded rendering mode - Libretro: Memory map and achievement support (leiradel) + - GUI: Add UI control remapping Bugfixes: - SDL: Fix axes being mapped wrong - GBA Memory: Fix mirror on non-overdumped Classic NES games
@@ -272,6 +272,9 @@
static void _saveAll(const struct mInputMap* map, uint32_t type, const char* sectionName, struct Configuration* config) { size_t i; for (i = 0; i < map->info->nKeys; ++i) { + if (!map->info->keyId[i]) { + continue; + } _saveKey(map, type, sectionName, config, i, map->info->keyId[i]); _clearAxis(sectionName, config, map->info->keyId[i]); }@@ -338,6 +341,9 @@ }
void mInputBindKey(struct mInputMap* map, uint32_t type, int key, int input) { struct mInputMapImpl* impl = _guaranteeMap(map, type); + if (input < 0 || (size_t) input >= map->info->nKeys) { + return; + } mInputUnbindKey(map, type, input); impl->map[input] = key; }
@@ -6,7 +6,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gui-config.h" #include "core/config.h" -#include "core/core.h" #include "feature/gui/gui-runner.h" #include "feature/gui/remap.h" #include "gba/gba.h"@@ -96,7 +95,7 @@ item = GUIMenuItemListGetPointer(&menu.items, i);
if (!item->validStates || !item->data) { continue; } - mCoreConfigGetUIntValue(&runner->core->config, item->data, &item->state); + mCoreConfigGetUIntValue(&runner->config, item->data, &item->state); } while (true) {@@ -106,16 +105,16 @@ break;
} if (!strcmp(item->data, "*SAVE")) { if (biosPath[0]) { - mCoreConfigSetValue(&runner->core->config, "bios", biosPath); + mCoreConfigSetValue(&runner->config, "bios", biosPath); } for (i = 0; i < GUIMenuItemListSize(&menu.items); ++i) { item = GUIMenuItemListGetPointer(&menu.items, i); if (!item->validStates || !item->data) { continue; } - mCoreConfigSetUIntValue(&runner->core->config, item->data, item->state); + mCoreConfigSetUIntValue(&runner->config, item->data, item->state); } - mCoreConfigSave(&runner->core->config); + mCoreConfigSave(&runner->config); break; } if (!strcmp(item->data, "*REMAP")) {
@@ -51,6 +51,23 @@ RUNNER_STATE_8 = 0x80000,
RUNNER_STATE_9 = 0x90000, }; +static const struct mInputPlatformInfo _mGUIKeyInfo = { + .platformName = "gui", + .keyId = (const char*[GUI_INPUT_MAX]) { + "Select", + "Back", + "Cancel", + "Up", + "Down", + "Left", + "Right", + [mGUI_INPUT_INCREASE_BRIGHTNESS] = "Increase solar brightness", + [mGUI_INPUT_DECREASE_BRIGHTNESS] = "Decrease solar brightness", + [mGUI_INPUT_SCREEN_MODE] = "Screen mode" + }, + .nKeys = GUI_INPUT_MAX +}; + static void _log(struct mLogger*, int category, enum mLogLevel level, const char* format, va_list args); static struct mGUILogger {@@ -140,6 +157,13 @@ runner->lastFpsCheck = 0;
runner->totalDelta = 0; CircleBufferInit(&runner->fpsBuffer, FPS_BUFFER_SIZE * sizeof(uint32_t)); + mInputMapInit(&runner->params.keyMap, &_mGUIKeyInfo); + mCoreConfigInit(&runner->config, runner->port); + // TODO: Do we need to load more defaults? + mCoreConfigSetDefaultIntValue(&runner->config, "volume", 0x100); + mCoreConfigSetDefaultValue(&runner->config, "idleOptimization", "detect"); + mCoreConfigLoad(&runner->config); + char path[PATH_MAX]; mCoreConfigDirectory(path, PATH_MAX); strncat(path, PATH_SEP "log", PATH_MAX - strlen(path));@@ -152,6 +176,8 @@ if (runner->teardown) {
runner->teardown(runner); } CircleBufferDeinit(&runner->fpsBuffer); + mInputMapDeinit(&runner->params.keyMap); + mCoreConfigDeinit(&runner->config); if (logger.vf) { logger.vf->close(logger.vf); logger.vf = NULL;@@ -251,7 +277,6 @@ if (runner->core) {
mLOG(GUI_RUNNER, INFO, "Found core"); runner->core->init(runner->core); mInputMapInit(&runner->core->inputMap, &GBAInputInfo); - mCoreInitConfig(runner->core, runner->port); found = mCoreLoadFile(runner->core, path); if (!found) { mLOG(GUI_RUNNER, WARN, "Failed to load %s!", path);@@ -278,18 +303,8 @@ }
if (runner->core->platform(runner->core) == PLATFORM_GBA) { ((struct GBA*) runner->core->board)->luminanceSource = &runner->luminanceSource.d; } - if (runner->core->config.port && runner->keySources) { - mLOG(GUI_RUNNER, DEBUG, "Loading key sources for %s...", runner->core->config.port); - size_t i; - for (i = 0; runner->keySources[i].id; ++i) { - mInputMapLoad(&runner->core->inputMap, runner->keySources[i].id, mCoreConfigGetInput(&runner->core->config)); - } - } - // TODO: Do we need to load more defaults? - mCoreConfigSetDefaultIntValue(&runner->core->config, "volume", 0x100); - mCoreConfigSetDefaultValue(&runner->core->config, "idleOptimization", "detect"); mLOG(GUI_RUNNER, DEBUG, "Loading config..."); - mCoreLoadConfig(runner->core); + mCoreLoadForeignConfig(runner->core, &runner->config); logger.logLevel = runner->core->opts.logLevel; mLOG(GUI_RUNNER, DEBUG, "Loading save...");@@ -298,6 +313,13 @@ if (runner->setup) {
mLOG(GUI_RUNNER, DEBUG, "Setting up runner..."); runner->setup(runner); } + if (runner->config.port && runner->keySources) { + mLOG(GUI_RUNNER, DEBUG, "Loading key sources for %s...", runner->config.port); + size_t i; + for (i = 0; runner->keySources[i].id; ++i) { + mInputMapLoad(&runner->core->inputMap, runner->keySources[i].id, mCoreConfigGetInput(&runner->config)); + } + } mLOG(GUI_RUNNER, DEBUG, "Reseting..."); runner->core->reset(runner->core); mLOG(GUI_RUNNER, DEBUG, "Reset!");@@ -347,7 +369,7 @@ runner->core->setKeys(runner->core, keys);
runner->core->runFrame(runner->core); if (runner->drawFrame) { int drawFps = false; - mCoreConfigGetIntValue(&runner->core->config, "fpsCounter", &drawFps); + mCoreConfigGetIntValue(&runner->config, "fpsCounter", &drawFps); runner->params.drawStart(); runner->drawFrame(runner, false);@@ -413,7 +435,7 @@ mCoreTakeScreenshot(runner->core);
break; case RUNNER_CONFIG: mGUIShowConfig(runner, runner->configExtra, runner->nConfigExtra); - mCoreLoadConfig(runner->core); + mCoreLoadForeignConfig(runner->core, &runner->config); break; case RUNNER_CONTINUE: break;@@ -445,16 +467,18 @@ runner->core->desiredVideoDimensions(runner->core, &w, &h);
mappedMemoryFree(drawState.screenshot, w * h * 4); } - if (runner->core->config.port) { + if (runner->config.port) { mLOG(GUI_RUNNER, DEBUG, "Saving key sources..."); if (runner->keySources) { size_t i; for (i = 0; runner->keySources[i].id; ++i) { - mInputMapSave(&runner->core->inputMap, runner->keySources[i].id, mCoreConfigGetInput(&runner->core->config)); + mInputMapSave(&runner->core->inputMap, runner->keySources[i].id, mCoreConfigGetInput(&runner->config)); + mInputMapSave(&runner->params.keyMap, runner->keySources[i].id, mCoreConfigGetInput(&runner->config)); } } - mCoreConfigSave(&runner->core->config); + mCoreConfigSave(&runner->config); } + mInputMapDeinit(&runner->core->inputMap); mLOG(GUI_RUNNER, DEBUG, "Deinitializing core..."); runner->core->deinit(runner->core);@@ -465,6 +489,13 @@ mLOG(GUI_RUNNER, INFO, "Game stopped!");
} void mGUIRunloop(struct mGUIRunner* runner) { + if (runner->keySources) { + mLOG(GUI_RUNNER, DEBUG, "Loading key sources for %s...", runner->config.port); + size_t i; + for (i = 0; runner->keySources[i].id; ++i) { + mInputMapLoad(&runner->params.keyMap, runner->keySources[i].id, mCoreConfigGetInput(&runner->config)); + } + } while (true) { char path[PATH_MAX]; if (!GUISelectFile(&runner->params, path, sizeof(path), 0)) {
@@ -8,6 +8,7 @@ #define GUI_RUNNER_H
#include "util/common.h" +#include "core/config.h" #include "feature/gui/remap.h" #include "gba/hardware.h" #include "util/circle-buffer.h"@@ -40,6 +41,8 @@
struct mGUIBackground background; struct mGUIRunnerLux luminanceSource; + struct mInputMap guiKeys; + struct mCoreConfig config; struct GUIMenuItem* configExtra; size_t nConfigExtra;
@@ -5,7 +5,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "remap.h" -#include "gba/input.h" #include "util/gui.h" #include "util/gui/menu.h"@@ -20,10 +19,14 @@ const char* keyNames[keys->nKeys + 1];
memcpy(&keyNames[1], keys->keyNames, keys->nKeys * sizeof(keyNames[0])); keyNames[0] = "Unmapped"; size_t i; - for (i = 0; i < GBA_KEY_MAX; ++i) { + *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { + .title = "Game keys:", + .data = 0, + }; + for (i = 0; i < map->info->nKeys; ++i) { *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { - .title = GBAInputInfo.keyId[i], - .data = (void*) (GUI_INPUT_MAX + i), + .title = map->info->keyId[i], + .data = (void*) (GUI_INPUT_MAX + i + 1), .submenu = 0, .state = mInputQueryBinding(map, keys->id, i) + 1, .validStates = keyNames,@@ -31,8 +34,25 @@ .nStates = keys->nKeys + 1
}; } *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { + .title = "Interface keys:", + .data = 0, + }; + for (i = 0; i < params->keyMap.info->nKeys; ++i) { + if (!params->keyMap.info->keyId[i]) { + continue; + } + *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { + .title = params->keyMap.info->keyId[i], + .data = (void*) i + 1, + .submenu = 0, + .state = mInputQueryBinding(¶ms->keyMap, keys->id, i) + 1, + .validStates = keyNames, + .nStates = keys->nKeys + 1 + }; + } + *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Save", - .data = (void*) (GUI_INPUT_MAX + GBA_KEY_MAX + 2), + .data = (void*) (GUI_INPUT_MAX + map->info->nKeys + 2), }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Cancel",@@ -46,11 +66,16 @@ reason = GUIShowMenu(params, &menu, &item);
if (reason != GUI_MENU_EXIT_ACCEPT || !item->data) { break; } - if (item->data == (void*) (GUI_INPUT_MAX + GBA_KEY_MAX + 2)) { + if (item->data == (void*) (GUI_INPUT_MAX + map->info->nKeys + 2)) { for (i = 0; i < GUIMenuItemListSize(&menu.items); ++i) { item = GUIMenuItemListGetPointer(&menu.items, i); - if (i < GBA_KEY_MAX) { - mInputBindKey(map, keys->id, item->state - 1, i); + if ((uint32_t) item->data < 1) { + continue; + } + if ((uint32_t) item->data < GUI_INPUT_MAX + 1) { + mInputBindKey(¶ms->keyMap, keys->id, item->state - 1, (uint32_t) item->data - 1); + } else if ((uint32_t) item->data < GUI_INPUT_MAX + map->info->nKeys + 1) { + mInputBindKey(map, keys->id, item->state - 1, (uint32_t) item->data - GUI_INPUT_MAX - 1); } } break;
@@ -218,8 +218,8 @@ static void _setup(struct mGUIRunner* runner) {
bool isNew3DS = false; APT_CheckNew3DS(&isNew3DS); if (isNew3DS && !envIsHomebrew()) { - mCoreConfigSetDefaultIntValue(&runner->core->config, "threadedVideo", 1); - mCoreLoadConfig(runner->core); + mCoreConfigSetDefaultIntValue(&runner->config, "threadedVideo", 1); + mCoreLoadForeignConfig(runner->core, &runner->config); } runner->core->setRotation(runner->core, &rotation.d);@@ -242,7 +242,7 @@ outputBuffer = linearMemAlign(256 * VIDEO_VERTICAL_PIXELS * 2, 0x80);
runner->core->setVideoBuffer(runner->core, outputBuffer, 256); unsigned mode; - if (mCoreConfigGetUIntValue(&runner->core->config, "screenMode", &mode) && mode < SM_MAX) { + if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode < SM_MAX) { screenMode = mode; }@@ -288,7 +288,7 @@ } else if (hasSound == DSP_SUPPORTED) {
memset(audioLeft, 0, AUDIO_SAMPLE_BUFFER * 2 * sizeof(int16_t)); } unsigned mode; - if (mCoreConfigGetUIntValue(&runner->core->config, "screenMode", &mode) && mode != screenMode) { + if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode != screenMode) { screenMode = mode; } }@@ -454,47 +454,16 @@
static void _incrementScreenMode(struct mGUIRunner* runner) { UNUSED(runner); screenMode = (screenMode + 1) % SM_MAX; - mCoreConfigSetUIntValue(&runner->core->config, "screenMode", screenMode); + mCoreConfigSetUIntValue(&runner->config, "screenMode", screenMode); C3D_RenderBufClear(&bottomScreen); C3D_RenderBufClear(&topScreen); } -static uint32_t _pollInput(void) { +static uint32_t _pollInput(const struct mInputMap* map) { hidScanInput(); - uint32_t keys = 0; int activeKeys = hidKeysHeld(); - if (activeKeys & KEY_X) { - keys |= 1 << GUI_INPUT_CANCEL; - } - if (activeKeys & KEY_Y) { - keys |= 1 << mGUI_INPUT_SCREEN_MODE; - } - if (activeKeys & KEY_B) { - keys |= 1 << GUI_INPUT_BACK; - } - if (activeKeys & KEY_A) { - keys |= 1 << GUI_INPUT_SELECT; - } - if (activeKeys & KEY_LEFT) { - keys |= 1 << GUI_INPUT_LEFT; - } - if (activeKeys & KEY_RIGHT) { - keys |= 1 << GUI_INPUT_RIGHT; - } - if (activeKeys & KEY_UP) { - keys |= 1 << GUI_INPUT_UP; - } - if (activeKeys & KEY_DOWN) { - keys |= 1 << GUI_INPUT_DOWN; - } - if (activeKeys & KEY_CSTICK_UP) { - keys |= 1 << mGUI_INPUT_INCREASE_BRIGHTNESS; - } - if (activeKeys & KEY_CSTICK_DOWN) { - keys |= 1 << mGUI_INPUT_DECREASE_BRIGHTNESS; - } - return keys; + return mInputMapKeyBits(map, _3DS_INPUT, activeKeys, 0); } static enum GUICursorState _pollCursor(unsigned* x, unsigned* y) {@@ -724,6 +693,18 @@ .pollGameInput = _pollGameInput
}; mGUIInit(&runner, "3ds"); + + _map3DSKey(&runner.params.keyMap, KEY_X, GUI_INPUT_CANCEL); + _map3DSKey(&runner.params.keyMap, KEY_Y, mGUI_INPUT_SCREEN_MODE); + _map3DSKey(&runner.params.keyMap, KEY_B, GUI_INPUT_BACK); + _map3DSKey(&runner.params.keyMap, KEY_A, GUI_INPUT_SELECT); + _map3DSKey(&runner.params.keyMap, KEY_UP, GUI_INPUT_UP); + _map3DSKey(&runner.params.keyMap, KEY_DOWN, GUI_INPUT_DOWN); + _map3DSKey(&runner.params.keyMap, KEY_LEFT, GUI_INPUT_LEFT); + _map3DSKey(&runner.params.keyMap, KEY_RIGHT, GUI_INPUT_RIGHT); + _map3DSKey(&runner.params.keyMap, KEY_CSTICK_UP, mGUI_INPUT_INCREASE_BRIGHTNESS); + _map3DSKey(&runner.params.keyMap, KEY_CSTICK_DOWN, mGUI_INPUT_DECREASE_BRIGHTNESS); + mGUIRunloop(&runner); mGUIDeinit(&runner);
@@ -38,22 +38,10 @@ vita2d_set_vblank_wait(oldVCount + 1 >= vcount);
vita2d_swap_buffers(); } -static uint32_t _pollInput(void) { +static uint32_t _pollInput(const struct mInputMap* map) { SceCtrlData pad; sceCtrlPeekBufferPositive(0, &pad, 1); - int input = 0; - if (pad.buttons & SCE_CTRL_TRIANGLE) { - input |= 1 << GUI_INPUT_CANCEL; - } - if (pad.buttons & SCE_CTRL_SQUARE) { - input |= 1 << mGUI_INPUT_SCREEN_MODE; - } - if (pad.buttons & SCE_CTRL_CIRCLE) { - input |= 1 << GUI_INPUT_BACK; - } - if (pad.buttons & SCE_CTRL_CROSS) { - input |= 1 << GUI_INPUT_SELECT; - } + int input = mInputMapKeyBits(map, PSP2_INPUT, pad.buttons, 0); if (pad.buttons & SCE_CTRL_UP || pad.ly < 64) { input |= 1 << GUI_INPUT_UP;@@ -165,6 +153,16 @@ sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START);
sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG_WIDE); mGUIInit(&runner, "psvita"); + + mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_CROSS, GUI_INPUT_SELECT); + mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_CIRCLE, GUI_INPUT_BACK); + mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_TRIANGLE, GUI_INPUT_CANCEL); + mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_UP, GUI_INPUT_UP); + mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_DOWN, GUI_INPUT_DOWN); + mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_LEFT, GUI_INPUT_LEFT); + mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_RIGHT, GUI_INPUT_RIGHT); + mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_SQUARE, mGUI_INPUT_SCREEN_MODE); + mGUIRunloop(&runner); vita2d_fini();
@@ -73,7 +73,7 @@ Condition cond;
bool running; } audioContext; -static void _mapVitaKey(struct mInputMap* map, int pspKey, enum GBAKey key) { +void mPSP2MapKey(struct mInputMap* map, int pspKey, int key) { mInputBindKey(map, PSP2_INPUT, __builtin_ctz(pspKey), key); }@@ -144,7 +144,7 @@ SceCtrlData pad;
sceCtrlPeekBufferPositive(0, &pad, 1); int activeKeys = mInputMapKeyBits(&runner->core->inputMap, PSP2_INPUT, pad.buttons, 0); - enum GBAKey angles = mInputMapAxis(&runner->core->inputMap, PSP2_INPUT, 0, pad.ly); + int angles = mInputMapAxis(&runner->core->inputMap, PSP2_INPUT, 0, pad.ly); if (angles != GBA_KEY_NONE) { activeKeys |= 1 << angles; }@@ -164,20 +164,20 @@ return activeKeys;
} void mPSP2Setup(struct mGUIRunner* runner) { - mCoreConfigSetDefaultIntValue(&runner->core->config, "threadedVideo", 1); - mCoreLoadConfig(runner->core); + mCoreConfigSetDefaultIntValue(&runner->config, "threadedVideo", 1); + mCoreLoadForeignConfig(runner->core, &runner->config); scePowerSetArmClockFrequency(80); - _mapVitaKey(&runner->core->inputMap, SCE_CTRL_CROSS, GBA_KEY_A); - _mapVitaKey(&runner->core->inputMap, SCE_CTRL_CIRCLE, GBA_KEY_B); - _mapVitaKey(&runner->core->inputMap, SCE_CTRL_START, GBA_KEY_START); - _mapVitaKey(&runner->core->inputMap, SCE_CTRL_SELECT, GBA_KEY_SELECT); - _mapVitaKey(&runner->core->inputMap, SCE_CTRL_UP, GBA_KEY_UP); - _mapVitaKey(&runner->core->inputMap, SCE_CTRL_DOWN, GBA_KEY_DOWN); - _mapVitaKey(&runner->core->inputMap, SCE_CTRL_LEFT, GBA_KEY_LEFT); - _mapVitaKey(&runner->core->inputMap, SCE_CTRL_RIGHT, GBA_KEY_RIGHT); - _mapVitaKey(&runner->core->inputMap, SCE_CTRL_LTRIGGER, GBA_KEY_L); - _mapVitaKey(&runner->core->inputMap, SCE_CTRL_RTRIGGER, GBA_KEY_R); + mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_CROSS, GBA_KEY_A); + mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_CIRCLE, GBA_KEY_B); + mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_START, GBA_KEY_START); + mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_SELECT, GBA_KEY_SELECT); + mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_UP, GBA_KEY_UP); + mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_DOWN, GBA_KEY_DOWN); + mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_LEFT, GBA_KEY_LEFT); + mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_RIGHT, GBA_KEY_RIGHT); + mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_LTRIGGER, GBA_KEY_L); + mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_RTRIGGER, GBA_KEY_R); struct mInputAxis desc = { GBA_KEY_DOWN, GBA_KEY_UP, 192, 64 }; mInputBindAxis(&runner->core->inputMap, PSP2_INPUT, 0, &desc);@@ -203,7 +203,7 @@
backdrop = vita2d_load_PNG_buffer(_binary_backdrop_png_start); unsigned mode; - if (mCoreConfigGetUIntValue(&runner->core->config, "screenMode", &mode) && mode < SM_MAX) { + if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode < SM_MAX) { screenMode = mode; } }@@ -286,7 +286,7 @@ }
void mPSP2Unpaused(struct mGUIRunner* runner) { unsigned mode; - if (mCoreConfigGetUIntValue(&runner->core->config, "screenMode", &mode) && mode != screenMode) { + if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode != screenMode) { screenMode = mode; } }@@ -377,7 +377,7 @@ }
void mPSP2IncrementScreenMode(struct mGUIRunner* runner) { screenMode = (screenMode + 1) % SM_MAX; - mCoreConfigSetUIntValue(&runner->core->config, "screenMode", screenMode); + mCoreConfigSetUIntValue(&runner->config, "screenMode", screenMode); } __attribute__((noreturn, weak)) void __assert_func(const char* file, int line, const char* func, const char* expr) {
@@ -12,6 +12,7 @@
struct mGUIRunner; void mPSP2Setup(struct mGUIRunner* runner); void mPSP2Teardown(struct mGUIRunner* runner); +void mPSP2MapKey(struct mInputMap* map, int pspKey, int key); void mPSP2LoadROM(struct mGUIRunner* runner); void mPSP2UnloadROM(struct mGUIRunner* runner);
@@ -44,7 +44,7 @@ enum FilterMode {
FM_NEAREST, FM_LINEAR, FM_MAX -}; +} filterMode = FM_NEAREST; #define SAMPLES 1024 #define GUI_SCALE 1.35@@ -60,7 +60,7 @@ static int32_t _readGyroZ(struct mRotationSource* source);
static void _drawStart(void); static void _drawEnd(void); -static uint32_t _pollInput(void); +static uint32_t _pollInput(const struct mInputMap*); static enum GUICursorState _pollCursor(unsigned* x, unsigned* y); static void _guiPrepare(void); static void _guiFinish(void);@@ -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 _incrementScreenMode(struct mGUIRunner* runner); static s8 WPAD_StickX(u8 chan, u8 right); static s8 WPAD_StickY(u8 chan, u8 right);@@ -361,10 +362,42 @@ .prepareForFrame = 0,
.drawFrame = _drawFrame, .paused = _gameUnloaded, .unpaused = _unpaused, + .incrementScreenMode = _incrementScreenMode, .pollGameInput = _pollGameInput }; mGUIInit(&runner, "wii"); + + _mapKey(&runner.params.keyMap, GCN1_INPUT, PAD_BUTTON_A, GUI_INPUT_SELECT); + _mapKey(&runner.params.keyMap, GCN1_INPUT, PAD_BUTTON_B, GUI_INPUT_BACK); + _mapKey(&runner.params.keyMap, GCN1_INPUT, PAD_TRIGGER_Z, GUI_INPUT_CANCEL); + _mapKey(&runner.params.keyMap, GCN1_INPUT, PAD_BUTTON_UP, GUI_INPUT_UP); + _mapKey(&runner.params.keyMap, GCN1_INPUT, PAD_BUTTON_DOWN, GUI_INPUT_DOWN); + _mapKey(&runner.params.keyMap, GCN1_INPUT, PAD_BUTTON_LEFT, GUI_INPUT_LEFT); + _mapKey(&runner.params.keyMap, GCN1_INPUT, PAD_BUTTON_RIGHT, GUI_INPUT_RIGHT); + + _mapKey(&runner.params.keyMap, WIIMOTE_INPUT, WPAD_BUTTON_2, GUI_INPUT_SELECT); + _mapKey(&runner.params.keyMap, WIIMOTE_INPUT, WPAD_BUTTON_1, GUI_INPUT_BACK); + _mapKey(&runner.params.keyMap, WIIMOTE_INPUT, WPAD_BUTTON_HOME, GUI_INPUT_CANCEL); + _mapKey(&runner.params.keyMap, WIIMOTE_INPUT, WPAD_BUTTON_RIGHT, GUI_INPUT_UP); + _mapKey(&runner.params.keyMap, WIIMOTE_INPUT, WPAD_BUTTON_LEFT, GUI_INPUT_DOWN); + _mapKey(&runner.params.keyMap, WIIMOTE_INPUT, WPAD_BUTTON_UP, GUI_INPUT_LEFT); + _mapKey(&runner.params.keyMap, WIIMOTE_INPUT, WPAD_BUTTON_DOWN, GUI_INPUT_RIGHT); + + _mapKey(&runner.params.keyMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_A, GUI_INPUT_SELECT); + _mapKey(&runner.params.keyMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_Y, GUI_INPUT_SELECT); + _mapKey(&runner.params.keyMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_B, GUI_INPUT_BACK); + _mapKey(&runner.params.keyMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_X, GUI_INPUT_BACK); + _mapKey(&runner.params.keyMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_HOME, GUI_INPUT_CANCEL); + _mapKey(&runner.params.keyMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_UP, GUI_INPUT_UP); + _mapKey(&runner.params.keyMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_DOWN, GUI_INPUT_DOWN); + _mapKey(&runner.params.keyMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_LEFT, GUI_INPUT_LEFT); + _mapKey(&runner.params.keyMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_RIGHT, GUI_INPUT_RIGHT); + if (argc > 1) { + size_t i; + for (i = 0; runner.keySources[i].id; ++i) { + mInputMapLoad(&runner.params.keyMap, runner.keySources[i].id, mCoreConfigGetInput(&runner.config)); + } mGUIRun(&runner, argv[1]); } else { mGUIRunloop(&runner);@@ -421,7 +454,7 @@ ++referenceRetraceCount;
_CPU_ISR_Restore(level); } -static uint32_t _pollInput(void) { +static uint32_t _pollInput(const struct mInputMap* map) { PAD_ScanPads(); u16 padkeys = PAD_ButtonsHeld(0);@@ -431,6 +464,12 @@ u32 ext = 0;
WPAD_Probe(0, &ext); int keys = 0; + keys |= mInputMapKeyBits(map, GCN1_INPUT, padkeys, 0); + keys |= mInputMapKeyBits(map, GCN2_INPUT, padkeys, 0); + keys |= mInputMapKeyBits(map, WIIMOTE_INPUT, wiiPad, 0); + if (ext == WPAD_EXP_CLASSIC) { + keys |= mInputMapKeyBits(map, CLASSIC_INPUT, wiiPad, 0); + } int x = PAD_StickX(0); int y = PAD_StickY(0); int w_x = WPAD_StickX(0, 0);@@ -447,34 +486,6 @@ }
if (y > 0x20 || w_y > 0x20) { keys |= 1 << GUI_INPUT_UP; } - if ((padkeys & PAD_BUTTON_A) || (wiiPad & WPAD_BUTTON_2) || - ((ext == WPAD_EXP_CLASSIC) && (wiiPad & (WPAD_CLASSIC_BUTTON_A | WPAD_CLASSIC_BUTTON_Y)))) { - keys |= 1 << GUI_INPUT_SELECT; - } - if ((padkeys & PAD_BUTTON_B) || (wiiPad & WPAD_BUTTON_1) || (wiiPad & WPAD_BUTTON_B) || - ((ext == WPAD_EXP_CLASSIC) && (wiiPad & (WPAD_CLASSIC_BUTTON_B | WPAD_CLASSIC_BUTTON_X)))) { - keys |= 1 << GUI_INPUT_BACK; - } - if ((padkeys & PAD_TRIGGER_Z) || (wiiPad & WPAD_BUTTON_HOME) || - ((ext == WPAD_EXP_CLASSIC) && (wiiPad & (WPAD_CLASSIC_BUTTON_HOME)))) { - keys |= 1 << GUI_INPUT_CANCEL; - } - if ((padkeys & PAD_BUTTON_LEFT)|| (wiiPad & WPAD_BUTTON_UP) || - ((ext == WPAD_EXP_CLASSIC) && (wiiPad & WPAD_CLASSIC_BUTTON_LEFT))) { - keys |= 1 << GUI_INPUT_LEFT; - } - if ((padkeys & PAD_BUTTON_RIGHT) || (wiiPad & WPAD_BUTTON_DOWN) || - ((ext == WPAD_EXP_CLASSIC) && (wiiPad & WPAD_CLASSIC_BUTTON_RIGHT))) { - keys |= 1 << GUI_INPUT_RIGHT; - } - if ((padkeys & PAD_BUTTON_UP) || (wiiPad & WPAD_BUTTON_RIGHT) || - ((ext == WPAD_EXP_CLASSIC) && (wiiPad & WPAD_CLASSIC_BUTTON_UP))) { - keys |= 1 << GUI_INPUT_UP; - } - if ((padkeys & PAD_BUTTON_DOWN) || (wiiPad & WPAD_BUTTON_LEFT) || - ((ext == WPAD_EXP_CLASSIC) && (wiiPad & WPAD_CLASSIC_BUTTON_DOWN))) { - keys |= 1 << GUI_INPUT_DOWN; - } return keys; }@@ -603,10 +614,11 @@ referenceRetraceCount = retraceCount;
_CPU_ISR_Restore(level); unsigned mode; - if (mCoreConfigGetUIntValue(&runner->core->config, "screenMode", &mode) && mode < SM_MAX) { + if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode < SM_MAX) { screenMode = mode; } - if (mCoreConfigGetUIntValue(&runner->core->config, "filter", &mode) && mode < FM_MAX) { + if (mCoreConfigGetUIntValue(&runner->config, "filter", &mode) && mode < FM_MAX) { + filterMode = mode; switch (mode) { case FM_NEAREST: default:@@ -721,6 +733,30 @@ }
} return keys; +} + +void _incrementScreenMode(struct mGUIRunner* runner) { + UNUSED(runner); + int mode = screenMode | (filterMode << 1); + ++mode; + screenMode = mode % SM_MAX; + filterMode = (mode >> 1) % FM_MAX; + mCoreConfigSetUIntValue(&runner->config, "screenMode", screenMode); + mCoreConfigSetUIntValue(&runner->config, "filter", filterMode); + if (screenMode == SM_PA) { + _reproj(corew * scaleFactor, coreh * scaleFactor); + } else { + _reproj2(corew, coreh); + } + switch (filterMode) { + case FM_NEAREST: + default: + GX_InitTexObjFilterMode(&tex, GX_NEAR, GX_NEAR); + break; + case FM_LINEAR: + GX_InitTexObjFilterMode(&tex, GX_LINEAR, GX_LINEAR); + break; + } } void _setRumble(struct mRumble* rumble, int enable) {
@@ -11,7 +11,7 @@ strncpy(params->currentPath, params->basePath, PATH_MAX);
} void GUIPollInput(struct GUIParams* params, uint32_t* newInputOut, uint32_t* heldInput) { - uint32_t input = params->pollInput(); + uint32_t input = params->pollInput(¶ms->keyMap); uint32_t newInput = 0; for (int i = 0; i < GUI_INPUT_MAX; ++i) { if (input & (1 << i)) {
@@ -8,6 +8,7 @@ #define GUI_H
#include "util/common.h" +#include "core/input.h" #include "util/vector.h" struct GUIFont;@@ -23,7 +24,7 @@ GUI_INPUT_DOWN,
GUI_INPUT_LEFT, GUI_INPUT_RIGHT, - GUI_INPUT_USER_START = 0x10, + GUI_INPUT_USER_START = 0x8, GUI_INPUT_MAX = 0x20 };@@ -58,13 +59,14 @@ const char* basePath;
void (*drawStart)(void); void (*drawEnd)(void); - uint32_t (*pollInput)(void); + uint32_t (*pollInput)(const struct mInputMap*); enum GUICursorState (*pollCursor)(unsigned* x, unsigned* y); int (*batteryState)(void); void (*guiPrepare)(void); void (*guiFinish)(void); // State + struct mInputMap keyMap; int inputHistory[GUI_INPUT_MAX]; enum GUICursorState cursorState; int cx, cy;@@ -74,7 +76,7 @@ char currentPath[PATH_MAX];
size_t fileIndex; }; -#define GUI_PARAMS_TRAIL {}, GUI_CURSOR_NOT_PRESENT, 0, 0, "", 0 +#define GUI_PARAMS_TRAIL {0}, {}, GUI_CURSOR_NOT_PRESENT, 0, 0, "", 0 void GUIInit(struct GUIParams* params); void GUIPollInput(struct GUIParams* params, uint32_t* newInput, uint32_t* heldInput);