added new aime card reader generation

- Added new aime generation: 837-15286 and 837-15396
- New config setting `[aime] gen=3` for 837-15396
- Updated LED information for card reader
- Updated all games with the needed reader generation?
This commit is contained in:
Dniel97 2023-12-03 18:45:42 +01:00
parent 8c12853051
commit 793417e891
Signed by: Dniel97
GPG Key ID: 6180B3C768FB2E08
25 changed files with 81 additions and 47 deletions

View File

@ -79,7 +79,6 @@ $(BUILD_DIR_ZIP)/fgo.zip:
$(V)mkdir -p $(BUILD_DIR_ZIP)/fgo/DEVICE
$(V)cp $(BUILD_DIR_64)/subprojects/capnhook/inject/inject.exe \
$(BUILD_DIR_64)/fgohook/fgohook.dll \
$(DIST_DIR)/fgo/config_hook.json \
$(DIST_DIR)/fgo/segatools.ini \
$(DIST_DIR)/fgo/start.bat \
$(BUILD_DIR_ZIP)/fgo

View File

@ -31,6 +31,7 @@ void aime_config_load(struct aime_config *cfg, const wchar_t *filename)
aime_dll_config_load(&cfg->dll, filename);
cfg->enable = GetPrivateProfileIntW(L"aime", L"enable", 1, filename);
cfg->high_baudrate = GetPrivateProfileIntW(L"aime", L"highbaud", 1, filename);
cfg->gen = GetPrivateProfileIntW(L"aime", L"gen", 0, filename);
}
void io4_config_load(struct io4_config *cfg, const wchar_t *filename)

View File

