mirror of https://github.com/mgba-emu/mgba.git
Core: Refactor GBAInput into mInput
This commit is contained in:
parent
bc1a094bea
commit
59f78a05e4
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
564
src/gba/input.c
564
src/gba/input.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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*);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue