bananatools/taikohook/bnusio.c

280 lines
5.9 KiB
C

#include <windows.h>
#include <assert.h>
#include <synchapi.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "taikohook/bnusio.h"
#include "taikohook/taiko-dll.h"
#include "hook/table.h"
#include "util/dprintf.h"
/* Handles the USB IO board Ninjro and on use.
* Communicates with the game through AMFW, so
* we have to hook AMFW once it gets loaded by
* the game. Inputs are fairly streight forward,
* test switch, operator menu navigation buttons,
* and 8 analog inputs for the taiko drums. Analog
* ids are, from 0 to 7:
* Left Player Rim Left,
* Left Player Center Left,
* Left Player Center Right,
* Left Player Rim Right,
* Right Player Rim Left,
* Right Player Center Left,
* Right Player Center Right,
* Right Player Rim Right,
*/
uint16_t sys_err = 0;
uint16_t pl_count = 0;
bool mod_enabled = false;
bool testsw_state = false;
static int my_bnusio_Open();
static int my_bnusio_Close();
static int my_bnusio_GetFirmwareVersion();
static int my_bnusio_SetSystemError(uint16_t err);
static int my_bnusio_ClearSram();
static BOOL my_bnusio_ResetIoBoard();
static int my_bnusio_Communication(uint64_t com);
static int my_bnusio_GetSystemError();
static void my_bnusio_SetPLCounter(uint16_t pl_ct);
static int my_bnusio_SetGout(uint8_t id, uint8_t value);
static int my_bnusio_GetAnalogIn(uint8_t id);
static int my_bnusio_GetSwIn();
static int my_bnusio_SetCoinLock(uint8_t id, char value);
static int my_bnusio_GetCoin(uint8_t id);
static int my_bnusio_GetCoinError(uint8_t id);
static int my_bnusio_GetService(uint8_t id);
static int my_bnusio_GetServiceError(uint8_t id);
static const struct hook_symbol bnusio_hooks[] = {
{
.name = "bnusio_Open",
.patch = my_bnusio_Open
},
{
.name = "bnusio_GetFirmwareVersion",
.patch = my_bnusio_GetFirmwareVersion
},
{
.name = "bnusio_Close",
.patch = my_bnusio_Close
},
{
.name = "bnusio_SetSystemError",
.patch = my_bnusio_SetSystemError
},
{
.name = "bnusio_ClearSram",
.patch = my_bnusio_ClearSram
},
{
.name = "bnusio_ResetIoBoard",
.patch = my_bnusio_ResetIoBoard
},
{
.name = "bnusio_Communication",
.patch = my_bnusio_Communication
},
{
.name = "bnusio_GetSystemError",
.patch = my_bnusio_GetSystemError
},
{
.name = "bnusio_SetPLCounter",
.patch = my_bnusio_SetPLCounter
},
{
.name = "bnusio_SetGout",
.patch = my_bnusio_SetGout
},
{
.name = "bnusio_GetAnalogIn",
.patch = my_bnusio_GetAnalogIn
},
{
.name = "bnusio_GetSwIn",
.patch = my_bnusio_GetSwIn
},
{
.name = "bnusio_SetCoinLock",
.patch = my_bnusio_SetCoinLock
},
{
.name = "bnusio_GetCoin",
.patch = my_bnusio_GetCoin
},
{
.name = "bnusio_GetCoinError",
.patch = my_bnusio_GetCoinError
},
{
.name = "bnusio_GetService",
.patch = my_bnusio_GetService
},
{
.name = "bnusio_GetServiceError",
.patch = my_bnusio_GetServiceError
}
};
HRESULT bnusio_hook_init(const struct bnusio_config *cfg)
{
mod_enabled = cfg->enable;
if (mod_enabled) {
dprintf("bnusio: Init\n");
}
return S_OK;
}
void bnusio_insert_hooks(HMODULE target)
{
if (mod_enabled) {
dprintf("bnusio: Apply hooks\n");
hook_table_apply(
target,
"bnusio.dll",
bnusio_hooks,
_countof(bnusio_hooks));
}
}
static int my_bnusio_Open()
{
dprintf("bnusio: Open\n");
return 0;
}
static int my_bnusio_GetFirmwareVersion()
{
dprintf("bnusio: GetFirmwareVersion\n");
return 126;
}
static int my_bnusio_Close()
{
dprintf("bnusio: Close\n");
return 0;
}
static int my_bnusio_SetSystemError(uint16_t err)
{
dprintf("bnusio: SetSystemError %d\n", err);
sys_err = err;
return 0;
}
static int my_bnusio_ClearSram()
{
dprintf("bnusio: ClearSram\n");
return 0;
}
static BOOL my_bnusio_ResetIoBoard()
{
dprintf("bnusio: ResetIoBoard\n");
return false;
}
static int my_bnusio_Communication(uint64_t com)
{
return 0;
}
static int my_bnusio_GetSystemError()
{
dprintf("bnusio: SetSystemError %d\n", sys_err);
return sys_err;
}
static void my_bnusio_SetPLCounter(uint16_t pl_ct)
{
//dprintf("bnusio: SetPLCounter %d\n", pl_ct);
pl_count = pl_ct;
}
static int my_bnusio_SetGout(uint8_t id, uint8_t value)
{
return 0;
}
static int my_bnusio_GetAnalogIn(uint8_t id)
{
uint8_t gamebtns = 0;
taiko_dll.poll();
taiko_dll.get_gamebtns(&gamebtns);
if (gamebtns & 1 << id) {
return 0xffff;
}
return 0;
}
static int my_bnusio_GetSwIn()
{
uint8_t opbtn;
uint32_t opbtn_out = 0;
taiko_dll.poll();
taiko_dll.get_opbtns(&opbtn);
if (opbtn & 0x01) {
// TODO: Toggle so you don't have to hold down the button
opbtn_out |= 1 << 7; // Test
}
if (opbtn & 0x02) {
opbtn_out |= 1 << 14; // Service
}
if (opbtn & 0x04) {
opbtn_out |= 1 << 13; // Up
}
if (opbtn & 0x08) {
opbtn_out |= 1 << 12; // Down
}
if (opbtn & 0x10) {
opbtn_out |= 1 << 9; // Enter
}
return opbtn_out;
}
static int my_bnusio_SetCoinLock(uint8_t id, char value)
{
dprintf("bnusio: SetCoinLock %d %x\n", id, value);
return 0;
}
static int my_bnusio_GetCoin(uint8_t id)
{
uint16_t coins;
uint16_t services;
taiko_dll.read_coin_counter(&coins, &services);
return coins;
}
static int my_bnusio_GetCoinError(uint8_t id)
{
//dprintf("bnusio: GetCoinError %d\n", id);
return 0;
}
static int my_bnusio_GetService(uint8_t id)
{
uint16_t coins;
uint16_t services;
taiko_dll.read_coin_counter(&coins, &services);
return services;
}
static int my_bnusio_GetServiceError(uint8_t id)
{
//dprintf("bnusio: GetServiceError %d\n", id);
return 0;
}