Invert analog + mapper save versioning #275

Merged
ahnada merged 4 commits from asc into master 2024-01-31 23:40:22 +03:00
9 changed files with 187 additions and 20 deletions
+38
View File
@@ -49,11 +49,13 @@ static INT_PTR analog_ui_handle_init(HWND hwnd, struct analog_def *def);
static void analog_ui_handle_init_label(HWND hwnd);
static void analog_ui_handle_init_dev(HWND hwnd);
static void analog_ui_handle_init_sensitivity(HWND hwnd);
static void analog_ui_handle_init_invert(HWND hwnd);
static bool analog_ui_match_device(struct hid_stub *hid);
static void analog_ui_populate_controls(HWND hwnd);
static INT_PTR analog_ui_handle_device_change(HWND hwnd);
static INT_PTR analog_ui_handle_control_change(HWND hwnd);
static INT_PTR analog_ui_handle_sensitivity_change(HWND hwnd);
static INT_PTR analog_ui_handle_invert_change(HWND hwnd);
static INT_PTR analog_ui_handle_tick(HWND hwnd);
static INT_PTR analog_ui_handle_fini(HWND hwnd);
@@ -213,6 +215,15 @@ analog_ui_dlg_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
return FALSE;
}
case BN_CLICKED:
switch (LOWORD(wparam)) {
case IDC_ANALOG_INVERT:
return analog_ui_handle_invert_change(hwnd);
default:
return FALSE;
}
default:
return FALSE;
}
@@ -248,6 +259,7 @@ static INT_PTR analog_ui_handle_init(HWND hwnd, struct analog_def *def)
analog_ui_handle_init_label(hwnd);
analog_ui_handle_init_dev(hwnd);
analog_ui_handle_init_sensitivity(hwnd);
analog_ui_handle_init_invert(hwnd);
return TRUE;
}
@@ -343,6 +355,17 @@ static void analog_ui_handle_init_sensitivity(HWND hwnd)
EnableWindow(slider, !mapper_is_analog_absolute(ui->def->tag));
}
static void analog_ui_handle_init_invert(HWND hwnd)
{
struct analog_ui *ui;
ui = (struct analog_ui *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
if (mapper_get_analog_invert(ui->def->tag)) {
SendMessage(GetDlgItem(hwnd, IDC_ANALOG_INVERT), BM_SETCHECK, BST_CHECKED, 0);
}
}
static bool analog_ui_match_device(struct hid_stub *hid)
{
struct hid_control *controls;
@@ -519,6 +542,21 @@ static INT_PTR analog_ui_handle_sensitivity_change(HWND hwnd)
return TRUE;
}
static INT_PTR analog_ui_handle_invert_change(HWND hwnd)
{
struct analog_ui *ui;
HWND btn;
bool invert;
ui = (struct analog_ui *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
btn = GetDlgItem(hwnd, IDC_ANALOG_INVERT);
invert = SendMessage(btn, BM_GETCHECK, 0, 0) == BST_CHECKED;
mapper_set_analog_invert(ui->def->tag, invert);
return TRUE;
}
static INT_PTR analog_ui_handle_tick(HWND hwnd)
{
struct analog_ui *ui;
+4 -3
View File
@@ -22,18 +22,19 @@ IDR_USAGES USAGES "config/usages.txt"
// Dialog resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_ANALOG DIALOG 0, 0, 220, 100
IDD_ANALOG DIALOG 0, 0, 220, 115
STYLE DS_3DLOOK | DS_CENTER | DS_SHELLFONT | WS_VISIBLE | WS_CHILDWINDOW
EXSTYLE WS_EX_CONTROLPARENT
FONT 8, "Ms Shell Dlg"
{
GROUPBOX "", IDC_GROUP, 5, 5, 210, 90
GROUPBOX "", IDC_GROUP, 5, 5, 210, 105
CONTROL "", IDC_SENSITIVITY, TRACKBAR_CLASS, WS_TABSTOP | TBS_AUTOTICKS, 10, 75, 200, 15
LTEXT "Device", IDC_STATIC, 15, 15, 24, 8, SS_LEFT
COMBOBOX IDC_DEVICE, 15, 25, 135, 30, WS_GROUP | WS_TABSTOP | CBS_DROPDOWNLIST | CBS_HASSTRINGS
COMBOBOX IDC_CONTROL, 15, 50, 135, 30, WS_TABSTOP | CBS_DROPDOWNLIST | CBS_HASSTRINGS
LTEXT "Sensitivity", IDC_STATIC, 15, 65, 32, 8, SS_LEFT
LTEXT "Control", IDC_STATIC, 15, 40, 23, 8, SS_LEFT
AUTOCHECKBOX "Invert Axis", IDC_ANALOG_INVERT, 15, 95, 141, 8
CONTROL "", IDC_POSITION, "spinner", 0x50020000, 160, 15, 50, 50, 0x02002000
}
@@ -126,7 +127,7 @@ FONT 8, "Ms Shell Dlg"
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_TAB_ANALOGS DIALOG 0, 0, 220, 215
IDD_TAB_ANALOGS DIALOG 0, 0, 220, 230
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
CAPTION "Analogs"
FONT 8, "Ms Shell Dlg"
+1
View File
@@ -30,6 +30,7 @@
#define IDC_DEVICE 1005
#define IDC_BINDING_EDIT 1006
#define IDC_CONTROL 1006
#define IDC_ANALOG_INVERT 1007
#define IDC_BINDING_CLEAR 1007
#define IDC_BINDING_MIN 1008
#define IDC_PAGE_TEXT 1008
+2
View File
@@ -35,6 +35,7 @@ EXPORTS
mapper_get_action_map
mapper_get_analog_map
mapper_get_analog_sensitivity
mapper_get_analog_invert
mapper_get_npages
mapper_get_nanalogs
mapper_get_nlights
@@ -44,6 +45,7 @@ EXPORTS
mapper_set_action_map
mapper_set_analog_map
mapper_set_analog_sensitivity
mapper_set_analog_invert
mapper_set_light_map
mapper_set_nanalogs
mapper_set_nlights
+2
View File
@@ -15,6 +15,7 @@ bool mapper_get_action_map(
uint8_t action, uint8_t page, struct mapped_action *ma);
bool mapper_get_analog_map(uint8_t analog, struct mapped_analog *ma);
int32_t mapper_get_analog_sensitivity(uint8_t analog);
bool mapper_get_analog_invert(uint8_t analog);
uint8_t mapper_get_nanalogs(void);
uint8_t mapper_get_nlights(void);
uint8_t mapper_get_npages(void);
@@ -25,6 +26,7 @@ void mapper_set_action_map(
uint8_t action, uint8_t page, uint8_t bit, const struct mapped_action *ma);
bool mapper_set_analog_map(uint8_t analog, const struct mapped_analog *ma);
bool mapper_set_analog_sensitivity(uint8_t analog, int32_t sensitivity);
bool mapper_set_analog_invert(uint8_t analog, bool invert);
void mapper_set_nanalogs(uint8_t nanalogs);
void mapper_set_nlights(uint8_t nlights);
void mapper_set_light_map(const struct mapped_light *ml, uint8_t game_light);
+22 -2
View File
@@ -25,10 +25,20 @@ static volatile long input_init_count;
static FILE *mapper_config_open(const char *game_type, const char *mode)
{
char path[MAX_PATH];
FILE *f;
str_format(path, sizeof(path), "%s_v5_00a07.bin", game_type);
str_format(path, sizeof(path), "%s.bin", game_type);
f = fopen_appdata("DJHACKERS", path, mode);
return fopen_appdata("DJHACKERS", path, mode);
// Try to load the old save file only if we're loading
if (f == NULL) {
if (strchr(mode, 'r') != NULL) {
str_format(path, sizeof(path), "%s_v5_00a07.bin", game_type);
f = fopen_appdata("DJHACKERS", path, mode);
}
}
return f;
}
void input_set_loggers(
@@ -144,6 +154,11 @@ int32_t mapper_get_analog_sensitivity(uint8_t analog)
return mapper_impl_get_analog_sensitivity(mapper_inst, analog);
}
bool mapper_get_analog_invert(uint8_t analog)
{
return mapper_impl_get_analog_invert(mapper_inst, analog);
}
uint8_t mapper_get_nanalogs(void)
{
return mapper_impl_get_nanalogs(mapper_inst);
@@ -190,6 +205,11 @@ bool mapper_set_analog_sensitivity(uint8_t analog, int32_t sensitivity)
return mapper_impl_set_analog_sensitivity(mapper_inst, analog, sensitivity);
}
bool mapper_set_analog_invert(uint8_t analog, bool invert)
{
return mapper_impl_set_analog_invert(mapper_inst, analog, invert);
}
void mapper_set_light_map(const struct mapped_light *ml, uint8_t game_light)
{
mapper_impl_set_light_map(mapper_inst, ml, game_light);
+70 -9
View File
@@ -6,9 +6,25 @@
#include "util/fs.h"
#include "util/mem.h"
static bool mapper_impl_config_load_actions(struct mapper *m, FILE *f);
static bool mapper_impl_config_load_analogs(struct mapper *m, FILE *f);
static bool mapper_impl_config_load_lights(struct mapper *m, FILE *f);
enum mapper_config_version {
MAPPER_VERSION_BEFORE_VERSIONING = 0,
MAPPER_VERSION_INVERT_AXIS,
// --- Add new versions above this line --- //
MAPPER_VERSION_PLUS_ONE,
MAPPER_VERSION_LATEST = MAPPER_VERSION_PLUS_ONE - 1,
};
#define FOURCC(a, b, c, d) \
((uint32_t) (((d) << 24) | ((c) << 16) | ((b) << 8) | (a)))
// Bemanitools Mapper Data
static const uint32_t mapper_fourcc = FOURCC('B', 'T', 'M', 'D');
static uint32_t mapper_impl_config_load_version(FILE *f);
static bool mapper_impl_config_load_actions(struct mapper *m, FILE *f, uint32_t version);
static bool mapper_impl_config_load_analogs(struct mapper *m, FILE *f, uint32_t version);
static bool mapper_impl_config_load_lights(struct mapper *m, FILE *f, uint32_t version);
static void mapper_impl_config_save_actions(struct mapper *m, FILE *f);
static void mapper_impl_config_save_analogs(struct mapper *m, FILE *f);
static void mapper_impl_config_save_lights(struct mapper *m, FILE *f);
@@ -16,14 +32,17 @@ static void mapper_impl_config_save_lights(struct mapper *m, FILE *f);
struct mapper *mapper_impl_config_load(FILE *f)
{
struct mapper *m;
uint32_t version = MAPPER_VERSION_BEFORE_VERSIONING;
hid_mgr_lock(); /* Need to convert from HID objects to /dev nodes */
version = mapper_impl_config_load_version(f);
m = mapper_impl_create();
if (!mapper_impl_config_load_actions(m, f) ||
!mapper_impl_config_load_analogs(m, f) ||
!mapper_impl_config_load_lights(m, f)) {
if (!mapper_impl_config_load_actions(m, f, version) ||
!mapper_impl_config_load_analogs(m, f, version) ||
!mapper_impl_config_load_lights(m, f, version)) {
mapper_impl_destroy(m);
m = NULL;
}
@@ -33,7 +52,29 @@ struct mapper *mapper_impl_config_load(FILE *f)
return m;
}
static bool mapper_impl_config_load_actions(struct mapper *m, FILE *f)
static uint32_t mapper_impl_config_load_version(FILE *f)
{
uint32_t fourcc = 0;
uint32_t version = MAPPER_VERSION_BEFORE_VERSIONING;
if (!read_u32(f, &fourcc)) {
return 0;
}
if (fourcc == mapper_fourcc) {
if (!read_u32(f, &version)) {
fseek(f, -4, SEEK_CUR);
}
} else {
fseek(f, -4, SEEK_CUR);
}
return version;
}
static bool mapper_impl_config_load_actions(struct mapper *m, FILE *f, uint32_t version)
{
char *dev_node;
struct mapped_action ma;
@@ -69,11 +110,12 @@ static bool mapper_impl_config_load_actions(struct mapper *m, FILE *f)
return true;
}
static bool mapper_impl_config_load_analogs(struct mapper *m, FILE *f)
static bool mapper_impl_config_load_analogs(struct mapper *m, FILE *f, uint32_t version)
{
char *dev_node;
struct mapped_analog ma;
int32_t sensitivity;
bool invert;
uint8_t nanalogs;
uint8_t i;
@@ -101,8 +143,19 @@ static bool mapper_impl_config_load_analogs(struct mapper *m, FILE *f)
return false;
}
if (version >= MAPPER_VERSION_INVERT_AXIS) {
if (!read_u8(f, &invert)) {
return false;
}
} else {
invert = false;
}
mapper_impl_set_analog_map(m, i, &ma);
mapper_impl_set_analog_sensitivity(m, i, sensitivity);
mapper_impl_set_analog_invert(m, i, invert);
}
free(dev_node);
@@ -111,7 +164,7 @@ static bool mapper_impl_config_load_analogs(struct mapper *m, FILE *f)
return true;
}
static bool mapper_impl_config_load_lights(struct mapper *m, FILE *f)
static bool mapper_impl_config_load_lights(struct mapper *m, FILE *f, uint32_t version)
{
char *dev_node;
struct mapped_light ml;
@@ -156,8 +209,13 @@ static bool mapper_impl_config_load_lights(struct mapper *m, FILE *f)
void mapper_impl_config_save(struct mapper *m, FILE *f)
{
const uint32_t mapper_latest_version = MAPPER_VERSION_LATEST;
hid_mgr_lock();
write_u32(f, &mapper_fourcc);
write_u32(f, &mapper_latest_version);
mapper_impl_config_save_actions(m, f);
mapper_impl_config_save_analogs(m, f);
mapper_impl_config_save_lights(m, f);
@@ -211,6 +269,7 @@ static void mapper_impl_config_save_analogs(struct mapper *m, FILE *f)
{
struct mapped_analog ma;
int32_t sensitivity;
bool invert;
uint8_t nanalogs;
uint8_t i;
@@ -224,10 +283,12 @@ static void mapper_impl_config_save_analogs(struct mapper *m, FILE *f)
write_str(f, "");
} else {
sensitivity = mapper_impl_get_analog_sensitivity(m, i);
invert = mapper_impl_get_analog_invert(m, i);
write_str(f, hid_stub_get_dev_node(ma.hid));
write_u32(f, &ma.control_no);
write_u32(f, &sensitivity);
write_u8(f, &invert);
}
}
}
+45 -6
View File
@@ -26,8 +26,10 @@ struct analog_mapping {
bool bound;
bool valid;
bool absolute;
double affine_scale;
double affine_bias;
bool invert;
double analog_min;
double analog_max;
double inv_analog_range;
uint8_t pos;
};
@@ -169,8 +171,9 @@ static void analog_mapping_bind(struct analog_mapping *am)
ctl = &controls[am->src.control_no];
am->affine_bias = ctl->value_min;
am->affine_scale = ctl->value_max - ctl->value_min;
am->analog_min = ctl->value_min;
am->analog_max = ctl->value_max;
am->inv_analog_range = 1.0 / ((int64_t)ctl->value_max - ctl->value_min);
am->absolute = !(ctl->flags & HID_FLAG_RELATIVE);
am->valid = true;
@@ -187,6 +190,7 @@ static void analog_mapping_update(struct analog_mapping *am)
{
double tmp;
int32_t value;
int8_t delta;
if (!am->bound) {
analog_mapping_bind(am);
@@ -201,10 +205,24 @@ static void analog_mapping_update(struct analog_mapping *am)
}
if (am->absolute) {
tmp = (value - am->affine_bias) / am->affine_scale;
if (am->invert) {
tmp = am->analog_max - value;
} else {
tmp = value - am->analog_min;
}
// Scale the input value to [0,1] range
tmp *= am->inv_analog_range;
am->pos = (uint8_t) ((tmp + 0.5) * 256.0);
} else {
am->pos += (int8_t) (value * exp(am->sensitivity / 256.0));
delta = (int8_t) (value * exp(am->sensitivity / 256.0));
if (am->invert) {
delta *= -1;
}
am->pos += delta;
}
}
@@ -406,6 +424,15 @@ int32_t mapper_impl_get_analog_sensitivity(struct mapper *m, uint8_t analog)
return m->analogs[analog].sensitivity;
}
bool mapper_impl_get_analog_invert(struct mapper* m, uint8_t analog)
{
if (analog >= m->nanalogs) {
return 0;
}
return m->analogs[analog].invert;
}
uint8_t mapper_impl_get_nanalogs(struct mapper *m)
{
return m->nanalogs;
@@ -531,6 +558,18 @@ bool mapper_impl_set_analog_sensitivity(
return true;
}
bool mapper_impl_set_analog_invert(
struct mapper *m, uint8_t analog, bool invert)
{
if (analog >= m->nanalogs) {
return false;
}
m->analogs[analog].invert = invert;
return true;
}
void mapper_impl_set_light_map(
struct mapper *m, const struct mapped_light *ml, uint8_t game_light)
{
+3
View File
@@ -57,6 +57,7 @@ bool mapper_impl_get_analog_map(
bool mapper_impl_get_action_map(
struct mapper *m, uint8_t action, uint8_t page, struct mapped_action *ma);
int32_t mapper_impl_get_analog_sensitivity(struct mapper *m, uint8_t analog);
bool mapper_impl_get_analog_invert(struct mapper *m, uint8_t analog);
uint8_t mapper_impl_get_nanalogs(struct mapper *m);
uint8_t mapper_impl_get_nlights(struct mapper *m);
uint8_t mapper_impl_get_npages(struct mapper *m);
@@ -73,6 +74,8 @@ bool mapper_impl_set_analog_map(
struct mapper *m, uint8_t analog, const struct mapped_analog *ma);
bool mapper_impl_set_analog_sensitivity(
struct mapper *m, uint8_t analog, int32_t sensitivity);
bool mapper_impl_set_analog_invert(
struct mapper *m, uint8_t analog, bool invert);
void mapper_impl_set_light_map(
struct mapper *m, const struct mapped_light *ml, uint8_t game_light);
void mapper_impl_set_nanalogs(struct mapper *m, uint8_t nanalogs);