diff --git a/Module.mk b/Module.mk index 99892a0a..f9067465 100644 --- a/Module.mk +++ b/Module.mk @@ -110,6 +110,7 @@ include src/main/ddrhook2/Module.mk include src/main/ddrio-async/Module.mk include src/main/ddrio-p3io/Module.mk include src/main/ddrio-mm/Module.mk +include src/main/ddrio-mm-aux/Module.mk include src/main/ddrio-smx/Module.mk include src/main/ddriotest/Module.mk include src/main/ddrio/Module.mk @@ -761,6 +762,7 @@ $(zipdir)/ddr-hwio-x86.zip: \ build/bin/indep-32/ddrio-async.dll \ build/bin/indep-32/ddrio-p3io.dll \ build/bin/indep-32/ddrio-mm.dll \ + build/bin/indep-32/ddrio-mm-aux.dll \ build/bin/indep-32/ddrio-smx.dll \ build/bin/indep-32/extiotest.exe \ build/bin/indep-32/p3io-ddr-tool.exe \ @@ -773,6 +775,7 @@ $(zipdir)/ddr-hwio-x64.zip: \ build/bin/indep-64/ddrio-async.dll \ build/bin/indep-64/ddrio-p3io.dll \ build/bin/indep-64/ddrio-mm.dll \ + build/bin/indep-64/ddrio-mm-aux.dll \ build/bin/indep-64/ddrio-smx.dll \ build/bin/indep-64/extiotest.exe \ build/bin/indep-64/p3io-ddr-tool.exe \ diff --git a/doc/ddrhook/README.md b/doc/ddrhook/README.md index e7fb6fb8..6697be8a 100644 --- a/doc/ddrhook/README.md +++ b/doc/ddrhook/README.md @@ -40,6 +40,7 @@ use: - `ddrio`: Default implementation supporting keyboard, mouse and USB game controllers - ddrio-mm: Support Minimaid custom interface +- ddrio-mm-aux: Minimaid custom interface + default implementation (i.e. augment minimaid with normal hid use) - [ddrio-smx](ddrio-smx.md): Support for StepManiaX dance platforms - [ddrio-p3io](ddrio-p3io.md): P3IO + EXTIO driver implementation - [ddrio-async](ddrio-async.md): Wrapper/shim library to drive another ddrio in a dedicated IO diff --git a/src/main/ddrio-mm-aux/Module.mk b/src/main/ddrio-mm-aux/Module.mk new file mode 100644 index 00000000..541e3297 --- /dev/null +++ b/src/main/ddrio-mm-aux/Module.mk @@ -0,0 +1,14 @@ +dlls += ddrio-mm-aux + +ldflags_ddrio-mm-aux:= \ + -lhid \ + -lsetupapi \ + +libs_ddrio-mm-aux := \ + geninput \ + mm \ + util \ + +src_ddrio-mm-aux := \ + ddrio.c \ + diff --git a/src/main/ddrio-mm-aux/ddrio-mm-aux.def b/src/main/ddrio-mm-aux/ddrio-mm-aux.def new file mode 100644 index 00000000..3a2c0e83 --- /dev/null +++ b/src/main/ddrio-mm-aux/ddrio-mm-aux.def @@ -0,0 +1,11 @@ +LIBRARY ddrio-mm-aux + +EXPORTS + ddr_io_set_loggers + ddr_io_fini + ddr_io_init + ddr_io_read_pad + ddr_io_set_lights_extio + ddr_io_set_lights_p3io + ddr_io_set_lights_hdxs_panel + ddr_io_set_lights_hdxs_rgb diff --git a/src/main/ddrio-mm-aux/ddrio.c b/src/main/ddrio-mm-aux/ddrio.c new file mode 100644 index 00000000..fd1147ac --- /dev/null +++ b/src/main/ddrio-mm-aux/ddrio.c @@ -0,0 +1,260 @@ +#include + +#include +#include +#include +#include + +#include "bemanitools/ddrio.h" +#include "bemanitools/input.h" +#include "mm/mm.h" + +#include "util/cmdline.h" +#include "util/defs.h" +#include "util/log.h" +#include "util/mem.h" + +struct ddr_bittrans { + uint32_t mm; + uint32_t p3io; +}; + +static const struct ddr_bittrans input_map[] = { + {0x00000001, 1 << DDR_SERVICE}, + {0x00000002, 1 << DDR_TEST}, + {0x00100000, 1 << DDR_P1_MENU_LEFT}, + {0x00400000, 1 << DDR_P1_MENU_RIGHT}, + {0x00000100, 1 << DDR_P1_START}, + {0x00200000, 1 << DDR_P2_MENU_LEFT}, + {0x00800000, 1 << DDR_P2_MENU_RIGHT}, + {0x00000200, 1 << DDR_P2_START}, + {0x00004000, 1 << DDR_P1_LEFT}, + {0x00010000, 1 << DDR_P1_RIGHT}, + {0x00000400, 1 << DDR_P1_UP}, + {0x00001000, 1 << DDR_P1_DOWN}, + {0x00008000, 1 << DDR_P2_LEFT}, + {0x00020000, 1 << DDR_P2_RIGHT}, + {0x00000800, 1 << DDR_P2_UP}, + {0x00002000, 1 << DDR_P2_DOWN}, + + /* Nonstandard */ + {0x01000000, 1 << DDR_P1_MENU_UP}, + {0x04000000, 1 << DDR_P1_MENU_DOWN}, + {0x02000000, 1 << DDR_P2_MENU_UP}, + {0x08000000, 1 << DDR_P2_MENU_DOWN}, +}; + +static const struct ddr_bittrans extio_light_map[] = { + {0x00000100, 1 << LIGHT_P1_UP}, + {0x00000200, 1 << LIGHT_P1_DOWN}, + {0x00000400, 1 << LIGHT_P1_LEFT}, + {0x00000800, 1 << LIGHT_P1_RIGHT}, + {0x00010000, 1 << LIGHT_P2_UP}, + {0x00020000, 1 << LIGHT_P2_DOWN}, + {0x00040000, 1 << LIGHT_P2_LEFT}, + {0x00080000, 1 << LIGHT_P2_RIGHT}, + {0x01000000, 1 << LIGHT_NEONS}, +}; + +static const struct ddr_bittrans p3io_light_map[] = { + {0x00000004, 1 << LIGHT_P1_MENU}, + {0x00000008, 1 << LIGHT_P2_MENU}, + {0x00000010, 1 << LIGHT_P2_LOWER_LAMP}, + {0x00000020, 1 << LIGHT_P2_UPPER_LAMP}, + {0x00000040, 1 << LIGHT_P1_LOWER_LAMP}, + {0x00000080, 1 << LIGHT_P1_UPPER_LAMP}, +}; + +static bool initted; +static CRITICAL_SECTION cs; +static struct mm_output out; + +static int ddr_io_get_lag_param(void) +{ + int argc; + char **argv; + int result; + int i; + + result = 0; + + args_recover(&argc, &argv); + + for (i = 1; i < argc; i++) { + if (argv[i][0] != '-') { + continue; + } + + switch (argv[i][1]) { + case 'a': + if (i + 1 == argc) { + continue; + } + + result = atoi(argv[i + 1]); + + break; + } + } + + args_free(argc, argv); + + if (result < 0) { + /* snark snark */ + log_warning( + "This PCB is incapable of seeing into the future. " + "Defaulting to 0 injected lag samples"); + + result = 0; + } + + return result; +} + +void ddr_io_set_loggers( + log_formatter_t misc, + log_formatter_t info, + log_formatter_t warning, + log_formatter_t fatal) +{ + log_to_external(misc, info, warning, fatal); + input_set_loggers(misc, info, warning, fatal); +} + +bool ddr_io_init( + thread_create_t thread_create, + thread_join_t thread_join, + thread_destroy_t thread_destroy) +{ + bool ok; + + log_assert(!initted); + + /* Use geninput for menu/operator btns */ + input_init(thread_create, thread_join, thread_destroy); + mapper_config_load("ddr"); + + ok = mm_init(2 + ddr_io_get_lag_param()); + + if (!ok) { + return false; + } + + InitializeCriticalSection(&cs); + out.lights = 0x00101000; /* Hold pad IO board FSMs in reset */ + //out.kbd_enable = 1; /* allow kb input */ + initted = true; + + return true; +} + +uint32_t ddr_io_read_pad(void) +{ + struct mm_input in; + uint32_t i; + uint32_t pad; + + EnterCriticalSection(&cs); + + mm_update(&out, &in); + pad = 0; + + for (i = 0; i < lengthof(input_map); i++) { + if (in.jamma & input_map[i].mm) { + pad |= input_map[i].p3io; + } + } + + LeaveCriticalSection(&cs); + + // or results from minimaid and normal bt5 input mappings + return pad | mapper_update(); +} + +void ddr_io_set_lights_extio(uint32_t extio_lights) +{ + // MINIMAID LIGHTS + uint32_t clr; + uint32_t set; + int i; + + clr = 0; + set = 0; + + for (i = 0; i < lengthof(extio_light_map); i++) { + if (extio_lights & extio_light_map[i].p3io /* misnomer but w/e */) { + set |= extio_light_map[i].mm; + } else { + clr |= extio_light_map[i].mm; + } + } + + atomic_fetch_or(&out.lights, set); + atomic_fetch_and(&out.lights, ~clr); + + // NORMAL HID LIGHTS + uint8_t j; + for (j = 0x0E; j <= 0x1E; j++) { + mapper_write_light(j, extio_lights & (1 << j) ? 255 : 0); + } +} + +void ddr_io_set_lights_p3io(uint32_t p3io_lights) +{ + // MINIMAID LIGHTS + uint32_t clr; + uint32_t set; + int i; + + clr = 0; + set = 0; + + for (i = 0; i < lengthof(p3io_light_map); i++) { + if (p3io_lights & p3io_light_map[i].p3io) { + set |= p3io_light_map[i].mm; + } else { + clr |= p3io_light_map[i].mm; + } + } + + atomic_fetch_or(&out.lights, set); + atomic_fetch_and(&out.lights, ~clr); + + // NORMAL HID LIGHTS + uint8_t j; + for (j = 0x00; j <= 0x07; j++) { + mapper_write_light(j, p3io_lights & (1 << j) ? 255 : 0); + } +} + +void ddr_io_set_lights_hdxs_panel(uint32_t lights) +{ + // NORMAL HID LIGHTS + uint8_t i; + + for (i = 0x08; i <= 0x0D; i++) { + mapper_write_light(i, lights & (1 << i) ? 255 : 0); + } +} + +void ddr_io_set_lights_hdxs_rgb(uint8_t idx, uint8_t r, uint8_t g, uint8_t b) +{ + // NORMAL HID LIGHTS + if (idx < 4) { + uint8_t base = 0x20 + idx * 3; + mapper_write_light(base + 0, r); + mapper_write_light(base + 1, g); + mapper_write_light(base + 2, b); + } +} + +void ddr_io_fini(void) +{ + input_fini(); + + if (initted) { + mm_fini(); + DeleteCriticalSection(&cs); + initted = false; + } +}