GUI: Add UI control remapping

This commit is contained in:
Jeffrey Pfau 2016-08-15 22:15:45 -07:00
parent 3a3062ee50
commit c191ec88b8
13 changed files with 219 additions and 136 deletions

View File

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

View File

@ -272,6 +272,9 @@ static bool _loadAll(struct mInputMap* map, uint32_t type, const char* sectionNa
static void _saveAll(const struct mInputMap* map, uint32_t type, const char* sectionName, struct Configuration* config) { static void _saveAll(const struct mInputMap* map, uint32_t type, const char* sectionName, struct Configuration* config) {
size_t i; size_t i;
for (i = 0; i < map->info->nKeys; ++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]); _saveKey(map, type, sectionName, config, i, map->info->keyId[i]);
_clearAxis(sectionName, config, map->info->keyId[i]); _clearAxis(sectionName, config, map->info->keyId[i]);
} }
@ -338,6 +341,9 @@ int mInputMapKeyBits(const struct mInputMap* map, uint32_t type, uint32_t bits,
void mInputBindKey(struct mInputMap* map, uint32_t type, int key, int input) { void mInputBindKey(struct mInputMap* map, uint32_t type, int key, int input) {
struct mInputMapImpl* impl = _guaranteeMap(map, type); struct mInputMapImpl* impl = _guaranteeMap(map, type);
if (input < 0 || (size_t) input >= map->info->nKeys) {
return;
}
mInputUnbindKey(map, type, input); mInputUnbindKey(map, type, input);
impl->map[input] = key; impl->map[input] = key;
} }

View File

@ -6,7 +6,6 @@
#include "gui-config.h" #include "gui-config.h"
#include "core/config.h" #include "core/config.h"
#include "core/core.h"
#include "feature/gui/gui-runner.h" #include "feature/gui/gui-runner.h"
#include "feature/gui/remap.h" #include "feature/gui/remap.h"
#include "gba/gba.h" #include "gba/gba.h"
@ -96,7 +95,7 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t
if (!item->validStates || !item->data) { if (!item->validStates || !item->data) {
continue; continue;
} }
mCoreConfigGetUIntValue(&runner->core->config, item->data, &item->state); mCoreConfigGetUIntValue(&runner->config, item->data, &item->state);
} }
while (true) { while (true) {
@ -106,16 +105,16 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t
} }
if (!strcmp(item->data, "*SAVE")) { if (!strcmp(item->data, "*SAVE")) {
if (biosPath[0]) { if (biosPath[0]) {
mCoreConfigSetValue(&runner->core->config, "bios", biosPath); mCoreConfigSetValue(&runner->config, "bios", biosPath);
} }
for (i = 0; i < GUIMenuItemListSize(&menu.items); ++i) { for (i = 0; i < GUIMenuItemListSize(&menu.items); ++i) {
item = GUIMenuItemListGetPointer(&menu.items, i); item = GUIMenuItemListGetPointer(&menu.items, i);
if (!item->validStates || !item->data) { if (!item->validStates || !item->data) {
continue; continue;
} }
mCoreConfigSetUIntValue(&runner->core->config, item->data, item->state); mCoreConfigSetUIntValue(&runner->config, item->data, item->state);
} }
mCoreConfigSave(&runner->core->config); mCoreConfigSave(&runner->config);
break; break;
} }
if (!strcmp(item->data, "*REMAP")) { if (!strcmp(item->data, "*REMAP")) {

View File

@ -51,6 +51,23 @@ enum {
RUNNER_STATE_9 = 0x90000, 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 void _log(struct mLogger*, int category, enum mLogLevel level, const char* format, va_list args);
static struct mGUILogger { static struct mGUILogger {
@ -140,6 +157,13 @@ void mGUIInit(struct mGUIRunner* runner, const char* port) {
runner->totalDelta = 0; runner->totalDelta = 0;
CircleBufferInit(&runner->fpsBuffer, FPS_BUFFER_SIZE * sizeof(uint32_t)); 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]; char path[PATH_MAX];
mCoreConfigDirectory(path, PATH_MAX); mCoreConfigDirectory(path, PATH_MAX);
strncat(path, PATH_SEP "log", PATH_MAX - strlen(path)); strncat(path, PATH_SEP "log", PATH_MAX - strlen(path));
@ -152,6 +176,8 @@ void mGUIDeinit(struct mGUIRunner* runner) {
runner->teardown(runner); runner->teardown(runner);
} }
CircleBufferDeinit(&runner->fpsBuffer); CircleBufferDeinit(&runner->fpsBuffer);
mInputMapDeinit(&runner->params.keyMap);
mCoreConfigDeinit(&runner->config);
if (logger.vf) { if (logger.vf) {
logger.vf->close(logger.vf); logger.vf->close(logger.vf);
logger.vf = NULL; logger.vf = NULL;
@ -251,7 +277,6 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) {
mLOG(GUI_RUNNER, INFO, "Found core"); mLOG(GUI_RUNNER, INFO, "Found core");
runner->core->init(runner->core); runner->core->init(runner->core);
mInputMapInit(&runner->core->inputMap, &GBAInputInfo); mInputMapInit(&runner->core->inputMap, &GBAInputInfo);
mCoreInitConfig(runner->core, runner->port);
found = mCoreLoadFile(runner->core, path); found = mCoreLoadFile(runner->core, path);
if (!found) { if (!found) {
mLOG(GUI_RUNNER, WARN, "Failed to load %s!", path); mLOG(GUI_RUNNER, WARN, "Failed to load %s!", path);
@ -278,18 +303,8 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) {
if (runner->core->platform(runner->core) == PLATFORM_GBA) { if (runner->core->platform(runner->core) == PLATFORM_GBA) {
((struct GBA*) runner->core->board)->luminanceSource = &runner->luminanceSource.d; ((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..."); mLOG(GUI_RUNNER, DEBUG, "Loading config...");
mCoreLoadConfig(runner->core); mCoreLoadForeignConfig(runner->core, &runner->config);
logger.logLevel = runner->core->opts.logLevel; logger.logLevel = runner->core->opts.logLevel;
mLOG(GUI_RUNNER, DEBUG, "Loading save..."); mLOG(GUI_RUNNER, DEBUG, "Loading save...");
@ -298,6 +313,13 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) {
mLOG(GUI_RUNNER, DEBUG, "Setting up runner..."); mLOG(GUI_RUNNER, DEBUG, "Setting up runner...");
runner->setup(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..."); mLOG(GUI_RUNNER, DEBUG, "Reseting...");
runner->core->reset(runner->core); runner->core->reset(runner->core);
mLOG(GUI_RUNNER, DEBUG, "Reset!"); mLOG(GUI_RUNNER, DEBUG, "Reset!");
@ -347,7 +369,7 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) {
runner->core->runFrame(runner->core); runner->core->runFrame(runner->core);
if (runner->drawFrame) { if (runner->drawFrame) {
int drawFps = false; int drawFps = false;
mCoreConfigGetIntValue(&runner->core->config, "fpsCounter", &drawFps); mCoreConfigGetIntValue(&runner->config, "fpsCounter", &drawFps);
runner->params.drawStart(); runner->params.drawStart();
runner->drawFrame(runner, false); runner->drawFrame(runner, false);
@ -413,7 +435,7 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) {
break; break;
case RUNNER_CONFIG: case RUNNER_CONFIG:
mGUIShowConfig(runner, runner->configExtra, runner->nConfigExtra); mGUIShowConfig(runner, runner->configExtra, runner->nConfigExtra);
mCoreLoadConfig(runner->core); mCoreLoadForeignConfig(runner->core, &runner->config);
break; break;
case RUNNER_CONTINUE: case RUNNER_CONTINUE:
break; break;
@ -445,16 +467,18 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) {
mappedMemoryFree(drawState.screenshot, w * h * 4); mappedMemoryFree(drawState.screenshot, w * h * 4);
} }
if (runner->core->config.port) { if (runner->config.port) {
mLOG(GUI_RUNNER, DEBUG, "Saving key sources..."); mLOG(GUI_RUNNER, DEBUG, "Saving key sources...");
if (runner->keySources) { if (runner->keySources) {
size_t i; size_t i;
for (i = 0; runner->keySources[i].id; ++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..."); mLOG(GUI_RUNNER, DEBUG, "Deinitializing core...");
runner->core->deinit(runner->core); runner->core->deinit(runner->core);
@ -465,6 +489,13 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) {
} }
void mGUIRunloop(struct mGUIRunner* runner) { 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) { while (true) {
char path[PATH_MAX]; char path[PATH_MAX];
if (!GUISelectFile(&runner->params, path, sizeof(path), 0)) { if (!GUISelectFile(&runner->params, path, sizeof(path), 0)) {

View File

@ -8,6 +8,7 @@
#include "util/common.h" #include "util/common.h"
#include "core/config.h"
#include "feature/gui/remap.h" #include "feature/gui/remap.h"
#include "gba/hardware.h" #include "gba/hardware.h"
#include "util/circle-buffer.h" #include "util/circle-buffer.h"
@ -40,6 +41,8 @@ struct mGUIRunner {
struct mGUIBackground background; struct mGUIBackground background;
struct mGUIRunnerLux luminanceSource; struct mGUIRunnerLux luminanceSource;
struct mInputMap guiKeys;
struct mCoreConfig config;
struct GUIMenuItem* configExtra; struct GUIMenuItem* configExtra;
size_t nConfigExtra; size_t nConfigExtra;

View File

@ -5,7 +5,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "remap.h" #include "remap.h"
#include "gba/input.h"
#include "util/gui.h" #include "util/gui.h"
#include "util/gui/menu.h" #include "util/gui/menu.h"
@ -20,19 +19,40 @@ void mGUIRemapKeys(struct GUIParams* params, struct mInputMap* map, const struct
memcpy(&keyNames[1], keys->keyNames, keys->nKeys * sizeof(keyNames[0])); memcpy(&keyNames[1], keys->keyNames, keys->nKeys * sizeof(keyNames[0]));
keyNames[0] = "Unmapped"; keyNames[0] = "Unmapped";
size_t i; 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) { *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
.title = GBAInputInfo.keyId[i], .title = map->info->keyId[i],
.data = (void*) (GUI_INPUT_MAX + i), .data = (void*) (GUI_INPUT_MAX + i + 1),
.submenu = 0, .submenu = 0,
.state = mInputQueryBinding(map, keys->id, i) + 1, .state = mInputQueryBinding(map, keys->id, i) + 1,
.validStates = keyNames, .validStates = keyNames,
.nStates = keys->nKeys + 1 .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(&params->keyMap, keys->id, i) + 1,
.validStates = keyNames,
.nStates = keys->nKeys + 1
};
}
*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
.title = "Save", .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) { *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
.title = "Cancel", .title = "Cancel",
@ -46,11 +66,16 @@ void mGUIRemapKeys(struct GUIParams* params, struct mInputMap* map, const struct
if (reason != GUI_MENU_EXIT_ACCEPT || !item->data) { if (reason != GUI_MENU_EXIT_ACCEPT || !item->data) {
break; 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) { for (i = 0; i < GUIMenuItemListSize(&menu.items); ++i) {
item = GUIMenuItemListGetPointer(&menu.items, i); item = GUIMenuItemListGetPointer(&menu.items, i);
if (i < GBA_KEY_MAX) { if ((uint32_t) item->data < 1) {
mInputBindKey(map, keys->id, item->state - 1, i); continue;
}
if ((uint32_t) item->data < GUI_INPUT_MAX + 1) {
mInputBindKey(&params->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; break;

View File

@ -218,8 +218,8 @@ static void _setup(struct mGUIRunner* runner) {
bool isNew3DS = false; bool isNew3DS = false;
APT_CheckNew3DS(&isNew3DS); APT_CheckNew3DS(&isNew3DS);
if (isNew3DS && !envIsHomebrew()) { if (isNew3DS && !envIsHomebrew()) {
mCoreConfigSetDefaultIntValue(&runner->core->config, "threadedVideo", 1); mCoreConfigSetDefaultIntValue(&runner->config, "threadedVideo", 1);
mCoreLoadConfig(runner->core); mCoreLoadForeignConfig(runner->core, &runner->config);
} }
runner->core->setRotation(runner->core, &rotation.d); runner->core->setRotation(runner->core, &rotation.d);
@ -242,7 +242,7 @@ static void _setup(struct mGUIRunner* runner) {
runner->core->setVideoBuffer(runner->core, outputBuffer, 256); runner->core->setVideoBuffer(runner->core, outputBuffer, 256);
unsigned mode; unsigned mode;
if (mCoreConfigGetUIntValue(&runner->core->config, "screenMode", &mode) && mode < SM_MAX) { if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode < SM_MAX) {
screenMode = mode; screenMode = mode;
} }
@ -288,7 +288,7 @@ static void _gameLoaded(struct mGUIRunner* runner) {
memset(audioLeft, 0, AUDIO_SAMPLE_BUFFER * 2 * sizeof(int16_t)); memset(audioLeft, 0, AUDIO_SAMPLE_BUFFER * 2 * sizeof(int16_t));
} }
unsigned mode; unsigned mode;
if (mCoreConfigGetUIntValue(&runner->core->config, "screenMode", &mode) && mode != screenMode) { if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode != screenMode) {
screenMode = mode; screenMode = mode;
} }
} }
@ -454,47 +454,16 @@ static uint16_t _pollGameInput(struct mGUIRunner* runner) {
static void _incrementScreenMode(struct mGUIRunner* runner) { static void _incrementScreenMode(struct mGUIRunner* runner) {
UNUSED(runner); UNUSED(runner);
screenMode = (screenMode + 1) % SM_MAX; screenMode = (screenMode + 1) % SM_MAX;
mCoreConfigSetUIntValue(&runner->core->config, "screenMode", screenMode); mCoreConfigSetUIntValue(&runner->config, "screenMode", screenMode);
C3D_RenderBufClear(&bottomScreen); C3D_RenderBufClear(&bottomScreen);
C3D_RenderBufClear(&topScreen); C3D_RenderBufClear(&topScreen);
} }
static uint32_t _pollInput(void) { static uint32_t _pollInput(const struct mInputMap* map) {
hidScanInput(); hidScanInput();
uint32_t keys = 0;
int activeKeys = hidKeysHeld(); int activeKeys = hidKeysHeld();
if (activeKeys & KEY_X) { return mInputMapKeyBits(map, _3DS_INPUT, activeKeys, 0);
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;
} }
static enum GUICursorState _pollCursor(unsigned* x, unsigned* y) { static enum GUICursorState _pollCursor(unsigned* x, unsigned* y) {
@ -724,6 +693,18 @@ int main() {
}; };
mGUIInit(&runner, "3ds"); 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); mGUIRunloop(&runner);
mGUIDeinit(&runner); mGUIDeinit(&runner);

View File

@ -38,22 +38,10 @@ static void _drawEnd(void) {
vita2d_swap_buffers(); vita2d_swap_buffers();
} }
static uint32_t _pollInput(void) { static uint32_t _pollInput(const struct mInputMap* map) {
SceCtrlData pad; SceCtrlData pad;
sceCtrlPeekBufferPositive(0, &pad, 1); sceCtrlPeekBufferPositive(0, &pad, 1);
int input = 0; int input = mInputMapKeyBits(map, PSP2_INPUT, pad.buttons, 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;
}
if (pad.buttons & SCE_CTRL_UP || pad.ly < 64) { if (pad.buttons & SCE_CTRL_UP || pad.ly < 64) {
input |= 1 << GUI_INPUT_UP; input |= 1 << GUI_INPUT_UP;
@ -165,6 +153,16 @@ int main() {
sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG_WIDE); sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG_WIDE);
mGUIInit(&runner, "psvita"); 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); mGUIRunloop(&runner);
vita2d_fini(); vita2d_fini();

View File

@ -73,7 +73,7 @@ static struct mPSP2AudioContext {
bool running; bool running;
} audioContext; } 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); mInputBindKey(map, PSP2_INPUT, __builtin_ctz(pspKey), key);
} }
@ -144,7 +144,7 @@ uint16_t mPSP2PollInput(struct mGUIRunner* runner) {
sceCtrlPeekBufferPositive(0, &pad, 1); sceCtrlPeekBufferPositive(0, &pad, 1);
int activeKeys = mInputMapKeyBits(&runner->core->inputMap, PSP2_INPUT, pad.buttons, 0); 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) { if (angles != GBA_KEY_NONE) {
activeKeys |= 1 << angles; activeKeys |= 1 << angles;
} }
@ -164,20 +164,20 @@ uint16_t mPSP2PollInput(struct mGUIRunner* runner) {
} }
void mPSP2Setup(struct mGUIRunner* runner) { void mPSP2Setup(struct mGUIRunner* runner) {
mCoreConfigSetDefaultIntValue(&runner->core->config, "threadedVideo", 1); mCoreConfigSetDefaultIntValue(&runner->config, "threadedVideo", 1);
mCoreLoadConfig(runner->core); mCoreLoadForeignConfig(runner->core, &runner->config);
scePowerSetArmClockFrequency(80); scePowerSetArmClockFrequency(80);
_mapVitaKey(&runner->core->inputMap, SCE_CTRL_CROSS, GBA_KEY_A); mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_CROSS, GBA_KEY_A);
_mapVitaKey(&runner->core->inputMap, SCE_CTRL_CIRCLE, GBA_KEY_B); mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_CIRCLE, GBA_KEY_B);
_mapVitaKey(&runner->core->inputMap, SCE_CTRL_START, GBA_KEY_START); mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_START, GBA_KEY_START);
_mapVitaKey(&runner->core->inputMap, SCE_CTRL_SELECT, GBA_KEY_SELECT); mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_SELECT, GBA_KEY_SELECT);
_mapVitaKey(&runner->core->inputMap, SCE_CTRL_UP, GBA_KEY_UP); mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_UP, GBA_KEY_UP);
_mapVitaKey(&runner->core->inputMap, SCE_CTRL_DOWN, GBA_KEY_DOWN); mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_DOWN, GBA_KEY_DOWN);
_mapVitaKey(&runner->core->inputMap, SCE_CTRL_LEFT, GBA_KEY_LEFT); mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_LEFT, GBA_KEY_LEFT);
_mapVitaKey(&runner->core->inputMap, SCE_CTRL_RIGHT, GBA_KEY_RIGHT); mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_RIGHT, GBA_KEY_RIGHT);
_mapVitaKey(&runner->core->inputMap, SCE_CTRL_LTRIGGER, GBA_KEY_L); mPSP2MapKey(&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_RTRIGGER, GBA_KEY_R);
struct mInputAxis desc = { GBA_KEY_DOWN, GBA_KEY_UP, 192, 64 }; struct mInputAxis desc = { GBA_KEY_DOWN, GBA_KEY_UP, 192, 64 };
mInputBindAxis(&runner->core->inputMap, PSP2_INPUT, 0, &desc); mInputBindAxis(&runner->core->inputMap, PSP2_INPUT, 0, &desc);
@ -203,7 +203,7 @@ void mPSP2Setup(struct mGUIRunner* runner) {
backdrop = vita2d_load_PNG_buffer(_binary_backdrop_png_start); backdrop = vita2d_load_PNG_buffer(_binary_backdrop_png_start);
unsigned mode; unsigned mode;
if (mCoreConfigGetUIntValue(&runner->core->config, "screenMode", &mode) && mode < SM_MAX) { if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode < SM_MAX) {
screenMode = mode; screenMode = mode;
} }
} }
@ -286,7 +286,7 @@ void mPSP2Paused(struct mGUIRunner* runner) {
void mPSP2Unpaused(struct mGUIRunner* runner) { void mPSP2Unpaused(struct mGUIRunner* runner) {
unsigned mode; unsigned mode;
if (mCoreConfigGetUIntValue(&runner->core->config, "screenMode", &mode) && mode != screenMode) { if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode != screenMode) {
screenMode = mode; screenMode = mode;
} }
} }
@ -377,7 +377,7 @@ void mPSP2DrawScreenshot(struct mGUIRunner* runner, const uint32_t* pixels, unsi
void mPSP2IncrementScreenMode(struct mGUIRunner* runner) { void mPSP2IncrementScreenMode(struct mGUIRunner* runner) {
screenMode = (screenMode + 1) % SM_MAX; 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) { __attribute__((noreturn, weak)) void __assert_func(const char* file, int line, const char* func, const char* expr) {

View File

@ -12,6 +12,7 @@
struct mGUIRunner; struct mGUIRunner;
void mPSP2Setup(struct mGUIRunner* runner); void mPSP2Setup(struct mGUIRunner* runner);
void mPSP2Teardown(struct mGUIRunner* runner); void mPSP2Teardown(struct mGUIRunner* runner);
void mPSP2MapKey(struct mInputMap* map, int pspKey, int key);
void mPSP2LoadROM(struct mGUIRunner* runner); void mPSP2LoadROM(struct mGUIRunner* runner);
void mPSP2UnloadROM(struct mGUIRunner* runner); void mPSP2UnloadROM(struct mGUIRunner* runner);

View File

@ -44,7 +44,7 @@ enum FilterMode {
FM_NEAREST, FM_NEAREST,
FM_LINEAR, FM_LINEAR,
FM_MAX FM_MAX
}; } filterMode = FM_NEAREST;
#define SAMPLES 1024 #define SAMPLES 1024
#define GUI_SCALE 1.35 #define GUI_SCALE 1.35
@ -60,7 +60,7 @@ static int32_t _readGyroZ(struct mRotationSource* source);
static void _drawStart(void); static void _drawStart(void);
static void _drawEnd(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 enum GUICursorState _pollCursor(unsigned* x, unsigned* y);
static void _guiPrepare(void); static void _guiPrepare(void);
static void _guiFinish(void); static void _guiFinish(void);
@ -71,6 +71,7 @@ static void _gameUnloaded(struct mGUIRunner* runner);
static void _unpaused(struct mGUIRunner* runner); static void _unpaused(struct mGUIRunner* runner);
static void _drawFrame(struct mGUIRunner* runner, bool faded); static void _drawFrame(struct mGUIRunner* runner, bool faded);
static uint16_t _pollGameInput(struct mGUIRunner* runner); static uint16_t _pollGameInput(struct mGUIRunner* runner);
static void _incrementScreenMode(struct mGUIRunner* runner);
static s8 WPAD_StickX(u8 chan, u8 right); static s8 WPAD_StickX(u8 chan, u8 right);
static s8 WPAD_StickY(u8 chan, u8 right); static s8 WPAD_StickY(u8 chan, u8 right);
@ -361,10 +362,42 @@ int main(int argc, char* argv[]) {
.drawFrame = _drawFrame, .drawFrame = _drawFrame,
.paused = _gameUnloaded, .paused = _gameUnloaded,
.unpaused = _unpaused, .unpaused = _unpaused,
.incrementScreenMode = _incrementScreenMode,
.pollGameInput = _pollGameInput .pollGameInput = _pollGameInput
}; };
mGUIInit(&runner, "wii"); 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) { 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]); mGUIRun(&runner, argv[1]);
} else { } else {
mGUIRunloop(&runner); mGUIRunloop(&runner);
@ -421,7 +454,7 @@ static void _drawEnd(void) {
_CPU_ISR_Restore(level); _CPU_ISR_Restore(level);
} }
static uint32_t _pollInput(void) { static uint32_t _pollInput(const struct mInputMap* map) {
PAD_ScanPads(); PAD_ScanPads();
u16 padkeys = PAD_ButtonsHeld(0); u16 padkeys = PAD_ButtonsHeld(0);
@ -431,6 +464,12 @@ static uint32_t _pollInput(void) {
WPAD_Probe(0, &ext); WPAD_Probe(0, &ext);
int keys = 0; 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 x = PAD_StickX(0);
int y = PAD_StickY(0); int y = PAD_StickY(0);
int w_x = WPAD_StickX(0, 0); int w_x = WPAD_StickX(0, 0);
@ -447,34 +486,6 @@ static uint32_t _pollInput(void) {
if (y > 0x20 || w_y > 0x20) { if (y > 0x20 || w_y > 0x20) {
keys |= 1 << GUI_INPUT_UP; 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; return keys;
} }
@ -603,10 +614,11 @@ void _unpaused(struct mGUIRunner* runner) {
_CPU_ISR_Restore(level); _CPU_ISR_Restore(level);
unsigned mode; unsigned mode;
if (mCoreConfigGetUIntValue(&runner->core->config, "screenMode", &mode) && mode < SM_MAX) { if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode < SM_MAX) {
screenMode = mode; 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) { switch (mode) {
case FM_NEAREST: case FM_NEAREST:
default: default:
@ -723,6 +735,30 @@ uint16_t _pollGameInput(struct mGUIRunner* runner) {
return keys; 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) { void _setRumble(struct mRumble* rumble, int enable) {
UNUSED(rumble); UNUSED(rumble);
WPAD_Rumble(0, enable); WPAD_Rumble(0, enable);

View File

@ -11,7 +11,7 @@ void GUIInit(struct GUIParams* params) {
} }
void GUIPollInput(struct GUIParams* params, uint32_t* newInputOut, uint32_t* heldInput) { void GUIPollInput(struct GUIParams* params, uint32_t* newInputOut, uint32_t* heldInput) {
uint32_t input = params->pollInput(); uint32_t input = params->pollInput(&params->keyMap);
uint32_t newInput = 0; uint32_t newInput = 0;
for (int i = 0; i < GUI_INPUT_MAX; ++i) { for (int i = 0; i < GUI_INPUT_MAX; ++i) {
if (input & (1 << i)) { if (input & (1 << i)) {

View File

@ -8,6 +8,7 @@
#include "util/common.h" #include "util/common.h"
#include "core/input.h"
#include "util/vector.h" #include "util/vector.h"
struct GUIFont; struct GUIFont;
@ -23,7 +24,7 @@ enum GUIInput {
GUI_INPUT_LEFT, GUI_INPUT_LEFT,
GUI_INPUT_RIGHT, GUI_INPUT_RIGHT,
GUI_INPUT_USER_START = 0x10, GUI_INPUT_USER_START = 0x8,
GUI_INPUT_MAX = 0x20 GUI_INPUT_MAX = 0x20
}; };
@ -58,13 +59,14 @@ struct GUIParams {
void (*drawStart)(void); void (*drawStart)(void);
void (*drawEnd)(void); void (*drawEnd)(void);
uint32_t (*pollInput)(void); uint32_t (*pollInput)(const struct mInputMap*);
enum GUICursorState (*pollCursor)(unsigned* x, unsigned* y); enum GUICursorState (*pollCursor)(unsigned* x, unsigned* y);
int (*batteryState)(void); int (*batteryState)(void);
void (*guiPrepare)(void); void (*guiPrepare)(void);
void (*guiFinish)(void); void (*guiFinish)(void);
// State // State
struct mInputMap keyMap;
int inputHistory[GUI_INPUT_MAX]; int inputHistory[GUI_INPUT_MAX];
enum GUICursorState cursorState; enum GUICursorState cursorState;
int cx, cy; int cx, cy;
@ -74,7 +76,7 @@ struct GUIParams {
size_t fileIndex; 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 GUIInit(struct GUIParams* params);
void GUIPollInput(struct GUIParams* params, uint32_t* newInput, uint32_t* heldInput); void GUIPollInput(struct GUIParams* params, uint32_t* newInput, uint32_t* heldInput);