Core: Refactor GBAInput into mInput

This commit is contained in:
Jeffrey Pfau 2016-01-29 22:32:12 -08:00
parent bc1a094bea
commit 59f78a05e4
22 changed files with 770 additions and 769 deletions

513
src/core/input.c Normal file
View File

@ -0,0 +1,513 @@
/* Copyright (c) 2013-2016 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* 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 "input.h"
#include "util/configuration.h"
#include "util/table.h"
#include <inttypes.h>
#define SECTION_NAME_MAX 128
#define KEY_NAME_MAX 32
#define KEY_VALUE_MAX 16
#define AXIS_INFO_MAX 12
struct mInputMapImpl {
int* map;
uint32_t type;
struct Table axes;
};
struct mInputAxisSave {
struct Configuration* config;
const char* sectionName;
const struct mInputPlatformInfo* info;
};
struct mInputAxisEnumerate {
void (*handler)(int axis, const struct mInputAxis* description, void* user);
void* user;
};
static void _makeSectionName(const char* platform, char* sectionName, size_t len, uint32_t type) {
snprintf(sectionName, len, "%s.input.%c%c%c%c", platform, type >> 24, type >> 16, type >> 8, type);
sectionName[len - 1] = '\0';
}
static bool _getIntValue(const struct Configuration* config, const char* section, const char* key, int* value) {
const char* strValue = ConfigurationGetValue(config, section, key);
if (!strValue) {
return false;
}
char* end;
long intValue = strtol(strValue, &end, 10);
if (*end) {
return false;
}
*value = intValue;
return true;
}
static struct mInputMapImpl* _lookupMap(struct mInputMap* map, uint32_t type) {
size_t m;
struct mInputMapImpl* impl = 0;
for (m = 0; m < map->numMaps; ++m) {
if (map->maps[m].type == type) {
impl = &map->maps[m];
break;
}
}
return impl;
}
static const struct mInputMapImpl* _lookupMapConst(const struct mInputMap* map, uint32_t type) {
size_t m;
const struct mInputMapImpl* impl = 0;
for (m = 0; m < map->numMaps; ++m) {
if (map->maps[m].type == type) {
impl = &map->maps[m];
break;
}
}
return impl;
}
static struct mInputMapImpl* _guaranteeMap(struct mInputMap* map, uint32_t type) {
struct mInputMapImpl* impl = 0;
if (map->numMaps == 0) {
map->maps = malloc(sizeof(*map->maps));
map->numMaps = 1;
impl = &map->maps[0];
impl->type = type;
impl->map = malloc(map->info->nKeys * sizeof(int));
size_t i;
for (i = 0; i < map->info->nKeys; ++i) {
impl->map[i] = -1;
}
TableInit(&impl->axes, 2, free);
} else {
impl = _lookupMap(map, type);
}
if (!impl) {
size_t m;
for (m = 0; m < map->numMaps; ++m) {
if (!map->maps[m].type) {
impl = &map->maps[m];
break;
}
}
if (impl) {
impl->type = type;
impl->map = malloc(map->info->nKeys * sizeof(int));
size_t i;
for (i = 0; i < map->info->nKeys; ++i) {
impl->map[i] = -1;
}
} else {
map->maps = realloc(map->maps, sizeof(*map->maps) * map->numMaps * 2);
for (m = map->numMaps * 2 - 1; m > map->numMaps; --m) {
map->maps[m].type = 0;
map->maps[m].map = 0;
}
map->numMaps *= 2;
impl = &map->maps[m];
impl->type = type;
impl->map = malloc(map->info->nKeys * sizeof(int));
size_t i;
for (i = 0; i < map->info->nKeys; ++i) {
impl->map[i] = -1;
}
}
TableInit(&impl->axes, 2, free);
}
return impl;
}
static void _loadKey(struct mInputMap* map, uint32_t type, const char* sectionName, const struct Configuration* config, int key, const char* keyName) {
char keyKey[KEY_NAME_MAX];
snprintf(keyKey, KEY_NAME_MAX, "key%s", keyName);
keyKey[KEY_NAME_MAX - 1] = '\0';
int value;
if (!_getIntValue(config, sectionName, keyKey, &value)) {
return;
}
mInputBindKey(map, type, value, key);
}
static void _loadAxis(struct mInputMap* map, uint32_t type, const char* sectionName, const struct Configuration* config, int direction, const char* axisName) {
char axisKey[KEY_NAME_MAX];
snprintf(axisKey, KEY_NAME_MAX, "axis%sValue", axisName);
axisKey[KEY_NAME_MAX - 1] = '\0';
int value;
if (!_getIntValue(config, sectionName, axisKey, &value)) {
return;
}
snprintf(axisKey, KEY_NAME_MAX, "axis%sAxis", axisName);
axisKey[KEY_NAME_MAX - 1] = '\0';
int axis;
const char* strValue = ConfigurationGetValue(config, sectionName, axisKey);
if (!strValue || !strValue[0]) {
return;
}
char* end;
axis = strtoul(&strValue[1], &end, 10);
if (*end) {
return;
}
const struct mInputAxis* description = mInputQueryAxis(map, type, axis);
struct mInputAxis realDescription = { -1, -1, 0, 0 };
if (description) {
realDescription = *description;
}
if (strValue[0] == '+') {
realDescription.deadHigh = value;
realDescription.highDirection = direction;
} else if (strValue[0] == '-') {
realDescription.deadLow = value;
realDescription.lowDirection = direction;
}
mInputBindAxis(map, type, axis, &realDescription);
}
static void _saveKey(const struct mInputMap* map, uint32_t type, const char* sectionName, struct Configuration* config, int key, const char* keyName) {
char keyKey[KEY_NAME_MAX];
snprintf(keyKey, KEY_NAME_MAX, "key%s", keyName);
keyKey[KEY_NAME_MAX - 1] = '\0';
int value = mInputQueryBinding(map, type, key);
char keyValue[KEY_VALUE_MAX];
snprintf(keyValue, KEY_VALUE_MAX, "%" PRIi32, value);
ConfigurationSetValue(config, sectionName, keyKey, keyValue);
}
static void _clearAxis(const char* sectionName, struct Configuration* config, const char* axisName) {
char axisKey[KEY_NAME_MAX];
snprintf(axisKey, KEY_NAME_MAX, "axis%sValue", axisName);
axisKey[KEY_NAME_MAX - 1] = '\0';
ConfigurationClearValue(config, sectionName, axisKey);
snprintf(axisKey, KEY_NAME_MAX, "axis%sAxis", axisName);
axisKey[KEY_NAME_MAX - 1] = '\0';
ConfigurationClearValue(config, sectionName, axisKey);
}
static void _saveAxis(uint32_t axis, void* dp, void* up) {
struct mInputAxisSave* user = up;
const struct mInputAxis* description = dp;
const char* sectionName = user->sectionName;
if (description->lowDirection != -1) {
const char* keyName = user->info->keyId[description->lowDirection];
char axisKey[KEY_NAME_MAX];
snprintf(axisKey, KEY_NAME_MAX, "axis%sValue", keyName);
axisKey[KEY_NAME_MAX - 1] = '\0';
ConfigurationSetIntValue(user->config, sectionName, axisKey, description->deadLow);
snprintf(axisKey, KEY_NAME_MAX, "axis%sAxis", keyName);
axisKey[KEY_NAME_MAX - 1] = '\0';
char axisInfo[AXIS_INFO_MAX];
snprintf(axisInfo, AXIS_INFO_MAX, "-%u", axis);
axisInfo[AXIS_INFO_MAX - 1] = '\0';
ConfigurationSetValue(user->config, sectionName, axisKey, axisInfo);
}
if (description->highDirection != -1) {
const char* keyName = user->info->keyId[description->lowDirection];
char axisKey[KEY_NAME_MAX];
snprintf(axisKey, KEY_NAME_MAX, "axis%sValue", keyName);
axisKey[KEY_NAME_MAX - 1] = '\0';
ConfigurationSetIntValue(user->config, sectionName, axisKey, description->deadHigh);
snprintf(axisKey, KEY_NAME_MAX, "axis%sAxis", keyName);
axisKey[KEY_NAME_MAX - 1] = '\0';
char axisInfo[AXIS_INFO_MAX];
snprintf(axisInfo, AXIS_INFO_MAX, "+%u", axis);
axisInfo[AXIS_INFO_MAX - 1] = '\0';
ConfigurationSetValue(user->config, sectionName, axisKey, axisInfo);
}
}
void _enumerateAxis(uint32_t axis, void* dp, void* ep) {
struct mInputAxisEnumerate* enumUser = ep;
const struct mInputAxis* description = dp;
enumUser->handler(axis, description, enumUser->user);
}
void _unbindAxis(uint32_t axis, void* dp, void* user) {
UNUSED(axis);
int* key = user;
struct mInputAxis* description = dp;
if (description->highDirection == *key) {
description->highDirection = -1;
}
if (description->lowDirection == *key) {
description->lowDirection = -1;
}
}
static bool _loadAll(struct mInputMap* map, uint32_t type, const char* sectionName, const struct Configuration* config) {
if (!ConfigurationHasSection(config, sectionName)) {
return false;
}
size_t i;
for (i = 0; i < map->info->nKeys; ++i) {
_loadKey(map, type, sectionName, config, i, map->info->keyId[i]);
_loadAxis(map, type, sectionName, config, i, map->info->keyId[i]);
}
return true;
}
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) {
_saveKey(map, type, sectionName, config, i, map->info->keyId[i]);
_clearAxis(sectionName, config, map->info->keyId[i]);
}
const struct mInputMapImpl* impl = _lookupMapConst(map, type);
if (!impl) {
return;
}
struct mInputAxisSave save = {
config,
sectionName,
map->info
};
TableEnumerate(&impl->axes, _saveAxis, &save);
}
void mInputMapInit(struct mInputMap* map, const struct mInputPlatformInfo* info) {
map->maps = 0;
map->numMaps = 0;
map->info = info;
}
void mInputMapDeinit(struct mInputMap* map) {
size_t m;
for (m = 0; m < map->numMaps; ++m) {
if (map->maps[m].type) {
free(map->maps[m].map);
TableDeinit(&map->maps[m].axes);
}
}
free(map->maps);
map->maps = 0;
map->numMaps = 0;
}
int mInputMapKey(const struct mInputMap* map, uint32_t type, int key) {
size_t m;
const struct mInputMapImpl* impl = _lookupMapConst(map, type);
if (!impl || !impl->map) {
return -1;
}
for (m = 0; m < map->info->nKeys; ++m) {
if (impl->map[m] == key) {
return m;
}
}
return -1;
}
int mInputMapKeyBits(const struct mInputMap* map, uint32_t type, uint32_t bits, unsigned offset) {
int keys = 0;
for (; bits; bits >>= 1, ++offset) {
if (bits & 1) {
int key = mInputMapKey(map, type, offset);
if (key == -1) {
continue;
}
keys |= 1 << key;
}
}
return keys;
}
void mInputBindKey(struct mInputMap* map, uint32_t type, int key, int input) {
struct mInputMapImpl* impl = _guaranteeMap(map, type);
mInputUnbindKey(map, type, input);
impl->map[input] = key;
}
void mInputUnbindKey(struct mInputMap* map, uint32_t type, int input) {
struct mInputMapImpl* impl = _lookupMap(map, type);
if (input < 0 || (size_t) input >= map->info->nKeys) {
return;
}
if (impl) {
impl->map[input] = -1;
}
}
int mInputQueryBinding(const struct mInputMap* map, uint32_t type, int input) {
if (input < 0 || (size_t) input >= map->info->nKeys) {
return -1;
}
const struct mInputMapImpl* impl = _lookupMapConst(map, type);
if (!impl || !impl->map) {
return -1;
}
return impl->map[input];
}
int mInputMapAxis(const struct mInputMap* map, uint32_t type, int axis, int value) {
const struct mInputMapImpl* impl = _lookupMapConst(map, type);
if (!impl) {
return -1;
}
struct mInputAxis* description = TableLookup(&impl->axes, axis);
if (!description) {
return -1;
}
int state = 0;
if (value < description->deadLow) {
state = -1;
} else if (value > description->deadHigh) {
state = 1;
}
if (state > 0) {
return description->highDirection;
}
if (state < 0) {
return description->lowDirection;
}
return -1;
}
int mInputClearAxis(const struct mInputMap* map, uint32_t type, int axis, int keys) {
const struct mInputMapImpl* impl = _lookupMapConst(map, type);
if (!impl) {
return keys;
}
struct mInputAxis* description = TableLookup(&impl->axes, axis);
if (!description) {
return keys;
}
return keys &= ~((1 << description->highDirection) | (1 << description->lowDirection));
}
void mInputBindAxis(struct mInputMap* map, uint32_t type, int axis, const struct mInputAxis* description) {
struct mInputMapImpl* impl = _guaranteeMap(map, type);
struct mInputAxis d2 = *description;
TableEnumerate(&impl->axes, _unbindAxis, &d2.highDirection);
TableEnumerate(&impl->axes, _unbindAxis, &d2.lowDirection);
struct mInputAxis* dup = malloc(sizeof(struct mInputAxis));
*dup = *description;
TableInsert(&impl->axes, axis, dup);
}
void mInputUnbindAxis(struct mInputMap* map, uint32_t type, int axis) {
struct mInputMapImpl* impl = _lookupMap(map, type);
if (impl) {
TableRemove(&impl->axes, axis);
}
}
void mInputUnbindAllAxes(struct mInputMap* map, uint32_t type) {
struct mInputMapImpl* impl = _lookupMap(map, type);
if (impl) {
TableClear(&impl->axes);
}
}
const struct mInputAxis* mInputQueryAxis(const struct mInputMap* map, uint32_t type, int axis) {
const struct mInputMapImpl* impl = _lookupMapConst(map, type);
if (!impl) {
return 0;
}
return TableLookup(&impl->axes, axis);
}
void mInputEnumerateAxes(const struct mInputMap* map, uint32_t type, void (handler(int axis, const struct mInputAxis* description, void* user)), void* user) {
const struct mInputMapImpl* impl = _lookupMapConst(map, type);
if (!impl) {
return;
}
struct mInputAxisEnumerate enumUser = {
handler,
user
};
TableEnumerate(&impl->axes, _enumerateAxis, &enumUser);
}
void mInputMapLoad(struct mInputMap* map, uint32_t type, const struct Configuration* config) {
char sectionName[SECTION_NAME_MAX];
_makeSectionName(map->info->platformName, sectionName, SECTION_NAME_MAX, type);
_loadAll(map, type, sectionName, config);
}
void mInputMapSave(const struct mInputMap* map, uint32_t type, struct Configuration* config) {
char sectionName[SECTION_NAME_MAX];
_makeSectionName(map->info->platformName, sectionName, SECTION_NAME_MAX, type);
_saveAll(map, type, sectionName, config);
}
bool mInputProfileLoad(struct mInputMap* map, uint32_t type, const struct Configuration* config, const char* profile) {
char sectionName[SECTION_NAME_MAX];
snprintf(sectionName, SECTION_NAME_MAX, "%s.input-profile.%s", map->info->platformName, profile);
sectionName[SECTION_NAME_MAX - 1] = '\0';
return _loadAll(map, type, sectionName, config);
}
void mInputProfileSave(const struct mInputMap* map, uint32_t type, struct Configuration* config, const char* profile) {
char sectionName[SECTION_NAME_MAX];
snprintf(sectionName, SECTION_NAME_MAX, "%s.input-profile.%s", map->info->platformName, profile);
sectionName[SECTION_NAME_MAX - 1] = '\0';
_saveAll(map, type, sectionName, config);
}
const char* mInputGetPreferredDevice(const struct Configuration* config, const char* platformName, uint32_t type, int playerId) {
char sectionName[SECTION_NAME_MAX];
_makeSectionName(platformName, sectionName, SECTION_NAME_MAX, type);
char deviceId[KEY_NAME_MAX];
snprintf(deviceId, sizeof(deviceId), "device%i", playerId);
return ConfigurationGetValue(config, sectionName, deviceId);
}
void mInputSetPreferredDevice(struct Configuration* config, const char* platformName, uint32_t type, int playerId, const char* deviceName) {
char sectionName[SECTION_NAME_MAX];
_makeSectionName(platformName, sectionName, SECTION_NAME_MAX, type);
char deviceId[KEY_NAME_MAX];
snprintf(deviceId, sizeof(deviceId), "device%i", playerId);
return ConfigurationSetValue(config, sectionName, deviceId, deviceName);
}
const char* mInputGetCustomValue(const struct Configuration* config, const char* platformName, uint32_t type, const char* key, const char* profile) {
char sectionName[SECTION_NAME_MAX];
if (profile) {
snprintf(sectionName, SECTION_NAME_MAX, "%s.input-profile.%s", platformName, profile);
const char* value = ConfigurationGetValue(config, sectionName, key);
if (value) {
return value;
}
}
_makeSectionName(platformName, sectionName, SECTION_NAME_MAX, type);
return ConfigurationGetValue(config, sectionName, key);
}
void mInputSetCustomValue(struct Configuration* config, const char* platformName, uint32_t type, const char* key, const char* value, const char* profile) {
char sectionName[SECTION_NAME_MAX];
if (profile) {
snprintf(sectionName, SECTION_NAME_MAX, "%s.input-profile.%s", platformName, profile);
ConfigurationSetValue(config, sectionName, key, value);
}
_makeSectionName(platformName, sectionName, SECTION_NAME_MAX, type);
ConfigurationSetValue(config, sectionName, key, value);
}

63
src/core/input.h Normal file
View File

@ -0,0 +1,63 @@
/* Copyright (c) 2013-2016 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
#ifndef M_INPUT_H
#define M_INPUT_H
#include "util/common.h"
struct Configuration;
struct mInputPlatformInfo {
const char* platformName;
const char** keyId;
size_t nKeys;
};
struct mInputMap {
struct mInputMapImpl* maps;
size_t numMaps;
const struct mInputPlatformInfo* info;
};
struct mInputAxis {
int highDirection;
int lowDirection;
int32_t deadHigh;
int32_t deadLow;
};
void mInputMapInit(struct mInputMap*, const struct mInputPlatformInfo* info);
void mInputMapDeinit(struct mInputMap*);
int mInputMapKey(const struct mInputMap*, uint32_t type, int key);
int mInputMapKeyBits(const struct mInputMap* map, uint32_t type, uint32_t bits, unsigned offset);
void mInputBindKey(struct mInputMap*, uint32_t type, int key, int input);
int mInputQueryBinding(const struct mInputMap*, uint32_t type, int input);
void mInputUnbindKey(struct mInputMap*, uint32_t type, int input);
int mInputMapAxis(const struct mInputMap*, uint32_t type, int axis, int value);
int mInputClearAxis(const struct mInputMap*, uint32_t type, int axis, int keys);
void mInputBindAxis(struct mInputMap*, uint32_t type, int axis, const struct mInputAxis* description);
void mInputUnbindAxis(struct mInputMap*, uint32_t type, int axis);
void mInputUnbindAllAxes(struct mInputMap*, uint32_t type);
const struct mInputAxis* mInputQueryAxis(const struct mInputMap*, uint32_t type, int axis);
void mInputEnumerateAxes(const struct mInputMap*, uint32_t type, void (handler(int axis, const struct mInputAxis* description, void* user)), void* user);
void mInputMapLoad(struct mInputMap*, uint32_t type, const struct Configuration*);
void mInputMapSave(const struct mInputMap*, uint32_t type, struct Configuration*);
bool mInputProfileLoad(struct mInputMap*, uint32_t type, const struct Configuration*, const char* profile);
void mInputProfileSave(const struct mInputMap*, uint32_t type, struct Configuration*, const char* profile);
const char* mInputGetPreferredDevice(const struct Configuration*, const char* platformName, uint32_t type, int playerId);
void mInputSetPreferredDevice(struct Configuration*, const char* platformName, uint32_t type, int playerId, const char* deviceName);
const char* mInputGetCustomValue(const struct Configuration* config, const char* platformName, uint32_t type, const char* key,
const char* profile);
void mInputSetCustomValue(struct Configuration* config, const char* platformName, uint32_t type, const char* key, const char* value,
const char* profile);
#endif

View File

@ -27,7 +27,7 @@ struct GBAContext {
struct ARMComponent* components[GBA_COMPONENT_MAX];
struct mCoreConfig config;
struct GBAOptions opts;
struct GBAInputMap inputMap;
struct mInputMap inputMap;
};
bool GBAContextInit(struct GBAContext* context, const char* port);

View File

@ -124,7 +124,7 @@ void GBAGUIInit(struct GBAGUIRunner* runner, const char* port) {
if (runner->context.config.port && runner->keySources) {
size_t i;
for (i = 0; runner->keySources[i].id; ++i) {
GBAInputMapLoad(&runner->context.inputMap, runner->keySources[i].id, mCoreConfigGetInput(&runner->context.config));
mInputMapLoad(&runner->context.inputMap, runner->keySources[i].id, mCoreConfigGetInput(&runner->context.config));
}
}
}
@ -137,7 +137,7 @@ void GBAGUIDeinit(struct GBAGUIRunner* runner) {
if (runner->keySources) {
size_t i;
for (i = 0; runner->keySources[i].id; ++i) {
GBAInputMapSave(&runner->context.inputMap, runner->keySources[i].id, mCoreConfigGetInput(&runner->context.config));
mInputMapSave(&runner->context.inputMap, runner->keySources[i].id, mCoreConfigGetInput(&runner->context.config));
}
}
mCoreConfigSave(&runner->context.config);

View File

@ -9,7 +9,7 @@
#include "util/gui.h"
#include "util/gui/menu.h"
void GBAGUIRemapKeys(struct GUIParams* params, struct GBAInputMap* map, const struct GUIInputKeys* keys) {
void GBAGUIRemapKeys(struct GUIParams* params, struct mInputMap* map, const struct GUIInputKeys* keys) {
struct GUIMenu menu = {
.title = "Remap keys",
.index = 0,
@ -22,10 +22,10 @@ void GBAGUIRemapKeys(struct GUIParams* params, struct GBAInputMap* map, const st
size_t i;
for (i = 0; i < GBA_KEY_MAX; ++i) {
*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
.title = GBAKeyNames[i],
.title = GBAInputInfo.keyId[i],
.data = (void*) (GUI_INPUT_MAX + i),
.submenu = 0,
.state = GBAInputQueryBinding(map, keys->id, i) + 1,
.state = mInputQueryBinding(map, keys->id, i) + 1,
.validStates = keyNames,
.nStates = keys->nKeys + 1
};
@ -50,7 +50,7 @@ void GBAGUIRemapKeys(struct GUIParams* params, struct GBAInputMap* map, const st
for (i = 0; i < GUIMenuItemListSize(&menu.items); ++i) {
item = GUIMenuItemListGetPointer(&menu.items, i);
if (i < GBA_KEY_MAX) {
GBAInputBindKey(map, keys->id, item->state - 1, i);
mInputBindKey(map, keys->id, item->state - 1, i);
}
}
break;

View File

@ -16,8 +16,8 @@ struct GUIInputKeys {
};
struct GUIParams;
struct GBAInputMap;
struct mInputMap;
void GBAGUIRemapKeys(struct GUIParams*, struct GBAInputMap*, const struct GUIInputKeys*);
void GBAGUIRemapKeys(struct GUIParams*, struct mInputMap*, const struct GUIInputKeys*);
#endif

View File

@ -1,555 +1,25 @@
/* Copyright (c) 2013-2015 Jeffrey Pfau
/* Copyright (c) 2013-2016 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* 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 "input.h"
#include "util/configuration.h"
#include "util/table.h"
#include "gba/interface.h"
#include <inttypes.h>
#define SECTION_NAME_MAX 128
#define KEY_NAME_MAX 32
#define KEY_VALUE_MAX 16
#define AXIS_INFO_MAX 12
struct GBAInputMapImpl {
int* map;
uint32_t type;
struct Table axes;
const struct mInputPlatformInfo GBAInputInfo = {
.platformName = "gba",
.keyId = (const char*[]) {
"A",
"B",
"Select",
"Start",
"Right",
"Left",
"Up",
"Down",
"R",
"L"
},
.nKeys = GBA_KEY_MAX
};
struct GBAAxisSave {
struct Configuration* config;
const char* sectionName;
};
struct GBAAxisEnumerate {
void (*handler)(int axis, const struct GBAAxis* description, void* user);
void* user;
};
const char* GBAKeyNames[] = {
"A",
"B",
"Select",
"Start",
"Right",
"Left",
"Up",
"Down",
"R",
"L"
};
static void _makeSectionName(char* sectionName, size_t len, uint32_t type) {
snprintf(sectionName, len, "input.%c%c%c%c", type >> 24, type >> 16, type >> 8, type);
sectionName[len - 1] = '\0';
}
static bool _getIntValue(const struct Configuration* config, const char* section, const char* key, int* value) {
const char* strValue = ConfigurationGetValue(config, section, key);
if (!strValue) {
return false;
}
char* end;
long intValue = strtol(strValue, &end, 10);
if (*end) {
return false;
}
*value = intValue;
return true;
}
static struct GBAInputMapImpl* _lookupMap(struct GBAInputMap* map, uint32_t type) {
size_t m;
struct GBAInputMapImpl* impl = 0;
for (m = 0; m < map->numMaps; ++m) {
if (map->maps[m].type == type) {
impl = &map->maps[m];
break;
}
}
return impl;
}
static const struct GBAInputMapImpl* _lookupMapConst(const struct GBAInputMap* map, uint32_t type) {
size_t m;
const struct GBAInputMapImpl* impl = 0;
for (m = 0; m < map->numMaps; ++m) {
if (map->maps[m].type == type) {
impl = &map->maps[m];
break;
}
}
return impl;
}
static struct GBAInputMapImpl* _guaranteeMap(struct GBAInputMap* map, uint32_t type) {
struct GBAInputMapImpl* impl = 0;
if (map->numMaps == 0) {
map->maps = malloc(sizeof(*map->maps));
map->numMaps = 1;
impl = &map->maps[0];
impl->type = type;
impl->map = malloc(GBA_KEY_MAX * sizeof(int));
int i;
for (i = 0; i < GBA_KEY_MAX; ++i) {
impl->map[i] = GBA_KEY_NONE;
}
TableInit(&impl->axes, 2, free);
} else {
impl = _lookupMap(map, type);
}
if (!impl) {
size_t m;
for (m = 0; m < map->numMaps; ++m) {
if (!map->maps[m].type) {
impl = &map->maps[m];
break;
}
}
if (impl) {
impl->type = type;
impl->map = malloc(GBA_KEY_MAX * sizeof(int));
int i;
for (i = 0; i < GBA_KEY_MAX; ++i) {
impl->map[i] = GBA_KEY_NONE;
}
} else {
map->maps = realloc(map->maps, sizeof(*map->maps) * map->numMaps * 2);
for (m = map->numMaps * 2 - 1; m > map->numMaps; --m) {
map->maps[m].type = 0;
map->maps[m].map = 0;
}
map->numMaps *= 2;
impl = &map->maps[m];
impl->type = type;
impl->map = malloc(GBA_KEY_MAX * sizeof(int));
int i;
for (i = 0; i < GBA_KEY_MAX; ++i) {
impl->map[i] = GBA_KEY_NONE;
}
}
TableInit(&impl->axes, 2, free);
}
return impl;
}
static void _loadKey(struct GBAInputMap* map, uint32_t type, const char* sectionName, const struct Configuration* config, enum GBAKey key, const char* keyName) {
char keyKey[KEY_NAME_MAX];
snprintf(keyKey, KEY_NAME_MAX, "key%s", keyName);
keyKey[KEY_NAME_MAX - 1] = '\0';
int value;
if (!_getIntValue(config, sectionName, keyKey, &value)) {
return;
}
GBAInputBindKey(map, type, value, key);
}
static void _loadAxis(struct GBAInputMap* map, uint32_t type, const char* sectionName, const struct Configuration* config, enum GBAKey direction, const char* axisName) {
char axisKey[KEY_NAME_MAX];
snprintf(axisKey, KEY_NAME_MAX, "axis%sValue", axisName);
axisKey[KEY_NAME_MAX - 1] = '\0';
int value;
if (!_getIntValue(config, sectionName, axisKey, &value)) {
return;
}
snprintf(axisKey, KEY_NAME_MAX, "axis%sAxis", axisName);
axisKey[KEY_NAME_MAX - 1] = '\0';
int axis;
const char* strValue = ConfigurationGetValue(config, sectionName, axisKey);
if (!strValue || !strValue[0]) {
return;
}
char* end;
axis = strtoul(&strValue[1], &end, 10);
if (*end) {
return;
}
const struct GBAAxis* description = GBAInputQueryAxis(map, type, axis);
struct GBAAxis realDescription = { GBA_KEY_NONE, GBA_KEY_NONE, 0, 0 };
if (description) {
realDescription = *description;
}
if (strValue[0] == '+') {
realDescription.deadHigh = value;
realDescription.highDirection = direction;
} else if (strValue[0] == '-') {
realDescription.deadLow = value;
realDescription.lowDirection = direction;
}
GBAInputBindAxis(map, type, axis, &realDescription);
}
static void _saveKey(const struct GBAInputMap* map, uint32_t type, const char* sectionName, struct Configuration* config, enum GBAKey key, const char* keyName) {
char keyKey[KEY_NAME_MAX];
snprintf(keyKey, KEY_NAME_MAX, "key%s", keyName);
keyKey[KEY_NAME_MAX - 1] = '\0';
int value = GBAInputQueryBinding(map, type, key);
char keyValue[KEY_VALUE_MAX];
snprintf(keyValue, KEY_VALUE_MAX, "%" PRIi32, value);
ConfigurationSetValue(config, sectionName, keyKey, keyValue);
}
static void _clearAxis(const char* sectionName, struct Configuration* config, const char* axisName) {
char axisKey[KEY_NAME_MAX];
snprintf(axisKey, KEY_NAME_MAX, "axis%sValue", axisName);
axisKey[KEY_NAME_MAX - 1] = '\0';
ConfigurationClearValue(config, sectionName, axisKey);
snprintf(axisKey, KEY_NAME_MAX, "axis%sAxis", axisName);
axisKey[KEY_NAME_MAX - 1] = '\0';
ConfigurationClearValue(config, sectionName, axisKey);
}
static void _saveAxis(uint32_t axis, void* dp, void* up) {
struct GBAAxisSave* user = up;
const struct GBAAxis* description = dp;
const char* sectionName = user->sectionName;
if (description->lowDirection != GBA_KEY_NONE) {
const char* keyName = GBAKeyNames[description->lowDirection];
char axisKey[KEY_NAME_MAX];
snprintf(axisKey, KEY_NAME_MAX, "axis%sValue", keyName);
axisKey[KEY_NAME_MAX - 1] = '\0';
ConfigurationSetIntValue(user->config, sectionName, axisKey, description->deadLow);
snprintf(axisKey, KEY_NAME_MAX, "axis%sAxis", keyName);
axisKey[KEY_NAME_MAX - 1] = '\0';
char axisInfo[AXIS_INFO_MAX];
snprintf(axisInfo, AXIS_INFO_MAX, "-%u", axis);
axisInfo[AXIS_INFO_MAX - 1] = '\0';
ConfigurationSetValue(user->config, sectionName, axisKey, axisInfo);
}
if (description->highDirection != GBA_KEY_NONE) {
const char* keyName = GBAKeyNames[description->highDirection];
char axisKey[KEY_NAME_MAX];
snprintf(axisKey, KEY_NAME_MAX, "axis%sValue", keyName);
axisKey[KEY_NAME_MAX - 1] = '\0';
ConfigurationSetIntValue(user->config, sectionName, axisKey, description->deadHigh);
snprintf(axisKey, KEY_NAME_MAX, "axis%sAxis", keyName);
axisKey[KEY_NAME_MAX - 1] = '\0';
char axisInfo[AXIS_INFO_MAX];
snprintf(axisInfo, AXIS_INFO_MAX, "+%u", axis);
axisInfo[AXIS_INFO_MAX - 1] = '\0';
ConfigurationSetValue(user->config, sectionName, axisKey, axisInfo);
}
}
void _enumerateAxis(uint32_t axis, void* dp, void* ep) {
struct GBAAxisEnumerate* enumUser = ep;
const struct GBAAxis* description = dp;
enumUser->handler(axis, description, enumUser->user);
}
void _unbindAxis(uint32_t axis, void* dp, void* user) {
UNUSED(axis);
enum GBAKey* key = user;
struct GBAAxis* description = dp;
if (description->highDirection == *key) {
description->highDirection = GBA_KEY_NONE;
}
if (description->lowDirection == *key) {
description->lowDirection = GBA_KEY_NONE;
}
}
static bool _loadAll(struct GBAInputMap* map, uint32_t type, const char* sectionName, const struct Configuration* config) {
if (!ConfigurationHasSection(config, sectionName)) {
return false;
}
_loadKey(map, type, sectionName, config, GBA_KEY_A, "A");
_loadKey(map, type, sectionName, config, GBA_KEY_B, "B");
_loadKey(map, type, sectionName, config, GBA_KEY_L, "L");
_loadKey(map, type, sectionName, config, GBA_KEY_R, "R");
_loadKey(map, type, sectionName, config, GBA_KEY_START, "Start");
_loadKey(map, type, sectionName, config, GBA_KEY_SELECT, "Select");
_loadKey(map, type, sectionName, config, GBA_KEY_UP, "Up");
_loadKey(map, type, sectionName, config, GBA_KEY_DOWN, "Down");
_loadKey(map, type, sectionName, config, GBA_KEY_LEFT, "Left");
_loadKey(map, type, sectionName, config, GBA_KEY_RIGHT, "Right");
_loadAxis(map, type, sectionName, config, GBA_KEY_A, "A");
_loadAxis(map, type, sectionName, config, GBA_KEY_B, "B");
_loadAxis(map, type, sectionName, config, GBA_KEY_L, "L");
_loadAxis(map, type, sectionName, config, GBA_KEY_R, "R");
_loadAxis(map, type, sectionName, config, GBA_KEY_START, "Start");
_loadAxis(map, type, sectionName, config, GBA_KEY_SELECT, "Select");
_loadAxis(map, type, sectionName, config, GBA_KEY_UP, "Up");
_loadAxis(map, type, sectionName, config, GBA_KEY_DOWN, "Down");
_loadAxis(map, type, sectionName, config, GBA_KEY_LEFT, "Left");
_loadAxis(map, type, sectionName, config, GBA_KEY_RIGHT, "Right");
return true;
}
static void _saveAll(const struct GBAInputMap* map, uint32_t type, const char* sectionName, struct Configuration* config) {
_saveKey(map, type, sectionName, config, GBA_KEY_A, "A");
_saveKey(map, type, sectionName, config, GBA_KEY_B, "B");
_saveKey(map, type, sectionName, config, GBA_KEY_L, "L");
_saveKey(map, type, sectionName, config, GBA_KEY_R, "R");
_saveKey(map, type, sectionName, config, GBA_KEY_START, "Start");
_saveKey(map, type, sectionName, config, GBA_KEY_SELECT, "Select");
_saveKey(map, type, sectionName, config, GBA_KEY_UP, "Up");
_saveKey(map, type, sectionName, config, GBA_KEY_DOWN, "Down");
_saveKey(map, type, sectionName, config, GBA_KEY_LEFT, "Left");
_saveKey(map, type, sectionName, config, GBA_KEY_RIGHT, "Right");
_clearAxis(sectionName, config, "A");
_clearAxis(sectionName, config, "B");
_clearAxis(sectionName, config, "L");
_clearAxis(sectionName, config, "R");
_clearAxis(sectionName, config, "Start");
_clearAxis(sectionName, config, "Select");
_clearAxis(sectionName, config, "Up");
_clearAxis(sectionName, config, "Down");
_clearAxis(sectionName, config, "Left");
_clearAxis(sectionName, config, "Right");
const struct GBAInputMapImpl* impl = _lookupMapConst(map, type);
if (!impl) {
return;
}
struct GBAAxisSave save = {
config,
sectionName
};
TableEnumerate(&impl->axes, _saveAxis, &save);
}
void GBAInputMapInit(struct GBAInputMap* map) {
map->maps = 0;
map->numMaps = 0;
}
void GBAInputMapDeinit(struct GBAInputMap* map) {
size_t m;
for (m = 0; m < map->numMaps; ++m) {
if (map->maps[m].type) {
free(map->maps[m].map);
TableDeinit(&map->maps[m].axes);
}
}
free(map->maps);
map->maps = 0;
map->numMaps = 0;
}
enum GBAKey GBAInputMapKey(const struct GBAInputMap* map, uint32_t type, int key) {
size_t m;
const struct GBAInputMapImpl* impl = _lookupMapConst(map, type);
if (!impl || !impl->map) {
return GBA_KEY_NONE;
}
for (m = 0; m < GBA_KEY_MAX; ++m) {
if (impl->map[m] == key) {
return m;
}
}
return GBA_KEY_NONE;
}
int GBAInputMapKeyBits(const struct GBAInputMap* map, uint32_t type, uint32_t bits, unsigned offset) {
int keys = 0;
for (; bits; bits >>= 1, ++offset) {
if (bits & 1) {
enum GBAKey key = GBAInputMapKey(map, type, offset);
if (key == GBA_KEY_NONE) {
continue;
}
keys |= 1 << key;
}
}
return keys;
}
void GBAInputBindKey(struct GBAInputMap* map, uint32_t type, int key, enum GBAKey input) {
struct GBAInputMapImpl* impl = _guaranteeMap(map, type);
GBAInputUnbindKey(map, type, input);
impl->map[input] = key;
}
void GBAInputUnbindKey(struct GBAInputMap* map, uint32_t type, enum GBAKey input) {
struct GBAInputMapImpl* impl = _lookupMap(map, type);
if (input < 0 || input >= GBA_KEY_MAX) {
return;
}
if (impl) {
impl->map[input] = GBA_KEY_NONE;
}
}
int GBAInputQueryBinding(const struct GBAInputMap* map, uint32_t type, enum GBAKey input) {
if (input >= GBA_KEY_MAX) {
return GBA_KEY_NONE;
}
const struct GBAInputMapImpl* impl = _lookupMapConst(map, type);
if (!impl || !impl->map) {
return GBA_KEY_NONE;
}
return impl->map[input];
}
enum GBAKey GBAInputMapAxis(const struct GBAInputMap* map, uint32_t type, int axis, int value) {
const struct GBAInputMapImpl* impl = _lookupMapConst(map, type);
if (!impl) {
return GBA_KEY_NONE;
}
struct GBAAxis* description = TableLookup(&impl->axes, axis);
if (!description) {
return GBA_KEY_NONE;
}
int state = 0;
if (value < description->deadLow) {
state = -1;
} else if (value > description->deadHigh) {
state = 1;
}
if (state > 0) {
return description->highDirection;
}
if (state < 0) {
return description->lowDirection;
}
return GBA_KEY_NONE;
}
int GBAInputClearAxis(const struct GBAInputMap* map, uint32_t type, int axis, int keys) {
const struct GBAInputMapImpl* impl = _lookupMapConst(map, type);
if (!impl) {
return keys;
}
struct GBAAxis* description = TableLookup(&impl->axes, axis);
if (!description) {
return keys;
}
return keys &= ~((1 << description->highDirection) | (1 << description->lowDirection));
}
void GBAInputBindAxis(struct GBAInputMap* map, uint32_t type, int axis, const struct GBAAxis* description) {
struct GBAInputMapImpl* impl = _guaranteeMap(map, type);
struct GBAAxis d2 = *description;
TableEnumerate(&impl->axes, _unbindAxis, &d2.highDirection);
TableEnumerate(&impl->axes, _unbindAxis, &d2.lowDirection);
struct GBAAxis* dup = malloc(sizeof(struct GBAAxis));
*dup = *description;
TableInsert(&impl->axes, axis, dup);
}
void GBAInputUnbindAxis(struct GBAInputMap* map, uint32_t type, int axis) {
struct GBAInputMapImpl* impl = _lookupMap(map, type);
if (impl) {
TableRemove(&impl->axes, axis);
}
}
void GBAInputUnbindAllAxes(struct GBAInputMap* map, uint32_t type) {
struct GBAInputMapImpl* impl = _lookupMap(map, type);
if (impl) {
TableClear(&impl->axes);
}
}
const struct GBAAxis* GBAInputQueryAxis(const struct GBAInputMap* map, uint32_t type, int axis) {
const struct GBAInputMapImpl* impl = _lookupMapConst(map, type);
if (!impl) {
return 0;
}
return TableLookup(&impl->axes, axis);
}
void GBAInputEnumerateAxes(const struct GBAInputMap* map, uint32_t type, void (handler(int axis, const struct GBAAxis* description, void* user)), void* user) {
const struct GBAInputMapImpl* impl = _lookupMapConst(map, type);
if (!impl) {
return;
}
struct GBAAxisEnumerate enumUser = {
handler,
user
};
TableEnumerate(&impl->axes, _enumerateAxis, &enumUser);
}
void GBAInputMapLoad(struct GBAInputMap* map, uint32_t type, const struct Configuration* config) {
char sectionName[SECTION_NAME_MAX];
_makeSectionName(sectionName, SECTION_NAME_MAX, type);
_loadAll(map, type, sectionName, config);
}
void GBAInputMapSave(const struct GBAInputMap* map, uint32_t type, struct Configuration* config) {
char sectionName[SECTION_NAME_MAX];
_makeSectionName(sectionName, SECTION_NAME_MAX, type);
_saveAll(map, type, sectionName, config);
}
bool GBAInputProfileLoad(struct GBAInputMap* map, uint32_t type, const struct Configuration* config, const char* profile) {
char sectionName[SECTION_NAME_MAX];
snprintf(sectionName, SECTION_NAME_MAX, "input-profile.%s", profile);
sectionName[SECTION_NAME_MAX - 1] = '\0';
return _loadAll(map, type, sectionName, config);
}
void GBAInputProfileSave(const struct GBAInputMap* map, uint32_t type, struct Configuration* config, const char* profile) {
char sectionName[SECTION_NAME_MAX];
snprintf(sectionName, SECTION_NAME_MAX, "input-profile.%s", profile);
sectionName[SECTION_NAME_MAX - 1] = '\0';
_saveAll(map, type, sectionName, config);
}
const char* GBAInputGetPreferredDevice(const struct Configuration* config, uint32_t type, int playerId) {
char sectionName[SECTION_NAME_MAX];
_makeSectionName(sectionName, SECTION_NAME_MAX, type);
char deviceId[KEY_NAME_MAX];
snprintf(deviceId, sizeof(deviceId), "device%i", playerId);
return ConfigurationGetValue(config, sectionName, deviceId);
}
void GBAInputSetPreferredDevice(struct Configuration* config, uint32_t type, int playerId, const char* deviceName) {
char sectionName[SECTION_NAME_MAX];
_makeSectionName(sectionName, SECTION_NAME_MAX, type);
char deviceId[KEY_NAME_MAX];
snprintf(deviceId, sizeof(deviceId), "device%i", playerId);
return ConfigurationSetValue(config, sectionName, deviceId, deviceName);
}
const char* GBAInputGetCustomValue(const struct Configuration* config, uint32_t type, const char* key, const char* profile) {
char sectionName[SECTION_NAME_MAX];
if (profile) {
snprintf(sectionName, SECTION_NAME_MAX, "input-profile.%s", profile);
const char* value = ConfigurationGetValue(config, sectionName, key);
if (value) {
return value;
}
}
_makeSectionName(sectionName, SECTION_NAME_MAX, type);
return ConfigurationGetValue(config, sectionName, key);
}
void GBAInputSetCustomValue(struct Configuration* config, uint32_t type, const char* key, const char* value, const char* profile) {
char sectionName[SECTION_NAME_MAX];
if (profile) {
snprintf(sectionName, SECTION_NAME_MAX, "input-profile.%s", profile);
ConfigurationSetValue(config, sectionName, key, value);
}
_makeSectionName(sectionName, SECTION_NAME_MAX, type);
ConfigurationSetValue(config, sectionName, key, value);
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2013-2015 Jeffrey Pfau
/* Copyright (c) 2013-2016 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -6,53 +6,23 @@
#ifndef GBA_INPUT_H
#define GBA_INPUT_H
#include "gba/gba.h"
#include "core/input.h"
struct Configuration;
extern const struct mInputPlatformInfo GBAInputInfo;
struct GBAInputMap {
struct GBAInputMapImpl* maps;
size_t numMaps;
enum GBAKey {
GBA_KEY_A = 0,
GBA_KEY_B = 1,
GBA_KEY_SELECT = 2,
GBA_KEY_START = 3,
GBA_KEY_RIGHT = 4,
GBA_KEY_LEFT = 5,
GBA_KEY_UP = 6,
GBA_KEY_DOWN = 7,
GBA_KEY_R = 8,
GBA_KEY_L = 9,
GBA_KEY_MAX,
GBA_KEY_NONE = -1
};
struct GBAAxis {
enum GBAKey highDirection;
enum GBAKey lowDirection;
int32_t deadHigh;
int32_t deadLow;
};
extern const char* GBAKeyNames[];
void GBAInputMapInit(struct GBAInputMap*);
void GBAInputMapDeinit(struct GBAInputMap*);
enum GBAKey GBAInputMapKey(const struct GBAInputMap*, uint32_t type, int key);
int GBAInputMapKeyBits(const struct GBAInputMap* map, uint32_t type, uint32_t bits, unsigned offset);
void GBAInputBindKey(struct GBAInputMap*, uint32_t type, int key, enum GBAKey input);
void GBAInputUnbindKey(struct GBAInputMap*, uint32_t type, enum GBAKey input);
int GBAInputQueryBinding(const struct GBAInputMap*, uint32_t type, enum GBAKey input);
enum GBAKey GBAInputMapAxis(const struct GBAInputMap*, uint32_t type, int axis, int value);
int GBAInputClearAxis(const struct GBAInputMap*, uint32_t type, int axis, int keys);
void GBAInputBindAxis(struct GBAInputMap*, uint32_t type, int axis, const struct GBAAxis* description);
void GBAInputUnbindAxis(struct GBAInputMap*, uint32_t type, int axis);
void GBAInputUnbindAllAxes(struct GBAInputMap*, uint32_t type);
const struct GBAAxis* GBAInputQueryAxis(const struct GBAInputMap*, uint32_t type, int axis);
void GBAInputEnumerateAxes(const struct GBAInputMap*, uint32_t type, void (handler(int axis, const struct GBAAxis* description, void* user)), void* user);
void GBAInputMapLoad(struct GBAInputMap*, uint32_t type, const struct Configuration*);
void GBAInputMapSave(const struct GBAInputMap*, uint32_t type, struct Configuration*);
bool GBAInputProfileLoad(struct GBAInputMap*, uint32_t type, const struct Configuration*, const char* profile);
void GBAInputProfileSave(const struct GBAInputMap*, uint32_t type, struct Configuration*, const char* profile);
const char* GBAInputGetPreferredDevice(const struct Configuration*, uint32_t type, int playerId);
void GBAInputSetPreferredDevice(struct Configuration*, uint32_t type, int playerId, const char* deviceName);
const char* GBAInputGetCustomValue(const struct Configuration* config, uint32_t type, const char* key,
const char* profile);
void GBAInputSetCustomValue(struct Configuration* config, uint32_t type, const char* key, const char* value,
const char* profile);
#endif

View File

@ -26,21 +26,6 @@ enum GBALogLevel {
GBA_LOG_ALL = 0xF3F,
};
enum GBAKey {
GBA_KEY_A = 0,
GBA_KEY_B = 1,
GBA_KEY_SELECT = 2,
GBA_KEY_START = 3,
GBA_KEY_RIGHT = 4,
GBA_KEY_LEFT = 5,
GBA_KEY_UP = 6,
GBA_KEY_DOWN = 7,
GBA_KEY_R = 8,
GBA_KEY_L = 9,
GBA_KEY_MAX,
GBA_KEY_NONE = -1
};
enum GBASIOMode {
SIO_NORMAL_8 = 0,
SIO_NORMAL_32 = 1,

View File

@ -134,8 +134,8 @@ static void _aptHook(APT_HookType hook, void* user) {
}
}
static void _map3DSKey(struct GBAInputMap* map, int ctrKey, enum GBAKey key) {
GBAInputBindKey(map, _3DS_INPUT, __builtin_ctz(ctrKey), key);
static void _map3DSKey(struct mInputMap* map, int ctrKey, enum GBAKey key) {
mInputBindKey(map, _3DS_INPUT, __builtin_ctz(ctrKey), key);
}
static void _csndPlaySound(u32 flags, u32 sampleRate, float vol, void* left, void* right, u32 size) {
@ -428,7 +428,7 @@ static uint16_t _pollGameInput(struct GBAGUIRunner* runner) {
hidScanInput();
uint32_t activeKeys = hidKeysHeld();
uint16_t keys = GBAInputMapKeyBits(&runner->context.inputMap, _3DS_INPUT, activeKeys, 0);
uint16_t keys = mInputMapKeyBits(&runner->context.inputMap, _3DS_INPUT, activeKeys, 0);
keys |= (activeKeys >> 24) & 0xF0;
return keys;
}
@ -489,24 +489,24 @@ static enum GUICursorState _pollCursor(unsigned* x, unsigned* y) {
return GUI_CURSOR_DOWN;
}
static void _sampleRotation(struct GBARotationSource* source) {
static void _sampleRotation(struct mRotationSource* source) {
struct GBA3DSRotationSource* rotation = (struct GBA3DSRotationSource*) source;
// Work around ctrulib getting the entries wrong
rotation->accel = *(accelVector*)& hidSharedMem[0x48];
rotation->gyro = *(angularRate*)& hidSharedMem[0x5C];
}
static int32_t _readTiltX(struct GBARotationSource* source) {
static int32_t _readTiltX(struct mRotationSource* source) {
struct GBA3DSRotationSource* rotation = (struct GBA3DSRotationSource*) source;
return rotation->accel.x << 18L;
}
static int32_t _readTiltY(struct GBARotationSource* source) {
static int32_t _readTiltY(struct mRotationSource* source) {
struct GBA3DSRotationSource* rotation = (struct GBA3DSRotationSource*) source;
return rotation->accel.y << 18L;
}
static int32_t _readGyroZ(struct GBARotationSource* source) {
static int32_t _readGyroZ(struct mRotationSource* source) {
struct GBA3DSRotationSource* rotation = (struct GBA3DSRotationSource*) source;
return rotation->gyro.y << 18L; // Yes, y
}

View File

@ -58,8 +58,8 @@ static struct GBAPSP2AudioContext {
bool running;
} audioContext;
static void _mapVitaKey(struct GBAInputMap* map, int pspKey, enum GBAKey key) {
GBAInputBindKey(map, PSP2_INPUT, __builtin_ctz(pspKey), key);
static void _mapVitaKey(struct mInputMap* map, int pspKey, enum GBAKey key) {
mInputBindKey(map, PSP2_INPUT, __builtin_ctz(pspKey), key);
}
static THREAD_ENTRY _audioThread(void* context) {
@ -91,22 +91,22 @@ static THREAD_ENTRY _audioThread(void* context) {
return 0;
}
static void _sampleRotation(struct GBARotationSource* source) {
static void _sampleRotation(struct mRotationSource* source) {
struct GBASceRotationSource* rotation = (struct GBASceRotationSource*) source;
sceMotionGetSensorState(&rotation->state, 1);
}
static int32_t _readTiltX(struct GBARotationSource* source) {
static int32_t _readTiltX(struct mRotationSource* source) {
struct GBASceRotationSource* rotation = (struct GBASceRotationSource*) source;
return rotation->state.accelerometer.x * 0x60000000;
}
static int32_t _readTiltY(struct GBARotationSource* source) {
static int32_t _readTiltY(struct mRotationSource* source) {
struct GBASceRotationSource* rotation = (struct GBASceRotationSource*) source;
return rotation->state.accelerometer.y * 0x60000000;
}
static int32_t _readGyroZ(struct GBARotationSource* source) {
static int32_t _readGyroZ(struct mRotationSource* source) {
struct GBASceRotationSource* rotation = (struct GBASceRotationSource*) source;
return rotation->state.gyro.z * 0x10000000;
}
@ -115,20 +115,20 @@ uint16_t GBAPSP2PollInput(struct GBAGUIRunner* runner) {
SceCtrlData pad;
sceCtrlPeekBufferPositive(0, &pad, 1);
int activeKeys = GBAInputMapKeyBits(&runner->context.inputMap, PSP2_INPUT, pad.buttons, 0);
enum GBAKey angles = GBAInputMapAxis(&runner->context.inputMap, PSP2_INPUT, 0, pad.ly);
int activeKeys = mInputMapKeyBits(&runner->context.inputMap, PSP2_INPUT, pad.buttons, 0);
enum GBAKey angles = mInputMapAxis(&runner->context.inputMap, PSP2_INPUT, 0, pad.ly);
if (angles != GBA_KEY_NONE) {
activeKeys |= 1 << angles;
}
angles = GBAInputMapAxis(&runner->context.inputMap, PSP2_INPUT, 1, pad.lx);
angles = mInputMapAxis(&runner->context.inputMap, PSP2_INPUT, 1, pad.lx);
if (angles != GBA_KEY_NONE) {
activeKeys |= 1 << angles;
}
angles = GBAInputMapAxis(&runner->context.inputMap, PSP2_INPUT, 2, pad.ry);
angles = mInputMapAxis(&runner->context.inputMap, PSP2_INPUT, 2, pad.ry);
if (angles != GBA_KEY_NONE) {
activeKeys |= 1 << angles;
}
angles = GBAInputMapAxis(&runner->context.inputMap, PSP2_INPUT, 3, pad.rx);
angles = mInputMapAxis(&runner->context.inputMap, PSP2_INPUT, 3, pad.rx);
if (angles != GBA_KEY_NONE) {
activeKeys |= 1 << angles;
}
@ -148,10 +148,10 @@ void GBAPSP2Setup(struct GBAGUIRunner* runner) {
_mapVitaKey(&runner->context.inputMap, SCE_CTRL_LTRIGGER, GBA_KEY_L);
_mapVitaKey(&runner->context.inputMap, SCE_CTRL_RTRIGGER, GBA_KEY_R);
struct GBAAxis desc = { GBA_KEY_DOWN, GBA_KEY_UP, 192, 64 };
GBAInputBindAxis(&runner->context.inputMap, PSP2_INPUT, 0, &desc);
desc = (struct GBAAxis) { GBA_KEY_RIGHT, GBA_KEY_LEFT, 192, 64 };
GBAInputBindAxis(&runner->context.inputMap, PSP2_INPUT, 1, &desc);
struct mInputAxis desc = { GBA_KEY_DOWN, GBA_KEY_UP, 192, 64 };
mInputBindAxis(&runner->context.inputMap, PSP2_INPUT, 0, &desc);
desc = (struct mInputAxis) { GBA_KEY_RIGHT, GBA_KEY_LEFT, 192, 64 };
mInputBindAxis(&runner->context.inputMap, PSP2_INPUT, 1, &desc);
tex = vita2d_create_empty_texture_format(256, 256, SCE_GXM_TEXTURE_FORMAT_X8U8U8U8_1BGR);
screenshot = vita2d_create_empty_texture_format(256, 256, SCE_GXM_TEXTURE_FORMAT_X8U8U8U8_1BGR);

View File

@ -39,7 +39,7 @@ GBAKeyEditor::GBAKeyEditor(InputController* controller, int type, const QString&
setWindowFlags(windowFlags() & ~Qt::WindowFullscreenButtonHint);
setMinimumSize(300, 300);
const GBAInputMap* map = controller->map();
const mInputMap* map = controller->map();
controller->stealFocus(this);
m_keyDU = new KeyEditor(this);
@ -237,7 +237,7 @@ void GBAKeyEditor::save() {
}
void GBAKeyEditor::refresh() {
const GBAInputMap* map = m_controller->map();
const mInputMap* map = m_controller->map();
lookupBinding(map, m_keyDU, GBA_KEY_UP);
lookupBinding(map, m_keyDD, GBA_KEY_DOWN);
lookupBinding(map, m_keyDL, GBA_KEY_LEFT);
@ -250,31 +250,31 @@ void GBAKeyEditor::refresh() {
lookupBinding(map, m_keyR, GBA_KEY_R);
}
void GBAKeyEditor::lookupBinding(const GBAInputMap* map, KeyEditor* keyEditor, GBAKey key) {
void GBAKeyEditor::lookupBinding(const mInputMap* map, KeyEditor* keyEditor, GBAKey key) {
#ifdef BUILD_SDL
if (m_type == SDL_BINDING_BUTTON) {
int value = GBAInputQueryBinding(map, m_type, key);
int value = mInputQueryBinding(map, m_type, key);
if (value != GBA_KEY_NONE) {
keyEditor->setValueButton(value);
}
return;
}
#endif
keyEditor->setValueKey(GBAInputQueryBinding(map, m_type, key));
keyEditor->setValueKey(mInputQueryBinding(map, m_type, key));
}
#ifdef BUILD_SDL
void GBAKeyEditor::lookupAxes(const GBAInputMap* map) {
GBAInputEnumerateAxes(map, m_type, [](int axis, const GBAAxis* description, void* user) {
void GBAKeyEditor::lookupAxes(const mInputMap* map) {
mInputEnumerateAxes(map, m_type, [](int axis, const mInputAxis* description, void* user) {
GBAKeyEditor* self = static_cast<GBAKeyEditor*>(user);
if (description->highDirection != GBA_KEY_NONE) {
KeyEditor* key = self->keyById(description->highDirection);
KeyEditor* key = self->keyById(static_cast<enum GBAKey>(description->highDirection));
if (key) {
key->setValueAxis(axis, description->deadHigh);
}
}
if (description->lowDirection != GBA_KEY_NONE) {
KeyEditor* key = self->keyById(description->lowDirection);
KeyEditor* key = self->keyById(static_cast<enum GBAKey>(description->lowDirection));
if (key) {
key->setValueAxis(axis, description->deadLow);
}

View File

@ -57,13 +57,13 @@ private:
void setLocation(QWidget* widget, qreal x, qreal y);
void lookupBinding(const GBAInputMap*, KeyEditor*, GBAKey);
void lookupBinding(const mInputMap*, KeyEditor*, GBAKey);
void bindKey(const KeyEditor*, GBAKey);
bool findFocus(KeyEditor* needle = nullptr);
#ifdef BUILD_SDL
void lookupAxes(const GBAInputMap*);
void lookupAxes(const mInputMap*);
#endif
KeyEditor* keyById(GBAKey);

View File

@ -21,7 +21,7 @@ GamepadAxisEvent::GamepadAxisEvent(int axis, Direction direction, bool isNew, in
{
ignore();
if (controller) {
m_key = GBAInputMapAxis(controller->map(), type, axis, direction * INT_MAX);
m_key = static_cast<GBAKey>(mInputMapAxis(controller->map(), type, axis, direction * INT_MAX));
}
}

View File

@ -20,7 +20,7 @@ GamepadButtonEvent::GamepadButtonEvent(QEvent::Type pressType, int button, int t
{
ignore();
if (controller) {
m_key = GBAInputMapKey(controller->map(), type, button);
m_key = static_cast<GBAKey>(mInputMapKey(controller->map(), type, button));
}
}

View File

@ -37,7 +37,7 @@ InputController::InputController(int playerId, QWidget* topLevel, QObject* paren
, m_topLevel(topLevel)
, m_focusParent(topLevel)
{
GBAInputMapInit(&m_inputMap);
mInputMapInit(&m_inputMap, &GBAInputInfo);
#ifdef BUILD_SDL
if (s_sdlInited == 0) {
@ -58,20 +58,20 @@ InputController::InputController(int playerId, QWidget* topLevel, QObject* paren
m_gamepadTimer->setInterval(50);
m_gamepadTimer->start();
GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_X, GBA_KEY_A);
GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Z, GBA_KEY_B);
GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_A, GBA_KEY_L);
GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_S, GBA_KEY_R);
GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Return, GBA_KEY_START);
GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Backspace, GBA_KEY_SELECT);
GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Up, GBA_KEY_UP);
GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Down, GBA_KEY_DOWN);
GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Left, GBA_KEY_LEFT);
GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Right, GBA_KEY_RIGHT);
mInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_X, GBA_KEY_A);
mInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Z, GBA_KEY_B);
mInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_A, GBA_KEY_L);
mInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_S, GBA_KEY_R);
mInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Return, GBA_KEY_START);
mInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Backspace, GBA_KEY_SELECT);
mInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Up, GBA_KEY_UP);
mInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Down, GBA_KEY_DOWN);
mInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Left, GBA_KEY_LEFT);
mInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Right, GBA_KEY_RIGHT);
}
InputController::~InputController() {
GBAInputMapDeinit(&m_inputMap);
mInputMapDeinit(&m_inputMap);
#ifdef BUILD_SDL
if (m_playerAttached) {
@ -100,7 +100,7 @@ void InputController::setConfiguration(ConfigController* config) {
}
void InputController::loadConfiguration(uint32_t type) {
GBAInputMapLoad(&m_inputMap, type, m_config->input());
mInputMapLoad(&m_inputMap, type, m_config->input());
#ifdef BUILD_SDL
if (m_playerAttached) {
GBASDLPlayerLoadConfig(&m_sdlPlayer, m_config->input());
@ -109,7 +109,7 @@ void InputController::loadConfiguration(uint32_t type) {
}
void InputController::loadProfile(uint32_t type, const QString& profile) {
bool loaded = GBAInputProfileLoad(&m_inputMap, type, m_config->input(), profile.toUtf8().constData());
bool loaded = mInputProfileLoad(&m_inputMap, type, m_config->input(), profile.toUtf8().constData());
recalibrateAxes();
if (!loaded) {
const InputProfile* ip = InputProfile::findProfile(profile);
@ -133,12 +133,12 @@ void InputController::saveConfiguration() {
}
void InputController::saveConfiguration(uint32_t type) {
GBAInputMapSave(&m_inputMap, type, m_config->input());
mInputMapSave(&m_inputMap, type, m_config->input());
m_config->write();
}
void InputController::saveProfile(uint32_t type, const QString& profile) {
GBAInputProfileSave(&m_inputMap, type, m_config->input(), profile.toUtf8().constData());
mInputProfileSave(&m_inputMap, type, m_config->input(), profile.toUtf8().constData());
m_config->write();
}
@ -203,7 +203,7 @@ void InputController::setPreferredGamepad(uint32_t type, const QString& device)
if (!m_config) {
return;
}
GBAInputSetPreferredDevice(m_config->input(), type, m_playerId, device.toUtf8().constData());
mInputSetPreferredDevice(m_config->input(), "gba", type, m_playerId, device.toUtf8().constData());
}
GBARumble* InputController::rumble() {
@ -276,11 +276,11 @@ void InputController::setGyroSensitivity(float sensitivity) {
}
GBAKey InputController::mapKeyboard(int key) const {
return GBAInputMapKey(&m_inputMap, KEYBOARD, key);
return static_cast<GBAKey>(mInputMapKey(&m_inputMap, KEYBOARD, key));
}
void InputController::bindKey(uint32_t type, int key, GBAKey gbaKey) {
return GBAInputBindKey(&m_inputMap, type, key, gbaKey);
return mInputBindKey(&m_inputMap, type, key, gbaKey);
}
void InputController::updateJoysticks() {
@ -298,7 +298,7 @@ int InputController::pollEvents() {
int numButtons = SDL_JoystickNumButtons(joystick);
int i;
for (i = 0; i < numButtons; ++i) {
GBAKey key = GBAInputMapKey(&m_inputMap, SDL_BINDING_BUTTON, i);
GBAKey key = static_cast<GBAKey>(mInputMapKey(&m_inputMap, SDL_BINDING_BUTTON, i));
if (key == GBA_KEY_NONE) {
continue;
}
@ -330,7 +330,7 @@ int InputController::pollEvents() {
for (i = 0; i < numAxes; ++i) {
int value = SDL_JoystickGetAxis(joystick, i);
enum GBAKey key = GBAInputMapAxis(&m_inputMap, SDL_BINDING_BUTTON, i, value);
enum GBAKey key = static_cast<GBAKey>(mInputMapAxis(&m_inputMap, SDL_BINDING_BUTTON, i, value));
if (key != GBA_KEY_NONE) {
activeButtons |= 1 << key;
}
@ -401,8 +401,8 @@ QSet<QPair<int, GamepadAxisEvent::Direction>> InputController::activeGamepadAxes
}
void InputController::bindAxis(uint32_t type, int axis, GamepadAxisEvent::Direction direction, GBAKey key) {
const GBAAxis* old = GBAInputQueryAxis(&m_inputMap, type, axis);
GBAAxis description = { GBA_KEY_NONE, GBA_KEY_NONE, -AXIS_THRESHOLD, AXIS_THRESHOLD };
const mInputAxis* old = mInputQueryAxis(&m_inputMap, type, axis);
mInputAxis description = { GBA_KEY_NONE, GBA_KEY_NONE, -AXIS_THRESHOLD, AXIS_THRESHOLD };
if (old) {
description = *old;
}
@ -423,11 +423,11 @@ void InputController::bindAxis(uint32_t type, int axis, GamepadAxisEvent::Direct
default:
return;
}
GBAInputBindAxis(&m_inputMap, type, axis, &description);
mInputBindAxis(&m_inputMap, type, axis, &description);
}
void InputController::unbindAllAxes(uint32_t type) {
GBAInputUnbindAllAxes(&m_inputMap, type);
mInputUnbindAllAxes(&m_inputMap, type);
}
void InputController::testGamepad(int type) {

View File

@ -50,7 +50,7 @@ public:
void bindKey(uint32_t type, int key, GBAKey);
const GBAInputMap* map() const { return &m_inputMap; }
const mInputMap* map() const { return &m_inputMap; }
void updateJoysticks();
int pollEvents();
@ -99,7 +99,7 @@ private:
bool hasPendingEvent(GBAKey) const;
void sendGamepadEvent(QEvent*);
GBAInputMap m_inputMap;
mInputMap m_inputMap;
ConfigController* m_config;
int m_playerId;
bool m_allowOpposing;

View File

@ -138,9 +138,9 @@ void mSDLGLRunloopGB(struct mSDLRenderer* renderer, void* user) {
if (event.type == SDL_KEYUP || event.type == SDL_KEYDOWN) {
int key;
#if !defined(BUILD_PANDORA) && SDL_VERSION_ATLEAST(2, 0, 0)
key = GBAInputMapKey(renderer->player.bindings, SDL_BINDING_KEY, event.key.keysym.scancode);
key = mInputMapKey(renderer->player.bindings, SDL_BINDING_KEY, event.key.keysym.scancode);
#else
key = GBAInputMapKey(renderer->player.bindings, SDL_BINDING_KEY, event.key.keysym.sym);
key = mInputMapKey(renderer->player.bindings, SDL_BINDING_KEY, event.key.keysym.sym);
#endif
if (key != GBA_KEY_NONE) {
if (event.type == SDL_KEYDOWN) {

View File

@ -59,8 +59,8 @@ static int mSDLRunGB(struct mSDLRenderer* renderer, struct GBAArguments* args);
int main(int argc, char** argv) {
struct mSDLRenderer renderer = {};
struct GBAInputMap inputMap;
GBAInputMapInit(&inputMap);
struct mInputMap inputMap;
mInputMapInit(&inputMap, &GBAInputInfo);
struct mCoreConfig config;
mCoreConfigInit(&config, PORT);
@ -208,7 +208,7 @@ int main(int argc, char** argv) {
break;
}
GBASDLDetachPlayer(&renderer.events, &renderer.player);
GBAInputMapDeinit(&inputMap);
mInputMapDeinit(&inputMap);
mSDLDeinit(&renderer);

View File

@ -88,63 +88,63 @@ void GBASDLDeinitEvents(struct GBASDLEvents* context) {
}
void GBASDLEventsLoadConfig(struct GBASDLEvents* context, const struct Configuration* config) {
context->preferredJoysticks[0] = GBAInputGetPreferredDevice(config, SDL_BINDING_BUTTON, 0);
context->preferredJoysticks[1] = GBAInputGetPreferredDevice(config, SDL_BINDING_BUTTON, 1);
context->preferredJoysticks[2] = GBAInputGetPreferredDevice(config, SDL_BINDING_BUTTON, 2);
context->preferredJoysticks[3] = GBAInputGetPreferredDevice(config, SDL_BINDING_BUTTON, 3);
context->preferredJoysticks[0] = mInputGetPreferredDevice(config, "gba", SDL_BINDING_BUTTON, 0);
context->preferredJoysticks[1] = mInputGetPreferredDevice(config, "gba", SDL_BINDING_BUTTON, 1);
context->preferredJoysticks[2] = mInputGetPreferredDevice(config, "gba", SDL_BINDING_BUTTON, 2);
context->preferredJoysticks[3] = mInputGetPreferredDevice(config, "gba", SDL_BINDING_BUTTON, 3);
}
void GBASDLInitBindings(struct GBAInputMap* inputMap) {
void GBASDLInitBindings(struct mInputMap* inputMap) {
#ifdef BUILD_PANDORA
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_PAGEDOWN, GBA_KEY_A);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_END, GBA_KEY_B);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RSHIFT, GBA_KEY_L);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RCTRL, GBA_KEY_R);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_LALT, GBA_KEY_START);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_LCTRL, GBA_KEY_SELECT);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_UP, GBA_KEY_UP);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_DOWN, GBA_KEY_DOWN);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_LEFT, GBA_KEY_LEFT);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RIGHT, GBA_KEY_RIGHT);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_PAGEDOWN, GBA_KEY_A);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_END, GBA_KEY_B);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RSHIFT, GBA_KEY_L);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RCTRL, GBA_KEY_R);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_LALT, GBA_KEY_START);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_LCTRL, GBA_KEY_SELECT);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_UP, GBA_KEY_UP);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_DOWN, GBA_KEY_DOWN);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_LEFT, GBA_KEY_LEFT);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RIGHT, GBA_KEY_RIGHT);
#elif SDL_VERSION_ATLEAST(2, 0, 0)
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_X, GBA_KEY_A);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_Z, GBA_KEY_B);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_A, GBA_KEY_L);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_S, GBA_KEY_R);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_RETURN, GBA_KEY_START);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_BACKSPACE, GBA_KEY_SELECT);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_UP, GBA_KEY_UP);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_DOWN, GBA_KEY_DOWN);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_LEFT, GBA_KEY_LEFT);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_RIGHT, GBA_KEY_RIGHT);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_X, GBA_KEY_A);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_Z, GBA_KEY_B);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_A, GBA_KEY_L);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_S, GBA_KEY_R);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_RETURN, GBA_KEY_START);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_BACKSPACE, GBA_KEY_SELECT);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_UP, GBA_KEY_UP);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_DOWN, GBA_KEY_DOWN);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_LEFT, GBA_KEY_LEFT);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_RIGHT, GBA_KEY_RIGHT);
#else
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_x, GBA_KEY_A);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_z, GBA_KEY_B);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_a, GBA_KEY_L);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_s, GBA_KEY_R);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RETURN, GBA_KEY_START);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_BACKSPACE, GBA_KEY_SELECT);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_UP, GBA_KEY_UP);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_DOWN, GBA_KEY_DOWN);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_LEFT, GBA_KEY_LEFT);
GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RIGHT, GBA_KEY_RIGHT);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_x, GBA_KEY_A);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_z, GBA_KEY_B);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_a, GBA_KEY_L);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_s, GBA_KEY_R);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RETURN, GBA_KEY_START);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_BACKSPACE, GBA_KEY_SELECT);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_UP, GBA_KEY_UP);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_DOWN, GBA_KEY_DOWN);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_LEFT, GBA_KEY_LEFT);
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RIGHT, GBA_KEY_RIGHT);
#endif
GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 13, GBA_KEY_A);
GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 14, GBA_KEY_B);
GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 10, GBA_KEY_L);
GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 11, GBA_KEY_R);
GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 3, GBA_KEY_START);
GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 0, GBA_KEY_SELECT);
GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 4, GBA_KEY_UP);
GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 6, GBA_KEY_DOWN);
GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 7, GBA_KEY_LEFT);
GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 5, GBA_KEY_RIGHT);
mInputBindKey(inputMap, SDL_BINDING_BUTTON, 13, GBA_KEY_A);
mInputBindKey(inputMap, SDL_BINDING_BUTTON, 14, GBA_KEY_B);
mInputBindKey(inputMap, SDL_BINDING_BUTTON, 10, GBA_KEY_L);
mInputBindKey(inputMap, SDL_BINDING_BUTTON, 11, GBA_KEY_R);
mInputBindKey(inputMap, SDL_BINDING_BUTTON, 3, GBA_KEY_START);
mInputBindKey(inputMap, SDL_BINDING_BUTTON, 0, GBA_KEY_SELECT);
mInputBindKey(inputMap, SDL_BINDING_BUTTON, 4, GBA_KEY_UP);
mInputBindKey(inputMap, SDL_BINDING_BUTTON, 6, GBA_KEY_DOWN);
mInputBindKey(inputMap, SDL_BINDING_BUTTON, 7, GBA_KEY_LEFT);
mInputBindKey(inputMap, SDL_BINDING_BUTTON, 5, GBA_KEY_RIGHT);
struct GBAAxis description = { GBA_KEY_RIGHT, GBA_KEY_LEFT, 0x4000, -0x4000 };
GBAInputBindAxis(inputMap, SDL_BINDING_BUTTON, 0, &description);
description = (struct GBAAxis) { GBA_KEY_DOWN, GBA_KEY_UP, 0x4000, -0x4000 };
GBAInputBindAxis(inputMap, SDL_BINDING_BUTTON, 1, &description);
struct mInputAxis description = { GBA_KEY_RIGHT, GBA_KEY_LEFT, 0x4000, -0x4000 };
mInputBindAxis(inputMap, SDL_BINDING_BUTTON, 0, &description);
description = (struct mInputAxis) { GBA_KEY_DOWN, GBA_KEY_UP, 0x4000, -0x4000 };
mInputBindAxis(inputMap, SDL_BINDING_BUTTON, 1, &description);
}
bool GBASDLAttachPlayer(struct GBASDLEvents* events, struct GBASDLPlayer* player) {
@ -246,49 +246,49 @@ void GBASDLDetachPlayer(struct GBASDLEvents* events, struct GBASDLPlayer* player
}
void GBASDLPlayerLoadConfig(struct GBASDLPlayer* context, const struct Configuration* config) {
GBAInputMapLoad(context->bindings, SDL_BINDING_KEY, config);
mInputMapLoad(context->bindings, SDL_BINDING_KEY, config);
if (context->joystick) {
GBAInputMapLoad(context->bindings, SDL_BINDING_BUTTON, config);
mInputMapLoad(context->bindings, SDL_BINDING_BUTTON, config);
#if SDL_VERSION_ATLEAST(2, 0, 0)
const char* name = SDL_JoystickName(context->joystick->joystick);
#else
const char* name = SDL_JoystickName(SDL_JoystickIndex(context->joystick->joystick));
#endif
GBAInputProfileLoad(context->bindings, SDL_BINDING_BUTTON, config, name);
mInputProfileLoad(context->bindings, SDL_BINDING_BUTTON, config, name);
const char* value;
char* end;
int numAxes = SDL_JoystickNumAxes(context->joystick->joystick);
int axis;
value = GBAInputGetCustomValue(config, SDL_BINDING_BUTTON, "tiltAxisX", name);
value = mInputGetCustomValue(config, "gba", SDL_BINDING_BUTTON, "tiltAxisX", name);
if (value) {
axis = strtol(value, &end, 0);
if (axis >= 0 && axis < numAxes && end && !*end) {
context->rotation.axisX = axis;
}
}
value = GBAInputGetCustomValue(config, SDL_BINDING_BUTTON, "tiltAxisY", name);
value = mInputGetCustomValue(config, "gba", SDL_BINDING_BUTTON, "tiltAxisY", name);
if (value) {
axis = strtol(value, &end, 0);
if (axis >= 0 && axis < numAxes && end && !*end) {
context->rotation.axisY = axis;
}
}
value = GBAInputGetCustomValue(config, SDL_BINDING_BUTTON, "gyroAxisX", name);
value = mInputGetCustomValue(config, "gba", SDL_BINDING_BUTTON, "gyroAxisX", name);
if (value) {
axis = strtol(value, &end, 0);
if (axis >= 0 && axis < numAxes && end && !*end) {
context->rotation.gyroX = axis;
}
}
value = GBAInputGetCustomValue(config, SDL_BINDING_BUTTON, "gyroAxisY", name);
value = mInputGetCustomValue(config, "gba", SDL_BINDING_BUTTON, "gyroAxisY", name);
if (value) {
axis = strtol(value, &end, 0);
if (axis >= 0 && axis < numAxes && end && !*end) {
context->rotation.gyroY = axis;
}
}
value = GBAInputGetCustomValue(config, SDL_BINDING_BUTTON, "gyroSensitivity", name);
value = mInputGetCustomValue(config, "gba", SDL_BINDING_BUTTON, "gyroSensitivity", name);
if (value) {
float sensitivity = strtof_u(value, &end);
if (end && !*end) {
@ -307,15 +307,15 @@ void GBASDLPlayerSaveConfig(const struct GBASDLPlayer* context, struct Configura
#endif
char value[12];
snprintf(value, sizeof(value), "%i", context->rotation.axisX);
GBAInputSetCustomValue(config, SDL_BINDING_BUTTON, "tiltAxisX", value, name);
mInputSetCustomValue(config, "gba", SDL_BINDING_BUTTON, "tiltAxisX", value, name);
snprintf(value, sizeof(value), "%i", context->rotation.axisY);
GBAInputSetCustomValue(config, SDL_BINDING_BUTTON, "tiltAxisY", value, name);
mInputSetCustomValue(config, "gba", SDL_BINDING_BUTTON, "tiltAxisY", value, name);
snprintf(value, sizeof(value), "%i", context->rotation.gyroX);
GBAInputSetCustomValue(config, SDL_BINDING_BUTTON, "gyroAxisX", value, name);
mInputSetCustomValue(config, "gba", SDL_BINDING_BUTTON, "gyroAxisX", value, name);
snprintf(value, sizeof(value), "%i", context->rotation.gyroY);
GBAInputSetCustomValue(config, SDL_BINDING_BUTTON, "gyroAxisY", value, name);
mInputSetCustomValue(config, "gba", SDL_BINDING_BUTTON, "gyroAxisY", value, name);
snprintf(value, sizeof(value), "%g", context->rotation.gyroSensitivity);
GBAInputSetCustomValue(config, SDL_BINDING_BUTTON, "gyroSensitivity", value, name);
mInputSetCustomValue(config, "gba", SDL_BINDING_BUTTON, "gyroSensitivity", value, name);
}
}
@ -380,9 +380,9 @@ static void _GBASDLHandleKeypress(struct GBAThread* context, struct GBASDLPlayer
enum GBAKey key = GBA_KEY_NONE;
if (!event->keysym.mod) {
#if !defined(BUILD_PANDORA) && SDL_VERSION_ATLEAST(2, 0, 0)
key = GBAInputMapKey(sdlContext->bindings, SDL_BINDING_KEY, event->keysym.scancode);
key = mInputMapKey(sdlContext->bindings, SDL_BINDING_KEY, event->keysym.scancode);
#else
key = GBAInputMapKey(sdlContext->bindings, SDL_BINDING_KEY, event->keysym.sym);
key = mInputMapKey(sdlContext->bindings, SDL_BINDING_KEY, event->keysym.sym);
#endif
}
if (key != GBA_KEY_NONE) {
@ -495,7 +495,7 @@ static void _GBASDLHandleKeypress(struct GBAThread* context, struct GBASDLPlayer
static void _GBASDLHandleJoyButton(struct GBAThread* context, struct GBASDLPlayer* sdlContext, const struct SDL_JoyButtonEvent* event) {
enum GBAKey key = 0;
key = GBAInputMapKey(sdlContext->bindings, SDL_BINDING_BUTTON, event->button);
key = mInputMapKey(sdlContext->bindings, SDL_BINDING_BUTTON, event->button);
if (key == GBA_KEY_NONE) {
return;
}
@ -530,8 +530,8 @@ static void _GBASDLHandleJoyHat(struct GBAThread* context, const struct SDL_JoyH
static void _GBASDLHandleJoyAxis(struct GBAThread* context, struct GBASDLPlayer* sdlContext, const struct SDL_JoyAxisEvent* event) {
int keys = context->activeKeys;
keys = GBAInputClearAxis(sdlContext->bindings, SDL_BINDING_BUTTON, event->axis, keys);
enum GBAKey key = GBAInputMapAxis(sdlContext->bindings, SDL_BINDING_BUTTON, event->axis, event->value);
keys = mInputClearAxis(sdlContext->bindings, SDL_BINDING_BUTTON, event->axis, keys);
enum GBAKey key = mInputMapAxis(sdlContext->bindings, SDL_BINDING_BUTTON, event->axis, event->value);
if (key != GBA_KEY_NONE) {
keys |= 1 << key;
}

View File

@ -48,7 +48,7 @@ struct GBASDLEvents {
struct GBASDLPlayer {
size_t playerId;
struct GBAInputMap* bindings;
struct mInputMap* bindings;
struct SDL_JoystickCombo* joystick;
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_Window* window;
@ -92,7 +92,7 @@ void GBASDLEventsLoadConfig(struct GBASDLEvents*, const struct Configuration*);
void GBASDLPlayerChangeJoystick(struct GBASDLEvents*, struct GBASDLPlayer*, size_t index);
void GBASDLUpdateJoysticks(struct GBASDLEvents* events);
void GBASDLInitBindings(struct GBAInputMap* inputMap);
void GBASDLInitBindings(struct mInputMap* inputMap);
void GBASDLPlayerLoadConfig(struct GBASDLPlayer*, const struct Configuration*);
void GBASDLPlayerSaveConfig(const struct GBASDLPlayer*, struct Configuration*);

View File

@ -28,8 +28,8 @@
#define WIIMOTE_INPUT 0x5749494D
#define CLASSIC_INPUT 0x57494943
static void _mapKey(struct GBAInputMap* map, uint32_t binding, int nativeKey, enum GBAKey key) {
GBAInputBindKey(map, binding, __builtin_ctz(nativeKey), key);
static void _mapKey(struct mInputMap* map, uint32_t binding, int nativeKey, enum GBAKey key) {
mInputBindKey(map, binding, __builtin_ctz(nativeKey), key);
}
static enum ScreenMode {
@ -552,12 +552,12 @@ void _setup(struct GBAGUIRunner* runner) {
_mapKey(&runner->context.inputMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_FULL_L, GBA_KEY_L);
_mapKey(&runner->context.inputMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_FULL_R, GBA_KEY_R);
struct GBAAxis desc = { GBA_KEY_RIGHT, GBA_KEY_LEFT, 0x20, -0x20 };
GBAInputBindAxis(&runner->context.inputMap, GCN1_INPUT, 0, &desc);
GBAInputBindAxis(&runner->context.inputMap, CLASSIC_INPUT, 0, &desc);
desc = (struct GBAAxis) { GBA_KEY_UP, GBA_KEY_DOWN, 0x20, -0x20 };
GBAInputBindAxis(&runner->context.inputMap, GCN1_INPUT, 1, &desc);
GBAInputBindAxis(&runner->context.inputMap, CLASSIC_INPUT, 1, &desc);
struct mInputAxis desc = { GBA_KEY_RIGHT, GBA_KEY_LEFT, 0x20, -0x20 };
mInputBindAxis(&runner->context.inputMap, GCN1_INPUT, 0, &desc);
mInputBindAxis(&runner->context.inputMap, CLASSIC_INPUT, 0, &desc);
desc = (struct mInputAxis) { GBA_KEY_UP, GBA_KEY_DOWN, 0x20, -0x20 };
mInputBindAxis(&runner->context.inputMap, GCN1_INPUT, 1, &desc);
mInputBindAxis(&runner->context.inputMap, CLASSIC_INPUT, 1, &desc);
GBAVideoSoftwareRendererCreate(&renderer);
renderer.outputBuffer = memalign(32, 256 * 256 * BYTES_PER_PIXEL);
@ -694,25 +694,25 @@ uint16_t _pollGameInput(struct GBAGUIRunner* runner) {
u32 wiiPad = WPAD_ButtonsHeld(0);
u32 ext = 0;
WPAD_Probe(0, &ext);
uint16_t keys = GBAInputMapKeyBits(&runner->context.inputMap, GCN1_INPUT, padkeys, 0);
keys |= GBAInputMapKeyBits(&runner->context.inputMap, GCN2_INPUT, padkeys, 0);
keys |= GBAInputMapKeyBits(&runner->context.inputMap, WIIMOTE_INPUT, wiiPad, 0);
uint16_t keys = mInputMapKeyBits(&runner->context.inputMap, GCN1_INPUT, padkeys, 0);
keys |= mInputMapKeyBits(&runner->context.inputMap, GCN2_INPUT, padkeys, 0);
keys |= mInputMapKeyBits(&runner->context.inputMap, WIIMOTE_INPUT, wiiPad, 0);
enum GBAKey angles = GBAInputMapAxis(&runner->context.inputMap, GCN1_INPUT, 0, PAD_StickX(0));
enum GBAKey angles = mInputMapAxis(&runner->context.inputMap, GCN1_INPUT, 0, PAD_StickX(0));
if (angles != GBA_KEY_NONE) {
keys |= 1 << angles;
}
angles = GBAInputMapAxis(&runner->context.inputMap, GCN1_INPUT, 1, PAD_StickY(0));
angles = mInputMapAxis(&runner->context.inputMap, GCN1_INPUT, 1, PAD_StickY(0));
if (angles != GBA_KEY_NONE) {
keys |= 1 << angles;
}
if (ext == WPAD_EXP_CLASSIC) {
keys |= GBAInputMapKeyBits(&runner->context.inputMap, CLASSIC_INPUT, wiiPad, 0);
angles = GBAInputMapAxis(&runner->context.inputMap, CLASSIC_INPUT, 0, WPAD_StickX(0, 0));
keys |= mInputMapKeyBits(&runner->context.inputMap, CLASSIC_INPUT, wiiPad, 0);
angles = mInputMapAxis(&runner->context.inputMap, CLASSIC_INPUT, 0, WPAD_StickX(0, 0));
if (angles != GBA_KEY_NONE) {
keys |= 1 << angles;
}
angles = GBAInputMapAxis(&runner->context.inputMap, CLASSIC_INPUT, 1, WPAD_StickY(0, 0));
angles = mInputMapAxis(&runner->context.inputMap, CLASSIC_INPUT, 1, WPAD_StickY(0, 0));
if (angles != GBA_KEY_NONE) {
keys |= 1 << angles;
}