@ -17,7 +17,7 @@ struct sg_led_res_reset {
struct sg_led_res_get_info {
struct sg_res_header res;
uint8_t payload[9];
char payload[12];
};
struct sg_led_req_set_color {

View File

@ -27,14 +27,18 @@ static HRESULT sg_led_cmd_set_color(
const struct sg_led *led,
const struct sg_led_req_set_color *req);
static const uint8_t sg_led_info[] = {
'1', '5', '0', '8', '4', 0xFF, 0x10, 0x00, 0x12,
const char *sg_led_info[] = {
"15084\xFF\x10\x00\x12",
"000-00000\xFF\x11\x40",
// maybe the same?
"000-00000\xFF\x11\x40"
};
void sg_led_init(
struct sg_led *led,
uint8_t addr,
const struct sg_led_ops *ops,
unsigned int gen,
void *ctx)
{
assert(led != NULL);
@ -43,6 +47,7 @@ void sg_led_init(
led->ops = ops;
led->ops_ctx = ctx;
led->addr = addr;
led->gen = gen;
}
void sg_led_transact(
@ -150,8 +155,11 @@ static HRESULT sg_led_cmd_get_info(
struct sg_led_res_get_info *res)
{
sg_led_dprintf(led, "Get info\n");
sg_res_init(&res->res, req, sizeof(res->payload));
memcpy(res->payload, sg_led_info, sizeof(sg_led_info));
unsigned int len = strlen(sg_led_info[led->gen - 1]);
sg_res_init(&res->res, req, len);
memcpy(res->payload, sg_led_info[led->gen - 1], len);
return S_OK;
}

View File

@ -15,12 +15,14 @@ struct sg_led {
const struct sg_led_ops *ops;
void *ops_ctx;
uint8_t addr;
unsigned int gen;
};
void sg_led_init(
struct sg_led *led,
uint8_t addr,
const struct sg_led_ops *ops,
unsigned int gen,
void *ctx);
void sg_led_transact(

View File

@ -15,6 +15,7 @@ enum {
SG_NFC_CMD_MIFARE_READ_BLOCK = 0x52,
SG_NFC_CMD_MIFARE_SET_KEY_AIME = 0x54,
SG_NFC_CMD_MIFARE_AUTHENTICATE = 0x55, /* guess based on time sent */
SG_NFC_CMD_SEND_HEX_DATA = 0x61,
SG_NFC_CMD_RESET = 0x62,
SG_NFC_CMD_FELICA_ENCAP = 0x71,
};

View File

@ -65,10 +65,23 @@ static HRESULT sg_nfc_cmd_dummy(
const struct sg_req_header *req,
struct sg_res_header *res);
static const char *hw_version[] = {
"TN32MSEC003S H/W Ver3.0",
"837-15286",
"837-15396"
};
static const char *fw_version[] = {
"TN32MSEC003S F/W Ver1.2",
"\x94",
"\x94"
};
void sg_nfc_init(
struct sg_nfc *nfc,
uint8_t addr,
const struct sg_nfc_ops *ops,
unsigned int gen,
void *ops_ctx)
{
assert(nfc != NULL);
@ -77,6 +90,7 @@ void sg_nfc_init(
nfc->ops = ops;
nfc->ops_ctx = ops_ctx;
nfc->addr = addr;
nfc->gen = gen;
}
#ifdef NDEBUG
@ -176,6 +190,7 @@ static HRESULT sg_nfc_dispatch(
case SG_NFC_CMD_MIFARE_SET_KEY_BANA:
case SG_NFC_CMD_RADIO_ON:
case SG_NFC_CMD_RADIO_OFF:
case SG_NFC_CMD_SEND_HEX_DATA: // TODO: implement?
return sg_nfc_cmd_dummy(nfc, &req->simple, &res->simple);
default:
@ -202,9 +217,11 @@ static HRESULT sg_nfc_cmd_get_fw_version(
const struct sg_req_header *req,
struct sg_nfc_res_get_fw_version *res)
{
unsigned int len = strlen(fw_version[nfc->gen - 1]);
/* Dest version is not NUL terminated, this is intentional */
sg_res_init(&res->res, req, sizeof(res->version));
memcpy(res->version, "TN32MSEC003S F/W Ver1.2E", sizeof(res->version));
sg_res_init(&res->res, req, len);
memcpy(res->version, fw_version[nfc->gen - 1], len);
return S_OK;
}
@ -214,9 +231,11 @@ static HRESULT sg_nfc_cmd_get_hw_version(
const struct sg_req_header *req,
struct sg_nfc_res_get_hw_version *res)
{
unsigned int len = strlen(hw_version[nfc->gen - 1]);
/* Dest version is not NUL terminated, this is intentional */
sg_res_init(&res->res, req, sizeof(res->version));
memcpy(res->version, "TN32MSEC003S H/W Ver3.0J", sizeof(res->version));
sg_res_init(&res->res, req, len);
memcpy(res->version, hw_version[nfc->gen - 1], len);
return S_OK;
}

View File

@ -22,6 +22,7 @@ struct sg_nfc {
const struct sg_nfc_ops *ops;
void *ops_ctx;
uint8_t addr;
unsigned int gen;
struct felica felica;
struct mifare mifare;
};
@ -30,6 +31,7 @@ void sg_nfc_init(
struct sg_nfc *nfc,
uint8_t addr,
const struct sg_nfc_ops *ops,
unsigned int gen,
void *ops_ctx);
void sg_nfc_transact(

View File

@ -48,6 +48,7 @@ static struct sg_led sg_reader_led;
HRESULT sg_reader_hook_init(
const struct aime_config *cfg,
unsigned int port_no,
unsigned int gen,
HINSTANCE self)
{
HRESULT hr;
@ -65,8 +66,18 @@ HRESULT sg_reader_hook_init(
return hr;
}
sg_nfc_init(&sg_reader_nfc, 0x00, &sg_reader_nfc_ops, NULL);
sg_led_init(&sg_reader_led, 0x08, &sg_reader_led_ops, NULL);
if (cfg->gen != 0) {
gen = cfg->gen;
}
if (gen < 1 || gen > 3) {
dprintf("NFC Assembly: Invalid reader generation: %u\n", gen);
return E_INVALIDARG;
}
sg_nfc_init(&sg_reader_nfc, 0x00, &sg_reader_nfc_ops, gen, NULL);
sg_led_init(&sg_reader_led, 0x08, &sg_reader_led_ops, gen, NULL);
InitializeCriticalSection(&sg_reader_lock);

View File

@ -10,9 +10,11 @@ struct aime_config {
struct aime_dll_config dll;
bool enable;
bool high_baudrate;
unsigned int gen;
};
HRESULT sg_reader_hook_init(
const struct aime_config *cfg,
unsigned int port_no,
unsigned int gen,
HINSTANCE self);

View File

@ -102,7 +102,7 @@ static DWORD CALLBACK chuni_pre_startup(void)
goto fail;
}
hr = sg_reader_hook_init(&chuni_hook_cfg.aime, 12, chuni_hook_mod);
hr = sg_reader_hook_init(&chuni_hook_cfg.aime, 12, 1, chuni_hook_mod);
if (FAILED(hr)) {
goto fail;

View File

@ -105,8 +105,7 @@ static DWORD CALLBACK chusan_pre_startup(void)
goto fail;
}
hr = sg_reader_hook_init(&chusan_hook_cfg.aime, 4, chusan_hook_mod);
hr = sg_reader_hook_init(&chusan_hook_cfg.aime, 4, dipsw[2] ? 2 : 3, chusan_hook_mod);
if (FAILED(hr)) {
goto fail;

View File

@ -54,7 +54,7 @@ static DWORD CALLBACK cm_pre_startup(void)
goto fail;
}
hr = sg_reader_hook_init(&cm_hook_cfg.aime, 1, cm_hook_mod);
hr = sg_reader_hook_init(&cm_hook_cfg.aime, 1, 1, cm_hook_mod);
if (FAILED(hr)) {
goto fail;

View File

@ -91,7 +91,7 @@ static DWORD CALLBACK cxb_pre_startup(void)
goto fail;
}
hr = sg_reader_hook_init(&cxb_hook_cfg.aime, 12, cxb_hook_mod);
hr = sg_reader_hook_init(&cxb_hook_cfg.aime, 12, 1, cxb_hook_mod);
if (FAILED(hr)) {
goto fail;

View File

@ -1,12 +0,0 @@
{
"aime" :
{
"firmware_path" :
[
"am\\aime_firm\\update_15396_6728_94.bin",
"am\\aime_firm\\TN32MSEC003S_V12.hex",
"am\\aime_firm\\837-15286-P_LPC1112_NFC_RW_LED_BD_0x92.bin"
],
"high_baudrate" : true
}
}

View File

@ -1,13 +1,4 @@
{
"aime" :
{
"firmware_path" :
[
".\\aime_firm\\TN32MSEC003S_V12.hex",
".\\aime_firm\\update_15396_6728_94.bin"
],
"high_baudrate" : true
},
"network" :
{
"property" :

View File

@ -62,7 +62,7 @@ static DWORD CALLBACK diva_pre_startup(void)
goto fail;
}
hr = sg_reader_hook_init(&diva_hook_cfg.aime, 10, diva_hook_mod);
hr = sg_reader_hook_init(&diva_hook_cfg.aime, 10, 1, diva_hook_mod);
if (FAILED(hr)) {
goto fail;

View File

@ -38,6 +38,17 @@ Default: `1`
Enables the high baudrate of the Aime card reader to be 115200 (instead of 38400).
This is required for some games (e.g. Chunithm) but not others (e.g. WACCA).
### `gen`
Default: `1`
Changes the Aime card reader generation, this will also change the LED info
provided for the game.
- `1`: TN32MSEC003S H/W Ver3.0 / TN32MSEC003S F/W Ver1.2
- `2`: 837-15286 / 94
- `3`: 837-15396 / 94
### `aimePath`
Default: `DEVICE\aime.txt`

View File

@ -60,7 +60,7 @@ static DWORD CALLBACK fgo_pre_startup(void)
goto fail;
}
hr = sg_reader_hook_init(&fgo_hook_cfg.aime, 3, fgo_hook_mod);
hr = sg_reader_hook_init(&fgo_hook_cfg.aime, 3, 3, fgo_hook_mod);
if (FAILED(hr)) {
goto fail;
@ -102,7 +102,7 @@ static DWORD CALLBACK fgo_pre_startup(void)
goto fail;
}
hr = createprocess_push_hook_a("am/amdaemon.exe", "inject -d -k fgohook.dll ", " -c config_hook.json", false);
hr = createprocess_push_hook_a("am/amdaemon.exe", "inject -d -k fgohook.dll ", "", false);
if (FAILED(hr)) {
goto fail;

View File

@ -53,7 +53,7 @@ static DWORD CALLBACK idac_pre_startup(void)
goto fail;
}
hr = sg_reader_hook_init(&idac_hook_cfg.aime, 3, idac_hook_mod);
hr = sg_reader_hook_init(&idac_hook_cfg.aime, 3, 3, idac_hook_mod);
if (FAILED(hr)) {
goto fail;

View File

@ -97,7 +97,7 @@ static DWORD CALLBACK idz_pre_startup(void)
goto fail;
}
hr = sg_reader_hook_init(&idz_hook_cfg.aime, 10, idz_hook_mod);
hr = sg_reader_hook_init(&idz_hook_cfg.aime, 10, 1, idz_hook_mod);
if (FAILED(hr)) {
goto fail;

View File

@ -111,7 +111,7 @@ void idz_io_jvs_read_coin_counter(uint16_t *out)
/* Coin counter is not backend-specific */
if ( idz_io_cfg.vk_coin &&
if (idz_io_cfg.vk_coin &&
(GetAsyncKeyState(idz_io_cfg.vk_coin) & 0x8000)) {
if (!idz_io_coin) {
idz_io_coin = true;

View File

@ -51,7 +51,7 @@ static DWORD CALLBACK mai2_pre_startup(void)
goto fail;
}
hr = sg_reader_hook_init(&mai2_hook_cfg.aime, 1, mai2_hook_mod);
hr = sg_reader_hook_init(&mai2_hook_cfg.aime, 1, 1, mai2_hook_mod);
if (FAILED(hr)) {
goto fail;

View File

@ -58,7 +58,7 @@ static DWORD CALLBACK mercury_pre_startup(void)
goto fail;
}
hr = sg_reader_hook_init(&mercury_hook_cfg.aime, 1, mercury_hook_mod);
hr = sg_reader_hook_init(&mercury_hook_cfg.aime, 1, 1, mercury_hook_mod);
if (FAILED(hr)) {
goto fail;

View File

@ -54,7 +54,7 @@ static DWORD CALLBACK swdc_pre_startup(void)
goto fail;
}
hr = sg_reader_hook_init(&swdc_hook_cfg.aime, 3, swdc_hook_mod);
hr = sg_reader_hook_init(&swdc_hook_cfg.aime, 3, 3, swdc_hook_mod);
if (FAILED(hr)) {
goto fail;