aime, vfd: updated and improved
This commit is contained in:
parent
fadbd0d2bf
commit
bfa5d0dd6e
@ -17,6 +17,7 @@ struct aime_io_config {
|
||||
wchar_t aime_path[MAX_PATH];
|
||||
wchar_t felica_path[MAX_PATH];
|
||||
bool felica_gen;
|
||||
bool aime_gen;
|
||||
uint8_t vk_scan;
|
||||
};
|
||||
|
||||
@ -40,6 +41,11 @@ static HRESULT aime_io_generate_felica(
|
||||
uint8_t *bytes,
|
||||
size_t nbytes);
|
||||
|
||||
static HRESULT aime_io_generate_aime(
|
||||
const wchar_t *path,
|
||||
uint8_t *bytes,
|
||||
size_t nbytes);
|
||||
|
||||
static void aime_io_config_read(
|
||||
struct aime_io_config *cfg,
|
||||
const wchar_t *filename)
|
||||
@ -62,11 +68,16 @@ static void aime_io_config_read(
|
||||
cfg->felica_path,
|
||||
_countof(cfg->felica_path),
|
||||
filename);
|
||||
dprintf("NFC: felicaPath GetLastError %lx\n", GetLastError());
|
||||
|
||||
cfg->felica_gen = GetPrivateProfileIntW(
|
||||
L"aime",
|
||||
L"felicaGen",
|
||||
0,
|
||||
filename);
|
||||
|
||||
cfg->aime_gen = GetPrivateProfileIntW(
|
||||
L"aime",
|
||||
L"aimeGen",
|
||||
1,
|
||||
filename);
|
||||
|
||||
@ -136,7 +147,7 @@ static HRESULT aime_io_generate_felica(
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
for (i = 0 ; i < nbytes ; i++) {
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
bytes[i] = rand();
|
||||
}
|
||||
|
||||
@ -151,7 +162,7 @@ static HRESULT aime_io_generate_felica(
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < nbytes ; i++) {
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
fprintf(f, "%02X", bytes[i]);
|
||||
}
|
||||
|
||||
@ -163,6 +174,47 @@ static HRESULT aime_io_generate_felica(
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT aime_io_generate_aime(
|
||||
const wchar_t *path,
|
||||
uint8_t *bytes,
|
||||
size_t nbytes)
|
||||
{
|
||||
size_t i;
|
||||
FILE *f;
|
||||
|
||||
assert(path != NULL);
|
||||
assert(bytes != NULL);
|
||||
assert(nbytes > 0);
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
/* AiMe IDs should not start with 3, due to a missing check for BananaPass IDs */
|
||||
do {
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
bytes[i] = rand() % 10 << 4 | rand() % 10;
|
||||
}
|
||||
} while (bytes[0] >> 4 == 3);
|
||||
|
||||
f = _wfopen(path, L"w");
|
||||
|
||||
if (f == NULL) {
|
||||
dprintf("AimeIO DLL: %S: fopen failed: %i\n", path, (int) errno);
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
fprintf(f, "%02x", bytes[i]);
|
||||
}
|
||||
|
||||
fprintf(f, "\n");
|
||||
fclose(f);
|
||||
|
||||
dprintf("AimeIO DLL: Generated random AiMe ID\n");
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
uint16_t aime_io_get_api_version(void)
|
||||
{
|
||||
return 0x0100;
|
||||
@ -210,6 +262,22 @@ HRESULT aime_io_nfc_poll(uint8_t unit_no)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* Try generating AiMe IC (if enabled) */
|
||||
|
||||
if (aime_io_cfg.aime_gen) {
|
||||
hr = aime_io_generate_aime(
|
||||
aime_io_cfg.aime_path,
|
||||
aime_io_aime_id,
|
||||
sizeof(aime_io_aime_id));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
aime_io_aime_id_present = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* Try FeliCa IC */
|
||||
|
||||
hr = aime_io_read_id_file(
|
||||
|
@ -71,3 +71,13 @@ 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);
|
||||
}
|
||||
|
||||
void vfd_config_load(struct vfd_config *cfg, const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"vfd", L"enable", 1, filename);
|
||||
cfg->port = GetPrivateProfileIntW(L"vfd", L"portNo", 0, filename);
|
||||
cfg->utf_conversion = GetPrivateProfileIntW(L"vfd", L"utfConversion", 0, filename);
|
||||
}
|
||||
|
@ -7,8 +7,10 @@
|
||||
#include "board/bpreader.h"
|
||||
#include "board/qr.h"
|
||||
#include "board/sg-reader.h"
|
||||
#include "board/vfd.h"
|
||||
|
||||
void bpreader_config_load(struct bpreader_config *cfg, const wchar_t *filename);
|
||||
void usio_config_load(struct usio_config *cfg, const wchar_t *filename);
|
||||
void qr_config_load(struct qr_config *cfg, const wchar_t *filename);
|
||||
void aime_config_load(struct aime_config *cfg, const wchar_t *filename);
|
||||
void vfd_config_load(struct vfd_config *cfg, const wchar_t *filename);
|
||||
|
@ -39,6 +39,9 @@ board_lib = static_library(
|
||||
'sg-nfc-cmd.h',
|
||||
'sg-reader.c',
|
||||
'sg-reader.h',
|
||||
'vfd-cmd.h',
|
||||
'vfd-frame.c',
|
||||
'vfd-frame.h',
|
||||
'vfd.c',
|
||||
'vfd.h',
|
||||
],
|
||||
|
@ -25,6 +25,13 @@ struct sg_res_header {
|
||||
uint8_t payload_len;
|
||||
};
|
||||
|
||||
/* struct to save the version string with its length
|
||||
to fix NUL terminator issues */
|
||||
struct version_info {
|
||||
const char *version;
|
||||
uint8_t length;
|
||||
};
|
||||
|
||||
typedef HRESULT (*sg_dispatch_fn_t)(
|
||||
void *ctx,
|
||||
const void *req,
|
||||
|
@ -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,
|
||||
static const struct version_info led_version[] = {
|
||||
{"15084\xFF\x10\x00\x12", 9},
|
||||
{"000-00000\xFF\x11\x40", 12},
|
||||
// maybe the same?
|
||||
{"000-00000\xFF\x11\x40", 12}
|
||||
};
|
||||
|
||||
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));
|
||||
|
||||
const struct version_info *fw = &led_version[led->gen - 1];
|
||||
|
||||
sg_res_init(&res->res, req, fw->length);
|
||||
memcpy(res->payload, fw->version, fw->length);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -5,18 +5,21 @@
|
||||
#pragma pack(push, 1)
|
||||
|
||||
enum {
|
||||
SG_NFC_CMD_GET_FW_VERSION = 0x30,
|
||||
SG_NFC_CMD_GET_HW_VERSION = 0x32,
|
||||
SG_NFC_CMD_RADIO_ON = 0x40,
|
||||
SG_NFC_CMD_RADIO_OFF = 0x41,
|
||||
SG_NFC_CMD_POLL = 0x42,
|
||||
SG_NFC_CMD_MIFARE_SELECT_TAG = 0x43,
|
||||
SG_NFC_CMD_MIFARE_SET_KEY_BANA = 0x50,
|
||||
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_RESET = 0x62,
|
||||
SG_NFC_CMD_FELICA_ENCAP = 0x71,
|
||||
SG_NFC_CMD_GET_FW_VERSION = 0x30,
|
||||
SG_NFC_CMD_GET_HW_VERSION = 0x32,
|
||||
SG_NFC_CMD_RADIO_ON = 0x40,
|
||||
SG_NFC_CMD_RADIO_OFF = 0x41,
|
||||
SG_NFC_CMD_POLL = 0x42,
|
||||
SG_NFC_CMD_MIFARE_SELECT_TAG = 0x43,
|
||||
SG_NFC_CMD_MIFARE_SET_KEY_AIME = 0x50,
|
||||
SG_NFC_CMD_MIFARE_AUTHENTICATE_A = 0x51,
|
||||
SG_NFC_CMD_MIFARE_READ_BLOCK = 0x52,
|
||||
SG_NFC_CMD_MIFARE_SET_KEY_BANA = 0x54,
|
||||
SG_NFC_CMD_MIFARE_AUTHENTICATE_B = 0x55,
|
||||
SG_NFC_CMD_TO_UPDATE_MODE = 0x60,
|
||||
SG_NFC_CMD_SEND_HEX_DATA = 0x61,
|
||||
SG_NFC_CMD_RESET = 0x62,
|
||||
SG_NFC_CMD_FELICA_ENCAP = 0x71,
|
||||
};
|
||||
|
||||
struct sg_nfc_res_get_fw_version {
|
||||
@ -31,7 +34,7 @@ struct sg_nfc_res_get_hw_version {
|
||||
|
||||
struct sg_nfc_req_mifare_set_key {
|
||||
struct sg_req_header req;
|
||||
uint8_t key_a[6];
|
||||
uint8_t key[6];
|
||||
};
|
||||
|
||||
struct sg_nfc_req_mifare_50 {
|
||||
|
@ -60,15 +60,33 @@ static HRESULT sg_nfc_cmd_felica_encap(
|
||||
const struct sg_nfc_req_felica_encap *req,
|
||||
struct sg_nfc_res_felica_encap *res);
|
||||
|
||||
static HRESULT sg_nfc_cmd_send_hex_data(
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_req_header *req,
|
||||
struct sg_res_header *res);
|
||||
|
||||
static HRESULT sg_nfc_cmd_dummy(
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_req_header *req,
|
||||
struct sg_res_header *res);
|
||||
|
||||
static const struct version_info hw_version[] = {
|
||||
{"TN32MSEC003S H/W Ver3.0", 23},
|
||||
{"837-15286", 9},
|
||||
{"837-15396", 9}
|
||||
};
|
||||
|
||||
static const struct version_info fw_version[] = {
|
||||
{"TN32MSEC003S F/W Ver1.2", 23},
|
||||
{"\x94", 1},
|
||||
{"\x94", 1}
|
||||
};
|
||||
|
||||
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 +95,7 @@ void sg_nfc_init(
|
||||
nfc->ops = ops;
|
||||
nfc->ops_ctx = ops_ctx;
|
||||
nfc->addr = addr;
|
||||
nfc->gen = gen;
|
||||
}
|
||||
|
||||
#ifdef NDEBUG
|
||||
@ -170,12 +189,17 @@ static HRESULT sg_nfc_dispatch(
|
||||
&req->felica_encap,
|
||||
&res->felica_encap);
|
||||
|
||||
case SG_NFC_CMD_MIFARE_AUTHENTICATE:
|
||||
case SG_NFC_CMD_MIFARE_AUTHENTICATE_A:
|
||||
case SG_NFC_CMD_MIFARE_AUTHENTICATE_B:
|
||||
case SG_NFC_CMD_SEND_HEX_DATA:
|
||||
return sg_nfc_cmd_send_hex_data(nfc, &req->simple, &res->simple);
|
||||
|
||||
case SG_NFC_CMD_MIFARE_SELECT_TAG:
|
||||
case SG_NFC_CMD_MIFARE_SET_KEY_AIME:
|
||||
case SG_NFC_CMD_MIFARE_SET_KEY_BANA:
|
||||
case SG_NFC_CMD_RADIO_ON:
|
||||
case SG_NFC_CMD_RADIO_OFF:
|
||||
case SG_NFC_CMD_TO_UPDATE_MODE:
|
||||
return sg_nfc_cmd_dummy(nfc, &req->simple, &res->simple);
|
||||
|
||||
default:
|
||||
@ -202,9 +226,11 @@ static HRESULT sg_nfc_cmd_get_fw_version(
|
||||
const struct sg_req_header *req,
|
||||
struct sg_nfc_res_get_fw_version *res)
|
||||
{
|
||||
const struct version_info *fw = &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, "\x94", sizeof(res->version));
|
||||
sg_res_init(&res->res, req, fw->length);
|
||||
memcpy(res->version, fw->version, fw->length);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@ -214,9 +240,11 @@ static HRESULT sg_nfc_cmd_get_hw_version(
|
||||
const struct sg_req_header *req,
|
||||
struct sg_nfc_res_get_hw_version *res)
|
||||
{
|
||||
const struct version_info *hw = &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, "837-15396-6728", sizeof(res->version));
|
||||
sg_res_init(&res->res, req, hw->length);
|
||||
memcpy(res->version, hw->version, hw->length);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@ -423,6 +451,22 @@ static HRESULT sg_nfc_cmd_felica_encap(
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT sg_nfc_cmd_send_hex_data(
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_req_header *req,
|
||||
struct sg_res_header *res)
|
||||
{
|
||||
sg_res_init(res, req, 0);
|
||||
|
||||
/* Firmware checksum length? */
|
||||
if (req->payload_len == 0x2b) {
|
||||
/* The firmware is identical flag? */
|
||||
res->status = 0x20;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT sg_nfc_cmd_dummy(
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_req_header *req,
|
||||
|
@ -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(
|
||||
|
@ -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,11 +66,25 @@ 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);
|
||||
|
||||
if (!cfg->high_baudrate) {
|
||||
sg_reader_uart.baud.BaudRate = 38400;
|
||||
}
|
||||
|
||||
uart_init(&sg_reader_uart, port_no);
|
||||
sg_reader_uart.written.bytes = sg_reader_written_bytes;
|
||||
sg_reader_uart.written.nbytes = sizeof(sg_reader_written_bytes);
|
||||
|
@ -9,9 +9,12 @@
|
||||
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);
|
||||
|
@ -307,7 +307,7 @@ static int my_bnusio_SetCoinLock(uint8_t id, char value)
|
||||
|
||||
static int my_bnusio_GetCoin(uint8_t id)
|
||||
{
|
||||
//dprintf("USIO: GetCoin ID %d\n", id);
|
||||
// dprintf("USIO: GetCoin ID %d\n", id);
|
||||
usio_ops->poll(usio_ops_ctx, &state);
|
||||
if (id < 2) {
|
||||
return state.coins[id].current_coin_count;
|
||||
@ -317,7 +317,7 @@ static int my_bnusio_GetCoin(uint8_t id)
|
||||
|
||||
static int my_bnusio_GetCoinError(uint8_t id)
|
||||
{
|
||||
//dprintf("USIO: GetCoinErrorID %d\n", id);
|
||||
// dprintf("USIO: GetCoinErrorID %d\n", id);
|
||||
if (id >= _countof(state.coins)) {
|
||||
return 0;
|
||||
}
|
||||
@ -373,4 +373,4 @@ static intptr_t my_bnusio_GetIoBoardName()
|
||||
intptr_t ret = (intptr_t)malloc(sizeof(usio_name) / 2);
|
||||
wcstombs((char *)ret, usio_name, sizeof(usio_name) / 2);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
123
board/vfd-cmd.h
Normal file
123
board/vfd-cmd.h
Normal file
@ -0,0 +1,123 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/vfd-frame.h"
|
||||
|
||||
enum {
|
||||
VFD_CMD_GET_VERSION = 0x5B,
|
||||
VFD_CMD_RESET = 0x0B,
|
||||
VFD_CMD_CLEAR_SCREEN = 0x0C,
|
||||
VFD_CMD_SET_BRIGHTNESS = 0x20,
|
||||
VFD_CMD_SET_SCREEN_ON = 0x21,
|
||||
VFD_CMD_SET_H_SCROLL = 0x22,
|
||||
VFD_CMD_DRAW_IMAGE = 0x2E,
|
||||
VFD_CMD_SET_CURSOR = 0x30,
|
||||
VFD_CMD_SET_ENCODING = 0x32,
|
||||
VFD_CMD_SET_TEXT_WND = 0x40,
|
||||
VFD_CMD_SET_TEXT_SPEED = 0x41,
|
||||
VFD_CMD_WRITE_TEXT = 0x50,
|
||||
VFD_CMD_ENABLE_SCROLL = 0x51,
|
||||
VFD_CMD_DISABLE_SCROLL = 0x52,
|
||||
VFD_CMD_ROTATE = 0x5D,
|
||||
VFD_CMD_CREATE_CHAR = 0xA3,
|
||||
VFD_CMD_CREATE_CHAR2 = 0xA4,
|
||||
};
|
||||
|
||||
enum {
|
||||
VFD_ENC_GB2312 = 0,
|
||||
VFD_ENC_BIG5 = 1,
|
||||
VFD_ENC_SHIFT_JIS = 2,
|
||||
VFD_ENC_KSC5601 = 3,
|
||||
VFD_ENC_MAX = 3,
|
||||
};
|
||||
|
||||
struct vfd_req_hdr {
|
||||
uint8_t sync;
|
||||
uint8_t cmd;
|
||||
};
|
||||
|
||||
struct vfd_req_any {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint8_t payload[2054];
|
||||
};
|
||||
|
||||
struct vfd_req_board_info {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint8_t unk1;
|
||||
};
|
||||
|
||||
struct vfd_resp_board_info { // \x0201.20\x03
|
||||
uint8_t unk1;
|
||||
char version[5];
|
||||
uint8_t unk2;
|
||||
};
|
||||
|
||||
struct vfd_req_reset {
|
||||
struct vfd_req_hdr hdr;
|
||||
};
|
||||
|
||||
struct vfd_req_cls {
|
||||
struct vfd_req_hdr hdr;
|
||||
};
|
||||
|
||||
struct vfd_req_brightness {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint8_t brightness;
|
||||
};
|
||||
|
||||
struct vfd_req_power {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint8_t power_state;
|
||||
};
|
||||
|
||||
struct vfd_req_hscroll {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint8_t x_pos;
|
||||
};
|
||||
|
||||
struct vfd_req_draw {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint16_t x0;
|
||||
uint8_t y0;
|
||||
uint16_t x1;
|
||||
uint8_t y1;
|
||||
uint8_t image[2048];
|
||||
};
|
||||
|
||||
struct vfd_req_cursor {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint16_t x;
|
||||
uint8_t y;
|
||||
};
|
||||
|
||||
struct vfd_req_encoding {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint8_t encoding;
|
||||
};
|
||||
|
||||
struct vfd_req_wnd {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint16_t x0;
|
||||
uint8_t y0;
|
||||
uint16_t x1;
|
||||
uint8_t y1;
|
||||
};
|
||||
|
||||
struct vfd_req_speed {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint8_t encoding;
|
||||
};
|
||||
|
||||
struct vfd_req_scroll {
|
||||
struct vfd_req_hdr hdr;
|
||||
};
|
||||
|
||||
struct vfd_req_rotate {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint8_t unk1;
|
||||
};
|
||||
|
||||
struct vfd_req_create_char {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint8_t type;
|
||||
uint8_t pixels[32];
|
||||
};
|
88
board/vfd-frame.c
Normal file
88
board/vfd-frame.c
Normal file
@ -0,0 +1,88 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define SUPER_VERBOSE 1
|
||||
|
||||
#include "board/vfd-frame.h"
|
||||
|
||||
#include "hook/iobuf.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
|
||||
static HRESULT vfd_frame_encode_byte(struct iobuf *dest, uint8_t byte);
|
||||
|
||||
/* Frame structure:
|
||||
|
||||
REQUEST:
|
||||
[0] Sync byte (0x1A or 0x1B)
|
||||
[1] Packet ID
|
||||
[2...n-1] Data/payload
|
||||
|
||||
--- OR ---
|
||||
|
||||
if no sync byte is given, plain static text in the currently configured encoding is expected.
|
||||
|
||||
RESPONSE:
|
||||
This thing never responds, unless it's VFD_CMD_GET_VERSION
|
||||
*/
|
||||
|
||||
bool vfd_frame_sync(struct const_iobuf *src) {
|
||||
return src->bytes[src->pos] == VFD_SYNC_BYTE || src->bytes[src->pos] == VFD_SYNC_BYTE2;
|
||||
}
|
||||
|
||||
HRESULT vfd_frame_encode(
|
||||
struct iobuf *dest,
|
||||
const void *ptr,
|
||||
size_t nbytes) {
|
||||
const uint8_t *src;
|
||||
uint8_t byte;
|
||||
size_t i;
|
||||
HRESULT hr;
|
||||
|
||||
assert(dest != NULL);
|
||||
assert(dest->bytes != NULL || dest->nbytes == 0);
|
||||
assert(dest->pos <= dest->nbytes);
|
||||
assert(ptr != NULL);
|
||||
|
||||
src = ptr;
|
||||
|
||||
if (dest->pos >= dest->nbytes) {
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
#if SUPER_VERBOSE
|
||||
dprintf("VFD: RX Buffer:\n");
|
||||
#endif
|
||||
|
||||
for (i = 1; i < nbytes; i++) {
|
||||
byte = src[i];
|
||||
#if SUPER_VERBOSE
|
||||
dprintf("%02x ", byte);
|
||||
#endif
|
||||
|
||||
hr = vfd_frame_encode_byte(dest, byte);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
#if SUPER_VERBOSE
|
||||
dprintf("\n");
|
||||
#endif
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT vfd_frame_encode_byte(struct iobuf *dest, uint8_t byte) {
|
||||
if (dest->pos + 1 > dest->nbytes) {
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
dest->bytes[dest->pos++] = byte;
|
||||
|
||||
return S_OK;
|
||||
}
|
20
board/vfd-frame.h
Normal file
20
board/vfd-frame.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "hook/iobuf.h"
|
||||
|
||||
enum {
|
||||
VFD_SYNC_BYTE = 0x1B,
|
||||
VFD_SYNC_BYTE2 = 0x1A,
|
||||
};
|
||||
|
||||
bool vfd_frame_sync(struct const_iobuf *src);
|
||||
|
||||
HRESULT vfd_frame_encode(
|
||||
struct iobuf *dest,
|
||||
const void *ptr,
|
||||
size_t nbytes);
|
355
board/vfd.c
355
board/vfd.c
@ -3,16 +3,20 @@
|
||||
of electronic payments.
|
||||
|
||||
Part number in schematics is "VFD GP1232A02A FUTABA".
|
||||
|
||||
Little else about this board is known. Black-holing the RS232 comms that it
|
||||
receives seems to be sufficient for the time being. */
|
||||
|
||||
Credits:
|
||||
|
||||
Haruka
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "board/config.h"
|
||||
#include "board/vfd.h"
|
||||
#include "board/vfd-cmd.h"
|
||||
|
||||
#include "hook/iohook.h"
|
||||
|
||||
@ -21,15 +25,51 @@
|
||||
#include "util/dprintf.h"
|
||||
#include "util/dump.h"
|
||||
|
||||
#define SUPER_VERBOSE 0
|
||||
|
||||
static HRESULT vfd_handle_irp(struct irp *irp);
|
||||
|
||||
static struct uart vfd_uart;
|
||||
static uint8_t vfd_written[512];
|
||||
static uint8_t vfd_readable[512];
|
||||
static uint8_t vfd_written[4096];
|
||||
static uint8_t vfd_readable[4096];
|
||||
|
||||
HRESULT vfd_hook_init(unsigned int port_no)
|
||||
static int encoding = VFD_ENC_SHIFT_JIS;
|
||||
|
||||
HRESULT vfd_handle_get_version(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_reset(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_clear_screen(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_set_brightness(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_set_screen_on(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_set_h_scroll(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_draw_image(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_set_cursor(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_set_encoding(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_set_text_wnd(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_set_text_speed(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_write_text(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_enable_scroll(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_disable_scroll(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_rotate(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_create_char(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_create_char2(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
|
||||
static bool utf_enabled;
|
||||
|
||||
HRESULT vfd_hook_init(struct vfd_config *cfg, int default_port)
|
||||
{
|
||||
uart_init(&vfd_uart, port_no);
|
||||
if (!cfg->enable){
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
utf_enabled = cfg->utf_conversion;
|
||||
|
||||
int port = cfg->port;
|
||||
if (port == 0){
|
||||
port = default_port;
|
||||
}
|
||||
|
||||
dprintf("VFD: enabling (port=%d)\n", port);
|
||||
uart_init(&vfd_uart, port);
|
||||
vfd_uart.written.bytes = vfd_written;
|
||||
vfd_uart.written.nbytes = sizeof(vfd_written);
|
||||
vfd_uart.readable.bytes = vfd_readable;
|
||||
@ -38,6 +78,48 @@ HRESULT vfd_hook_init(unsigned int port_no)
|
||||
return iohook_push_handler(vfd_handle_irp);
|
||||
}
|
||||
|
||||
|
||||
const char* get_encoding_name(int b){
|
||||
switch (b){
|
||||
case 0: return "gb2312";
|
||||
case 1: return "big5";
|
||||
case 2: return "shift-jis";
|
||||
case 3: return "ks_c_5601-1987";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void print_vfd_text(const char* str, int len){
|
||||
|
||||
if (utf_enabled){
|
||||
|
||||
wchar_t encoded[1024];
|
||||
memset(encoded, 0, 1024 * sizeof(wchar_t));
|
||||
|
||||
int codepage = 0;
|
||||
if (encoding == VFD_ENC_GB2312){
|
||||
codepage = 936;
|
||||
} else if (encoding == VFD_ENC_BIG5){
|
||||
codepage = 950;
|
||||
} else if (encoding == VFD_ENC_SHIFT_JIS){
|
||||
codepage = 932;
|
||||
} else if (encoding == VFD_ENC_KSC5601) {
|
||||
codepage = 949;
|
||||
}
|
||||
|
||||
if (!MultiByteToWideChar(codepage, MB_USEGLYPHCHARS, str, len, encoded, 1024)){
|
||||
dprintf("VFD: Text conversion failed: %ld", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
dprintf("VFD: Text: %ls\n", encoded);
|
||||
} else {
|
||||
|
||||
dprintf("VFD: Text: %s\n", str);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT vfd_handle_irp(struct irp *irp)
|
||||
{
|
||||
HRESULT hr;
|
||||
@ -48,15 +130,274 @@ static HRESULT vfd_handle_irp(struct irp *irp)
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
if (irp->op == IRP_OP_OPEN){
|
||||
dprintf("VFD: Open\n");
|
||||
} else if (irp->op == IRP_OP_CLOSE){
|
||||
dprintf("VFD: Close\n");
|
||||
}
|
||||
|
||||
hr = uart_handle_irp(&vfd_uart, irp);
|
||||
|
||||
if (FAILED(hr) || irp->op != IRP_OP_WRITE) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
#if SUPER_VERBOSE
|
||||
dprintf("VFD TX:\n");
|
||||
dump_iobuf(&vfd_uart.written);
|
||||
#endif
|
||||
|
||||
struct const_iobuf reader;
|
||||
iobuf_flip(&reader, &vfd_uart.written);
|
||||
|
||||
struct iobuf* writer = &vfd_uart.readable;
|
||||
for (; reader.pos < reader.nbytes ; ){
|
||||
|
||||
if (vfd_frame_sync(&reader)) {
|
||||
|
||||
reader.pos++; // get the sync byte out of the way
|
||||
|
||||
uint8_t cmd;
|
||||
iobuf_read_8(&reader, &cmd);
|
||||
|
||||
if (cmd == VFD_CMD_GET_VERSION) {
|
||||
hr = vfd_handle_get_version(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_RESET) {
|
||||
hr = vfd_handle_reset(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_CLEAR_SCREEN) {
|
||||
hr = vfd_handle_clear_screen(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_SET_BRIGHTNESS) {
|
||||
hr = vfd_handle_set_brightness(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_SET_SCREEN_ON) {
|
||||
hr = vfd_handle_set_screen_on(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_SET_H_SCROLL) {
|
||||
hr = vfd_handle_set_h_scroll(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_DRAW_IMAGE) {
|
||||
hr = vfd_handle_draw_image(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_SET_CURSOR) {
|
||||
hr = vfd_handle_set_cursor(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_SET_ENCODING) {
|
||||
hr = vfd_handle_set_encoding(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_SET_TEXT_WND) {
|
||||
hr = vfd_handle_set_text_wnd(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_SET_TEXT_SPEED) {
|
||||
hr = vfd_handle_set_text_speed(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_WRITE_TEXT) {
|
||||
hr = vfd_handle_write_text(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_ENABLE_SCROLL) {
|
||||
hr = vfd_handle_enable_scroll(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_DISABLE_SCROLL) {
|
||||
hr = vfd_handle_disable_scroll(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_ROTATE) {
|
||||
hr = vfd_handle_rotate(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_CREATE_CHAR) {
|
||||
hr = vfd_handle_create_char(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_CREATE_CHAR2) {
|
||||
hr = vfd_handle_create_char2(&reader, writer, &vfd_uart);
|
||||
} else {
|
||||
dprintf("VFD: Unknown command 0x%x\n", cmd);
|
||||
dump_const_iobuf(&reader);
|
||||
hr = S_FALSE;
|
||||
}
|
||||
} else {
|
||||
|
||||
// if no sync byte is sent, we are just getting plain text...
|
||||
|
||||
if (reader.pos < reader.nbytes){
|
||||
int len = 0;
|
||||
|
||||
// read chars until we hit a new sync byte or the data ends
|
||||
while (reader.pos + len + 1 < reader.nbytes && reader.bytes[reader.pos + len] != VFD_SYNC_BYTE && reader.bytes[reader.pos + len] != VFD_SYNC_BYTE2){
|
||||
len++;
|
||||
}
|
||||
|
||||
char* str = malloc(len);
|
||||
memset(str, 0, len);
|
||||
iobuf_read(&reader, str, len);
|
||||
print_vfd_text(str, len);
|
||||
free(str);
|
||||
|
||||
reader.pos += len;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!SUCCEEDED(hr)){
|
||||
return hr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
vfd_uart.written.pos = 0;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT vfd_handle_get_version(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
dprintf("VFD: Get Version\n");
|
||||
|
||||
struct vfd_resp_board_info resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.unk1 = 2;
|
||||
strcpy(resp.version, "01.20");
|
||||
resp.unk2 = 1;
|
||||
|
||||
return vfd_frame_encode(writer, &resp, sizeof(resp));
|
||||
}
|
||||
HRESULT vfd_handle_reset(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
dprintf("VFD: Reset\n");
|
||||
|
||||
encoding = VFD_ENC_SHIFT_JIS;
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_clear_screen(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
dprintf("VFD: Clear Screen\n");
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_set_brightness(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint8_t b;
|
||||
iobuf_read_8(reader, &b);
|
||||
|
||||
if (b > 4){
|
||||
dprintf("VFD: Brightness, invalid argument\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
dprintf("VFD: Brightness, %d\n", b);
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_set_screen_on(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint8_t b;
|
||||
iobuf_read_8(reader, &b);
|
||||
|
||||
if (b > 1){
|
||||
dprintf("VFD: Screen Power, invalid argument\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
dprintf("VFD: Screen Power, %d\n", b);
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_set_h_scroll(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint8_t x;
|
||||
iobuf_read_8(reader, &x);
|
||||
|
||||
dprintf("VFD: Horizontal Scroll, X=%d\n", x);
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_draw_image(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
int w, h;
|
||||
uint16_t x0, x1;
|
||||
uint8_t y0, y1;
|
||||
uint8_t image[2048];
|
||||
|
||||
iobuf_read_be16(reader, &x0);
|
||||
iobuf_read_8(reader, &y0);
|
||||
iobuf_read_be16(reader, &x1);
|
||||
iobuf_read_8(reader, &y1);
|
||||
w = x1 - x0;
|
||||
h = y1 - y0;
|
||||
iobuf_read(reader, image, w*h);
|
||||
|
||||
dprintf("VFD: Draw image, %dx%d\n", w, h);
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT vfd_handle_set_cursor(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint16_t x;
|
||||
uint8_t y;
|
||||
|
||||
iobuf_read_be16(reader, &x);
|
||||
iobuf_read_8(reader, &y);
|
||||
|
||||
dprintf("VFD: Set Cursor, x=%d,y=%d\n", x, y);
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT vfd_handle_set_encoding(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint8_t b;
|
||||
iobuf_read_8(reader, &b);
|
||||
|
||||
dprintf("VFD: Set Encoding, %d (%s)\n", b, get_encoding_name(b));
|
||||
|
||||
if (b < 0 || b > VFD_ENC_MAX){
|
||||
dprintf("Invalid encoding specified\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
encoding = b;
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_set_text_wnd(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint16_t x0, x1;
|
||||
uint8_t y0, y1;
|
||||
|
||||
iobuf_read_be16(reader, &x0);
|
||||
iobuf_read_8(reader, &y0);
|
||||
iobuf_read_be16(reader, &x1);
|
||||
iobuf_read_8(reader, &y1);
|
||||
|
||||
dprintf("VFD: Set Text Window, p0:%d,%d, p1:%d,%d\n", x0, y0, x1, y1);
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_set_text_speed(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint8_t b;
|
||||
iobuf_read_8(reader, &b);
|
||||
|
||||
dprintf("VFD: Set Text Speed, %d\n", b);
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_write_text(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint8_t len;
|
||||
iobuf_read_8(reader, &len);
|
||||
|
||||
char* str = malloc(len);
|
||||
iobuf_read(reader, str, len);
|
||||
|
||||
print_vfd_text(str, len);
|
||||
free(str);
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_enable_scroll(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
dprintf("VFD: Enable Scrolling\n");
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_disable_scroll(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
dprintf("VFD: Disable Scrolling\n");
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_rotate(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint8_t b;
|
||||
iobuf_read_8(reader, &b);
|
||||
|
||||
dprintf("VFD: Rotate, %d\n", b);
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_create_char(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint8_t b;
|
||||
iobuf_read_8(reader, &b);
|
||||
char buf[32];
|
||||
|
||||
iobuf_read(reader, buf, 32);
|
||||
|
||||
dprintf("VFD: Create character, %d\n", b);
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_create_char2(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint8_t b, b2;
|
||||
iobuf_read_8(reader, &b);
|
||||
iobuf_read_8(reader, &b2);
|
||||
char buf[16];
|
||||
|
||||
iobuf_read(reader, buf, 16);
|
||||
|
||||
dprintf("VFD: Create character, %d, %d\n", b, b2);
|
||||
return S_FALSE;
|
||||
}
|
||||
|
10
board/vfd.h
10
board/vfd.h
@ -2,4 +2,12 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
HRESULT vfd_hook_init(unsigned int port_no);
|
||||
struct vfd_config {
|
||||
bool enable;
|
||||
int port;
|
||||
bool utf_conversion;
|
||||
};
|
||||
|
||||
|
||||
HRESULT vfd_hook_init(struct vfd_config *cfg, int default_port);
|
||||
|
||||
|
6
dist/sao/bananatools.ini
vendored
6
dist/sao/bananatools.ini
vendored
@ -30,10 +30,10 @@ windowed=1
|
||||
framed=0
|
||||
monitor=0
|
||||
|
||||
; Banapass reader
|
||||
[reader]
|
||||
; Aime reader
|
||||
[aime]
|
||||
enable=1
|
||||
access_code=00000000000000000000
|
||||
aimePath=DEVICE\\aime.txt
|
||||
|
||||
; Control the AMCUS replacement class
|
||||
[amcus]
|
||||
|
@ -32,6 +32,6 @@ void kizuna_hook_config_load(
|
||||
platform_config_load(&cfg->platform, filename);
|
||||
kizuna_dll_config_load(&cfg->dll, filename);
|
||||
gfx_config_load(&cfg->gfx, filename);
|
||||
bpreader_config_load(&cfg->reader, filename);
|
||||
usio_config_load(&cfg->usio, filename);
|
||||
vfd_config_load(&cfg->vfd, filename);
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ struct kizuna_hook_config {
|
||||
struct kizuna_dll_config dll;
|
||||
struct gfx_config gfx;
|
||||
struct amcus_config amcus;
|
||||
struct bpreader_config reader;
|
||||
struct usio_config usio;
|
||||
struct vfd_config vfd;
|
||||
};
|
||||
|
||||
void kizuna_dll_config_load(
|
||||
|
@ -44,13 +44,13 @@ static DWORD CALLBACK kizuna_pre_startup(void)
|
||||
ExitProcess(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
hr = sg_reader_hook_init(&kizuna_hook_cfg.aime, 1, kizuna_hook_mod);
|
||||
hr = sg_reader_hook_init(&kizuna_hook_cfg.aime, 1, 3, kizuna_hook_mod);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
ExitProcess(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
hr = vfd_hook_init(2);
|
||||
hr = vfd_hook_init(&kizuna_hook_cfg.vfd, 2);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
ExitProcess(EXIT_FAILURE);
|
||||
|
@ -64,8 +64,8 @@ void sao_hook_config_load(
|
||||
sao_dll_config_load(&cfg->dll, filename);
|
||||
gfx_config_load(&cfg->gfx, filename);
|
||||
qr_config_load(&cfg->qr, filename);
|
||||
bpreader_config_load(&cfg->reader, filename);
|
||||
usio_config_load(&cfg->usio, filename);
|
||||
systype_config_load(&cfg->systype, filename);
|
||||
sao_touch_config_load(&cfg->touch, filename);
|
||||
vfd_config_load(&cfg->vfd, filename);
|
||||
}
|
||||
|
@ -18,10 +18,10 @@ struct sao_hook_config {
|
||||
struct gfx_config gfx;
|
||||
struct amcus_config amcus;
|
||||
struct qr_config qr;
|
||||
struct bpreader_config reader;
|
||||
struct usio_config usio;
|
||||
struct systype_config systype;
|
||||
struct sao_touch_config touch;
|
||||
struct vfd_config vfd;
|
||||
};
|
||||
|
||||
void sao_dll_config_load(
|
||||
|
@ -47,13 +47,13 @@ static DWORD CALLBACK sao_pre_startup(void)
|
||||
ExitProcess(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
hr = sg_reader_hook_init(&sao_hook_cfg.aime, 1, sao_hook_mod);
|
||||
hr = sg_reader_hook_init(&sao_hook_cfg.aime, 1, 3, sao_hook_mod);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
ExitProcess(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
hr = vfd_hook_init(2);
|
||||
hr = vfd_hook_init(&sao_hook_cfg.vfd, 2);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
ExitProcess(EXIT_FAILURE);
|
||||
@ -89,6 +89,11 @@ static DWORD CALLBACK sao_pre_startup(void)
|
||||
ExitProcess(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Initialize Unity native plugin DLL hooks
|
||||
|
||||
There seems to be an issue with other DLL hooks if `LoadLibraryW` is
|
||||
hooked earlier in the `mu3hook` initialization. */
|
||||
|
||||
unity_hook_init();
|
||||
|
||||
gfx_hook_init(&sao_hook_cfg.gfx);
|
||||
|
@ -11,6 +11,7 @@ shared_library(
|
||||
xinput_lib,
|
||||
],
|
||||
link_with : [
|
||||
aimeio_lib,
|
||||
saoio_lib,
|
||||
amcus_lib,
|
||||
platform_lib,
|
||||
|
@ -103,4 +103,4 @@ end:
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
@ -12,4 +12,4 @@ EXPORTS
|
||||
sao_io_read_coin_counter
|
||||
sao_io_get_analog
|
||||
sao_io_get_gamebtns
|
||||
sao_io_get_opbtns
|
||||
sao_io_get_opbtns
|
||||
|
@ -108,4 +108,4 @@ static int my_GetSerialNumber(ULONG usercode, intptr_t serialnumber)
|
||||
wcstombs((char *)serialnumber, dong_config.serial, 32);
|
||||
dprintf("Systype: my_GetSerialNumber %ls\n", dong_config.serial);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -45,5 +45,5 @@ void taiko_hook_config_load(
|
||||
network_config_load(&cfg->network, filename);
|
||||
bpreader_config_load(&cfg->reader, filename);
|
||||
usio_config_load(&cfg->usio, filename);
|
||||
|
||||
vfd_config_load(&cfg->vfd, filename);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ struct taiko_hook_config {
|
||||
struct taiko_network_config network;
|
||||
struct bpreader_config reader;
|
||||
struct usio_config usio;
|
||||
struct vfd_config vfd;
|
||||
};
|
||||
|
||||
void taiko_dll_config_load(
|
||||
|
@ -66,7 +66,7 @@ static DWORD CALLBACK taiko_pre_startup(void)
|
||||
ExitProcess(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
hr = vfd_hook_init(2);
|
||||
hr = vfd_hook_init(&taiko_hook_cfg.vfd, 2);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
ExitProcess(EXIT_FAILURE);
|
||||
|
Loading…
Reference in New Issue
Block a user