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 untrusted user: 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)mkdir -p $(BUILD_DIR_ZIP)/fgo/DEVICE
$(V)cp $(BUILD_DIR_64)/subprojects/capnhook/inject/inject.exe \ $(V)cp $(BUILD_DIR_64)/subprojects/capnhook/inject/inject.exe \
$(BUILD_DIR_64)/fgohook/fgohook.dll \ $(BUILD_DIR_64)/fgohook/fgohook.dll \
$(DIST_DIR)/fgo/config_hook.json \
$(DIST_DIR)/fgo/segatools.ini \ $(DIST_DIR)/fgo/segatools.ini \
$(DIST_DIR)/fgo/start.bat \ $(DIST_DIR)/fgo/start.bat \
$(BUILD_DIR_ZIP)/fgo $(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); aime_dll_config_load(&cfg->dll, filename);
cfg->enable = GetPrivateProfileIntW(L"aime", L"enable", 1, filename); cfg->enable = GetPrivateProfileIntW(L"aime", L"enable", 1, filename);
cfg->high_baudrate = GetPrivateProfileIntW(L"aime", L"highbaud", 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) 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_led_res_get_info {
struct sg_res_header res; struct sg_res_header res;
uint8_t payload[9]; char payload[12];
}; };
struct sg_led_req_set_color { 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 *led,
const struct sg_led_req_set_color *req); const struct sg_led_req_set_color *req);
static const uint8_t sg_led_info[] = { const char *sg_led_info[] = {
'1', '5', '0', '8', '4', 0xFF, 0x10, 0x00, 0x12, "15084\xFF\x10\x00\x12",
"000-00000\xFF\x11\x40",
// maybe the same?
"000-00000\xFF\x11\x40"
}; };
void sg_led_init( void sg_led_init(
struct sg_led *led, struct sg_led *led,
uint8_t addr, uint8_t addr,
const struct sg_led_ops *ops, const struct sg_led_ops *ops,
unsigned int gen,
void *ctx) void *ctx)
{ {
assert(led != NULL); assert(led != NULL);
@ -43,6 +47,7 @@ void sg_led_init(
led->ops = ops; led->ops = ops;
led->ops_ctx = ctx; led->ops_ctx = ctx;
led->addr = addr; led->addr = addr;
led->gen = gen;
} }
void sg_led_transact( void sg_led_transact(
@ -150,8 +155,11 @@ static HRESULT sg_led_cmd_get_info(
struct sg_led_res_get_info *res) struct sg_led_res_get_info *res)
{ {
sg_led_dprintf(led, "Get info\n"); 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; return S_OK;
} }

View File

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

View File

@ -15,6 +15,7 @@ enum {
SG_NFC_CMD_MIFARE_READ_BLOCK = 0x52, SG_NFC_CMD_MIFARE_READ_BLOCK = 0x52,
SG_NFC_CMD_MIFARE_SET_KEY_AIME = 0x54, SG_NFC_CMD_MIFARE_SET_KEY_AIME = 0x54,
SG_NFC_CMD_MIFARE_AUTHENTICATE = 0x55, /* guess based on time sent */ 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_RESET = 0x62,
SG_NFC_CMD_FELICA_ENCAP = 0x71, SG_NFC_CMD_FELICA_ENCAP = 0x71,
}; };

View File

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

View File

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

View File

@ -48,6 +48,7 @@ static struct sg_led sg_reader_led;
HRESULT sg_reader_hook_init( HRESULT sg_reader_hook_init(
const struct aime_config *cfg, const struct aime_config *cfg,
unsigned int port_no, unsigned int port_no,
unsigned int gen,
HINSTANCE self) HINSTANCE self)
{ {
HRESULT hr; HRESULT hr;
@ -65,8 +66,18 @@ HRESULT sg_reader_hook_init(
return hr; return hr;
} }
sg_nfc_init(&sg_reader_nfc, 0x00, &sg_reader_nfc_ops, NULL); if (cfg->gen != 0) {
sg_led_init(&sg_reader_led, 0x08, &sg_reader_led_ops, NULL); 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); InitializeCriticalSection(&sg_reader_lock);

View File

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

View File

@ -102,7 +102,7 @@ static DWORD CALLBACK chuni_pre_startup(void)
goto fail; 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)) { if (FAILED(hr)) {
goto fail; goto fail;

View File

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

View File

@ -54,7 +54,7 @@ static DWORD CALLBACK cm_pre_startup(void)
goto fail; 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)) { if (FAILED(hr)) {
goto fail; goto fail;

View File

@ -91,7 +91,7 @@ static DWORD CALLBACK cxb_pre_startup(void)
goto fail; 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)) { if (FAILED(hr)) {
goto fail; 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" : "network" :
{ {
"property" : "property" :

View File

@ -62,7 +62,7 @@ static DWORD CALLBACK diva_pre_startup(void)
goto fail; 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)) { if (FAILED(hr)) {
goto fail; 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). 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). 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` ### `aimePath`
Default: `DEVICE\aime.txt` Default: `DEVICE\aime.txt`

View File

@ -60,7 +60,7 @@ static DWORD CALLBACK fgo_pre_startup(void)
goto fail; 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)) { if (FAILED(hr)) {
goto fail; goto fail;
@ -102,7 +102,7 @@ static DWORD CALLBACK fgo_pre_startup(void)
goto fail; 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)) { if (FAILED(hr)) {
goto fail; goto fail;

View File

@ -53,7 +53,7 @@ static DWORD CALLBACK idac_pre_startup(void)
goto fail; 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)) { if (FAILED(hr)) {
goto fail; goto fail;

View File

@ -97,7 +97,7 @@ static DWORD CALLBACK idz_pre_startup(void)
goto fail; 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)) { if (FAILED(hr)) {
goto fail; goto fail;

View File

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

View File

@ -51,7 +51,7 @@ static DWORD CALLBACK mai2_pre_startup(void)
goto fail; 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)) { if (FAILED(hr)) {
goto fail; goto fail;

View File

@ -58,7 +58,7 @@ static DWORD CALLBACK mercury_pre_startup(void)
goto fail; 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)) { if (FAILED(hr)) {
goto fail; goto fail;

View File

@ -54,7 +54,7 @@ static DWORD CALLBACK swdc_pre_startup(void)
goto fail; 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)) { if (FAILED(hr)) {
goto fail; goto fail;