forked from Hay1tsme/segatools
Compare commits
3 Commits
feature/ek
...
develop
Author | SHA1 | Date | |
---|---|---|---|
d9075bbfce
|
|||
6fe8744b0f
|
|||
19cd7cb8df
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -18,7 +18,6 @@ build/
|
|||||||
|
|
||||||
# External dependencies
|
# External dependencies
|
||||||
subprojects/capnhook
|
subprojects/capnhook
|
||||||
subprojects/cwinwebsocket
|
|
||||||
|
|
||||||
# For enabling debug logging on local builds
|
# For enabling debug logging on local builds
|
||||||
MesonLocalOptions.mk
|
MesonLocalOptions.mk
|
||||||
|
47
Package.mk
47
Package.mk
@ -256,52 +256,6 @@ $(BUILD_DIR_ZIP)/apm3.zip:
|
|||||||
$(V)strip $(BUILD_DIR_ZIP)/apm3/*.{exe,dll}
|
$(V)strip $(BUILD_DIR_ZIP)/apm3/*.{exe,dll}
|
||||||
$(V)cd $(BUILD_DIR_ZIP)/apm3 ; zip -r ../apm3.zip *
|
$(V)cd $(BUILD_DIR_ZIP)/apm3 ; zip -r ../apm3.zip *
|
||||||
|
|
||||||
$(BUILD_DIR_ZIP)/ekt.zip:
|
|
||||||
$(V)echo ... $@
|
|
||||||
$(V)mkdir -p $(BUILD_DIR_ZIP)/ekt
|
|
||||||
$(V)mkdir -p $(BUILD_DIR_ZIP)/ekt/DEVICE
|
|
||||||
$(V)cp $(BUILD_DIR_64)/subprojects/capnhook/inject/inject.exe \
|
|
||||||
$(BUILD_DIR_GAMES_64)/ekthook/ekthook.dll \
|
|
||||||
$(DIST_DIR)/ekt/segatools_terminal.ini \
|
|
||||||
$(DIST_DIR)/ekt/segatools_satellite.ini \
|
|
||||||
$(DIST_DIR)/ekt/launch_terminal.bat \
|
|
||||||
$(DIST_DIR)/ekt/launch_satellite.bat \
|
|
||||||
$(DIST_DIR)/ekt/card_player.html \
|
|
||||||
$(DIST_DIR)/ekt/config_hook.json \
|
|
||||||
$(BUILD_DIR_ZIP)/ekt
|
|
||||||
$(V)cp pki/billing.pub \
|
|
||||||
pki/ca.crt \
|
|
||||||
$(BUILD_DIR_ZIP)/ekt/DEVICE
|
|
||||||
$(V)strip $(BUILD_DIR_ZIP)/ekt/*.{exe,dll}
|
|
||||||
$(V)cd $(BUILD_DIR_ZIP)/ekt ; zip -r ../ekt.zip *
|
|
||||||
|
|
||||||
$(BUILD_DIR_ZIP)/sekito.zip:
|
|
||||||
$(V)echo ... $@
|
|
||||||
$(V)mkdir -p $(BUILD_DIR_ZIP)/sekito
|
|
||||||
$(V)mkdir -p $(BUILD_DIR_ZIP)/sekito/DEVICE
|
|
||||||
$(V)cp $(DIST_DIR)/sekito/segatools_terminal.ini \
|
|
||||||
$(DIST_DIR)/sekito/segatools_satellite.ini \
|
|
||||||
$(DIST_DIR)/sekito/launch_terminal.bat \
|
|
||||||
$(DIST_DIR)/sekito/launch_satellite.bat \
|
|
||||||
$(DIST_DIR)/sekito/card_player.html \
|
|
||||||
$(DIST_DIR)/sekito/config_hook.json \
|
|
||||||
$(BUILD_DIR_ZIP)/sekito
|
|
||||||
$(V)cp pki/billing.pub \
|
|
||||||
pki/ca.crt \
|
|
||||||
$(BUILD_DIR_ZIP)/sekito/DEVICE
|
|
||||||
$(V)cp $(BUILD_DIR_32)/subprojects/capnhook/inject/inject.exe \
|
|
||||||
$(BUILD_DIR_ZIP)/sekito/inject_x86.exe
|
|
||||||
$(V)cp $(BUILD_DIR_64)/subprojects/capnhook/inject/inject.exe \
|
|
||||||
$(BUILD_DIR_ZIP)/sekito/inject_x64.exe
|
|
||||||
$(V)cp $(BUILD_DIR_32)/subprojects/capnhook/inject/inject.exe \
|
|
||||||
$(BUILD_DIR_ZIP)/sekito/inject_x86.exe
|
|
||||||
$(V)cp $(BUILD_DIR_GAMES_32)/sekitohook/sekitohook.dll \
|
|
||||||
$(BUILD_DIR_ZIP)/sekito/sekitohook_x86.dll
|
|
||||||
$(V)cp $(BUILD_DIR_GAMES_64)/sekitohook/sekitohook.dll \
|
|
||||||
$(BUILD_DIR_ZIP)/sekito/sekitohook_x64.dll
|
|
||||||
$(V)strip $(BUILD_DIR_ZIP)/sekito/*.{exe,dll}
|
|
||||||
$(V)cd $(BUILD_DIR_ZIP)/sekito ; zip -r ../sekito.zip *
|
|
||||||
|
|
||||||
$(BUILD_DIR_ZIP)/doc.zip: \
|
$(BUILD_DIR_ZIP)/doc.zip: \
|
||||||
$(DOC_DIR)/config \
|
$(DOC_DIR)/config \
|
||||||
$(DOC_DIR)/chunihook.md \
|
$(DOC_DIR)/chunihook.md \
|
||||||
@ -328,7 +282,6 @@ $(BUILD_DIR_ZIP)/segatools.zip: \
|
|||||||
$(BUILD_DIR_ZIP)/fgo.zip \
|
$(BUILD_DIR_ZIP)/fgo.zip \
|
||||||
$(BUILD_DIR_ZIP)/kemono.zip \
|
$(BUILD_DIR_ZIP)/kemono.zip \
|
||||||
$(BUILD_DIR_ZIP)/apm3.zip \
|
$(BUILD_DIR_ZIP)/apm3.zip \
|
||||||
$(BUILD_DIR_ZIP)/ekt.zip \
|
|
||||||
CHANGELOG.md \
|
CHANGELOG.md \
|
||||||
README.md \
|
README.md \
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ void aime_config_load(struct aime_config *cfg, const wchar_t *filename)
|
|||||||
cfg->enable = GetPrivateProfileIntW(L"aime", L"enable", 1, filename);
|
cfg->enable = GetPrivateProfileIntW(L"aime", L"enable", 1, filename);
|
||||||
cfg->port_no = GetPrivateProfileIntW(L"aime", L"portNo", 0, filename);
|
cfg->port_no = GetPrivateProfileIntW(L"aime", L"portNo", 0, 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", 3, filename);
|
cfg->gen = GetPrivateProfileIntW(L"aime", L"gen", 0, filename);
|
||||||
cfg->proxy_flag = GetPrivateProfileIntW(L"aime", L"proxyFlag", 2, filename);
|
cfg->proxy_flag = GetPrivateProfileIntW(L"aime", L"proxyFlag", 2, filename);
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
GetPrivateProfileStringW(
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
|
|
||||||
#include "hooklib/config.h"
|
#include "hooklib/config.h"
|
||||||
#include "hooklib/dvd.h"
|
#include "hooklib/dvd.h"
|
||||||
#include "hooklib/y3.h"
|
|
||||||
#include "hooklib/y3-dll.h"
|
|
||||||
|
|
||||||
void dvd_config_load(struct dvd_config *cfg, const wchar_t *filename)
|
void dvd_config_load(struct dvd_config *cfg, const wchar_t *filename)
|
||||||
{
|
{
|
||||||
@ -28,7 +26,7 @@ void touch_screen_config_load(struct touch_screen_config *cfg, const wchar_t *fi
|
|||||||
cfg->cursor = GetPrivateProfileIntW(L"touch", L"cursor", 1, filename);
|
cfg->cursor = GetPrivateProfileIntW(L"touch", L"cursor", 1, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void printer_chc_config_load(struct printer_chc_config *cfg, const wchar_t *filename)
|
void printer_config_load(struct printer_config *cfg, const wchar_t *filename)
|
||||||
{
|
{
|
||||||
assert(cfg != NULL);
|
assert(cfg != NULL);
|
||||||
assert(filename != NULL);
|
assert(filename != NULL);
|
||||||
@ -86,161 +84,3 @@ void printer_chc_config_load(struct printer_chc_config *cfg, const wchar_t *file
|
|||||||
|
|
||||||
cfg->wait_time = GetPrivateProfileIntW(L"printer", L"waitTime", 0, filename);
|
cfg->wait_time = GetPrivateProfileIntW(L"printer", L"waitTime", 0, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void printer_cx_config_load(struct printer_cx_config *cfg, const wchar_t *filename){
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
|
|
||||||
char filenameA[MAX_PATH];
|
|
||||||
|
|
||||||
size_t n = wcstombs(filenameA, filename, MAX_PATH);
|
|
||||||
for (int i = n; i < MAX_PATH; i++)
|
|
||||||
{
|
|
||||||
filenameA[i] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg->enable = GetPrivateProfileIntW(L"printer", L"enable", 1, filename);
|
|
||||||
|
|
||||||
GetPrivateProfileStringA(
|
|
||||||
"printer",
|
|
||||||
"firmwareVersion",
|
|
||||||
"V04-03B",
|
|
||||||
cfg->printer_firm_version,
|
|
||||||
_countof(cfg->printer_firm_version),
|
|
||||||
filenameA);
|
|
||||||
|
|
||||||
GetPrivateProfileStringA(
|
|
||||||
"printer",
|
|
||||||
"configVersion",
|
|
||||||
"V01-75",
|
|
||||||
cfg->printer_config_version,
|
|
||||||
_countof(cfg->printer_config_version),
|
|
||||||
filenameA);
|
|
||||||
|
|
||||||
GetPrivateProfileStringA(
|
|
||||||
"printer",
|
|
||||||
"tableVersion",
|
|
||||||
"V01-E0",
|
|
||||||
cfg->printer_table_version,
|
|
||||||
_countof(cfg->printer_table_version),
|
|
||||||
filenameA);
|
|
||||||
|
|
||||||
GetPrivateProfileStringA(
|
|
||||||
"printer",
|
|
||||||
"cameraVersion",
|
|
||||||
"00.19",
|
|
||||||
cfg->printer_camera_version,
|
|
||||||
_countof(cfg->printer_camera_version),
|
|
||||||
filenameA);
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"printer",
|
|
||||||
L"printerOutPath",
|
|
||||||
L"DEVICE\\print",
|
|
||||||
cfg->printer_out_path,
|
|
||||||
_countof(cfg->printer_out_path),
|
|
||||||
filename);
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"printer",
|
|
||||||
L"printerDataPath",
|
|
||||||
L"DEVICE\\cx7000_data.bin",
|
|
||||||
cfg->printer_data_path,
|
|
||||||
_countof(cfg->printer_data_path),
|
|
||||||
filename);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void y3_dll_config_load(
|
|
||||||
struct y3_dll_config *cfg,
|
|
||||||
const wchar_t *filename)
|
|
||||||
{
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"y3io",
|
|
||||||
L"path",
|
|
||||||
L"",
|
|
||||||
cfg->path,
|
|
||||||
_countof(cfg->path),
|
|
||||||
filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
void y3_config_load(
|
|
||||||
struct y3_config *cfg,
|
|
||||||
const wchar_t *filename)
|
|
||||||
{
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
|
|
||||||
wchar_t tmpstr[5];
|
|
||||||
|
|
||||||
memset(cfg->firm_name_field, ' ', sizeof(cfg->firm_name_field) - 1);
|
|
||||||
cfg->firm_name_field[sizeof(cfg->firm_name_field) - 1] = '\0';
|
|
||||||
|
|
||||||
memset(cfg->firm_name_printer, ' ', sizeof(cfg->firm_name_printer) - 1);
|
|
||||||
cfg->firm_name_printer[sizeof(cfg->firm_name_printer) - 1] = '\0';
|
|
||||||
|
|
||||||
memset(cfg->target_code_field, ' ', sizeof(cfg->target_code_field) - 1);
|
|
||||||
cfg->target_code_field[sizeof(cfg->target_code_field) - 1] = '\0';
|
|
||||||
|
|
||||||
memset(cfg->target_code_printer, ' ', sizeof(cfg->target_code_printer) - 1);
|
|
||||||
cfg->target_code_printer[sizeof(cfg->target_code_printer) - 1] = '\0';
|
|
||||||
|
|
||||||
cfg->enable = GetPrivateProfileIntW(L"flatPanelReader", L"enable", 1, filename);
|
|
||||||
cfg->port_field = GetPrivateProfileIntW(L"flatPanelReader", L"port_field", 10, filename);
|
|
||||||
cfg->port_printer = GetPrivateProfileIntW(L"flatPanelReader", L"port_printer", 11, filename);
|
|
||||||
|
|
||||||
cfg->dll_version = (float)GetPrivateProfileIntW(
|
|
||||||
L"flatPanelReader",
|
|
||||||
L"dllVersion",
|
|
||||||
1,
|
|
||||||
filename);
|
|
||||||
|
|
||||||
cfg->firm_version = (float)GetPrivateProfileIntW(
|
|
||||||
L"flatPanelReader",
|
|
||||||
L"firmVersion",
|
|
||||||
1,
|
|
||||||
filename);
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"flatPanelReader",
|
|
||||||
L"firmNameField",
|
|
||||||
L"SFPR",
|
|
||||||
tmpstr,
|
|
||||||
_countof(tmpstr),
|
|
||||||
filename);
|
|
||||||
|
|
||||||
wcstombs(cfg->firm_name_field, tmpstr, sizeof(cfg->firm_name_field) - 1);
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"flatPanelReader",
|
|
||||||
L"firmNamePrinter",
|
|
||||||
L"SPRT",
|
|
||||||
tmpstr,
|
|
||||||
_countof(tmpstr),
|
|
||||||
filename);
|
|
||||||
|
|
||||||
wcstombs(cfg->firm_name_printer, tmpstr, sizeof(cfg->firm_name_printer) - 1);
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"flatPanelReader",
|
|
||||||
L"targetCodeField",
|
|
||||||
L"SFR0",
|
|
||||||
tmpstr,
|
|
||||||
_countof(tmpstr),
|
|
||||||
filename);
|
|
||||||
|
|
||||||
wcstombs(cfg->target_code_field, tmpstr, sizeof(cfg->target_code_field) - 1);
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"flatPanelReader",
|
|
||||||
L"targetCodePrinter",
|
|
||||||
L"SPT0",
|
|
||||||
tmpstr,
|
|
||||||
_countof(tmpstr),
|
|
||||||
filename);
|
|
||||||
|
|
||||||
wcstombs(cfg->target_code_printer, tmpstr, sizeof(cfg->target_code_printer) - 1);
|
|
||||||
}
|
|
@ -4,29 +4,8 @@
|
|||||||
|
|
||||||
#include "hooklib/dvd.h"
|
#include "hooklib/dvd.h"
|
||||||
#include "hooklib/touch.h"
|
#include "hooklib/touch.h"
|
||||||
#include "hooklib/printer_chc.h"
|
#include "hooklib/printer.h"
|
||||||
#include "hooklib/printer_cx.h"
|
|
||||||
|
|
||||||
struct y3_config {
|
|
||||||
bool enable;
|
|
||||||
|
|
||||||
float dll_version;
|
|
||||||
float firm_version;
|
|
||||||
char firm_name_field[5];
|
|
||||||
char firm_name_printer[5];
|
|
||||||
char target_code_field[5];
|
|
||||||
char target_code_printer[5];
|
|
||||||
uint8_t port_field;
|
|
||||||
uint8_t port_printer;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct y3_dll_config {
|
|
||||||
wchar_t path[MAX_PATH];
|
|
||||||
};
|
|
||||||
|
|
||||||
void dvd_config_load(struct dvd_config *cfg, const wchar_t *filename);
|
void dvd_config_load(struct dvd_config *cfg, const wchar_t *filename);
|
||||||
void touch_screen_config_load(struct touch_screen_config *cfg, const wchar_t *filename);
|
void touch_screen_config_load(struct touch_screen_config *cfg, const wchar_t *filename);
|
||||||
void printer_chc_config_load(struct printer_chc_config *cfg, const wchar_t *filename);
|
void printer_config_load(struct printer_config *cfg, const wchar_t *filename);
|
||||||
void printer_cx_config_load(struct printer_cx_config *cfg, const wchar_t *filename);
|
|
||||||
void y3_config_load(struct y3_config *cfg, const wchar_t *filename);
|
|
||||||
void y3_dll_config_load(struct y3_dll_config *cfg, const wchar_t *filename);
|
|
||||||
|
@ -1,212 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "imageutil.h"
|
|
||||||
|
|
||||||
// copy pasted from https://dev.s-ul.net/domeori/c310emu
|
|
||||||
#define BITMAPHEADERSIZE 0x36
|
|
||||||
|
|
||||||
int ConvertDataToBitmap(
|
|
||||||
DWORD dwBitCount,
|
|
||||||
DWORD dwWidth, DWORD dwHeight,
|
|
||||||
PBYTE pbInput, DWORD cbInput,
|
|
||||||
PBYTE pbOutput, DWORD cbOutput,
|
|
||||||
PDWORD pcbResult,
|
|
||||||
bool pFlip) {
|
|
||||||
if (!pbInput || !pbOutput || dwBitCount < 8) return -3;
|
|
||||||
|
|
||||||
if (cbInput < (dwWidth * dwHeight * dwBitCount / 8)) return -3;
|
|
||||||
|
|
||||||
PBYTE pBuffer = malloc(cbInput);
|
|
||||||
if (!pBuffer) return -2;
|
|
||||||
|
|
||||||
BYTE dwColors = (BYTE)(dwBitCount / 8);
|
|
||||||
if (!dwColors) {
|
|
||||||
free(pBuffer);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT16 cbColors;
|
|
||||||
RGBQUAD pbColors[256];
|
|
||||||
|
|
||||||
switch (dwBitCount) {
|
|
||||||
case 1:
|
|
||||||
cbColors = 1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
cbColors = 4;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
cbColors = 16;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
cbColors = 256;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
cbColors = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cbColors) {
|
|
||||||
BYTE dwStep = (BYTE)(256 / cbColors);
|
|
||||||
|
|
||||||
for (UINT16 i = 0; i < cbColors; ++i) {
|
|
||||||
pbColors[i].rgbRed = dwStep * i;
|
|
||||||
pbColors[i].rgbGreen = dwStep * i;
|
|
||||||
pbColors[i].rgbBlue = dwStep * i;
|
|
||||||
pbColors[i].rgbReserved = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD dwTable = cbColors * sizeof(RGBQUAD);
|
|
||||||
DWORD dwOffset = BITMAPHEADERSIZE + dwTable;
|
|
||||||
|
|
||||||
// calculate the padded row size, again
|
|
||||||
DWORD dwLineSize = (dwWidth * dwBitCount / 8 + 3) & ~3;
|
|
||||||
|
|
||||||
BITMAPFILEHEADER bFile = {0};
|
|
||||||
BITMAPINFOHEADER bInfo = {0};
|
|
||||||
|
|
||||||
bFile.bfType = 0x4D42; // MAGIC
|
|
||||||
bFile.bfSize = dwOffset + cbInput;
|
|
||||||
bFile.bfOffBits = dwOffset;
|
|
||||||
|
|
||||||
bInfo.biSize = sizeof(BITMAPINFOHEADER);
|
|
||||||
bInfo.biWidth = dwWidth;
|
|
||||||
bInfo.biHeight = dwHeight;
|
|
||||||
bInfo.biPlanes = 1;
|
|
||||||
bInfo.biBitCount = (WORD)dwBitCount;
|
|
||||||
bInfo.biCompression = BI_RGB;
|
|
||||||
bInfo.biSizeImage = cbInput;
|
|
||||||
|
|
||||||
if (cbOutput < bFile.bfSize) {
|
|
||||||
free(pBuffer);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flip the image (if necessary) and add padding to each row
|
|
||||||
if (pFlip) {
|
|
||||||
for (size_t i = 0; i < dwHeight; i++) {
|
|
||||||
for (size_t j = 0; j < dwWidth; j++) {
|
|
||||||
for (size_t k = 0; k < dwColors; k++) {
|
|
||||||
// Calculate the position in the padded buffer
|
|
||||||
// Make sure to also flip the colors from RGB to BRG
|
|
||||||
size_t x = (dwHeight - i - 1) * dwLineSize + (dwWidth - j - 1) * dwColors + (dwColors - k - 1);
|
|
||||||
size_t y = (dwHeight - i - 1) * dwWidth * dwColors + j * dwColors + k;
|
|
||||||
*(pBuffer + x) = *(pbInput + y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (size_t i = 0; i < dwHeight; i++) {
|
|
||||||
for (size_t j = 0; j < dwWidth; j++) {
|
|
||||||
for (size_t k = 0; k < dwColors; k++) {
|
|
||||||
// Calculate the position in the padded buffer
|
|
||||||
size_t x = i * dwLineSize + j * dwColors + (dwColors - k - 1);
|
|
||||||
size_t y = (dwHeight - i - 1) * dwWidth * dwColors + j * dwColors + k;
|
|
||||||
*(pBuffer + x) = *(pbInput + y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(pbOutput, &bFile, sizeof(BITMAPFILEHEADER));
|
|
||||||
memcpy(pbOutput + sizeof(BITMAPFILEHEADER), &bInfo, sizeof(BITMAPINFOHEADER));
|
|
||||||
if (cbColors) memcpy(pbOutput + BITMAPHEADERSIZE, pbColors, dwTable);
|
|
||||||
memcpy(pbOutput + dwOffset, pBuffer, cbInput);
|
|
||||||
|
|
||||||
*pcbResult = bFile.bfSize;
|
|
||||||
|
|
||||||
free(pBuffer);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int WriteDataToBitmapFile(
|
|
||||||
LPCWSTR lpFilePath, DWORD dwBitCount,
|
|
||||||
DWORD dwWidth, DWORD dwHeight,
|
|
||||||
PBYTE pbInput, DWORD cbInput,
|
|
||||||
PBYTE pbMetadata, DWORD cbMetadata,
|
|
||||||
bool pFlip) {
|
|
||||||
if (!lpFilePath || !pbInput) return -3;
|
|
||||||
|
|
||||||
HANDLE hFile;
|
|
||||||
DWORD dwBytesWritten;
|
|
||||||
|
|
||||||
hFile = CreateFileW(
|
|
||||||
lpFilePath,
|
|
||||||
GENERIC_WRITE,
|
|
||||||
FILE_SHARE_READ,
|
|
||||||
NULL,
|
|
||||||
CREATE_ALWAYS,
|
|
||||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
|
|
||||||
NULL);
|
|
||||||
if (hFile == INVALID_HANDLE_VALUE) return -1;
|
|
||||||
|
|
||||||
// calculate the padded row size and padded image size
|
|
||||||
DWORD dwLineSize = (dwWidth * dwBitCount / 8 + 3) & ~3;
|
|
||||||
DWORD dwImageSize = dwLineSize * dwHeight;
|
|
||||||
|
|
||||||
DWORD cbResult;
|
|
||||||
DWORD cbBuffer = dwImageSize + 0x500;
|
|
||||||
PBYTE pbBuffer = calloc(cbBuffer, 1);
|
|
||||||
if (!pbBuffer) return -2;
|
|
||||||
|
|
||||||
if (ConvertDataToBitmap(dwBitCount, dwWidth, dwHeight, pbInput, dwImageSize, pbBuffer, cbBuffer, &cbResult, pFlip) < 0) {
|
|
||||||
cbResult = -1;
|
|
||||||
goto WriteDataToBitmapFile_End;
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteFile(hFile, pbBuffer, cbResult, &dwBytesWritten, NULL);
|
|
||||||
|
|
||||||
if (pbMetadata)
|
|
||||||
WriteFile(hFile, pbMetadata, cbMetadata, &dwBytesWritten, NULL);
|
|
||||||
|
|
||||||
CloseHandle(hFile);
|
|
||||||
|
|
||||||
cbResult = dwBytesWritten;
|
|
||||||
|
|
||||||
WriteDataToBitmapFile_End:
|
|
||||||
free(pbBuffer);
|
|
||||||
return cbResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
int WriteArrayToFile(LPCSTR lpOutputFilePath, LPVOID lpDataTemp, DWORD nDataSize, BOOL isAppend) {
|
|
||||||
#ifdef NDEBUG
|
|
||||||
|
|
||||||
return nDataSize;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
HANDLE hFile;
|
|
||||||
DWORD dwBytesWritten;
|
|
||||||
DWORD dwDesiredAccess;
|
|
||||||
DWORD dwCreationDisposition;
|
|
||||||
|
|
||||||
if (isAppend) {
|
|
||||||
dwDesiredAccess = FILE_APPEND_DATA;
|
|
||||||
dwCreationDisposition = OPEN_ALWAYS;
|
|
||||||
} else {
|
|
||||||
dwDesiredAccess = GENERIC_WRITE;
|
|
||||||
dwCreationDisposition = CREATE_ALWAYS;
|
|
||||||
}
|
|
||||||
|
|
||||||
hFile = CreateFileA(
|
|
||||||
lpOutputFilePath,
|
|
||||||
dwDesiredAccess,
|
|
||||||
FILE_SHARE_READ,
|
|
||||||
NULL,
|
|
||||||
dwCreationDisposition,
|
|
||||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
|
|
||||||
NULL);
|
|
||||||
if (hFile == INVALID_HANDLE_VALUE) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteFile(hFile, lpDataTemp, nDataSize, &dwBytesWritten, NULL);
|
|
||||||
CloseHandle(hFile);
|
|
||||||
|
|
||||||
return dwBytesWritten;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
int ConvertDataToBitmap(
|
|
||||||
DWORD dwBitCount,
|
|
||||||
DWORD dwWidth, DWORD dwHeight,
|
|
||||||
PBYTE pbInput, DWORD cbInput,
|
|
||||||
PBYTE pbOutput, DWORD cbOutput,
|
|
||||||
PDWORD pcbResult,
|
|
||||||
bool pFlip);
|
|
||||||
|
|
||||||
int WriteDataToBitmapFile(
|
|
||||||
LPCWSTR lpFilePath, DWORD dwBitCount,
|
|
||||||
DWORD dwWidth, DWORD dwHeight,
|
|
||||||
PBYTE pbInput, DWORD cbInput,
|
|
||||||
PBYTE pbMetadata, DWORD cbMetadata,
|
|
||||||
bool pFlip);
|
|
||||||
|
|
||||||
int WriteArrayToFile(LPCSTR lpOutputFilePath, LPVOID lpDataTemp, DWORD nDataSize, BOOL isAppend);
|
|
@ -21,8 +21,6 @@ hooklib_lib = static_library(
|
|||||||
'dvd.h',
|
'dvd.h',
|
||||||
'fdshark.c',
|
'fdshark.c',
|
||||||
'fdshark.h',
|
'fdshark.h',
|
||||||
'imageutil.c',
|
|
||||||
'imageutil.h',
|
|
||||||
'path.c',
|
'path.c',
|
||||||
'path.h',
|
'path.h',
|
||||||
'reg.c',
|
'reg.c',
|
||||||
@ -33,13 +31,7 @@ hooklib_lib = static_library(
|
|||||||
'spike.h',
|
'spike.h',
|
||||||
'touch.c',
|
'touch.c',
|
||||||
'touch.h',
|
'touch.h',
|
||||||
'printer_chc.c',
|
'printer.c',
|
||||||
'printer_chc.h',
|
'printer.h',
|
||||||
'printer_cx.c',
|
|
||||||
'printer_cx.h',
|
|
||||||
'y3.c',
|
|
||||||
'y3.h',
|
|
||||||
'y3-dll.c',
|
|
||||||
'y3-dll.h',
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -9,9 +9,7 @@
|
|||||||
chc (emihiok)
|
chc (emihiok)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// ReSharper disable CppParameterNeverUsed
|
#include "hooklib/printer.h"
|
||||||
// ReSharper disable CppDFAConstantFunctionResult
|
|
||||||
#include "hooklib/printer_chc.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -100,7 +98,7 @@ int WINAPI chcusb_imageformat_330(
|
|||||||
uint16_t width,
|
uint16_t width,
|
||||||
uint16_t height,
|
uint16_t height,
|
||||||
uint16_t *rResult);
|
uint16_t *rResult);
|
||||||
int WINAPI chcusb_setmtf(int32_t *mtf);
|
int __fastcall chcusb_setmtf(int32_t *mtf);
|
||||||
int WINAPI chcusb_makeGamma(uint16_t k, uint8_t *intoneR, uint8_t *intoneG, uint8_t *intoneB);
|
int WINAPI chcusb_makeGamma(uint16_t k, uint8_t *intoneR, uint8_t *intoneG, uint8_t *intoneB);
|
||||||
int WINAPI chcusb_setIcctable(
|
int WINAPI chcusb_setIcctable(
|
||||||
LPCSTR icc1,
|
LPCSTR icc1,
|
||||||
@ -149,7 +147,6 @@ int WINAPI chcusb_getEEPROM(uint8_t index, uint8_t *rData, uint16_t *rResult);
|
|||||||
int WINAPI chcusb_setParameter(uint8_t a1, uint32_t a2, uint16_t *rResult);
|
int WINAPI chcusb_setParameter(uint8_t a1, uint32_t a2, uint16_t *rResult);
|
||||||
int WINAPI chcusb_getParameter(uint8_t a1, uint8_t *a2, uint16_t *rResult);
|
int WINAPI chcusb_getParameter(uint8_t a1, uint8_t *a2, uint16_t *rResult);
|
||||||
int WINAPI chcusb_universal_command(int32_t a1, uint8_t a2, int32_t a3, uint8_t *a4, uint16_t *rResult);
|
int WINAPI chcusb_universal_command(int32_t a1, uint8_t a2, int32_t a3, uint8_t *a4, uint16_t *rResult);
|
||||||
int WINAPI chcusb_writeIred(uint8_t* a1, uint8_t* a2, uint16_t* rResult);
|
|
||||||
|
|
||||||
/* PrintDLL API hooks */
|
/* PrintDLL API hooks */
|
||||||
|
|
||||||
@ -867,336 +864,6 @@ static const struct hook_symbol C3XXusb_hooks[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* CHC320 x86 hook table */
|
|
||||||
|
|
||||||
static const struct hook_symbol C320usb_hooks[] = {
|
|
||||||
{
|
|
||||||
.name = "__imp_chcusb_MakeThread",
|
|
||||||
.ordinal= 1,
|
|
||||||
.patch = chcusb_MakeThread,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_open",
|
|
||||||
.ordinal= 2,
|
|
||||||
.patch = chcusb_open,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_close",
|
|
||||||
.ordinal= 3,
|
|
||||||
.patch = chcusb_close,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_ReleaseThread",
|
|
||||||
.ordinal= 4,
|
|
||||||
.patch = chcusb_ReleaseThread,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_listupPrinter",
|
|
||||||
.ordinal= 5,
|
|
||||||
.patch = chcusb_listupPrinter,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_listupPrinterSN",
|
|
||||||
.ordinal= 6,
|
|
||||||
.patch = chcusb_listupPrinterSN,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_selectPrinter",
|
|
||||||
.ordinal= 7,
|
|
||||||
.patch = chcusb_selectPrinter,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_selectPrinterSN",
|
|
||||||
.ordinal= 8,
|
|
||||||
.patch = chcusb_selectPrinterSN,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_getPrinterInfo",
|
|
||||||
.ordinal= 9,
|
|
||||||
.patch = chcusb_getPrinterInfo,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_imageformat",
|
|
||||||
.ordinal= 10,
|
|
||||||
.patch = chcusb_imageformat_330,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_setmtf",
|
|
||||||
.ordinal= 11,
|
|
||||||
.patch = chcusb_setmtf,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_makeGamma",
|
|
||||||
.ordinal= 12,
|
|
||||||
.patch = chcusb_makeGamma,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_setIcctable",
|
|
||||||
.ordinal= 13,
|
|
||||||
.patch = chcusb_setIcctable,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_copies",
|
|
||||||
.ordinal= 14,
|
|
||||||
.patch = chcusb_copies,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_status",
|
|
||||||
.ordinal= 15,
|
|
||||||
.patch = chcusb_status,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_statusAll",
|
|
||||||
.ordinal= 16,
|
|
||||||
.patch = chcusb_statusAll,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_startpage",
|
|
||||||
.ordinal= 17,
|
|
||||||
.patch = chcusb_startpage,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_endpage",
|
|
||||||
.ordinal= 18,
|
|
||||||
.patch = chcusb_endpage,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_write",
|
|
||||||
.ordinal= 19,
|
|
||||||
.patch = chcusb_write,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_writeLaminate",
|
|
||||||
.ordinal= 20,
|
|
||||||
.patch = chcusb_writeLaminate,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_writeHolo",
|
|
||||||
.ordinal= 21,
|
|
||||||
.patch = chcusb_writeHolo,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_setPrinterInfo",
|
|
||||||
.ordinal= 22,
|
|
||||||
.patch = chcusb_setPrinterInfo,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_getGamma",
|
|
||||||
.ordinal= 23,
|
|
||||||
.patch = chcusb_getGamma,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_getMtf",
|
|
||||||
.ordinal= 24,
|
|
||||||
.patch = chcusb_getMtf,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_cancelCopies",
|
|
||||||
.ordinal= 25,
|
|
||||||
.patch = chcusb_cancelCopies,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_setPrinterToneCurve",
|
|
||||||
.ordinal= 26,
|
|
||||||
.patch = chcusb_setPrinterToneCurve,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_getPrinterToneCurve",
|
|
||||||
.ordinal= 27,
|
|
||||||
.patch = chcusb_getPrinterToneCurve,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "chcusb_blinkLED",
|
|
||||||
.ordinal= 28,
|
|
||||||
.patch = chcusb_blinkLED,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "chcusb_resetPrinter",
|
|
||||||
.ordinal= 29,
|
|
||||||
.patch = chcusb_resetPrinter,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_AttachThreadCount",
|
|
||||||
.ordinal= 30,
|
|
||||||
.patch = chcusb_AttachThreadCount,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_getPrintIDStatus",
|
|
||||||
.ordinal= 31,
|
|
||||||
.patch = chcusb_getPrintIDStatus,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_setPrintStandby",
|
|
||||||
.ordinal= 32,
|
|
||||||
.patch = chcusb_setPrintStandby,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "chcusb_testCardFeed",
|
|
||||||
.ordinal= 33,
|
|
||||||
.patch = chcusb_testCardFeed,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_exitCard",
|
|
||||||
.ordinal= 34,
|
|
||||||
.patch = chcusb_exitCard,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_getCardRfidTID",
|
|
||||||
.ordinal= 35,
|
|
||||||
.patch = chcusb_getCardRfidTID,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_commCardRfidReader",
|
|
||||||
.ordinal= 36,
|
|
||||||
.patch = chcusb_commCardRfidReader,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_updateCardRfidReader",
|
|
||||||
.ordinal= 37,
|
|
||||||
.patch = chcusb_updateCardRfidReader,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_getErrorLog",
|
|
||||||
.ordinal= 38,
|
|
||||||
.patch = chcusb_getErrorLog,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_getErrorStatus",
|
|
||||||
.ordinal= 39,
|
|
||||||
.patch = chcusb_getErrorStatus,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_setCutList",
|
|
||||||
.ordinal= 40,
|
|
||||||
.patch = chcusb_setCutList,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_setLaminatePattern",
|
|
||||||
.ordinal= 41,
|
|
||||||
.patch = chcusb_setLaminatePattern,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_color_adjustment",
|
|
||||||
.ordinal= 42,
|
|
||||||
.patch = chcusb_color_adjustment,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_color_adjustmentEx",
|
|
||||||
.ordinal= 43,
|
|
||||||
.patch = chcusb_color_adjustmentEx,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_writeIred",
|
|
||||||
.ordinal= 50,
|
|
||||||
.patch = chcusb_writeIred,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_getEEPROM",
|
|
||||||
.ordinal= 58,
|
|
||||||
.patch = chcusb_getEEPROM,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_setParameter",
|
|
||||||
.ordinal= 64,
|
|
||||||
.patch = chcusb_setParameter,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_getParameter",
|
|
||||||
.ordinal= 65,
|
|
||||||
.patch = chcusb_getParameter,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_chcusb_universal_command",
|
|
||||||
.ordinal= 73,
|
|
||||||
.patch = chcusb_universal_command,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct hook_symbol C320FWDLusb_hooks[] = {
|
|
||||||
{
|
|
||||||
.name = "__imp_fwdlusb_open",
|
|
||||||
.ordinal= 1,
|
|
||||||
.patch = fwdlusb_open,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_fwdlusb_close",
|
|
||||||
.ordinal= 2,
|
|
||||||
.patch = fwdlusb_close,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_fwdlusb_listupPrinter",
|
|
||||||
.ordinal= 3,
|
|
||||||
.patch = fwdlusb_listupPrinter,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_fwdlusb_listupPrinterSN",
|
|
||||||
.ordinal= 4,
|
|
||||||
.patch = fwdlusb_listupPrinterSN,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_fwdlusb_selectPrinter",
|
|
||||||
.ordinal= 5,
|
|
||||||
.patch = fwdlusb_selectPrinter,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_fwdlusb_selectPrinterSN",
|
|
||||||
.ordinal= 6,
|
|
||||||
.patch = fwdlusb_selectPrinterSN,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_fwdlusb_getPrinterInfo",
|
|
||||||
.ordinal= 7,
|
|
||||||
.patch = fwdlusb_getPrinterInfo,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_fwdlusb_status",
|
|
||||||
.ordinal= 8,
|
|
||||||
.patch = fwdlusb_status,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_fwdlusb_statusAll",
|
|
||||||
.ordinal= 9,
|
|
||||||
.patch = fwdlusb_statusAll,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_fwdlusb_resetPrinter",
|
|
||||||
.ordinal= 10,
|
|
||||||
.patch = fwdlusb_resetPrinter,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_fwdlusb_updateFirmware",
|
|
||||||
.ordinal= 11,
|
|
||||||
.patch = fwdlusb_updateFirmware,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_fwdlusb_getFirmwareInfo",
|
|
||||||
.ordinal= 12,
|
|
||||||
.patch = fwdlusb_getFirmwareInfo,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_fwdlusb_MakeThread",
|
|
||||||
.ordinal= 13,
|
|
||||||
.patch = fwdlusb_MakeThread,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_fwdlusb_ReleaseThread",
|
|
||||||
.ordinal= 14,
|
|
||||||
.patch = fwdlusb_ReleaseThread,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_fwdlusb_AttachThreadCount",
|
|
||||||
.ordinal= 15,
|
|
||||||
.patch = fwdlusb_AttachThreadCount,
|
|
||||||
.link = NULL
|
|
||||||
}, {
|
|
||||||
.name = "__imp_fwdlusb_getErrorLog",
|
|
||||||
.ordinal= 16,
|
|
||||||
.patch = fwdlusb_getErrorLog,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
/* PrintDLL hook tbl */
|
/* PrintDLL hook tbl */
|
||||||
|
|
||||||
static struct hook_symbol printdll_hooks[] = {
|
static struct hook_symbol printdll_hooks[] = {
|
||||||
@ -1483,9 +1150,9 @@ static struct hook_symbol printdll_hooks[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct printer_chc_config printer_config;
|
static struct printer_config printer_config;
|
||||||
|
|
||||||
void printer_chc_hook_init(const struct printer_chc_config *cfg, int rfid_port_no, HINSTANCE self) {
|
void printer_hook_init(const struct printer_config *cfg, int rfid_port_no, HINSTANCE self) {
|
||||||
HANDLE fwFile = NULL;
|
HANDLE fwFile = NULL;
|
||||||
DWORD bytesRead = 0;
|
DWORD bytesRead = 0;
|
||||||
|
|
||||||
@ -1503,7 +1170,7 @@ void printer_chc_hook_init(const struct printer_chc_config *cfg, int rfid_port_n
|
|||||||
rotate180 = cfg->rotate_180;
|
rotate180 = cfg->rotate_180;
|
||||||
|
|
||||||
memcpy(&printer_config, cfg, sizeof(*cfg));
|
memcpy(&printer_config, cfg, sizeof(*cfg));
|
||||||
printer_chc_hook_insert_hooks(NULL);
|
printer_hook_insert_hooks(NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (self != NULL) {
|
if (self != NULL) {
|
||||||
@ -1562,13 +1229,13 @@ void printer_chc_hook_init(const struct printer_chc_config *cfg, int rfid_port_n
|
|||||||
dprintf("Printer: hook enabled.\n");
|
dprintf("Printer: hook enabled.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void printer_chc_hook_insert_hooks(HMODULE target) {
|
void printer_hook_insert_hooks(HMODULE target) {
|
||||||
hook_table_apply(target, "C310Ausb.dll", C3XXusb_hooks, _countof(C3XXusb_hooks));
|
hook_table_apply(target, "C310Ausb.dll", C3XXusb_hooks, _countof(C3XXusb_hooks));
|
||||||
hook_table_apply(target, "C310Busb.dll", C3XXusb_hooks, _countof(C3XXusb_hooks));
|
hook_table_apply(target, "C310Busb.dll", C3XXusb_hooks, _countof(C3XXusb_hooks));
|
||||||
hook_table_apply(target, "C310FWDLusb.dll", C3XXFWDLusb_hooks, _countof(C3XXFWDLusb_hooks));
|
hook_table_apply(target, "C310FWDLusb.dll", C3XXFWDLusb_hooks, _countof(C3XXFWDLusb_hooks));
|
||||||
hook_table_apply(target, "C310BFWDLusb.dll", C3XXFWDLusb_hooks, _countof(C3XXFWDLusb_hooks));
|
hook_table_apply(target, "C310BFWDLusb.dll", C3XXFWDLusb_hooks, _countof(C3XXFWDLusb_hooks));
|
||||||
hook_table_apply(target, "C320Ausb.dll", C320usb_hooks, _countof(C3XXusb_hooks));
|
hook_table_apply(target, "C320Ausb.dll", C3XXusb_hooks, _countof(C3XXusb_hooks));
|
||||||
hook_table_apply(target, "C320AFWDLusb.dll", C320FWDLusb_hooks, _countof(C3XXFWDLusb_hooks));
|
hook_table_apply(target, "C320AFWDLusb.dll", C3XXFWDLusb_hooks, _countof(C3XXFWDLusb_hooks));
|
||||||
hook_table_apply(target, "C330Ausb.dll", C3XXusb_hooks, _countof(C3XXusb_hooks));
|
hook_table_apply(target, "C330Ausb.dll", C3XXusb_hooks, _countof(C3XXusb_hooks));
|
||||||
hook_table_apply(target, "C330AFWDLusb.dll", C3XXFWDLusb_hooks, _countof(C3XXFWDLusb_hooks));
|
hook_table_apply(target, "C330AFWDLusb.dll", C3XXFWDLusb_hooks, _countof(C3XXFWDLusb_hooks));
|
||||||
|
|
||||||
@ -2493,11 +2160,6 @@ int WINAPI chcusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t
|
|||||||
if (rBuffer) memset(rBuffer, 0, *rLen);
|
if (rBuffer) memset(rBuffer, 0, *rLen);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // unknown
|
|
||||||
if (*rLen != 0x17) *rLen = 0x17;
|
|
||||||
if (rBuffer) memset(rBuffer, 0, *rLen);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3: // getFirmwareVersion
|
case 3: // getFirmwareVersion
|
||||||
if (*rLen != 0x99) *rLen = 0x99;
|
if (*rLen != 0x99) *rLen = 0x99;
|
||||||
if (rBuffer) {
|
if (rBuffer) {
|
||||||
@ -2672,7 +2334,7 @@ int WINAPI chcusb_imageformat_330(
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WINAPI chcusb_setmtf(int32_t *mtf) {
|
int __fastcall chcusb_setmtf(int32_t *mtf) {
|
||||||
dprintf("Printer: C3XXusb: %s\n", __func__);
|
dprintf("Printer: C3XXusb: %s\n", __func__);
|
||||||
|
|
||||||
memcpy(MTF, mtf, sizeof(MTF));
|
memcpy(MTF, mtf, sizeof(MTF));
|
||||||
@ -3485,14 +3147,208 @@ int CHCUSB_writeLaminate(const void *handle, uint8_t *data, uint32_t offset, uin
|
|||||||
return chcusb_writeLaminate(data, writeSize, rResult);
|
return chcusb_writeLaminate(data, writeSize, rResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copy pasted from https://dev.s-ul.net/domeori/c310emu
|
||||||
|
#define BITMAPHEADERSIZE 0x36
|
||||||
|
|
||||||
|
DWORD ConvertDataToBitmap(
|
||||||
|
DWORD dwBitCount,
|
||||||
|
DWORD dwWidth, DWORD dwHeight,
|
||||||
|
PBYTE pbInput, DWORD cbInput,
|
||||||
|
PBYTE pbOutput, DWORD cbOutput,
|
||||||
|
PDWORD pcbResult,
|
||||||
|
bool pFlip) {
|
||||||
|
if (!pbInput || !pbOutput || dwBitCount < 8) return -3;
|
||||||
|
|
||||||
|
if (cbInput < (dwWidth * dwHeight * dwBitCount / 8)) return -3;
|
||||||
|
|
||||||
|
PBYTE pBuffer = (PBYTE)malloc(cbInput);
|
||||||
|
if (!pBuffer) return -2;
|
||||||
|
|
||||||
|
BYTE dwColors = (BYTE)(dwBitCount / 8);
|
||||||
|
if (!dwColors) return -1;
|
||||||
|
|
||||||
|
UINT16 cbColors;
|
||||||
|
RGBQUAD pbColors[256];
|
||||||
|
|
||||||
|
switch (dwBitCount) {
|
||||||
|
case 1:
|
||||||
|
cbColors = 1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
cbColors = 4;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
cbColors = 16;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
cbColors = 256;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cbColors = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cbColors) {
|
||||||
|
BYTE dwStep = (BYTE)(256 / cbColors);
|
||||||
|
|
||||||
|
for (UINT16 i = 0; i < cbColors; ++i) {
|
||||||
|
pbColors[i].rgbRed = dwStep * i;
|
||||||
|
pbColors[i].rgbGreen = dwStep * i;
|
||||||
|
pbColors[i].rgbBlue = dwStep * i;
|
||||||
|
pbColors[i].rgbReserved = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD dwTable = cbColors * sizeof(RGBQUAD);
|
||||||
|
DWORD dwOffset = BITMAPHEADERSIZE + dwTable;
|
||||||
|
|
||||||
|
// calculate the padded row size, again
|
||||||
|
DWORD dwLineSize = (dwWidth * dwBitCount / 8 + 3) & ~3;
|
||||||
|
|
||||||
|
BITMAPFILEHEADER bFile = {0};
|
||||||
|
BITMAPINFOHEADER bInfo = {0};
|
||||||
|
|
||||||
|
bFile.bfType = 0x4D42; // MAGIC
|
||||||
|
bFile.bfSize = dwOffset + cbInput;
|
||||||
|
bFile.bfOffBits = dwOffset;
|
||||||
|
|
||||||
|
bInfo.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
|
bInfo.biWidth = dwWidth;
|
||||||
|
bInfo.biHeight = dwHeight;
|
||||||
|
bInfo.biPlanes = 1;
|
||||||
|
bInfo.biBitCount = (WORD)dwBitCount;
|
||||||
|
bInfo.biCompression = BI_RGB;
|
||||||
|
bInfo.biSizeImage = cbInput;
|
||||||
|
|
||||||
|
if (cbOutput < bFile.bfSize) return -1;
|
||||||
|
|
||||||
|
// Flip the image (if necessary) and add padding to each row
|
||||||
|
if (pFlip) {
|
||||||
|
for (size_t i = 0; i < dwHeight; i++) {
|
||||||
|
for (size_t j = 0; j < dwWidth; j++) {
|
||||||
|
for (size_t k = 0; k < dwColors; k++) {
|
||||||
|
// Calculate the position in the padded buffer
|
||||||
|
// Make sure to also flip the colors from RGB to BRG
|
||||||
|
size_t x = (dwHeight - i - 1) * dwLineSize + (dwWidth - j - 1) * dwColors + (dwColors - k - 1);
|
||||||
|
size_t y = (dwHeight - i - 1) * dwWidth * dwColors + j * dwColors + k;
|
||||||
|
*(pBuffer + x) = *(pbInput + y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (size_t i = 0; i < dwHeight; i++) {
|
||||||
|
for (size_t j = 0; j < dwWidth; j++) {
|
||||||
|
for (size_t k = 0; k < dwColors; k++) {
|
||||||
|
// Calculate the position in the padded buffer
|
||||||
|
size_t x = i * dwLineSize + j * dwColors + (dwColors - k - 1);
|
||||||
|
size_t y = (dwHeight - i - 1) * dwWidth * dwColors + j * dwColors + k;
|
||||||
|
*(pBuffer + x) = *(pbInput + y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(pbOutput, &bFile, sizeof(BITMAPFILEHEADER));
|
||||||
|
memcpy(pbOutput + sizeof(BITMAPFILEHEADER), &bInfo, sizeof(BITMAPINFOHEADER));
|
||||||
|
if (cbColors) memcpy(pbOutput + BITMAPHEADERSIZE, pbColors, dwTable);
|
||||||
|
memcpy(pbOutput + dwOffset, pBuffer, cbInput);
|
||||||
|
|
||||||
|
*pcbResult = bFile.bfSize;
|
||||||
|
|
||||||
|
free(pBuffer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD WriteDataToBitmapFile(
|
||||||
|
LPCWSTR lpFilePath, DWORD dwBitCount,
|
||||||
|
DWORD dwWidth, DWORD dwHeight,
|
||||||
|
PBYTE pbInput, DWORD cbInput,
|
||||||
|
PBYTE pbMetadata, DWORD cbMetadata,
|
||||||
|
bool pFlip) {
|
||||||
|
if (!lpFilePath || !pbInput) return -3;
|
||||||
|
|
||||||
|
HANDLE hFile;
|
||||||
|
DWORD dwBytesWritten;
|
||||||
|
|
||||||
|
hFile = CreateFileW(
|
||||||
|
lpFilePath,
|
||||||
|
GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
NULL,
|
||||||
|
CREATE_ALWAYS,
|
||||||
|
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
|
||||||
|
NULL);
|
||||||
|
if (hFile == INVALID_HANDLE_VALUE) return -1;
|
||||||
|
|
||||||
|
// calculate the padded row size and padded image size
|
||||||
|
DWORD dwLineSize = (dwWidth * dwBitCount / 8 + 3) & ~3;
|
||||||
|
DWORD dwImageSize = dwLineSize * dwHeight;
|
||||||
|
|
||||||
|
DWORD cbResult;
|
||||||
|
DWORD cbBuffer = dwImageSize + 0x500;
|
||||||
|
PBYTE pbBuffer = (PBYTE)calloc(cbBuffer, 1);
|
||||||
|
if (!pbBuffer) return -2;
|
||||||
|
|
||||||
|
if (ConvertDataToBitmap(dwBitCount, dwWidth, dwHeight, pbInput, dwImageSize, pbBuffer, cbBuffer, &cbResult, pFlip) < 0) {
|
||||||
|
cbResult = -1;
|
||||||
|
goto WriteDataToBitmapFile_End;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteFile(hFile, pbBuffer, cbResult, &dwBytesWritten, NULL);
|
||||||
|
|
||||||
|
if (pbMetadata)
|
||||||
|
WriteFile(hFile, pbMetadata, cbMetadata, &dwBytesWritten, NULL);
|
||||||
|
|
||||||
|
CloseHandle(hFile);
|
||||||
|
|
||||||
|
cbResult = dwBytesWritten;
|
||||||
|
|
||||||
|
WriteDataToBitmapFile_End:
|
||||||
|
free(pbBuffer);
|
||||||
|
return cbResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD WriteArrayToFile(LPCSTR lpOutputFilePath, LPVOID lpDataTemp, DWORD nDataSize, BOOL isAppend) {
|
||||||
|
#ifdef NDEBUG
|
||||||
|
|
||||||
|
return nDataSize;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
HANDLE hFile;
|
||||||
|
DWORD dwBytesWritten;
|
||||||
|
DWORD dwDesiredAccess;
|
||||||
|
DWORD dwCreationDisposition;
|
||||||
|
|
||||||
|
if (isAppend) {
|
||||||
|
dwDesiredAccess = FILE_APPEND_DATA;
|
||||||
|
dwCreationDisposition = OPEN_ALWAYS;
|
||||||
|
} else {
|
||||||
|
dwDesiredAccess = GENERIC_WRITE;
|
||||||
|
dwCreationDisposition = CREATE_ALWAYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
hFile = CreateFileA(
|
||||||
|
lpOutputFilePath,
|
||||||
|
dwDesiredAccess,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
NULL,
|
||||||
|
dwCreationDisposition,
|
||||||
|
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
|
||||||
|
NULL);
|
||||||
|
if (hFile == INVALID_HANDLE_VALUE) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteFile(hFile, lpDataTemp, nDataSize, &dwBytesWritten, NULL);
|
||||||
|
CloseHandle(hFile);
|
||||||
|
|
||||||
|
return dwBytesWritten;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void printer_set_dimensions(int width, int height){
|
void printer_set_dimensions(int width, int height){
|
||||||
WIDTH = width;
|
WIDTH = width;
|
||||||
HEIGHT = height;
|
HEIGHT = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int WINAPI chcusb_writeIred(uint8_t* a1, uint8_t* a2, uint16_t* rResult) {
|
|
||||||
dprintf("Printer: C3XXusb: %s\n", __func__);
|
|
||||||
*rResult = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
@ -4,7 +4,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
struct printer_chc_config {
|
struct printer_config {
|
||||||
bool enable;
|
bool enable;
|
||||||
bool rotate_180;
|
bool rotate_180;
|
||||||
char serial_no[8];
|
char serial_no[8];
|
||||||
@ -15,8 +15,8 @@ struct printer_chc_config {
|
|||||||
uint32_t wait_time;
|
uint32_t wait_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
void printer_chc_hook_init(const struct printer_chc_config *cfg, int rfid_port_no, HINSTANCE self);
|
void printer_hook_init(const struct printer_config *cfg, int rfid_port_no, HINSTANCE self);
|
||||||
void printer_chc_hook_insert_hooks(HMODULE target);
|
void printer_hook_insert_hooks(HMODULE target);
|
||||||
|
|
||||||
void printer_set_dimensions(int width, int height);
|
void printer_set_dimensions(int width, int height);
|
||||||
int WINAPI fwdlusb_updateFirmware_main(uint8_t update, LPCSTR filename, uint16_t *rResult);
|
int WINAPI fwdlusb_updateFirmware_main(uint8_t update, LPCSTR filename, uint16_t *rResult);
|
@ -1,920 +0,0 @@
|
|||||||
// ReSharper disable CppParameterNeverUsed
|
|
||||||
// ReSharper disable CppParameterMayBeConstPtrOrRef
|
|
||||||
#include "printer_cx.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <windows.h>
|
|
||||||
#include <wtypes.h>
|
|
||||||
|
|
||||||
#include "imageutil.h"
|
|
||||||
#include "hook/procaddr.h"
|
|
||||||
#include "hook/table.h"
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
|
|
||||||
#pragma region prototypes
|
|
||||||
static int __stdcall hook_CXCMD_Retransfer();
|
|
||||||
|
|
||||||
static bool __stdcall hook_CXCMD_CheckIfConnected(int* pSlotId, int* pId);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_xImageOut();
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_MoveCard(int slotId, int id, int dest, int flip, int filmInit, int immed);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_xWriteMagData();
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_SecurityPrint(int slotId, int id, int color, int bufferIndex, int immed);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ScanPrinterNext();
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_Print(int slotId, int id, int color, int bufferIndex, int immed);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_RezeroUnit(int slotId, int id, int action);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_WriteMagData();
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_LogSense(int iSlot, int iID, int iPage, uint8_t* pbyBuffer);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_StandardInquiry(int iSlot, int iID, uint8_t* pbyBuffer);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ModeSense(int iSlot, int iID, int iPC, int iPage, uint8_t* pbyBuffer);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_UpdateFirmware(int iSlot, int iID, char* pFile, int iDataID);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ModeSelect(int iSlot, int iID, int iSp, int iPage, uint8_t* pbyData);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_GetPrintingStatus();
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_SendDiagnostic(int iSlot, int iID, int iTestMode, int iTestPatten, int iTestCount);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_RetransferAndTurn(int slotId, int id, int immed);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_LogSelect(int iSlot, int iID, int iMod);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ReadPosition(int slotId, int id, uint8_t* buffer);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_SecurityLock();
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_SetPrintingStatus();
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_xReadISOMagData();
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_WriteISO3TrackMagData();
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_PasswordSet();
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_GetPrinterStatus();
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_WriteProjectCode();
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_LoadCard(int slotId, int id, int dest, int flip, int filmInit, int immed);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ReadMagData();
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ScanPrinter(int* pSlotId, int* pId);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_xWriteISOMagData();
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ICControl();
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ImageOut(int slotId, int id, uint8_t* plane, int length, int color, int bufferIndex);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ReadBuffer(int iSlot, int iID, int iMode, int iBufferID, uint8_t* pbyData, int iOffset,
|
|
||||||
int iLength);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_xReadMagData();
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_WriteBuffer(int iSlot, int iID, int iMode, int iBufferID, uint8_t* pbyData, int iOffset,
|
|
||||||
int iLength);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_DefineLUT(int slotId, int id, int color, int length, uint8_t* buffer);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ReadISO3TrackMagData();
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_TestUnitReady(int slotId, int id);
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_RetransferAndEject(int slotId, int id, int immed);
|
|
||||||
|
|
||||||
static bool __stdcall hook_Lut24_Exchange(const wchar_t* pFile, uint8_t* y, uint8_t* m, uint8_t* c, int sizeY, int sizeM,
|
|
||||||
int sizeC);
|
|
||||||
|
|
||||||
static bool __stdcall hook_Wdata_create(uint8_t* pbyRdata, uint8_t* pbyGdata, uint8_t* pbyBdata, int iWidth,
|
|
||||||
int iHeight, bool bPortrait, int iAlgorithim, uint8_t* pbyWdata);
|
|
||||||
|
|
||||||
static int __cdecl hook_init_accesscodekey(BSTR fileName);
|
|
||||||
|
|
||||||
static int __cdecl hook_accesscodekeyoverwriteheader(void* context, BSTR header, int headerLen, BSTR accessheaderkey, int headerkeylen);
|
|
||||||
#pragma endregion
|
|
||||||
|
|
||||||
#pragma region hooktables
|
|
||||||
static const struct hook_symbol hook_pcp_syms[] = {
|
|
||||||
{
|
|
||||||
.name = "CXCMD_Retransfer",
|
|
||||||
.patch = hook_CXCMD_Retransfer,
|
|
||||||
.ordinal = 19,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_CheckIfConnected",
|
|
||||||
.patch = hook_CXCMD_CheckIfConnected,
|
|
||||||
.ordinal = 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_xImageOut",
|
|
||||||
.patch = hook_CXCMD_xImageOut,
|
|
||||||
.ordinal = 36,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_MoveCard",
|
|
||||||
.patch = hook_CXCMD_MoveCard,
|
|
||||||
.ordinal = 12,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_xWriteMagData",
|
|
||||||
.patch = hook_CXCMD_xWriteMagData,
|
|
||||||
.ordinal = 40,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_SecurityPrint",
|
|
||||||
.patch = hook_CXCMD_SecurityPrint,
|
|
||||||
.ordinal = 26,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_ScanPrinterNext",
|
|
||||||
.patch = hook_CXCMD_ScanPrinterNext,
|
|
||||||
.ordinal = 24,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_Print",
|
|
||||||
.patch = hook_CXCMD_Print,
|
|
||||||
.ordinal = 14,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_RezeroUnit",
|
|
||||||
.patch = hook_CXCMD_RezeroUnit,
|
|
||||||
.ordinal = 22,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_WriteMagData",
|
|
||||||
.patch = hook_CXCMD_WriteMagData,
|
|
||||||
.ordinal = 34,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_LogSense",
|
|
||||||
.patch = hook_CXCMD_LogSense,
|
|
||||||
.ordinal = 9,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_StandardInquiry",
|
|
||||||
.patch = hook_CXCMD_StandardInquiry,
|
|
||||||
.ordinal = 29,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_ModeSense",
|
|
||||||
.patch = hook_CXCMD_ModeSense,
|
|
||||||
.ordinal = 11,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_UpdateFirmware",
|
|
||||||
.patch = hook_CXCMD_UpdateFirmware,
|
|
||||||
.ordinal = 31,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_ModeSelect",
|
|
||||||
.patch = hook_CXCMD_ModeSelect,
|
|
||||||
.ordinal = 10,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_GetPrintingStatus",
|
|
||||||
.patch = hook_CXCMD_GetPrintingStatus,
|
|
||||||
.ordinal = 4,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_SendDiagnostic",
|
|
||||||
.patch = hook_CXCMD_SendDiagnostic,
|
|
||||||
.ordinal = 27,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_RetransferAndTurn",
|
|
||||||
.patch = hook_CXCMD_RetransferAndTurn,
|
|
||||||
.ordinal = 21,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_LogSelect",
|
|
||||||
.patch = hook_CXCMD_LogSelect,
|
|
||||||
.ordinal = 8,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_ReadPosition",
|
|
||||||
.patch = hook_CXCMD_ReadPosition,
|
|
||||||
.ordinal = 18,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_SecurityLock",
|
|
||||||
.patch = hook_CXCMD_SecurityLock,
|
|
||||||
.ordinal = 25,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_SetPrintingStatus",
|
|
||||||
.patch = hook_CXCMD_SetPrintingStatus,
|
|
||||||
.ordinal = 28,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_xReadISOMagData",
|
|
||||||
.patch = hook_CXCMD_xReadISOMagData,
|
|
||||||
.ordinal = 37,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_WriteISO3TrackMagData",
|
|
||||||
.patch = hook_CXCMD_WriteISO3TrackMagData,
|
|
||||||
.ordinal = 33,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_PasswordSet",
|
|
||||||
.patch = hook_CXCMD_PasswordSet,
|
|
||||||
.ordinal = 13,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_GetPrinterStatus",
|
|
||||||
.patch = hook_CXCMD_GetPrinterStatus,
|
|
||||||
.ordinal = 3,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_WriteProjectCode",
|
|
||||||
.patch = hook_CXCMD_WriteProjectCode,
|
|
||||||
.ordinal = 35,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_LoadCard",
|
|
||||||
.patch = hook_CXCMD_LoadCard,
|
|
||||||
.ordinal = 7,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_ReadMagData",
|
|
||||||
.patch = hook_CXCMD_ReadMagData,
|
|
||||||
.ordinal = 17,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_ScanPrinter",
|
|
||||||
.patch = hook_CXCMD_ScanPrinter,
|
|
||||||
.ordinal = 23,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_xWriteISOMagData",
|
|
||||||
.patch = hook_CXCMD_xWriteISOMagData,
|
|
||||||
.ordinal = 39,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_ICControl",
|
|
||||||
.patch = hook_CXCMD_ICControl,
|
|
||||||
.ordinal = 5,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_ImageOut",
|
|
||||||
.patch = hook_CXCMD_ImageOut,
|
|
||||||
.ordinal = 6,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_ReadBuffer",
|
|
||||||
.patch = hook_CXCMD_ReadBuffer,
|
|
||||||
.ordinal = 15,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_xReadMagData",
|
|
||||||
.patch = hook_CXCMD_xReadMagData,
|
|
||||||
.ordinal = 38,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_WriteBuffer",
|
|
||||||
.patch = hook_CXCMD_WriteBuffer,
|
|
||||||
.ordinal = 32,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_DefineLUT",
|
|
||||||
.patch = hook_CXCMD_DefineLUT,
|
|
||||||
.ordinal = 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_ReadISO3TrackMagData",
|
|
||||||
.patch = hook_CXCMD_ReadISO3TrackMagData,
|
|
||||||
.ordinal = 16,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_TestUnitReady",
|
|
||||||
.patch = hook_CXCMD_TestUnitReady,
|
|
||||||
.ordinal = 30,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "CXCMD_RetransferAndEject",
|
|
||||||
.patch = hook_CXCMD_RetransferAndEject,
|
|
||||||
.ordinal = 20,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct hook_symbol hook_lut_syms[] = {
|
|
||||||
{
|
|
||||||
.name = "Lut24_Exchange",
|
|
||||||
.patch = hook_Lut24_Exchange,
|
|
||||||
.ordinal = 1,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct hook_symbol hook_wdata_syms[] = {
|
|
||||||
{
|
|
||||||
.name = "Wdata_create",
|
|
||||||
.patch = hook_Wdata_create,
|
|
||||||
.ordinal = 1,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct hook_symbol hook_ac_syms[] = {
|
|
||||||
{
|
|
||||||
.name = "init_accesscodekey",
|
|
||||||
.patch = hook_init_accesscodekey,
|
|
||||||
},{
|
|
||||||
.name = "accesscodekeyoverwriteheader",
|
|
||||||
.patch = hook_accesscodekeyoverwriteheader,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
#pragma endregion
|
|
||||||
|
|
||||||
static void write_int(uint8_t* data, int index, int value) {
|
|
||||||
data[index] = value >> 24;
|
|
||||||
data[index + 1] = value >> 16;
|
|
||||||
data[index + 2] = value >> 8;
|
|
||||||
data[index + 3] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void write_short(uint8_t* data, int index, short value) {
|
|
||||||
data[index] = value >> 8;
|
|
||||||
data[index + 1] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct printer_cx_config printer_config;
|
|
||||||
static wchar_t printer_out_path[MAX_PATH];
|
|
||||||
static struct printer_cx_data printer_data;
|
|
||||||
|
|
||||||
#define HEIGHT 664
|
|
||||||
#define WIDTH 1036
|
|
||||||
#define IMAGE_BUFFER_SIZE WIDTH * HEIGHT
|
|
||||||
static uint8_t back_buffer[4][IMAGE_BUFFER_SIZE];
|
|
||||||
static uint8_t front_buffer[4][IMAGE_BUFFER_SIZE];
|
|
||||||
static uint64_t current_card_id;
|
|
||||||
|
|
||||||
DWORD load_printer_data() {
|
|
||||||
DWORD bytesRead = 0;
|
|
||||||
HANDLE hSave = CreateFileW(printer_config.printer_data_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
if (hSave != INVALID_HANDLE_VALUE) {
|
|
||||||
if (!ReadFile(hSave, &printer_data, sizeof(printer_data), &bytesRead, NULL)){
|
|
||||||
CloseHandle(hSave);
|
|
||||||
return GetLastError();
|
|
||||||
}
|
|
||||||
CloseHandle(hSave);
|
|
||||||
if (bytesRead != sizeof(printer_data)){
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (printer_data.version != PRINTER_DATA_VERSION) {
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return GetLastError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD save_printer_data() {
|
|
||||||
DWORD bytesWritten = 0;
|
|
||||||
HANDLE hSave = CreateFileW(printer_config.printer_data_path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
if (hSave != NULL) {
|
|
||||||
if (!WriteFile(hSave, &printer_data, sizeof(printer_data), &bytesWritten, NULL)){
|
|
||||||
CloseHandle(hSave);
|
|
||||||
dprintf("CX7000: Failed writing data: %lx\n", GetLastError());
|
|
||||||
return GetLastError();
|
|
||||||
}
|
|
||||||
CloseHandle(hSave);
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
dprintf("CX7000: Failed opening data file for writing: %lx\n", GetLastError());
|
|
||||||
return GetLastError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void printer_cx_hook_init(const struct printer_cx_config* cfg, HINSTANCE self) {
|
|
||||||
assert(cfg != NULL);
|
|
||||||
|
|
||||||
if (!cfg->enable) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&printer_config, cfg, sizeof(*cfg));
|
|
||||||
printer_cx_hook_insert_hooks(NULL);
|
|
||||||
|
|
||||||
CreateDirectoryW(cfg->printer_out_path, NULL);
|
|
||||||
memcpy(printer_out_path, cfg->printer_out_path, MAX_PATH);
|
|
||||||
|
|
||||||
if (load_printer_data() != 0) {
|
|
||||||
memset(&printer_data, 0, sizeof(printer_data));
|
|
||||||
printer_data.version = PRINTER_DATA_VERSION;
|
|
||||||
if (save_printer_data() == 0) {
|
|
||||||
dprintf("CX7000: Printer data initialized.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintf("CX7000: hook enabled.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void printer_cx_hook_insert_hooks(HMODULE target) {
|
|
||||||
hook_table_apply(target, "PCP21CT64.dll", hook_pcp_syms, _countof(hook_pcp_syms));
|
|
||||||
hook_table_apply(target, "LUT24EXG64.dll", hook_lut_syms, _countof(hook_lut_syms));
|
|
||||||
hook_table_apply(target, "WCREATE64.dll", hook_wdata_syms, _countof(hook_wdata_syms));
|
|
||||||
hook_table_apply(target, "accesscode_dll.dll", hook_ac_syms, _countof(hook_ac_syms));
|
|
||||||
|
|
||||||
/* Unity workaround */
|
|
||||||
proc_addr_table_push(target, "PCP21CT64.dll", hook_pcp_syms, _countof(hook_pcp_syms));
|
|
||||||
proc_addr_table_push(target, "LUT24EXG64.dll", hook_lut_syms, _countof(hook_lut_syms));
|
|
||||||
proc_addr_table_push(target, "WCREATE64.dll", hook_wdata_syms, _countof(hook_wdata_syms));
|
|
||||||
proc_addr_table_push(target, "accesscode_dll.dll", hook_ac_syms, _countof(hook_ac_syms));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_Retransfer() {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool __stdcall hook_CXCMD_CheckIfConnected(int* pSlotId, int* pId) {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
return printer_config.enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_xImageOut() {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_MoveCard(int slotId, int id, int dest, int flip, int filmInit, int immed) {
|
|
||||||
dprintf("CX7000: %s(%d, %d, %d, %d)\n", __func__, dest, flip, filmInit, immed);
|
|
||||||
return CX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_xWriteMagData() {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_SecurityPrint(int slotId, int id, int color, int bufferIndex, int immed) {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ScanPrinterNext() {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ImageOut(int slotId, int id, uint8_t* plane, int length, int color, int bufferIndex) {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
|
|
||||||
assert(color >= 0 && color <= 3);
|
|
||||||
assert(bufferIndex >= 0 && bufferIndex <= 1);
|
|
||||||
assert(length == IMAGE_BUFFER_SIZE);
|
|
||||||
|
|
||||||
// colorIndex: 0 = w, 1 = c, 2 = m, 3 = y
|
|
||||||
// bufferIndex: 0 = back, 1 = front
|
|
||||||
|
|
||||||
if (bufferIndex == 0) {
|
|
||||||
memcpy(back_buffer[color], plane, length);
|
|
||||||
} else {
|
|
||||||
memcpy(front_buffer[color], plane, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
return CX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_Print(int slotId, int id, int color, int bufferIndex, int immed) {
|
|
||||||
dprintf("CX7000: %s(%d, %d, %d)\n", __func__, color, bufferIndex, immed);
|
|
||||||
|
|
||||||
assert(bufferIndex >= 0 && bufferIndex <= 1);
|
|
||||||
|
|
||||||
SYSTEMTIME t;
|
|
||||||
GetLocalTime(&t);
|
|
||||||
|
|
||||||
// color: 1 = back, 3 = front
|
|
||||||
// bufferIndex: 0 = back, 1 = front
|
|
||||||
|
|
||||||
wchar_t dumpPath[MAX_PATH];
|
|
||||||
uint8_t metadata[5];
|
|
||||||
|
|
||||||
metadata[0] = current_card_id >> 32;
|
|
||||||
write_int(metadata, 1, (int32_t)current_card_id);
|
|
||||||
|
|
||||||
swprintf_s(
|
|
||||||
dumpPath, MAX_PATH,
|
|
||||||
L"%s\\CX7000_%04d%02d%02d_%02d%02d%02d_%s.bmp",
|
|
||||||
printer_out_path, t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond, bufferIndex == 0 ? L"back" : L"front");
|
|
||||||
|
|
||||||
// convert image from seperate CMY arrays to one RGB array
|
|
||||||
int size = IMAGE_BUFFER_SIZE * 3;
|
|
||||||
uint8_t* raw_image = (uint8_t*)malloc(size);
|
|
||||||
for (int i = 0; i < IMAGE_BUFFER_SIZE; i++) {
|
|
||||||
// 0 is "white" and we don't really care about that
|
|
||||||
raw_image[i * 3] = 0xFF - (bufferIndex == 0 ? back_buffer : front_buffer)[1][i];
|
|
||||||
raw_image[i * 3 + 1] = 0xFF - (bufferIndex == 0 ? back_buffer : front_buffer)[2][i];
|
|
||||||
raw_image[i * 3 + 2] = 0xFF - (bufferIndex == 0 ? back_buffer : front_buffer)[3][i];
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintf("CX7000: Saving %s image to %ls\n", bufferIndex == 0 ? "back" : "front", dumpPath);
|
|
||||||
|
|
||||||
int ret = WriteDataToBitmapFile(dumpPath, 24, WIDTH, HEIGHT, raw_image, size, metadata, 5, false);
|
|
||||||
|
|
||||||
free(raw_image);
|
|
||||||
|
|
||||||
if (ret < 0) {
|
|
||||||
dprintf("CX7000: WriteDataToBitmapFile returned %d\n", ret);
|
|
||||||
return CX_ERROR_FATAL_3301;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_RezeroUnit(int slotId, int id, int action) {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
return CX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_WriteMagData() {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_LogSense(int iSlot, int iID, int iPage, uint8_t* pbyBuffer) {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
|
|
||||||
const int size = 108;
|
|
||||||
memset(pbyBuffer, 0, size);
|
|
||||||
|
|
||||||
|
|
||||||
if (iPage == 56) {
|
|
||||||
dprintf("CX7000: MediumQuantity\n");
|
|
||||||
|
|
||||||
write_int(pbyBuffer, 8, (int)printer_data.print_counter); // total count
|
|
||||||
write_int(pbyBuffer, 16, 22); // free count
|
|
||||||
write_int(pbyBuffer, 24, 33); // head count
|
|
||||||
write_int(pbyBuffer, 32, (int)printer_data.print_counter_since_clean); // cleaning count
|
|
||||||
write_int(pbyBuffer, 40, 55); // error count
|
|
||||||
write_int(pbyBuffer, 48, 66); // cru cleaning count
|
|
||||||
|
|
||||||
return CX_OK;
|
|
||||||
} else if (iPage == 57) {
|
|
||||||
dprintf("CX7000: Miscellaneous\n");
|
|
||||||
|
|
||||||
write_int(pbyBuffer, 16, 234); // re transfer hr power on time
|
|
||||||
write_int(pbyBuffer, 24, 456); // remedy hr power on time
|
|
||||||
write_int(pbyBuffer, 40, 789); // unresettable re transfer hr power on time
|
|
||||||
write_int(pbyBuffer, 48, 1023); // unresettable remedy hr power on time
|
|
||||||
|
|
||||||
return CX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintf("CX7000: Unknown LogSense\n");
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_StandardInquiry(int iSlot, int iID, uint8_t* pbyBuffer) {
|
|
||||||
const int size = 96;
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
|
|
||||||
memset(pbyBuffer, 0, size);
|
|
||||||
memcpy(pbyBuffer + 32, printer_config.printer_firm_version, 8);
|
|
||||||
memcpy(pbyBuffer + 50, printer_config.printer_camera_version, 8);
|
|
||||||
memcpy(pbyBuffer + 71, printer_config.printer_config_version, 8);
|
|
||||||
memcpy(pbyBuffer + 79, printer_config.printer_table_version, 8);
|
|
||||||
//memcpy(pbyBuffer + 58, printer_config.thermal_head_info, 13); // unused
|
|
||||||
|
|
||||||
return CX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ModeSense(int iSlot, int iID, int iPC, int iPage, uint8_t* pbyBuffer) {
|
|
||||||
dprintf("CX7000: %s(%d, %d)\n", __func__, iPC, iPage);
|
|
||||||
|
|
||||||
const int size = 104;
|
|
||||||
memset(pbyBuffer, 0, size);
|
|
||||||
|
|
||||||
if (iPC == 1 && iPage == 40) { // GetMediaInfo
|
|
||||||
pbyBuffer[51] = 10; // film count (10=100%)
|
|
||||||
pbyBuffer[52] = 50; // ink count (50=100%)
|
|
||||||
return CX_OK;
|
|
||||||
} else if (iPC == 1 && iPage == 35) { // ReadInkInfo
|
|
||||||
pbyBuffer[6] = 0; // "b"
|
|
||||||
write_short(pbyBuffer, 8, 50); // Remain
|
|
||||||
return CX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintf("CX7000: Unknown ModeSense\n");
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_UpdateFirmware(int iSlot, int iID, char* pFile, int iDataID) {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // intentionally not implemented
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ModeSelect(int iSlot, int iID, int iSp, int iPage, uint8_t* pbyData) {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_GetPrintingStatus() {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_SendDiagnostic(int iSlot, int iID, int iTestMode, int iTestPatten, int iTestCount) {
|
|
||||||
dprintf("CX7000: %s(%d, %d, %d)\n", __func__, iTestMode, iTestPatten, iTestCount);
|
|
||||||
if (iTestMode == 19) {
|
|
||||||
dprintf("CX7000: Printer Front Buttons Enabled: %d\n", iTestPatten);
|
|
||||||
return CX_OK;
|
|
||||||
} else if (iTestMode == 17) {
|
|
||||||
dprintf("CX7000: Printer was cleaned (haha)\n");
|
|
||||||
printer_data.print_counter_since_clean = 0;
|
|
||||||
save_printer_data();
|
|
||||||
return CX_OK;
|
|
||||||
} else if (iTestMode == 18) {
|
|
||||||
dprintf("CX7000: Transport Mode enabled\n");
|
|
||||||
printer_data.is_transport = true;
|
|
||||||
save_printer_data();
|
|
||||||
return CX_OK;
|
|
||||||
} else if (iTestMode == 20) {
|
|
||||||
dprintf("CX7000: Transport Mode disabled\n");
|
|
||||||
printer_data.is_transport = false;
|
|
||||||
save_printer_data();
|
|
||||||
return CX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintf("CX7000: Unknown SendDiagnostic\n");
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_RetransferAndTurn(int slotId, int id, int immed) {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
return CX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_LogSelect(int iSlot, int iID, int iMod) {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ReadPosition(int slotId, int id, uint8_t* buffer) {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
const int size = 8;
|
|
||||||
|
|
||||||
memset(buffer, 0, size);
|
|
||||||
buffer[0] = 1 << 2; // IsExist (0 means YES!)
|
|
||||||
buffer[7] = 0; // position (of card; 0 = printer, 1 = "IR")
|
|
||||||
|
|
||||||
return CX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_SecurityLock() {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_SetPrintingStatus() {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_xReadISOMagData() {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_WriteISO3TrackMagData() {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_PasswordSet() {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_GetPrinterStatus() {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_WriteProjectCode() {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_LoadCard(int slotId, int id, int dest, int flip, int filmInit, int immed) {
|
|
||||||
dprintf("CX7000: %s(%d, %d, %d, %d)\n", __func__, dest, flip, filmInit, immed);
|
|
||||||
return CX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ReadMagData() {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ScanPrinter(int* pSlotId, int* pId) {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
|
|
||||||
if (!printer_config.enable) {
|
|
||||||
return CX_ERROR_NOT_CONNECTED_6804;
|
|
||||||
}
|
|
||||||
|
|
||||||
*pSlotId = 1;
|
|
||||||
*pId = 1;
|
|
||||||
|
|
||||||
return CX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_xWriteISOMagData() {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ICControl() {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ReadBuffer(int iSlot, int iID, int iMode, int iBufferID, uint8_t* pbyData, int iOffset,
|
|
||||||
int iLength) {
|
|
||||||
dprintf("CX7000: %s(%d, %d, %d)\n", __func__, iMode, iBufferID, iLength);
|
|
||||||
|
|
||||||
memset(pbyData, 0, iLength);
|
|
||||||
|
|
||||||
if (iMode == 2 && iBufferID == 87 && iLength == 10) {
|
|
||||||
dprintf("CX7000: ReadCondition\n");
|
|
||||||
|
|
||||||
pbyData[0] = printer_data.is_transport; // transport mode
|
|
||||||
pbyData[1] = 0; // head white ink level, unused
|
|
||||||
pbyData[2] = 0; // main white ink level, unused
|
|
||||||
pbyData[3] = 0; // total white ink level, unused
|
|
||||||
|
|
||||||
return CX_OK;
|
|
||||||
} else if (iMode == 2 && iBufferID == 112 && iLength == 6) {
|
|
||||||
dprintf("CX7000: GetMacAddress\n");
|
|
||||||
|
|
||||||
pbyData[0] = 0x12; // displays in test menu, else ununused?
|
|
||||||
pbyData[1] = 0x34;
|
|
||||||
pbyData[2] = 0x56;
|
|
||||||
pbyData[3] = 0x78;
|
|
||||||
pbyData[4] = 0x9A;
|
|
||||||
pbyData[5] = 0xBC;
|
|
||||||
|
|
||||||
return CX_OK;
|
|
||||||
} else if (iMode == 2 && iBufferID == 82 && iLength == 4) {
|
|
||||||
dprintf("CX7000: GetCleaningWaitCount\n");
|
|
||||||
|
|
||||||
// seemingly unused
|
|
||||||
write_short(pbyData, 0, 0);
|
|
||||||
|
|
||||||
return CX_OK;
|
|
||||||
} else if (iMode == 2 && iBufferID == 85 && iLength == 10) {
|
|
||||||
dprintf("CX7000: GetSensorInfo\n");
|
|
||||||
|
|
||||||
pbyData[0] = 244; // retransfer heat roller thermistor; must be over 243
|
|
||||||
pbyData[1] = 0; // main pwb thermistor; unused
|
|
||||||
pbyData[2] = 0; // thermal head thermistor; unused
|
|
||||||
pbyData[3] = 0; // heater cover thermistor; unused
|
|
||||||
|
|
||||||
return CX_OK;
|
|
||||||
} else if (iMode == 2 && iBufferID == 88 && iLength == 16) {
|
|
||||||
dprintf("CX7000: ReadErrorStatus\n");
|
|
||||||
|
|
||||||
pbyData[1] = 0; // is door open?
|
|
||||||
//pbyData[2...] = // any of the error codes that fit in a byte (from CX_ERROR_FATAL_3301 to CX_ERROR_PRINT_INTERRUPT_6805_3)
|
|
||||||
|
|
||||||
return CX_OK;
|
|
||||||
} else if (iMode == 2 && iBufferID == 224 && iLength == 10) {
|
|
||||||
dprintf("CX7000: ReadCode\n");
|
|
||||||
|
|
||||||
printer_data.print_counter_since_clean++;
|
|
||||||
current_card_id = ++printer_data.print_counter;
|
|
||||||
dprintf("CX7000: Generated new card ID: %lld\n", current_card_id);
|
|
||||||
|
|
||||||
save_printer_data();
|
|
||||||
|
|
||||||
pbyData[0] = current_card_id >> 32; // MSB of card id
|
|
||||||
write_int(pbyData, 1, (int32_t)current_card_id); // lower 4 bytes of card id
|
|
||||||
pbyData[5] = 0x0; // Direction (1 = rotate image by 180 degrees)
|
|
||||||
pbyData[6] = 0x1; // CheckCode (0 = error)
|
|
||||||
|
|
||||||
return CX_OK;
|
|
||||||
} else if (iMode == 2 && iBufferID == 144 && iLength == 260) {
|
|
||||||
dprintf("CX7000: ReadErrorLog\n");
|
|
||||||
|
|
||||||
write_int(pbyData, 0, 0); // LogCount
|
|
||||||
/*for (int i = 0; false; i++) { // list of error ids
|
|
||||||
write_int(pbyData, i + 4, 0);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
return CX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintf("CX7000: Unknown ReadBuffer\n");
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_xReadMagData() {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_WriteBuffer(int iSlot, int iID, int iMode, int iBufferID, uint8_t* pbyData, int iOffset, // NOLINT(*-non-const-parameter)
|
|
||||||
int iLength) {
|
|
||||||
dprintf("CX7000: %s(%d, %d, %d, %d)\n", __func__, iMode, iBufferID, iOffset, iLength);
|
|
||||||
if (iMode == 2 && iBufferID == 82 && iLength == 4) {
|
|
||||||
int val = pbyData[0] << 8 | pbyData[1];
|
|
||||||
dprintf("CX7000: Set cleaning limit: %d\n", val);
|
|
||||||
|
|
||||||
return CX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintf("CX7000: Unknown WriteBuffer\n");
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_DefineLUT(int slotId, int id, int color, int length, uint8_t* buffer) {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_ReadISO3TrackMagData() {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
dprintf("CX7000: Unimplemented\n"); // unused
|
|
||||||
return CX_ERROR_USB_COM_3201;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_TestUnitReady(int slotId, int id) {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
|
|
||||||
if (!printer_config.enable) {
|
|
||||||
return CX_ERROR_NOT_CONNECTED_6804;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __stdcall hook_CXCMD_RetransferAndEject(int slotId, int id, int immed) {
|
|
||||||
dprintf("CX7000: %s\n", __func__);
|
|
||||||
return CX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool __stdcall hook_Lut24_Exchange(const wchar_t* pFile, uint8_t* y, uint8_t* m, uint8_t* c, int sizeY, int sizeM,
|
|
||||||
int sizeC) {
|
|
||||||
dprintf("CX7000: %s(%ls)\n", __func__, pFile);
|
|
||||||
|
|
||||||
// stub?
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool __stdcall hook_Wdata_create(uint8_t* pbyRdata, uint8_t* pbyGdata, uint8_t* pbyBdata, int iWidth,
|
|
||||||
int iHeight, bool bPortrait, int iAlgorithim, uint8_t* pbyWdata) {
|
|
||||||
dprintf("CX7000: %s(%d, %d, %d)\n", __func__, iHeight, bPortrait, iAlgorithim);
|
|
||||||
|
|
||||||
// stub?
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: these two only exist while we have no decrypted dump of accesscode_dll
|
|
||||||
static int __cdecl hook_init_accesscodekey(BSTR fileName) {
|
|
||||||
dprintf("AccesscodeKey: Init\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __cdecl hook_accesscodekeyoverwriteheader(void* context, BSTR header, int headerLen, BSTR accessheaderkey, int headerkeylen) {
|
|
||||||
dprintf("AccesscodeKey: Overwrite Header\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#define PRINTER_DATA_VERSION 1
|
|
||||||
|
|
||||||
struct printer_cx_config {
|
|
||||||
bool enable;
|
|
||||||
wchar_t printer_out_path[MAX_PATH];
|
|
||||||
wchar_t printer_data_path[MAX_PATH];
|
|
||||||
char printer_firm_version[8];
|
|
||||||
char printer_camera_version[8];
|
|
||||||
char printer_config_version[8];
|
|
||||||
char printer_table_version[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct printer_cx_data {
|
|
||||||
uint8_t version;
|
|
||||||
uint64_t print_counter;
|
|
||||||
uint64_t print_counter_since_clean;
|
|
||||||
bool is_transport;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
CX_OK = 0,
|
|
||||||
CX_ERROR_FATAL_3301 = -1,
|
|
||||||
CX_ERROR_USB_COM_3201 = -2,
|
|
||||||
CX_ERROR_PRINT_INTERRUPT_6805_4 = -4,
|
|
||||||
CX_ERROR_CODE_UNREADABLE_3303 = -5,
|
|
||||||
CX_ERROR_INK_LOW_3202 = -6,
|
|
||||||
CX_ERROR_PRINT_INTERRUPT_6805_3 = -7,
|
|
||||||
CX_ERROR_NO_CARD_6801 = -16961536,
|
|
||||||
CX_ERROR_DOOR_OPEN_6808 = -16961792,
|
|
||||||
CX_ERROR_6831 = -16963328,
|
|
||||||
CX_ERROR_6810 = -16964864,
|
|
||||||
CX_ERROR_CLEAN_PRINTER_3999 = -16973056,
|
|
||||||
CX_ERROR_JAM_6805_1 = -17010688,
|
|
||||||
CX_ERROR_REVERSE_JAM_6805_2 = -17010944,
|
|
||||||
CX_ERROR_CAMERA_JAM_6805_3 = -17011200,
|
|
||||||
CX_ERROR_TRANSPORT_JAM_6805_4 = -17011456,
|
|
||||||
CX_ERROR_PAPER_SENSOR_JAM_6805_5 = -17011712,
|
|
||||||
CX_ERROR_RETRANSFER_JAM_6805_6 = -17011968,
|
|
||||||
CX_ERROR_PAPER_RIPPED_6813_3 = -17015040,
|
|
||||||
CX_ERROR_CODE_READ_6811 = -17018112,
|
|
||||||
CX_ERROR_UNAUTHORIZED_INK_6803_1 = -17018880,
|
|
||||||
CX_ERROR_INK_EMPTY_6813_1 = -17019136,
|
|
||||||
CX_ERROR_PRINT_TIMEOUT_6810_3 = -17056768,
|
|
||||||
CX_ERROR_CAMERA_HARDWARE_FAULT_6810_5 = -17083136,
|
|
||||||
CX_ERROR_CAMERA_COM_6810_6 = -17083392,
|
|
||||||
CX_ERROR_ROLLER_6810_15 = -17088768,
|
|
||||||
CX_ERROR_OVER_TEMPERATURE_6810_16 = -17089024,
|
|
||||||
CX_ERROR_POWER_INTERRUPT_6810_1 = -17089280,
|
|
||||||
CX_ERROR_INITIALIZATION_6810_2 = -17094656,
|
|
||||||
CX_ERROR_OVER_TEMPERATURE_6810_10 = -17100800,
|
|
||||||
CX_ERROR_RETRANSFER_ROLLER_6810_11 = -17101056,
|
|
||||||
CX_ERROR_THERMOSTAT_6810_12 = -17101312,
|
|
||||||
CX_ERROR_OVER_TEMPERATURE_6810_20 = -17101568,
|
|
||||||
CX_ERROR_STRAIGHTEN_ROLLER_6810_21 = -17101824,
|
|
||||||
CX_ERROR_THERMOSTAT_6810_22 = -17102080,
|
|
||||||
CX_ERROR_PRINTER_TOO_COLD_6833_1 = -16971264,
|
|
||||||
CX_ERROR_OVER_TEMPERATURE_6810_25 = -17102848,
|
|
||||||
CX_ERROR_CAMERA_NOT_FOUND_6810_7 = -17116672,
|
|
||||||
CX_ERROR_RETRANSFER_ROLL_EMPTY_6802_3 = -21144064,
|
|
||||||
CX_ERROR_INK_ROLL_EMPTY_6802_1 = -21148160,
|
|
||||||
CX_ERROR_NOT_CONNECTED_6804 = -33554432,
|
|
||||||
CX_ERROR_CAMERA_JAM_6805_7 = -17012224,
|
|
||||||
CX_ERROR_INVALID_CLEANING_CARD_6832_1 = -16965376,
|
|
||||||
CX_ERROR_TEMPERATURE_RESOLVED_6833_2 = -16971520,
|
|
||||||
};
|
|
||||||
|
|
||||||
void printer_cx_hook_init(const struct printer_cx_config *cfg, HINSTANCE self);
|
|
||||||
void printer_cx_hook_insert_hooks(HMODULE target);
|
|
@ -1,109 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "hooklib/config.h"
|
|
||||||
|
|
||||||
#include "util/dll-bind.h"
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
|
|
||||||
#include "y3.h"
|
|
||||||
#include "y3-dll.h"
|
|
||||||
|
|
||||||
const struct dll_bind_sym y3_dll_syms[] = {
|
|
||||||
{
|
|
||||||
.sym = "y3_io_init",
|
|
||||||
.off = offsetof(struct y3_dll, init),
|
|
||||||
}, {
|
|
||||||
.sym = "y3_io_get_cards",
|
|
||||||
.off = offsetof(struct y3_dll, get_cards),
|
|
||||||
}, {
|
|
||||||
.sym = "y3_io_close",
|
|
||||||
.off = offsetof(struct y3_dll, close),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct y3_dll y3_dll;
|
|
||||||
|
|
||||||
// Copypasta DLL binding and diagnostic message boilerplate.
|
|
||||||
// Not much of this lends itself to being easily factored out. Also there
|
|
||||||
// will be a lot of API-specific branching code here eventually as new API
|
|
||||||
// versions get defined, so even though these functions all look the same
|
|
||||||
// now this won't remain the case forever.
|
|
||||||
|
|
||||||
HRESULT y3_dll_init(const struct y3_dll_config *cfg, HINSTANCE self)
|
|
||||||
{
|
|
||||||
uint16_t (*get_api_version)(void);
|
|
||||||
const struct dll_bind_sym *sym;
|
|
||||||
HINSTANCE owned;
|
|
||||||
HINSTANCE src;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(self != NULL);
|
|
||||||
|
|
||||||
if (cfg->path[0] != L'\0') {
|
|
||||||
owned = LoadLibraryW(cfg->path);
|
|
||||||
|
|
||||||
if (owned == NULL) {
|
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
||||||
dprintf("Y3: Failed to load IO DLL: %lx: %S\n",
|
|
||||||
hr,
|
|
||||||
cfg->path);
|
|
||||||
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintf("Y3: Using custom IO DLL: %S\n", cfg->path);
|
|
||||||
src = owned;
|
|
||||||
} else {
|
|
||||||
owned = NULL;
|
|
||||||
src = self;
|
|
||||||
}
|
|
||||||
|
|
||||||
get_api_version = (void *) GetProcAddress(src, "y3_io_get_api_version");
|
|
||||||
|
|
||||||
if (get_api_version != NULL) {
|
|
||||||
y3_dll.api_version = get_api_version();
|
|
||||||
} else {
|
|
||||||
y3_dll.api_version = 0x0100;
|
|
||||||
dprintf("Custom IO DLL does not expose y3_io_get_api_version, "
|
|
||||||
"assuming API version 1.0.\n"
|
|
||||||
"Please ask the developer to update their DLL.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y3_dll.api_version >= 0x0200) {
|
|
||||||
hr = E_NOTIMPL;
|
|
||||||
dprintf("Y3: Custom IO DLL implements an unsupported "
|
|
||||||
"API version (%#04x). Please update Segatools.\n",
|
|
||||||
y3_dll.api_version);
|
|
||||||
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
sym = y3_dll_syms;
|
|
||||||
hr = dll_bind(&y3_dll, src, &sym, _countof(y3_dll_syms));
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
if (src != self) {
|
|
||||||
dprintf("Y3: Custom IO DLL does not provide function "
|
|
||||||
"\"%s\". Please contact your IO DLL's developer for "
|
|
||||||
"further assistance.\n",
|
|
||||||
sym->sym);
|
|
||||||
|
|
||||||
goto end;
|
|
||||||
} else {
|
|
||||||
dprintf("Internal error: could not reflect \"%s\"\n", sym->sym);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
owned = NULL;
|
|
||||||
|
|
||||||
end:
|
|
||||||
if (owned != NULL) {
|
|
||||||
FreeLibrary(owned);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "hooklib/y3.h"
|
|
||||||
|
|
||||||
|
|
||||||
struct y3_dll {
|
|
||||||
uint16_t api_version;
|
|
||||||
HRESULT (*init)(void);
|
|
||||||
HRESULT (*close)(void);
|
|
||||||
HRESULT (*get_cards)(struct CardInfo* cards, int* len);
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct y3_dll y3_dll;
|
|
||||||
|
|
||||||
HRESULT y3_dll_init(const struct y3_dll_config *cfg, HINSTANCE self);
|
|
@ -1,631 +0,0 @@
|
|||||||
// ReSharper disable CppParameterNeverUsed
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "y3.h"
|
|
||||||
|
|
||||||
#include "hook/table.h"
|
|
||||||
#include "hook/procaddr.h"
|
|
||||||
|
|
||||||
#include "hooklib/y3-dll.h"
|
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
|
|
||||||
#if _WIN32 || _WIN64
|
|
||||||
#if _WIN64
|
|
||||||
#define ENV64BIT
|
|
||||||
#else
|
|
||||||
#define ENV32BIT
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Check GCC
|
|
||||||
#if __GNUC__
|
|
||||||
#if __x86_64__ || __ppc64__
|
|
||||||
#define ENV64BIT
|
|
||||||
#else
|
|
||||||
#define ENV32BIT
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENV64BIT
|
|
||||||
#define CALL
|
|
||||||
#else
|
|
||||||
#define CALL __cdecl
|
|
||||||
#endif
|
|
||||||
|
|
||||||
float CALL API_DLLVersion();
|
|
||||||
uint32_t CALL API_GetLastError(int* hDevice);
|
|
||||||
uint32_t CALL API_GetErrorMessage(uint32_t errNo, char* szMessage, int numBytes);
|
|
||||||
int* CALL API_Connect(char* szPortName);
|
|
||||||
int CALL API_Close(int* hDevice);
|
|
||||||
int CALL API_Start(int* hDevice);
|
|
||||||
int CALL API_Stop(int* hDevice);
|
|
||||||
float CALL API_GetFirmVersion(int* hDevice);
|
|
||||||
uint32_t CALL API_GetFirmName(int* hDevice);
|
|
||||||
uint32_t CALL API_GetTargetCode(int* hDevice);
|
|
||||||
uint32_t CALL API_GetStatus(int* hDevice);
|
|
||||||
uint32_t CALL API_GetCounter(int* hDevice);
|
|
||||||
int CALL API_ClearError(int* hDevice);
|
|
||||||
int CALL API_Reset(int* hDevice, bool isHardReset);
|
|
||||||
int CALL API_GetCardInfo(int* hDevice, int numCards, struct CardInfo* pCardInfo);
|
|
||||||
int CALL API_GetCardInfoCharSize();
|
|
||||||
int CALL API_FirmwareUpdate(int* hDevice, uint32_t address, uint32_t size, uint8_t* buffer);
|
|
||||||
int CALL API_Calibration(int* hDevice, int calib);
|
|
||||||
int CALL API_GetCalibrationResult(int* hDevice, int calib, uint32_t* result);
|
|
||||||
uint32_t CALL API_GetProcTime(int* hDevice);
|
|
||||||
uint32_t CALL API_GetMemStatus(int* hDevice);
|
|
||||||
uint32_t CALL API_GetMemCounter(int* hDevice);
|
|
||||||
int CALL API_SetParameter(int* hDevice, uint32_t uParam, uint32_t* pParam);
|
|
||||||
int CALL API_GetParameter(int* hDevice, uint32_t uParam, uint32_t* pParam);
|
|
||||||
|
|
||||||
signed int CALL API_SetDevice(int a1, int a2);
|
|
||||||
signed int CALL API_SetCommand(int a1, int a2, int a3, int* a4);
|
|
||||||
signed int CALL API_SetSysControl(int a1, int a2, int* a3);
|
|
||||||
signed int CALL API_GetSysControl(int a1, int a2, int* a3);
|
|
||||||
int CALL API_TestReset(int a1);
|
|
||||||
signed int API_DebugReset(int a1, ...);
|
|
||||||
int CALL API_GetBoardType(int a1);
|
|
||||||
int CALL API_GetCardDataSize(int a1);
|
|
||||||
int CALL API_GetFirmDate(int a1);
|
|
||||||
int API_SystemCommand(int a1, char a2, ...);
|
|
||||||
int CALL API_CalcCheckSum(DWORD* a1, int a2, int a3);
|
|
||||||
int CALL API_GetCheckSumResult(int a1);
|
|
||||||
int CALL API_BlockRead(int a1, int a2, int a3, SIZE_T dwBytes);
|
|
||||||
int CALL API_GetBlockReadResult(int a1, void* a2);
|
|
||||||
int CALL API_BlockWrite(int a1, int a2, int a3, SIZE_T dwBytes, void* a5);
|
|
||||||
signed int CALL API_GetDebugParam(int a1, int a2, DWORD* a3);
|
|
||||||
|
|
||||||
uint32_t convert_string_to_uint(const char* firmName);
|
|
||||||
|
|
||||||
static const struct hook_symbol Y3_hooks[] = {
|
|
||||||
{
|
|
||||||
.name = "API_DLLVersion",
|
|
||||||
.patch = API_DLLVersion,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetLastError",
|
|
||||||
.patch = API_GetLastError,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetErrorMessage",
|
|
||||||
.patch = API_GetErrorMessage,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_Connect",
|
|
||||||
.patch = API_Connect,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_Close",
|
|
||||||
.patch = API_Close,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_Start",
|
|
||||||
.patch = API_Start,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_Stop",
|
|
||||||
.patch = API_Stop,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetFirmVersion",
|
|
||||||
.patch = API_GetFirmVersion,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetFirmName",
|
|
||||||
.patch = API_GetFirmName,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetTargetCode",
|
|
||||||
.patch = API_GetTargetCode,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetStatus",
|
|
||||||
.patch = API_GetStatus,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetCounter",
|
|
||||||
.patch = API_GetCounter,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_Reset",
|
|
||||||
.patch = API_Reset,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetCardInfo",
|
|
||||||
.patch = API_GetCardInfo,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetCardInfoCharSize",
|
|
||||||
.patch = API_GetCardInfoCharSize,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_FirmwareUpdate",
|
|
||||||
.patch = API_FirmwareUpdate,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_Calibration",
|
|
||||||
.patch = API_Calibration,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetCalibrationResult",
|
|
||||||
.patch = API_GetCalibrationResult,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetProcTime",
|
|
||||||
.patch = API_GetProcTime,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetMemStatus",
|
|
||||||
.patch = API_GetMemStatus,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetMemCounter",
|
|
||||||
.patch = API_GetMemCounter,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_SetParameter",
|
|
||||||
.patch = API_SetParameter,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetParameter",
|
|
||||||
.patch = API_GetParameter,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_SetDevice",
|
|
||||||
.patch = API_SetDevice,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_SetCommand",
|
|
||||||
.patch = API_SetCommand,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_SetSysControl",
|
|
||||||
.patch = API_SetSysControl,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetSysControl",
|
|
||||||
.patch = API_GetSysControl,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_TestReset",
|
|
||||||
.patch = API_TestReset,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_DebugReset",
|
|
||||||
.patch = API_DebugReset,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetBoardType",
|
|
||||||
.patch = API_GetBoardType,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetCardDataSize",
|
|
||||||
.patch = API_GetCardDataSize,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetFirmDate",
|
|
||||||
.patch = API_GetFirmDate,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_SystemCommand",
|
|
||||||
.patch = API_SystemCommand,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_CalcCheckSum",
|
|
||||||
.patch = API_CalcCheckSum,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetCheckSumResult",
|
|
||||||
.patch = API_GetCheckSumResult,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_BlockRead",
|
|
||||||
.patch = API_BlockRead,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetBlockReadResult",
|
|
||||||
.patch = API_GetBlockReadResult,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_BlockWrite",
|
|
||||||
.patch = API_BlockWrite,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "API_GetDebugParam",
|
|
||||||
.patch = API_GetDebugParam,
|
|
||||||
.link = NULL
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct y3_config y3_config;
|
|
||||||
|
|
||||||
#define MAX_CARD_SIZE 32
|
|
||||||
static struct CardInfo card_data[MAX_CARD_SIZE];
|
|
||||||
|
|
||||||
static int* Y3_COM_FIELD = (int*)10;
|
|
||||||
static int* Y3_COM_PRINT = (int*)11;
|
|
||||||
|
|
||||||
HRESULT y3_hook_init(const struct y3_config* cfg, HINSTANCE self, const wchar_t* config_filename) {
|
|
||||||
HRESULT hr;
|
|
||||||
assert(cfg != NULL);
|
|
||||||
|
|
||||||
if (!cfg->enable) {
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&y3_config, cfg, sizeof(*cfg));
|
|
||||||
Y3_COM_FIELD = (int*)(uintptr_t)cfg->port_field;
|
|
||||||
Y3_COM_PRINT = (int*)(uintptr_t)cfg->port_printer;
|
|
||||||
|
|
||||||
y3_insert_hooks(NULL);
|
|
||||||
|
|
||||||
memset(card_data, 0, sizeof(card_data));
|
|
||||||
|
|
||||||
struct y3_dll_config config;
|
|
||||||
y3_dll_config_load(&config, config_filename);
|
|
||||||
|
|
||||||
hr = y3_dll_init(&config, self);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintf("Y3: hook enabled (field port = %d, printer port = %d)\n", cfg->port_field, cfg->port_printer);
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void y3_insert_hooks(HMODULE target) {
|
|
||||||
hook_table_apply(
|
|
||||||
target,
|
|
||||||
"Y3CodeReaderNE.dll",
|
|
||||||
Y3_hooks,
|
|
||||||
_countof(Y3_hooks));
|
|
||||||
|
|
||||||
proc_addr_table_push(
|
|
||||||
target,
|
|
||||||
"Y3CodeReaderNE.dll",
|
|
||||||
Y3_hooks,
|
|
||||||
_countof(Y3_hooks));
|
|
||||||
}
|
|
||||||
|
|
||||||
float CALL API_DLLVersion() {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t CALL API_GetLastError(int* hDevice) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
if (!y3_config.enable) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t CALL API_GetErrorMessage(uint32_t errNo, char* szMessage,
|
|
||||||
int numBytes) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
if (!y3_config.enable) {
|
|
||||||
strcpy_s(szMessage, numBytes,
|
|
||||||
"Y3Emu is disabled but emulator DLL is called");
|
|
||||||
} else {
|
|
||||||
strcpy_s(szMessage, numBytes, "No error - Y3Emu");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int* CALL API_Connect(char* szPortName) {
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
dprintf("Y3: %s(%s)\n", __func__, szPortName);
|
|
||||||
|
|
||||||
if (!y3_config.enable) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
char number[2];
|
|
||||||
strncpy(number, szPortName + 3, 2);
|
|
||||||
int* hDevice = (int*)(uintptr_t)atoi(number);
|
|
||||||
|
|
||||||
if (hDevice == Y3_COM_FIELD) {
|
|
||||||
hr = y3_dll.init();
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
dprintf("Y3: Hook DLL initialization failed: %lx\n", hr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hDevice;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_Close(int* hDevice) {
|
|
||||||
dprintf("Y3: %s(%p)\n", __func__, hDevice);
|
|
||||||
|
|
||||||
if (hDevice == Y3_COM_FIELD) {
|
|
||||||
y3_dll.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_Start(int* hDevice) {
|
|
||||||
dprintf("Y3: %s(%p)\n", __func__, hDevice);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_Stop(int* hDevice) {
|
|
||||||
dprintf("Y3: %s(%p)\n", __func__, hDevice);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
float CALL API_GetFirmVersion(int* hDevice) {
|
|
||||||
dprintf("Y3: %s(%p)\n", __func__, hDevice);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t CALL API_GetFirmName(int* hDevice) {
|
|
||||||
uint32_t result = 0;
|
|
||||||
dprintf("Y3: %s(%p)\n", __func__, hDevice);
|
|
||||||
|
|
||||||
if (hDevice == Y3_COM_FIELD) {
|
|
||||||
result = convert_string_to_uint(y3_config.firm_name_field);
|
|
||||||
dprintf("Y3: This device is a FIELD: %s\n", y3_config.firm_name_field);
|
|
||||||
} else if (hDevice == Y3_COM_PRINT) {
|
|
||||||
result = convert_string_to_uint(y3_config.firm_name_printer);
|
|
||||||
dprintf("Y3: This device is a PRINTER: %s\n", y3_config.firm_name_printer);
|
|
||||||
} else {
|
|
||||||
dprintf("Y3: This device is UNKNOWN\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t CALL API_GetTargetCode(int* hDevice) {
|
|
||||||
uint32_t result = 1162760014;
|
|
||||||
dprintf("Y3: %s(%p)\n", __func__, hDevice);
|
|
||||||
|
|
||||||
if (hDevice == Y3_COM_FIELD) {
|
|
||||||
result = convert_string_to_uint(y3_config.target_code_field);
|
|
||||||
dprintf("Y3: This device is a FIELD: %s\n", y3_config.target_code_field);
|
|
||||||
} else if (hDevice == Y3_COM_PRINT) {
|
|
||||||
result = convert_string_to_uint(y3_config.target_code_printer);
|
|
||||||
dprintf("Y3: This device is a PRINTER: %s\n", y3_config.target_code_printer);
|
|
||||||
} else {
|
|
||||||
dprintf("Y3: This Y3 device is UNKNOWN\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t CALL API_GetStatus(int* hDevice) {
|
|
||||||
// dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t CALL API_GetCounter(int* hDevice) {
|
|
||||||
// dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_ClearError(int* hDevice) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_Reset(int* hDevice, bool isHardReset) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_GetCardInfo(int* hDevice, int numCards, struct CardInfo* pCardInfo) {
|
|
||||||
// dprintf("Y3: %s(%p), %d\n", __func__, hDevice, numCards);
|
|
||||||
// ret = num cards
|
|
||||||
// numCards = max cards
|
|
||||||
|
|
||||||
if (hDevice == Y3_COM_FIELD) {
|
|
||||||
|
|
||||||
int cards = numCards;
|
|
||||||
HRESULT hr = y3_dll.get_cards(pCardInfo, &cards);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
dprintf("Y3: DLL returned error when retrieving cards: %lx\n", hr);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cards;
|
|
||||||
} else if (hDevice == Y3_COM_PRINT) {
|
|
||||||
pCardInfo[0].fX = 0;
|
|
||||||
pCardInfo[0].fY = 0;
|
|
||||||
pCardInfo[0].fAngle = 0;
|
|
||||||
pCardInfo[0].eCardType = TYPE0;
|
|
||||||
pCardInfo[0].eCardStatus = MARKER;
|
|
||||||
pCardInfo[0].uID = 0x10;
|
|
||||||
pCardInfo[0].nNumChars = 0;
|
|
||||||
pCardInfo[0].ubChar0.Data = 0;
|
|
||||||
pCardInfo[0].ubChar1.Data = 0x4000;
|
|
||||||
pCardInfo[0].ubChar2.Data = 0;
|
|
||||||
pCardInfo[0].ubChar3.Data = 0x0; // 40
|
|
||||||
pCardInfo[0].ubChar4.Data = 0;
|
|
||||||
pCardInfo[0].ubChar5.Data = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_GetCardInfoCharSize() {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_FirmwareUpdate(int* hDevice, uint32_t address, uint32_t size,
|
|
||||||
uint8_t* buffer) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 1; // not supported
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_Calibration(int* hDevice, int calib) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_GetCalibrationResult(int* hDevice, int calib, uint32_t* result) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t CALL API_GetProcTime(int* hDevice) {
|
|
||||||
// dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t CALL API_GetMemStatus(int* hDevice) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
uint32_t CALL API_GetMemCounter(int* hDevice) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_SetParameter(int* hDevice, uint32_t uParam, uint32_t* pParam) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_GetParameter(int* hDevice, uint32_t uParam, uint32_t* pParam) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
signed int CALL API_SetDevice(int a1, int a2) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
signed int CALL API_SetCommand(int a1, int a2, int a3, int* a4) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
signed int CALL API_SetSysControl(int a1, int a2, int* a3) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
signed int CALL API_GetSysControl(int a1, int a2, int* a3) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_TestReset(int a1) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
signed int API_DebugReset(int a1, ...) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_GetBoardType(int a1) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_GetCardDataSize(int a1) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_GetFirmDate(int a1) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int API_SystemCommand(int a1, char a2, ...) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_CalcCheckSum(DWORD* a1, int a2, int a3) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_GetCheckSumResult(int a1) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_BlockRead(int a1, int a2, int a3, SIZE_T dwBytes) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_GetBlockReadResult(int a1, void* a2) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CALL API_BlockWrite(int a1, int a2, int a3, SIZE_T dwBytes, void* a5) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
signed int CALL API_GetDebugParam(int a1, int a2, DWORD* a3) {
|
|
||||||
dprintf("Y3: %s\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t convert_string_to_uint(const char* firmName) {
|
|
||||||
uint32_t result = 0;
|
|
||||||
|
|
||||||
// Iterate over each character in the string and construct the uint32_t
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
result |= (uint32_t)firmName[i] << (i * 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include "hooklib/config.h"
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
|
|
||||||
// Value held on a card.
|
|
||||||
struct CardByteData {
|
|
||||||
unsigned int Data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Unused
|
|
||||||
enum CardType {
|
|
||||||
TYPE0 = 0,
|
|
||||||
TYPE1,
|
|
||||||
TYPE2,
|
|
||||||
TYPE3,
|
|
||||||
TYPE4,
|
|
||||||
TYPE5,
|
|
||||||
TYPE6,
|
|
||||||
TYPE7 = 7
|
|
||||||
};
|
|
||||||
|
|
||||||
enum CardStatus {
|
|
||||||
// Unset entry
|
|
||||||
INVALID = 0,
|
|
||||||
// Valid card
|
|
||||||
VALID = 1,
|
|
||||||
// Not a card but rather infrared interference. Only relevant in test mode.
|
|
||||||
INFERENCE = 2,
|
|
||||||
// This is only used by the printer camera.
|
|
||||||
MARKER = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CardInfo {
|
|
||||||
// X position of the card.
|
|
||||||
float fX; // 0x00|0
|
|
||||||
// Y position of the card.
|
|
||||||
float fY; // 0x04|4
|
|
||||||
// Rotation of the card in degrees >=0.0 && <360.0
|
|
||||||
float fAngle; // 0x08|8
|
|
||||||
// Unused
|
|
||||||
enum CardType eCardType; // 0x0C|12
|
|
||||||
// see enum CardStatus
|
|
||||||
enum CardStatus eCardStatus; // 0x10|16
|
|
||||||
// card's BaseCode. used for a reference to the card being tracked as well as part of the IvCode.
|
|
||||||
unsigned int uID; // 0x14|20
|
|
||||||
// Unused
|
|
||||||
int nNumChars; // 0x18|24
|
|
||||||
// Title Code. Is 8589934592 for EKT.
|
|
||||||
struct CardByteData ubChar0; // 0x1C|28
|
|
||||||
// Must be 0x4000 for the printer camera.
|
|
||||||
struct CardByteData ubChar1; // 0x20|32
|
|
||||||
// Unused
|
|
||||||
struct CardByteData ubChar2; // 0x24|36
|
|
||||||
// Must be 0x0 for the printer camera.
|
|
||||||
struct CardByteData ubChar3; // 0x28|40
|
|
||||||
// Unused
|
|
||||||
struct CardByteData ubChar4; // 0x2C|44
|
|
||||||
// Unused
|
|
||||||
struct CardByteData ubChar5; // 0x30|48
|
|
||||||
};
|
|
||||||
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
HRESULT y3_hook_init(const struct y3_config *cfg, HINSTANCE self, const wchar_t* config_path);
|
|
||||||
|
|
||||||
void y3_insert_hooks(HMODULE target);
|
|
@ -18,7 +18,6 @@
|
|||||||
static HRESULT amvideo_reg_read_name(void *bytes, uint32_t *nbytes);
|
static HRESULT amvideo_reg_read_name(void *bytes, uint32_t *nbytes);
|
||||||
static HRESULT amvideo_reg_read_port_X(void *bytes, uint32_t *nbytes);
|
static HRESULT amvideo_reg_read_port_X(void *bytes, uint32_t *nbytes);
|
||||||
static HRESULT amvideo_reg_read_resolution_1(void *bytes, uint32_t *nbytes);
|
static HRESULT amvideo_reg_read_resolution_1(void *bytes, uint32_t *nbytes);
|
||||||
static HRESULT amvideo_reg_read_resolution_2(void *bytes, uint32_t *nbytes);
|
|
||||||
static HRESULT amvideo_reg_read_setting(void *bytes, uint32_t *nbytes);
|
static HRESULT amvideo_reg_read_setting(void *bytes, uint32_t *nbytes);
|
||||||
static HRESULT amvideo_reg_read_use_segatiming(void *bytes, uint32_t *nbytes);
|
static HRESULT amvideo_reg_read_use_segatiming(void *bytes, uint32_t *nbytes);
|
||||||
|
|
||||||
@ -82,10 +81,6 @@ static const struct reg_hook_val amvideo_reg_mode_vals[] = {
|
|||||||
.name = L"resolution_1",
|
.name = L"resolution_1",
|
||||||
.read = amvideo_reg_read_resolution_1,
|
.read = amvideo_reg_read_resolution_1,
|
||||||
.type = REG_SZ,
|
.type = REG_SZ,
|
||||||
}, {
|
|
||||||
.name = L"resolution_2",
|
|
||||||
.read = amvideo_reg_read_resolution_2,
|
|
||||||
.type = REG_SZ,
|
|
||||||
}, {
|
}, {
|
||||||
.name = L"use_segatiming",
|
.name = L"use_segatiming",
|
||||||
.read = amvideo_reg_read_use_segatiming,
|
.read = amvideo_reg_read_use_segatiming,
|
||||||
@ -176,11 +171,6 @@ static HRESULT amvideo_reg_read_resolution_1(void *bytes, uint32_t *nbytes)
|
|||||||
return reg_hook_read_wstr(bytes, nbytes, L"1920x1080");
|
return reg_hook_read_wstr(bytes, nbytes, L"1920x1080");
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT amvideo_reg_read_resolution_2(void *bytes, uint32_t *nbytes)
|
|
||||||
{
|
|
||||||
return reg_hook_read_wstr(bytes, nbytes, L"1920x1080");
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT amvideo_reg_read_setting(void *bytes, uint32_t *nbytes)
|
static HRESULT amvideo_reg_read_setting(void *bytes, uint32_t *nbytes)
|
||||||
{
|
{
|
||||||
return reg_hook_read_wstr(bytes, nbytes, L"0");
|
return reg_hook_read_wstr(bytes, nbytes, L"0");
|
||||||
|
@ -12,9 +12,6 @@
|
|||||||
#include "platform/amvideo.h"
|
#include "platform/amvideo.h"
|
||||||
#include "platform/clock.h"
|
#include "platform/clock.h"
|
||||||
#include "platform/config.h"
|
#include "platform/config.h"
|
||||||
|
|
||||||
#include <shlwapi.h>
|
|
||||||
|
|
||||||
#include "platform/dns.h"
|
#include "platform/dns.h"
|
||||||
#include "platform/epay.h"
|
#include "platform/epay.h"
|
||||||
#include "platform/hwmon.h"
|
#include "platform/hwmon.h"
|
||||||
@ -26,21 +23,14 @@
|
|||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
#include "platform/vfs.h"
|
#include "platform/vfs.h"
|
||||||
#include "platform/system.h"
|
#include "platform/system.h"
|
||||||
#include "util/dprintf.h"
|
#include "platform/openssl.h"
|
||||||
|
|
||||||
|
|
||||||
void platform_config_load(struct platform_config *cfg, const wchar_t *filename)
|
void platform_config_load(struct platform_config *cfg, const wchar_t *filename)
|
||||||
{
|
{
|
||||||
assert(cfg != NULL);
|
assert(cfg != NULL);
|
||||||
assert(filename != NULL);
|
assert(filename != NULL);
|
||||||
|
|
||||||
if (!PathFileExistsW(filename)) {
|
|
||||||
wchar_t temp[MAX_PATH];
|
|
||||||
dprintf("ERROR: Configuration does not exist\n");
|
|
||||||
dprintf(" Configured: \"%ls\"\n", filename);
|
|
||||||
GetFullPathNameW(filename, _countof(temp), temp, NULL);
|
|
||||||
dprintf(" Expanded: \"%ls\"\n", temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
amvideo_config_load(&cfg->amvideo, filename);
|
amvideo_config_load(&cfg->amvideo, filename);
|
||||||
clock_config_load(&cfg->clock, filename);
|
clock_config_load(&cfg->clock, filename);
|
||||||
dns_config_load(&cfg->dns, filename);
|
dns_config_load(&cfg->dns, filename);
|
||||||
@ -53,6 +43,7 @@ void platform_config_load(struct platform_config *cfg, const wchar_t *filename)
|
|||||||
nusec_config_load(&cfg->nusec, filename);
|
nusec_config_load(&cfg->nusec, filename);
|
||||||
vfs_config_load(&cfg->vfs, filename);
|
vfs_config_load(&cfg->vfs, filename);
|
||||||
system_config_load(&cfg->system, filename);
|
system_config_load(&cfg->system, filename);
|
||||||
|
openssl_config_load(&cfg->openssl, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void amvideo_config_load(struct amvideo_config *cfg, const wchar_t *filename)
|
void amvideo_config_load(struct amvideo_config *cfg, const wchar_t *filename)
|
||||||
@ -213,7 +204,6 @@ void nusec_config_load(struct nusec_config *cfg, const wchar_t *filename)
|
|||||||
wchar_t game_id[5];
|
wchar_t game_id[5];
|
||||||
wchar_t platform_id[5];
|
wchar_t platform_id[5];
|
||||||
wchar_t subnet[16];
|
wchar_t subnet[16];
|
||||||
wchar_t bcast[16];
|
|
||||||
unsigned int ip[4];
|
unsigned int ip[4];
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
@ -225,7 +215,6 @@ void nusec_config_load(struct nusec_config *cfg, const wchar_t *filename)
|
|||||||
memset(game_id, 0, sizeof(game_id));
|
memset(game_id, 0, sizeof(game_id));
|
||||||
memset(platform_id, 0, sizeof(platform_id));
|
memset(platform_id, 0, sizeof(platform_id));
|
||||||
memset(subnet, 0, sizeof(subnet));
|
memset(subnet, 0, sizeof(subnet));
|
||||||
memset(bcast, 0, sizeof(bcast));
|
|
||||||
|
|
||||||
cfg->enable = GetPrivateProfileIntW(L"keychip", L"enable", 1, filename);
|
cfg->enable = GetPrivateProfileIntW(L"keychip", L"enable", 1, filename);
|
||||||
|
|
||||||
@ -269,14 +258,6 @@ void nusec_config_load(struct nusec_config *cfg, const wchar_t *filename)
|
|||||||
_countof(subnet),
|
_countof(subnet),
|
||||||
filename);
|
filename);
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"netenv",
|
|
||||||
L"broadcast",
|
|
||||||
L"255.255.255.255",
|
|
||||||
bcast,
|
|
||||||
_countof(bcast),
|
|
||||||
filename);
|
|
||||||
|
|
||||||
for (i = 0 ; i < 16 ; i++) {
|
for (i = 0 ; i < 16 ; i++) {
|
||||||
cfg->keychip_id[i] = (char) keychip_id[i];
|
cfg->keychip_id[i] = (char) keychip_id[i];
|
||||||
}
|
}
|
||||||
@ -292,9 +273,6 @@ void nusec_config_load(struct nusec_config *cfg, const wchar_t *filename)
|
|||||||
swscanf(subnet, L"%u.%u.%u.%u", &ip[0], &ip[1], &ip[2], &ip[3]);
|
swscanf(subnet, L"%u.%u.%u.%u", &ip[0], &ip[1], &ip[2], &ip[3]);
|
||||||
cfg->subnet = (ip[0] << 24) | (ip[1] << 16) | (ip[2] << 8) | 0;
|
cfg->subnet = (ip[0] << 24) | (ip[1] << 16) | (ip[2] << 8) | 0;
|
||||||
|
|
||||||
swscanf(bcast, L"%u.%u.%u.%u", &ip[0], &ip[1], &ip[2], &ip[3]);
|
|
||||||
cfg->bcast = (ip[0] << 24) | (ip[1] << 16) | (ip[2] << 8) | (ip[3]);
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
GetPrivateProfileStringW(
|
||||||
L"keychip",
|
L"keychip",
|
||||||
L"billingCa",
|
L"billingCa",
|
||||||
@ -387,3 +365,12 @@ void epay_config_load(struct epay_config *cfg, const wchar_t *filename)
|
|||||||
cfg->enable = GetPrivateProfileIntW(L"epay", L"enable", 1, filename);
|
cfg->enable = GetPrivateProfileIntW(L"epay", L"enable", 1, filename);
|
||||||
cfg->hook = GetPrivateProfileIntW(L"epay", L"hook", 1, filename);
|
cfg->hook = GetPrivateProfileIntW(L"epay", L"hook", 1, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void openssl_config_load(struct openssl_config *cfg, const wchar_t *filename)
|
||||||
|
{
|
||||||
|
assert(cfg != NULL);
|
||||||
|
assert(filename != NULL);
|
||||||
|
|
||||||
|
cfg->enable = GetPrivateProfileIntW(L"openssl", L"enable", 1, filename);
|
||||||
|
cfg->override = GetPrivateProfileIntW(L"openssl", L"override", 0, filename);
|
||||||
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
#include "platform/vfs.h"
|
#include "platform/vfs.h"
|
||||||
#include "platform/system.h"
|
#include "platform/system.h"
|
||||||
|
#include "platform/openssl.h"
|
||||||
|
|
||||||
void platform_config_load(
|
void platform_config_load(
|
||||||
struct platform_config *cfg,
|
struct platform_config *cfg,
|
||||||
@ -36,3 +37,4 @@ void nusec_config_load(struct nusec_config *cfg, const wchar_t *filename);
|
|||||||
void pcbid_config_load(struct pcbid_config *cfg, const wchar_t *filename);
|
void pcbid_config_load(struct pcbid_config *cfg, const wchar_t *filename);
|
||||||
void vfs_config_load(struct vfs_config *cfg, const wchar_t *filename);
|
void vfs_config_load(struct vfs_config *cfg, const wchar_t *filename);
|
||||||
void system_config_load(struct system_config *cfg, const wchar_t *filename);
|
void system_config_load(struct system_config *cfg, const wchar_t *filename);
|
||||||
|
void openssl_config_load(struct openssl_config *cfg, const wchar_t *filename);
|
||||||
|
@ -38,5 +38,7 @@ platform_lib = static_library(
|
|||||||
'vfs.h',
|
'vfs.h',
|
||||||
'system.c',
|
'system.c',
|
||||||
'system.h',
|
'system.h',
|
||||||
|
'openssl.c',
|
||||||
|
'openssl.h'
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
#include "hook/table.h"
|
#include "hook/table.h"
|
||||||
|
|
||||||
#include "platform/netenv.h"
|
#include "platform/netenv.h"
|
||||||
|
|
||||||
#include "hook/procaddr.h"
|
|
||||||
#include "platform/nusec.h"
|
#include "platform/nusec.h"
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
#include "util/dprintf.h"
|
||||||
@ -74,14 +72,6 @@ static uint32_t WINAPI hook_IcmpSendEcho2(
|
|||||||
uint32_t ReplySize,
|
uint32_t ReplySize,
|
||||||
uint32_t Timeout);
|
uint32_t Timeout);
|
||||||
|
|
||||||
static int WINAPI hook_sendto(
|
|
||||||
SOCKET s,
|
|
||||||
const char* buf,
|
|
||||||
int len,
|
|
||||||
int flags,
|
|
||||||
const struct sockaddr *to,
|
|
||||||
int tolen);
|
|
||||||
|
|
||||||
/* Link pointers */
|
/* Link pointers */
|
||||||
|
|
||||||
static uint32_t (WINAPI *next_GetAdaptersAddresses)(
|
static uint32_t (WINAPI *next_GetAdaptersAddresses)(
|
||||||
@ -118,15 +108,6 @@ static uint32_t (WINAPI *next_IcmpSendEcho2)(
|
|||||||
uint32_t ReplySize,
|
uint32_t ReplySize,
|
||||||
uint32_t Timeout);
|
uint32_t Timeout);
|
||||||
|
|
||||||
static int (WINAPI *next_sendto)(
|
|
||||||
SOCKET s,
|
|
||||||
const char *buf,
|
|
||||||
int len,
|
|
||||||
int flags,
|
|
||||||
const struct sockaddr *to,
|
|
||||||
int tolen);
|
|
||||||
|
|
||||||
|
|
||||||
static const struct hook_symbol netenv_hook_syms[] = {
|
static const struct hook_symbol netenv_hook_syms[] = {
|
||||||
{
|
{
|
||||||
.name = "GetAdaptersAddresses",
|
.name = "GetAdaptersAddresses",
|
||||||
@ -151,17 +132,7 @@ static const struct hook_symbol netenv_hook_syms[] = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct hook_symbol netenv_hook_syms_ws2[] = {
|
|
||||||
{
|
|
||||||
.name = "sendto",
|
|
||||||
.patch = hook_sendto,
|
|
||||||
.ordinal = 20,
|
|
||||||
.link = (void **) &next_sendto
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint32_t netenv_ip_prefix;
|
static uint32_t netenv_ip_prefix;
|
||||||
static uint32_t netenv_ip_bcast;
|
|
||||||
static uint32_t netenv_ip_iface;
|
static uint32_t netenv_ip_iface;
|
||||||
static uint32_t netenv_ip_router;
|
static uint32_t netenv_ip_router;
|
||||||
static uint8_t netenv_mac_addr[6];
|
static uint8_t netenv_mac_addr[6];
|
||||||
@ -184,34 +155,17 @@ HRESULT netenv_hook_init(
|
|||||||
}
|
}
|
||||||
|
|
||||||
netenv_ip_prefix = kc_cfg->subnet;
|
netenv_ip_prefix = kc_cfg->subnet;
|
||||||
netenv_ip_bcast = kc_cfg->bcast;
|
|
||||||
netenv_ip_iface = kc_cfg->subnet | cfg->addr_suffix;
|
netenv_ip_iface = kc_cfg->subnet | cfg->addr_suffix;
|
||||||
netenv_ip_router = kc_cfg->subnet | cfg->router_suffix;
|
netenv_ip_router = kc_cfg->subnet | cfg->router_suffix;
|
||||||
memcpy(netenv_mac_addr, cfg->mac_addr, sizeof(netenv_mac_addr));
|
memcpy(netenv_mac_addr, cfg->mac_addr, sizeof(netenv_mac_addr));
|
||||||
|
|
||||||
netenv_hook_apply_hooks(NULL);
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void netenv_hook_apply_hooks(HMODULE mod) {
|
|
||||||
hook_table_apply(
|
hook_table_apply(
|
||||||
mod,
|
NULL,
|
||||||
"iphlpapi.dll",
|
"iphlpapi.dll",
|
||||||
netenv_hook_syms,
|
netenv_hook_syms,
|
||||||
_countof(netenv_hook_syms));
|
_countof(netenv_hook_syms));
|
||||||
|
|
||||||
hook_table_apply(
|
return S_OK;
|
||||||
mod,
|
|
||||||
"ws2_32.dll",
|
|
||||||
netenv_hook_syms_ws2,
|
|
||||||
_countof(netenv_hook_syms_ws2));
|
|
||||||
|
|
||||||
proc_addr_table_push(
|
|
||||||
mod,
|
|
||||||
"ws2_32.dll",
|
|
||||||
netenv_hook_syms_ws2,
|
|
||||||
_countof(netenv_hook_syms_ws2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t WINAPI hook_GetAdaptersAddresses(
|
static uint32_t WINAPI hook_GetAdaptersAddresses(
|
||||||
@ -552,39 +506,3 @@ static uint32_t WINAPI hook_IcmpSendEcho2(
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int WINAPI hook_sendto(
|
|
||||||
SOCKET s,
|
|
||||||
const char* buf,
|
|
||||||
int len,
|
|
||||||
int flags,
|
|
||||||
const struct sockaddr* to,
|
|
||||||
int tolen) {
|
|
||||||
if (to->sa_family != AF_INET) {
|
|
||||||
// we only care about IP packets
|
|
||||||
return next_sendto(s, buf, len, flags, to, tolen);
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct sockaddr_in* original_to = (struct sockaddr_in*)to;
|
|
||||||
|
|
||||||
uint32_t bc_addr = _byteswap_ulong(netenv_ip_prefix | 0xFF);
|
|
||||||
|
|
||||||
if (original_to->sin_addr.S_un.S_addr == bc_addr) {
|
|
||||||
|
|
||||||
uint32_t src_addr = _byteswap_ulong(original_to->sin_addr.S_un.S_addr);
|
|
||||||
uint32_t dest_addr = _byteswap_ulong(netenv_ip_bcast);
|
|
||||||
|
|
||||||
dprintf("Netenv: sendTo broadcast %u.%u.%u.%u -> %u.%u.%u.%u\n",
|
|
||||||
(src_addr >> 24) & 0xff, (src_addr >> 16) & 0xff, (src_addr >> 8) & 0xff, src_addr & 0xff,
|
|
||||||
(dest_addr >> 24) & 0xff, (dest_addr >> 16) & 0xff, (dest_addr >> 8) & 0xff, dest_addr & 0xff);
|
|
||||||
|
|
||||||
struct sockaddr_in modified_to = {0};
|
|
||||||
memcpy(&modified_to, original_to, tolen);
|
|
||||||
|
|
||||||
modified_to.sin_addr.S_un.S_addr = dest_addr;
|
|
||||||
|
|
||||||
return next_sendto(s, buf, len, flags, (struct sockaddr*)&modified_to, sizeof(modified_to));
|
|
||||||
}
|
|
||||||
|
|
||||||
return next_sendto(s, buf, len, flags, to, tolen);
|
|
||||||
}
|
|
@ -18,4 +18,3 @@ HRESULT netenv_hook_init(
|
|||||||
const struct netenv_config *cfg,
|
const struct netenv_config *cfg,
|
||||||
const struct nusec_config *kc_cfg);
|
const struct nusec_config *kc_cfg);
|
||||||
|
|
||||||
void netenv_hook_apply_hooks(HMODULE mod);
|
|
@ -14,7 +14,6 @@ struct nusec_config {
|
|||||||
uint8_t region;
|
uint8_t region;
|
||||||
uint8_t system_flag;
|
uint8_t system_flag;
|
||||||
uint32_t subnet;
|
uint32_t subnet;
|
||||||
uint32_t bcast;
|
|
||||||
uint16_t billing_type;
|
uint16_t billing_type;
|
||||||
wchar_t billing_ca[MAX_PATH];
|
wchar_t billing_ca[MAX_PATH];
|
||||||
wchar_t billing_pub[MAX_PATH];
|
wchar_t billing_pub[MAX_PATH];
|
||||||
|
116
common/platform/openssl.c
Normal file
116
common/platform/openssl.c
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <intrin.h>
|
||||||
|
|
||||||
|
#include "hook/table.h"
|
||||||
|
|
||||||
|
#include "hooklib/config.h"
|
||||||
|
|
||||||
|
#include "platform/openssl.h"
|
||||||
|
|
||||||
|
#include "util/dprintf.h"
|
||||||
|
|
||||||
|
/* API hooks */
|
||||||
|
|
||||||
|
static char * __cdecl hook_getenv(const char *name);
|
||||||
|
|
||||||
|
/* Link pointers */
|
||||||
|
|
||||||
|
static char * (__cdecl *next_getenv)(const char *name);
|
||||||
|
|
||||||
|
static bool openssl_hook_initted;
|
||||||
|
static struct openssl_config openssl_config;
|
||||||
|
|
||||||
|
static const struct hook_symbol openssl_hooks[] = {
|
||||||
|
{
|
||||||
|
.name = "getenv",
|
||||||
|
.patch = hook_getenv,
|
||||||
|
.link = (void **) &next_getenv
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int check_intel_sha_extension() {
|
||||||
|
int n_ids;
|
||||||
|
int is_intel;
|
||||||
|
char vendor[0x20] = {0};
|
||||||
|
int cpui[4] = {0};
|
||||||
|
|
||||||
|
/* OpenSSL 1.0.2 beta to 1.0.2k contain bugs that crash "AM Daemon" due to
|
||||||
|
bad SHA values on processors with the SHA extensions, such as Intel 10th
|
||||||
|
gen CPUs or higher.
|
||||||
|
|
||||||
|
Credits: kagaminehaku */
|
||||||
|
|
||||||
|
__cpuid(cpui, 0);
|
||||||
|
n_ids = cpui[0];
|
||||||
|
|
||||||
|
*((int *) vendor) = cpui[1];
|
||||||
|
*((int *) (vendor + 4)) = cpui[3];
|
||||||
|
*((int *) (vendor + 8)) = cpui[2];
|
||||||
|
|
||||||
|
/* Check that the CPU vendor is Intel */
|
||||||
|
is_intel = (strcmp(vendor, "GenuineIntel") == 0);
|
||||||
|
|
||||||
|
if (is_intel && n_ids >= 7) {
|
||||||
|
__cpuidex(cpui, 7, 0);
|
||||||
|
|
||||||
|
/* SHA extensions supported */
|
||||||
|
return (cpui[1] & (1 << 29)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT openssl_hook_init(const struct openssl_config *cfg)
|
||||||
|
{
|
||||||
|
assert(cfg != NULL);
|
||||||
|
|
||||||
|
if (!cfg->enable) {
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (openssl_hook_initted) {
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg->override) {
|
||||||
|
dprintf("OpenSSL: hook enabled.\n");
|
||||||
|
} else if (check_intel_sha_extension()) {
|
||||||
|
dprintf("OpenSSL: Intel CPU SHA extension detected, hook enabled.\n");
|
||||||
|
} else {
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
openssl_hook_initted = true;
|
||||||
|
|
||||||
|
memcpy(&openssl_config, cfg, sizeof(*cfg));
|
||||||
|
hook_table_apply(
|
||||||
|
NULL,
|
||||||
|
"msvcr110.dll",
|
||||||
|
openssl_hooks,
|
||||||
|
_countof(openssl_hooks)
|
||||||
|
);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char * __cdecl hook_getenv(const char *name)
|
||||||
|
{
|
||||||
|
/* Overrides OpenSSL's Intel CPU identification. This disables the OpenSSL
|
||||||
|
code check for SHA extensions. */
|
||||||
|
if (name && strcmp(name, "OPENSSL_ia32cap") == 0) {
|
||||||
|
static char override[] = "~0x20000000";
|
||||||
|
|
||||||
|
dprintf("OpenSSL: Overriding OPENSSL_ia32cap -> %s\n", override);
|
||||||
|
|
||||||
|
return override;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *real_val = next_getenv(name);
|
||||||
|
|
||||||
|
return real_val;
|
||||||
|
}
|
12
common/platform/openssl.h
Normal file
12
common/platform/openssl.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
struct openssl_config {
|
||||||
|
bool enable;
|
||||||
|
bool override;
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT openssl_hook_init(const struct openssl_config *cfg);
|
@ -14,6 +14,7 @@
|
|||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
#include "platform/vfs.h"
|
#include "platform/vfs.h"
|
||||||
#include "platform/system.h"
|
#include "platform/system.h"
|
||||||
|
#include "platform/openssl.h"
|
||||||
|
|
||||||
HRESULT platform_hook_init(
|
HRESULT platform_hook_init(
|
||||||
const struct platform_config *cfg,
|
const struct platform_config *cfg,
|
||||||
@ -94,5 +95,11 @@ HRESULT platform_hook_init(
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hr = openssl_hook_init(&cfg->openssl);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "platform/pcbid.h"
|
#include "platform/pcbid.h"
|
||||||
#include "platform/vfs.h"
|
#include "platform/vfs.h"
|
||||||
#include "platform/system.h"
|
#include "platform/system.h"
|
||||||
|
#include "platform/openssl.h"
|
||||||
|
|
||||||
struct platform_config {
|
struct platform_config {
|
||||||
struct amvideo_config amvideo;
|
struct amvideo_config amvideo;
|
||||||
@ -28,6 +29,7 @@ struct platform_config {
|
|||||||
struct nusec_config nusec;
|
struct nusec_config nusec;
|
||||||
struct vfs_config vfs;
|
struct vfs_config vfs;
|
||||||
struct system_config system;
|
struct system_config system;
|
||||||
|
struct openssl_config openssl;
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT platform_hook_init(
|
HRESULT platform_hook_init(
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#include "hooklib/dll.h"
|
#include "hooklib/dll.h"
|
||||||
#include "hooklib/path.h"
|
#include "hooklib/path.h"
|
||||||
#include "hooklib/printer_chc.h"
|
#include "hooklib/printer.h"
|
||||||
#include "hooklib/reg.h"
|
#include "hooklib/reg.h"
|
||||||
#include "hooklib/touch.h"
|
#include "hooklib/touch.h"
|
||||||
#include "hooklib/serial.h"
|
#include "hooklib/serial.h"
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
|
|
||||||
#include "hooklib/y3.h"
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t y3_io_get_api_version() {
|
|
||||||
return 0x0100;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT y3_io_init() {
|
|
||||||
dprintf("Y3 Dummy Cards: initialized\n");
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT y3_io_close() {
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT y3_io_get_cards(struct CardInfo* pCardInfo, int* numCards) {
|
|
||||||
memset(pCardInfo, 0, sizeof(struct CardInfo) * *numCards);
|
|
||||||
|
|
||||||
const float paddingX = 86.0f;
|
|
||||||
const float paddingY = 54.0f;
|
|
||||||
|
|
||||||
// Dimensions of the flat panel
|
|
||||||
const float panelHeight = 1232.0f;
|
|
||||||
const float panelWidth = 1160.0f;
|
|
||||||
|
|
||||||
// Number of cards in each row and column
|
|
||||||
const int numRows = 4;
|
|
||||||
const int numCols = 4;
|
|
||||||
int activeCards = numRows * numCols;
|
|
||||||
|
|
||||||
if (*numCards < activeCards) {
|
|
||||||
activeCards = *numCards;
|
|
||||||
}
|
|
||||||
*numCards = activeCards;
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate spacing between cards
|
|
||||||
const float cardWidth = (panelWidth - paddingY * 2) / (numCols - 1);
|
|
||||||
const float cardHeight = (panelHeight - paddingX * 2) / (numRows - 1);
|
|
||||||
|
|
||||||
// Create example card info
|
|
||||||
for (int i = 0; i < activeCards; i++) {
|
|
||||||
int row = i / numCols;
|
|
||||||
int col = i % numCols;
|
|
||||||
|
|
||||||
pCardInfo[i].fX = paddingX + (col * cardHeight);
|
|
||||||
pCardInfo[i].fY = paddingY + (row * cardWidth);
|
|
||||||
pCardInfo[i].fAngle = 0.0f;
|
|
||||||
pCardInfo[i].eCardType = TYPE0;
|
|
||||||
pCardInfo[i].eCardStatus = VALID;
|
|
||||||
pCardInfo[i].uID = 1000 + i;
|
|
||||||
pCardInfo[i].nNumChars = 0;
|
|
||||||
pCardInfo[i].ubChar0.Data = 0;
|
|
||||||
pCardInfo[i].ubChar1.Data = 0;
|
|
||||||
pCardInfo[i].ubChar2.Data = 0;
|
|
||||||
pCardInfo[i].ubChar3.Data = 0;
|
|
||||||
pCardInfo[i].ubChar4.Data = 0;
|
|
||||||
pCardInfo[i].ubChar5.Data = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
3191
common/y3io/impl/websockets/3rdparty/cjson/cJSON.c
vendored
3191
common/y3io/impl/websockets/3rdparty/cjson/cJSON.c
vendored
File diff suppressed because it is too large
Load Diff
306
common/y3io/impl/websockets/3rdparty/cjson/cJSON.h
vendored
306
common/y3io/impl/websockets/3rdparty/cjson/cJSON.h
vendored
@ -1,306 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef cJSON__h
|
|
||||||
#define cJSON__h
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
|
||||||
#define __WINDOWS__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __WINDOWS__
|
|
||||||
|
|
||||||
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
|
|
||||||
|
|
||||||
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
|
||||||
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
|
||||||
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
|
||||||
|
|
||||||
For *nix builds that support visibility attribute, you can define similar behavior by
|
|
||||||
|
|
||||||
setting default visibility to hidden by adding
|
|
||||||
-fvisibility=hidden (for gcc)
|
|
||||||
or
|
|
||||||
-xldscope=hidden (for sun cc)
|
|
||||||
to CFLAGS
|
|
||||||
|
|
||||||
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define CJSON_CDECL __cdecl
|
|
||||||
#define CJSON_STDCALL __stdcall
|
|
||||||
|
|
||||||
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
|
||||||
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
|
||||||
#define CJSON_EXPORT_SYMBOLS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CJSON_HIDE_SYMBOLS)
|
|
||||||
#define CJSON_PUBLIC(type) type CJSON_STDCALL
|
|
||||||
#elif defined(CJSON_EXPORT_SYMBOLS)
|
|
||||||
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
|
|
||||||
#elif defined(CJSON_IMPORT_SYMBOLS)
|
|
||||||
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
|
|
||||||
#endif
|
|
||||||
#else /* !__WINDOWS__ */
|
|
||||||
#define CJSON_CDECL
|
|
||||||
#define CJSON_STDCALL
|
|
||||||
|
|
||||||
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
|
|
||||||
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
|
||||||
#else
|
|
||||||
#define CJSON_PUBLIC(type) type
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* project version */
|
|
||||||
#define CJSON_VERSION_MAJOR 1
|
|
||||||
#define CJSON_VERSION_MINOR 7
|
|
||||||
#define CJSON_VERSION_PATCH 18
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
/* cJSON Types: */
|
|
||||||
#define cJSON_Invalid (0)
|
|
||||||
#define cJSON_False (1 << 0)
|
|
||||||
#define cJSON_True (1 << 1)
|
|
||||||
#define cJSON_NULL (1 << 2)
|
|
||||||
#define cJSON_Number (1 << 3)
|
|
||||||
#define cJSON_String (1 << 4)
|
|
||||||
#define cJSON_Array (1 << 5)
|
|
||||||
#define cJSON_Object (1 << 6)
|
|
||||||
#define cJSON_Raw (1 << 7) /* raw json */
|
|
||||||
|
|
||||||
#define cJSON_IsReference 256
|
|
||||||
#define cJSON_StringIsConst 512
|
|
||||||
|
|
||||||
/* The cJSON structure: */
|
|
||||||
typedef struct cJSON
|
|
||||||
{
|
|
||||||
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
|
||||||
struct cJSON *next;
|
|
||||||
struct cJSON *prev;
|
|
||||||
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
|
||||||
struct cJSON *child;
|
|
||||||
|
|
||||||
/* The type of the item, as above. */
|
|
||||||
int type;
|
|
||||||
|
|
||||||
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
|
||||||
char *valuestring;
|
|
||||||
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
|
||||||
int valueint;
|
|
||||||
/* The item's number, if type==cJSON_Number */
|
|
||||||
double valuedouble;
|
|
||||||
|
|
||||||
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
|
||||||
char *string;
|
|
||||||
} cJSON;
|
|
||||||
|
|
||||||
typedef struct cJSON_Hooks
|
|
||||||
{
|
|
||||||
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
|
|
||||||
void *(CJSON_CDECL *malloc_fn)(size_t sz);
|
|
||||||
void (CJSON_CDECL *free_fn)(void *ptr);
|
|
||||||
} cJSON_Hooks;
|
|
||||||
|
|
||||||
typedef int cJSON_bool;
|
|
||||||
|
|
||||||
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
|
||||||
* This is to prevent stack overflows. */
|
|
||||||
#ifndef CJSON_NESTING_LIMIT
|
|
||||||
#define CJSON_NESTING_LIMIT 1000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Limits the length of circular references can be before cJSON rejects to parse them.
|
|
||||||
* This is to prevent stack overflows. */
|
|
||||||
#ifndef CJSON_CIRCULAR_LIMIT
|
|
||||||
#define CJSON_CIRCULAR_LIMIT 10000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* returns the version of cJSON as a string */
|
|
||||||
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
|
||||||
|
|
||||||
/* Supply malloc, realloc and free functions to cJSON */
|
|
||||||
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
|
||||||
|
|
||||||
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
|
||||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
|
|
||||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
|
||||||
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
|
|
||||||
|
|
||||||
/* Render a cJSON entity to text for transfer/storage. */
|
|
||||||
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
|
||||||
/* Render a cJSON entity to text for transfer/storage without any formatting. */
|
|
||||||
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
|
||||||
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
|
||||||
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
|
||||||
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
|
|
||||||
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
|
||||||
/* Delete a cJSON entity and all subentities. */
|
|
||||||
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
|
|
||||||
|
|
||||||
/* Returns the number of items in an array (or object). */
|
|
||||||
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
|
||||||
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
|
||||||
/* Get item "string" from object. Case insensitive. */
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
|
||||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
|
||||||
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
|
||||||
|
|
||||||
/* Check item type and return its value */
|
|
||||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
|
|
||||||
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
|
|
||||||
|
|
||||||
/* These functions check the type of an item */
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
|
|
||||||
|
|
||||||
/* These calls create a cJSON item of the appropriate type. */
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
|
||||||
/* raw json */
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
|
||||||
|
|
||||||
/* Create a string where valuestring references a string so
|
|
||||||
* it will not be freed by cJSON_Delete */
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
|
||||||
/* Create an object/array that only references it's elements so
|
|
||||||
* they will not be freed by cJSON_Delete */
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
|
||||||
|
|
||||||
/* These utilities create an Array of count items.
|
|
||||||
* The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
|
|
||||||
|
|
||||||
/* Append item to the specified array/object. */
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
|
||||||
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
|
|
||||||
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
|
||||||
* writing to `item->string` */
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
|
||||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
|
||||||
|
|
||||||
/* Remove/Detach items from Arrays/Objects. */
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
|
||||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
|
||||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
|
||||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
|
||||||
|
|
||||||
/* Update array items. */
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
|
||||||
|
|
||||||
/* Duplicate a cJSON item */
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
|
||||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
|
||||||
* need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
|
||||||
* The item->next and ->prev pointers are always zero on return from Duplicate. */
|
|
||||||
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
|
||||||
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
|
||||||
|
|
||||||
/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
|
|
||||||
* The input pointer json cannot point to a read-only address area, such as a string constant,
|
|
||||||
* but should point to a readable and writable address area. */
|
|
||||||
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
|
||||||
|
|
||||||
/* Helper functions for creating and adding items to an object at the same time.
|
|
||||||
* They return the added item or NULL on failure. */
|
|
||||||
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
|
|
||||||
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
|
|
||||||
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
|
|
||||||
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
|
|
||||||
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
|
|
||||||
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
|
|
||||||
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
|
|
||||||
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
|
|
||||||
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
|
||||||
|
|
||||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
|
||||||
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
|
|
||||||
/* helper for the cJSON_SetNumberValue macro */
|
|
||||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
|
||||||
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
|
||||||
/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
|
|
||||||
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
|
|
||||||
|
|
||||||
/* If the object is not a boolean type this does nothing and returns cJSON_Invalid else it returns the new type*/
|
|
||||||
#define cJSON_SetBoolValue(object, boolValue) ( \
|
|
||||||
(object != NULL && ((object)->type & (cJSON_False|cJSON_True))) ? \
|
|
||||||
(object)->type=((object)->type &(~(cJSON_False|cJSON_True)))|((boolValue)?cJSON_True:cJSON_False) : \
|
|
||||||
cJSON_Invalid\
|
|
||||||
)
|
|
||||||
|
|
||||||
/* Macro for iterating over an array or object */
|
|
||||||
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
|
||||||
|
|
||||||
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
|
|
||||||
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
|
||||||
CJSON_PUBLIC(void) cJSON_free(void *object);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
1481
common/y3io/impl/websockets/3rdparty/cjson/cJSON_Utils.c
vendored
1481
common/y3io/impl/websockets/3rdparty/cjson/cJSON_Utils.c
vendored
File diff suppressed because it is too large
Load Diff
@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef cJSON_Utils__h
|
|
||||||
#define cJSON_Utils__h
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "cJSON.h"
|
|
||||||
|
|
||||||
/* Implement RFC6901 (https://tools.ietf.org/html/rfc6901) JSON Pointer spec. */
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSONUtils_GetPointer(cJSON * const object, const char *pointer);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSONUtils_GetPointerCaseSensitive(cJSON * const object, const char *pointer);
|
|
||||||
|
|
||||||
/* Implement RFC6902 (https://tools.ietf.org/html/rfc6902) JSON Patch spec. */
|
|
||||||
/* NOTE: This modifies objects in 'from' and 'to' by sorting the elements by their key */
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatches(cJSON * const from, cJSON * const to);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatchesCaseSensitive(cJSON * const from, cJSON * const to);
|
|
||||||
/* Utility for generating patch array entries. */
|
|
||||||
CJSON_PUBLIC(void) cJSONUtils_AddPatchToArray(cJSON * const array, const char * const operation, const char * const path, const cJSON * const value);
|
|
||||||
/* Returns 0 for success. */
|
|
||||||
CJSON_PUBLIC(int) cJSONUtils_ApplyPatches(cJSON * const object, const cJSON * const patches);
|
|
||||||
CJSON_PUBLIC(int) cJSONUtils_ApplyPatchesCaseSensitive(cJSON * const object, const cJSON * const patches);
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Note that ApplyPatches is NOT atomic on failure. To implement an atomic ApplyPatches, use:
|
|
||||||
//int cJSONUtils_AtomicApplyPatches(cJSON **object, cJSON *patches)
|
|
||||||
//{
|
|
||||||
// cJSON *modme = cJSON_Duplicate(*object, 1);
|
|
||||||
// int error = cJSONUtils_ApplyPatches(modme, patches);
|
|
||||||
// if (!error)
|
|
||||||
// {
|
|
||||||
// cJSON_Delete(*object);
|
|
||||||
// *object = modme;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// cJSON_Delete(modme);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return error;
|
|
||||||
//}
|
|
||||||
// Code not added to library since this strategy is a LOT slower.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Implement RFC7386 (https://tools.ietf.org/html/rfc7396) JSON Merge Patch spec. */
|
|
||||||
/* target will be modified by patch. return value is new ptr for target. */
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSONUtils_MergePatch(cJSON *target, const cJSON * const patch);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSONUtils_MergePatchCaseSensitive(cJSON *target, const cJSON * const patch);
|
|
||||||
/* generates a patch to move from -> to */
|
|
||||||
/* NOTE: This modifies objects in 'from' and 'to' by sorting the elements by their key */
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatch(cJSON * const from, cJSON * const to);
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatchCaseSensitive(cJSON * const from, cJSON * const to);
|
|
||||||
|
|
||||||
/* Given a root object and a target object, construct a pointer from one to the other. */
|
|
||||||
CJSON_PUBLIC(char *) cJSONUtils_FindPointerFromObjectTo(const cJSON * const object, const cJSON * const target);
|
|
||||||
|
|
||||||
/* Sorts the members of the object into alphabetical order. */
|
|
||||||
CJSON_PUBLIC(void) cJSONUtils_SortObject(cJSON * const object);
|
|
||||||
CJSON_PUBLIC(void) cJSONUtils_SortObjectCaseSensitive(cJSON * const object);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,39 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
void y3ws_config_load(struct y3ws_config *cfg, const wchar_t *filename)
|
|
||||||
{
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
|
|
||||||
cfg->enable = GetPrivateProfileIntW(L"y3ws", L"enable", 1, filename);
|
|
||||||
cfg->debug = GetPrivateProfileIntW(L"y3ws", L"debug", 0, filename);
|
|
||||||
|
|
||||||
cfg->port = GetPrivateProfileIntW(L"y3ws", L"port", 3594, filename);
|
|
||||||
|
|
||||||
wchar_t tmpstr[16];
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"y3ws",
|
|
||||||
L"gameId",
|
|
||||||
L"SDEY",
|
|
||||||
tmpstr,
|
|
||||||
_countof(tmpstr),
|
|
||||||
filename);
|
|
||||||
|
|
||||||
wcstombs(cfg->game_id, tmpstr, sizeof(cfg->game_id));
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"y3ws",
|
|
||||||
L"cardDirectory",
|
|
||||||
L"DEVICE\\print",
|
|
||||||
cfg->card_path,
|
|
||||||
_countof(cfg->card_path),
|
|
||||||
filename);
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "hooklib/dvd.h"
|
|
||||||
#include "hooklib/touch.h"
|
|
||||||
#include "hooklib/printer_chc.h"
|
|
||||||
#include "hooklib/printer_cx.h"
|
|
||||||
|
|
||||||
struct y3ws_config {
|
|
||||||
bool enable;
|
|
||||||
bool debug;
|
|
||||||
|
|
||||||
uint16_t port;
|
|
||||||
char game_id[5];
|
|
||||||
wchar_t card_path[MAX_PATH];
|
|
||||||
};
|
|
||||||
|
|
||||||
void y3ws_config_load(struct y3ws_config *cfg, const wchar_t *filename);
|
|
@ -1,352 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <windows.h>
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <ws2tcpip.h>
|
|
||||||
|
|
||||||
#include "3rdparty/cjson/cJSON.h"
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "y3ws.h"
|
|
||||||
|
|
||||||
#include <wchar.h>
|
|
||||||
|
|
||||||
#include "hooklib/y3.h"
|
|
||||||
|
|
||||||
#include "winwebsocket.h"
|
|
||||||
#include "lib/base64.h"
|
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
#include "util/env.h"
|
|
||||||
|
|
||||||
static void onopen(struct wws_connection*);
|
|
||||||
static void onclose(struct wws_connection*);
|
|
||||||
static void onmessage(struct wws_connection*, const char*, size_t);
|
|
||||||
static void onlog(const char*, ...);
|
|
||||||
|
|
||||||
#define PROTOCOL_VERSION 1
|
|
||||||
#define GAME_MAX_CARDS 32
|
|
||||||
#define MAX_CARDS 500
|
|
||||||
#define CARD_ID_LEN 5
|
|
||||||
#define OUTPUT_BUFFER_SIZE (1024 * 1024 * 5)
|
|
||||||
|
|
||||||
static struct y3ws_config cfg;
|
|
||||||
|
|
||||||
static bool is_initialized = false;
|
|
||||||
static struct CardInfo card_info[GAME_MAX_CARDS];
|
|
||||||
static int card_info_size = 0;
|
|
||||||
static CRITICAL_SECTION card_info_lock;
|
|
||||||
|
|
||||||
#pragma region y3-dll functions
|
|
||||||
uint16_t y3_io_get_api_version() {
|
|
||||||
return 0x0100;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT y3_io_init() {
|
|
||||||
if (is_initialized) {
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
y3ws_config_load(&cfg, get_config_path());
|
|
||||||
|
|
||||||
memset(card_info, 0, sizeof(card_info));
|
|
||||||
InitializeCriticalSection(&card_info_lock);
|
|
||||||
|
|
||||||
wws_set_callbacks(onopen, onclose, onmessage, onlog);
|
|
||||||
wws_set_verbose(cfg.debug);
|
|
||||||
|
|
||||||
HRESULT hr = wws_start(cfg.port);
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
dprintf("Y3WS: Started server on port %d\n", cfg.port);
|
|
||||||
if (cfg.debug) {
|
|
||||||
dprintf("Y3WS: WS debug logging is on\n");
|
|
||||||
}
|
|
||||||
is_initialized = true;
|
|
||||||
} else {
|
|
||||||
dprintf("Y3WS: Error starting server: %lx\n", hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT y3_io_close() {
|
|
||||||
|
|
||||||
HRESULT hr = wws_stop();
|
|
||||||
|
|
||||||
DeleteCriticalSection(&card_info_lock);
|
|
||||||
|
|
||||||
is_initialized = false;
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT y3_io_get_cards(struct CardInfo* pCardInfo, int* numCards) {
|
|
||||||
EnterCriticalSection(&card_info_lock);
|
|
||||||
for (int i = 0; i < card_info_size; i++) {
|
|
||||||
memcpy(&pCardInfo[i], &card_info[i], sizeof(struct CardInfo));
|
|
||||||
}
|
|
||||||
*numCards = card_info_size;
|
|
||||||
LeaveCriticalSection(&card_info_lock);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
#pragma endregion
|
|
||||||
|
|
||||||
#pragma region y3ws functions
|
|
||||||
static void y3ws_make_error_packet(const char* message, char* output_data, size_t* output_size) {
|
|
||||||
dprintf("Y3WS: Error: %s\n", message);
|
|
||||||
*output_size = sprintf_s((char*)output_data, *output_size, "{\"version\":%d, \"success\":false,\"error\":\"%s\"}", PROTOCOL_VERSION, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void y3ws_make_success_packet(char* output_data, size_t* output_size) {
|
|
||||||
*output_size = sprintf_s((char*)output_data, *output_size, "{\"version\":%d, \"success\":true}", PROTOCOL_VERSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void y3ws_read_cards(char* output_data, size_t* output_size) {
|
|
||||||
WIN32_FIND_DATAW ffd;
|
|
||||||
|
|
||||||
wchar_t path[MAX_PATH];
|
|
||||||
swprintf(path, MAX_PATH, L"%ls\\*", cfg.card_path);
|
|
||||||
|
|
||||||
HANDLE hFind = FindFirstFileW(path, &ffd);
|
|
||||||
if (INVALID_HANDLE_VALUE == hFind) {
|
|
||||||
dprintf("Y3WS: Failed to access directory: %ls (%ld)\n", path, GetLastError());
|
|
||||||
y3ws_make_error_packet("Could not read from card directory", output_data, output_size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cJSON* response = cJSON_CreateObject();
|
|
||||||
cJSON* pversion = cJSON_CreateNumber(PROTOCOL_VERSION);
|
|
||||||
cJSON_AddItemToObject(response, "version", pversion);
|
|
||||||
cJSON* success = cJSON_CreateBool(true);
|
|
||||||
cJSON_AddItemToObject(response, "success", success);
|
|
||||||
cJSON* cards = cJSON_CreateArray();
|
|
||||||
cJSON_AddItemToObject(response, "cards", cards);
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
do {
|
|
||||||
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
swprintf(path, MAX_PATH, L"%ls\\%ls", cfg.card_path, ffd.cFileName);
|
|
||||||
|
|
||||||
HANDLE hImage = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
if (hImage == INVALID_HANDLE_VALUE) {
|
|
||||||
dprintf("Y3WS: Error opening %ls: %ld\n", path, GetLastError());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
DWORD ret = SetFilePointer(hImage, -CARD_ID_LEN, NULL, FILE_END);
|
|
||||||
if (ret == INVALID_SET_FILE_POINTER) {
|
|
||||||
dprintf("Y3WS: Error seeking in %ls: %ld\n", path, GetLastError());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
uint8_t buf[CARD_ID_LEN];
|
|
||||||
DWORD bytesRead = 0;
|
|
||||||
if (!ReadFile(hImage, &buf, CARD_ID_LEN, &bytesRead, NULL) || bytesRead != CARD_ID_LEN) {
|
|
||||||
dprintf("Y3WS: Error reading card ID from %ls: %ld\n", path, GetLastError());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
cJSON* card = cJSON_CreateObject();
|
|
||||||
cJSON_AddItemToArray(cards, card);
|
|
||||||
|
|
||||||
// cJSON isn't wide...
|
|
||||||
char fpatha[MAX_PATH];
|
|
||||||
size_t fpatha_len = 0;
|
|
||||||
wcstombs_s(&fpatha_len, fpatha, MAX_PATH, ffd.cFileName, MAX_PATH);
|
|
||||||
fpatha[fpatha_len] = 0;
|
|
||||||
|
|
||||||
// ReSharper disable once CppRedundantCastExpression
|
|
||||||
cJSON* path_str = cJSON_CreateString(fpatha);
|
|
||||||
cJSON_AddItemToObject(card, "path", path_str);
|
|
||||||
cJSON* card_id = cJSON_CreateNumber((double)((uint64_t)buf[0] >> 32 | (uint64_t)buf[1] >> 24 | (uint64_t)buf[2] >> 16 | (uint64_t)buf[3] >> 8 | buf[4]));
|
|
||||||
cJSON_AddItemToObject(card, "card_id", card_id);
|
|
||||||
|
|
||||||
} while (FindNextFileW(hFind, &ffd) != 0 && count++ < MAX_CARDS);
|
|
||||||
|
|
||||||
cJSON_PrintPreallocated(response, output_data, (int)*output_size, false);
|
|
||||||
*output_size = strlen(output_data);
|
|
||||||
|
|
||||||
dprintf("Y3WS: Sent %d card(s) to the client\n", count);
|
|
||||||
|
|
||||||
cJSON_Delete(response);
|
|
||||||
FindClose(hFind);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void y3ws_read_card_image(char* file_name, char* output_data, size_t* output_size) {
|
|
||||||
wchar_t path[MAX_PATH];
|
|
||||||
swprintf(path, MAX_PATH, L"%ls\\%hs", cfg.card_path, file_name);
|
|
||||||
|
|
||||||
HANDLE hImage = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
if (hImage == INVALID_HANDLE_VALUE) {
|
|
||||||
dprintf("Y3WS: Failed to access file: %ls (%ld)\n", path, GetLastError());
|
|
||||||
y3ws_make_error_packet("Could not read file", output_data, output_size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD size = GetFileSize(hImage, NULL);
|
|
||||||
if (size == INVALID_FILE_SIZE) {
|
|
||||||
dprintf("Y3WS: Failed to access file size: %ls (%ld)\n", path, GetLastError());
|
|
||||||
y3ws_make_error_packet("Could not read file", output_data, output_size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* buf = malloc(size);
|
|
||||||
size_t b64size = ((size * 4) / 3) + (size / 96) + 6;
|
|
||||||
char* b64buf = malloc(b64size);
|
|
||||||
if (buf == NULL) {
|
|
||||||
dprintf("Y3WS: Allocation error for file: %ls (%ld)\n", path, GetLastError());
|
|
||||||
y3ws_make_error_packet("Could not read file", output_data, output_size);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD bytesRead = 0;
|
|
||||||
if (!ReadFile(hImage, buf, size, &bytesRead, NULL) || bytesRead != size) {
|
|
||||||
dprintf("Y3WS: File read failed: %ls (%ld)\n", path, GetLastError());
|
|
||||||
y3ws_make_error_packet("Could not read file", output_data, output_size);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
b64size = base64_encode(buf, size, b64buf);
|
|
||||||
|
|
||||||
if (b64size + 100 > *output_size) {
|
|
||||||
dprintf("Y3WS: Encoded file size exceeds buffer: %ls (%lld / %lld)\n", path, b64size, *output_size);
|
|
||||||
y3ws_make_error_packet("File too large", output_data, output_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
*output_size = sprintf_s((char*)output_data, *output_size, "{\"version\":%d, \"success\":true,\"data\":\"%s\"}", PROTOCOL_VERSION, (char*)b64buf);
|
|
||||||
end:
|
|
||||||
free(buf);
|
|
||||||
free(b64buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void y3ws_set_cards_from_json(const cJSON* cards, char* output_data, size_t* output_size) {
|
|
||||||
|
|
||||||
const cJSON* card = NULL;
|
|
||||||
card_info_size = 0;
|
|
||||||
|
|
||||||
EnterCriticalSection(&card_info_lock);
|
|
||||||
memset(card_info, 0, sizeof(card_info));
|
|
||||||
cJSON_ArrayForEach(card, cards) {
|
|
||||||
cJSON* x = cJSON_GetObjectItemCaseSensitive(card, "x");
|
|
||||||
cJSON* y = cJSON_GetObjectItemCaseSensitive(card, "y");
|
|
||||||
cJSON* r = cJSON_GetObjectItemCaseSensitive(card, "rotation");
|
|
||||||
cJSON* id = cJSON_GetObjectItemCaseSensitive(card, "card_id");
|
|
||||||
|
|
||||||
if (cJSON_IsNumber(x) && cJSON_IsNumber(y) && cJSON_IsNumber(r) && cJSON_IsNumber(id)) {
|
|
||||||
card_info[card_info_size].eCardStatus = VALID;
|
|
||||||
card_info[card_info_size].fX = (float)x->valuedouble;
|
|
||||||
card_info[card_info_size].fY = (float)y->valuedouble;
|
|
||||||
card_info[card_info_size].fAngle = (float)r->valuedouble;
|
|
||||||
card_info[card_info_size].uID = id->valueint;
|
|
||||||
} else {
|
|
||||||
dprintf("Y3WS: Invalid object in card array at index %d\n", card_info_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (++card_info_size >= GAME_MAX_CARDS) {
|
|
||||||
dprintf("Y3WS: too many cards specified, truncating!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
LeaveCriticalSection(&card_info_lock);
|
|
||||||
y3ws_make_success_packet(output_data, output_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void y3ws_handle(const char* input_data, uint32_t input_length, char* output_data, size_t* output_size) {
|
|
||||||
cJSON* json = cJSON_ParseWithLength(input_data, input_length);
|
|
||||||
if (json == NULL) {
|
|
||||||
const char *error_ptr = cJSON_GetErrorPtr();
|
|
||||||
|
|
||||||
dprintf("Y3WS: Invalid JSON received!\n");
|
|
||||||
dprintf("Y3WS: Message was: %s\n", input_data);
|
|
||||||
dprintf("Y3WS: Error at: %s\n", error_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
const cJSON* ver = cJSON_GetObjectItemCaseSensitive(json, "version");
|
|
||||||
const cJSON* cmd = cJSON_GetObjectItemCaseSensitive(json, "command");
|
|
||||||
|
|
||||||
if (!cJSON_IsNumber(ver) || ver->valueint <= 0) {
|
|
||||||
y3ws_make_error_packet("Missing version attribute", output_data, output_size);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
if (!cJSON_IsString(cmd)) {
|
|
||||||
y3ws_make_error_packet("Missing command attribute", output_data, output_size);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
if (ver->valueint != PROTOCOL_VERSION) {
|
|
||||||
y3ws_make_error_packet("Incompatible version", output_data, output_size);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(cmd->valuestring, "ping") == 0) {
|
|
||||||
y3ws_make_success_packet(output_data, output_size);
|
|
||||||
} else if (strcmp(cmd->valuestring, "get_game_id") == 0) {
|
|
||||||
*output_size = sprintf_s((char*)output_data, *output_size, "{\"version\":%d, \"success\":true,\"game_id\":\"%s\"}", PROTOCOL_VERSION, cfg.game_id);
|
|
||||||
} else if (strcmp(cmd->valuestring, "get_cards") == 0) {
|
|
||||||
y3ws_read_cards(output_data, output_size);
|
|
||||||
} else if (strcmp(cmd->valuestring, "get_card_image") == 0) {
|
|
||||||
const cJSON* path = cJSON_GetObjectItemCaseSensitive(json, "path");
|
|
||||||
if (cJSON_IsString(path)) {
|
|
||||||
y3ws_read_card_image(path->valuestring, output_data, output_size);
|
|
||||||
} else {
|
|
||||||
y3ws_make_error_packet("Missing attribute", output_data, output_size);
|
|
||||||
}
|
|
||||||
} else if (strcmp(cmd->valuestring, "set_field") == 0) {
|
|
||||||
const cJSON* cards = cJSON_GetObjectItemCaseSensitive(json, "cards");
|
|
||||||
if (cJSON_IsArray(cards)) {
|
|
||||||
y3ws_set_cards_from_json(cards, output_data, output_size);
|
|
||||||
} else {
|
|
||||||
y3ws_make_error_packet("Missing attribute", output_data, output_size);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
y3ws_make_error_packet("Unknown command", output_data, output_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
|
||||||
cJSON_Delete(json);
|
|
||||||
}
|
|
||||||
#pragma endregion
|
|
||||||
|
|
||||||
#pragma region websocket callbacks
|
|
||||||
|
|
||||||
static void onopen(struct wws_connection* client) {
|
|
||||||
dprintf("Y3WS: Connection opened, addr: %s\n", client->ip_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void onclose(struct wws_connection* client) {
|
|
||||||
dprintf("Y3WS: Connection closed, addr: %s\n", client->ip_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void onmessage(struct wws_connection* client, const char* msg, size_t size) {
|
|
||||||
if (cfg.debug) {
|
|
||||||
dprintf("Y3WS: Message: %.*s\n", (int)size, msg);
|
|
||||||
}
|
|
||||||
char* out_buf = malloc(OUTPUT_BUFFER_SIZE);
|
|
||||||
if (out_buf == NULL) {
|
|
||||||
dprintf("Y3WS: out of memory for allocating response buffer\n");
|
|
||||||
client->is_connected = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
size_t out_size = OUTPUT_BUFFER_SIZE;
|
|
||||||
|
|
||||||
y3ws_handle(msg, size, out_buf, &out_size);
|
|
||||||
HRESULT hr = wws_send(client, out_buf, out_size);
|
|
||||||
if (!SUCCEEDED(hr)) {
|
|
||||||
dprintf("Y3WS: Error sending message: %lx\n", hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(out_buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void onlog(const char* format, ...) {
|
|
||||||
va_list args;
|
|
||||||
va_start (args, format);
|
|
||||||
dprintf("Websocket: ");
|
|
||||||
dprintfv(format, args);
|
|
||||||
va_end (args);
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma endregion
|
|
@ -1,4 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <windows.h>
|
|
@ -1,31 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include "hooklib/y3.h"
|
|
||||||
|
|
||||||
/* Get the version of the Y3 IO API that this DLL supports. This
|
|
||||||
function should return a positive 16-bit integer, where the high byte is
|
|
||||||
the major version and the low byte is the minor version (as defined by the
|
|
||||||
Semantic Versioning standard).
|
|
||||||
|
|
||||||
The latest API version as of this writing is 0x0100. */
|
|
||||||
uint16_t y3_io_get_api_version();
|
|
||||||
|
|
||||||
/* Initialize the Y3 board. This function will be called before any other
|
|
||||||
y3_io_*() function calls. Errors returned from this function will
|
|
||||||
manifest as a disconnected Y3 board.
|
|
||||||
|
|
||||||
This method may be called multiple times.
|
|
||||||
|
|
||||||
Minimum API version: 0x0100 */
|
|
||||||
HRESULT y3_io_init();
|
|
||||||
|
|
||||||
/* Fills the given buffer with cards that are detected on the play field.
|
|
||||||
For the values inside CardInfo, see y3.h.
|
|
||||||
The input value of numCards is the size of the pCardInfo array.
|
|
||||||
The output value of numCards is how many cards (>=0) have been set in pCardInfo.
|
|
||||||
|
|
||||||
Minimum API version: 0x0100 */
|
|
||||||
HRESULT y3_io_get_cards(struct CardInfo* pCardInfo, int* numCards);
|
|
@ -1,25 +0,0 @@
|
|||||||
y3io_lib = static_library(
|
|
||||||
'y3io',
|
|
||||||
name_prefix : '',
|
|
||||||
include_directories: inc,
|
|
||||||
implicit_include_directories : false,
|
|
||||||
dependencies : [
|
|
||||||
capnhook.get_variable('hook_dep'),
|
|
||||||
capnhook.get_variable('hooklib_dep'),
|
|
||||||
cwinwebsocket.get_variable('cws_dep'),
|
|
||||||
],
|
|
||||||
link_with : [
|
|
||||||
util_lib,
|
|
||||||
],
|
|
||||||
sources : [
|
|
||||||
'impl/websockets/config.c',
|
|
||||||
'impl/websockets/config.h',
|
|
||||||
'impl/websockets/y3ws.c',
|
|
||||||
'impl/websockets/y3ws.h',
|
|
||||||
'impl/websockets/3rdparty/cjson/cJSON.c',
|
|
||||||
'impl/websockets/3rdparty/cjson/cJSON.h',
|
|
||||||
'impl/websockets/3rdparty/cjson/cJSON_Utils.c',
|
|
||||||
'impl/websockets/3rdparty/cjson/cJSON_Utils.h',
|
|
||||||
'impl/y3io.h',
|
|
||||||
],
|
|
||||||
)
|
|
224
dist/ekt/card_player.html
vendored
224
dist/ekt/card_player.html
vendored
@ -1,224 +0,0 @@
|
|||||||
<!-- very basic thing, I can't do UX/CSS/design, don't blame me, I'm a network engineer lmao -->
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Taisen Card Field</title>
|
|
||||||
</head>
|
|
||||||
<style>
|
|
||||||
html, body {
|
|
||||||
width: 99%;
|
|
||||||
height: 99%;
|
|
||||||
}
|
|
||||||
.playfield {
|
|
||||||
width: 79%;
|
|
||||||
height: 100%;
|
|
||||||
float: left;
|
|
||||||
border: 1px solid black;
|
|
||||||
}
|
|
||||||
.card_menu {
|
|
||||||
width: 20%;
|
|
||||||
height: 100%;
|
|
||||||
border: 1px solid black;
|
|
||||||
overflow-x: hidden;
|
|
||||||
overflow-y: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
width: 200px;
|
|
||||||
transform: rotate(-90deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
#playfield .card {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
#status {
|
|
||||||
margin-bottom: 50px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
|
||||||
var VERSION = 1;
|
|
||||||
|
|
||||||
var socket;
|
|
||||||
var state = 0;
|
|
||||||
var game_id;
|
|
||||||
var cards = [];
|
|
||||||
var current_card_fetch = 0;
|
|
||||||
|
|
||||||
function send(obj){
|
|
||||||
if (!socket){ return; }
|
|
||||||
var data = JSON.stringify(obj);
|
|
||||||
console.log("Sending: " + data);
|
|
||||||
socket.send(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
function connect(){
|
|
||||||
socket = new WebSocket("ws://127.0.0.1:3594/y3io");
|
|
||||||
|
|
||||||
socket.onopen = function(e) {
|
|
||||||
document.getElementById("status").innerText = "Connected. Loading information...";
|
|
||||||
state = 0;
|
|
||||||
send({
|
|
||||||
version: VERSION,
|
|
||||||
command: "get_game_id"
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.onmessage = function(event) {
|
|
||||||
console.log("Received: " + event.data);
|
|
||||||
handle_response(JSON.parse(event.data));
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.onclose = function(event) {
|
|
||||||
state = -1;
|
|
||||||
document.getElementById("status").innerHTML = "Disconnected. <a href='javascript:window.location.reload();'>Reconnect</a>";
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.onerror = function(error) {
|
|
||||||
console.log(error);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function handle_response(obj){
|
|
||||||
if (!obj.success){
|
|
||||||
alert("Error receiving data while in state " + state + ": " + obj.error);
|
|
||||||
socket.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (state == 0){
|
|
||||||
game_id = obj.game_id;
|
|
||||||
document.getElementById("status").innerText = "Connected to "+game_id+". Loading cards...";
|
|
||||||
state = 1;
|
|
||||||
send({
|
|
||||||
version: VERSION,
|
|
||||||
command: "get_cards"
|
|
||||||
});
|
|
||||||
} else if (state == 1){
|
|
||||||
cards = obj.cards;
|
|
||||||
document.getElementById("status").innerText = "Connected to "+game_id+". Loading card images...";
|
|
||||||
document.getElementById("cards").innerHTML = "";
|
|
||||||
document.getElementById("playfield").innerHTML = "";
|
|
||||||
current_card_fetch = 0;
|
|
||||||
state = 2;
|
|
||||||
if (cards.length > 0){
|
|
||||||
fetch_next_card();
|
|
||||||
} else {
|
|
||||||
document.getElementById("status").innerText = "Connected to "+game_id+". No cards available.";
|
|
||||||
}
|
|
||||||
} else if (state == 2){
|
|
||||||
cards[current_card_fetch].image = obj.data;
|
|
||||||
document.getElementById("cards").innerHTML += "<img class='card' src='data:image/bmp;base64, "+obj.data+"' onclick='spawn_card("+current_card_fetch+");' />";
|
|
||||||
|
|
||||||
if (++current_card_fetch >= cards.length){
|
|
||||||
document.getElementById("status").innerText = "Connected to "+game_id+".";
|
|
||||||
state = 3;
|
|
||||||
} else {
|
|
||||||
fetch_next_card();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function fetch_next_card(){
|
|
||||||
var p = cards[current_card_fetch].path;
|
|
||||||
if (!p.includes("_front")){
|
|
||||||
current_card_fetch++;
|
|
||||||
fetch_next_card();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
send({
|
|
||||||
version: VERSION,
|
|
||||||
command: "get_card_image",
|
|
||||||
path: p
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function spawn_card(i){
|
|
||||||
if (state != 3){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById("playfield").innerHTML += "<img class='card' src='data:image/bmp;base64, "+cards[i].image+"' onmousedown='startMoving(event, this, "+i+");' />";
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_pos(i, x, y){
|
|
||||||
if (state != 3){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var panelHeight = 1272;
|
|
||||||
var panelWidth = 1260;
|
|
||||||
|
|
||||||
cards[i].x = panelHeight - ((y / window.screen.height) * panelHeight);
|
|
||||||
cards[i].y = panelWidth - ((x / window.screen.width) * panelWidth);
|
|
||||||
cards[i].rotation = 0;
|
|
||||||
|
|
||||||
|
|
||||||
var list = [];
|
|
||||||
for (var j = 0; j < cards.length; j++){
|
|
||||||
var c = cards[j];
|
|
||||||
if (c.x && c.y){
|
|
||||||
list.push({
|
|
||||||
card_id: c.card_id,
|
|
||||||
x: c.x,
|
|
||||||
y: c.y,
|
|
||||||
rotation: c.rotation
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
send({
|
|
||||||
version: VERSION,
|
|
||||||
command: "set_field",
|
|
||||||
cards: list
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<script>
|
|
||||||
var mousePosition;
|
|
||||||
var offset = [-75,-75];
|
|
||||||
var div;
|
|
||||||
var current_card = -1;
|
|
||||||
var isDown = false;
|
|
||||||
|
|
||||||
function startMoving(e, el, card){
|
|
||||||
div = el;
|
|
||||||
isDown = true;
|
|
||||||
current_card = card;
|
|
||||||
offset = [
|
|
||||||
div.offsetLeft - e.clientX,
|
|
||||||
div.offsetTop - e.clientY
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener('mouseup', function() {
|
|
||||||
isDown = false;
|
|
||||||
current_card = -1;
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
document.addEventListener('mousemove', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
if (isDown) {
|
|
||||||
mousePosition = {
|
|
||||||
|
|
||||||
x : event.clientX,
|
|
||||||
y : event.clientY
|
|
||||||
|
|
||||||
};
|
|
||||||
div.style.left = (mousePosition.x + offset[0]) + 'px';
|
|
||||||
div.style.top = (mousePosition.y + offset[1]) + 'px';
|
|
||||||
update_pos(current_card, event.clientX, event.clientY);
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
</script>
|
|
||||||
<body onload="connect();">
|
|
||||||
<div id="playfield" class="playfield">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="card_menu">
|
|
||||||
<div id="status">Please wait...</div>
|
|
||||||
<div id="cards">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
13
dist/ekt/config_hook.json
vendored
13
dist/ekt/config_hook.json
vendored
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"common": {
|
|
||||||
"language": "english"
|
|
||||||
},
|
|
||||||
"network": {
|
|
||||||
"property": {
|
|
||||||
"dhcp": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"allnet_auth": {
|
|
||||||
"type": "1.0"
|
|
||||||
}
|
|
||||||
}
|
|
18
dist/ekt/launch_satellite.bat
vendored
18
dist/ekt/launch_satellite.bat
vendored
@ -1,18 +0,0 @@
|
|||||||
@echo off
|
|
||||||
set SEGATOOLS_CONFIG_PATH=.\segatools_satellite.ini
|
|
||||||
|
|
||||||
pushd %~dp0
|
|
||||||
|
|
||||||
start "AM Daemon" /min inject -d -k ekthook.dll ..\PackageBase\amdaemon.exe -c ..\PackageBase\config_sate.json config_hook.json
|
|
||||||
|
|
||||||
pushd ..\PackageBase\am_capture
|
|
||||||
start "AM Capture" /min AmCapture.exe
|
|
||||||
popd
|
|
||||||
|
|
||||||
inject -d -k ekthook.dll ekt.exe -logfile satellite.log -screen-fullscreen 1 -screen-width 1920 -screen-height 1080 -screen-quality Ultra -silent-crashes
|
|
||||||
|
|
||||||
taskkill /f /im amdaemon.exe > nul 2>&1
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo Game processes have terminated
|
|
||||||
pause
|
|
13
dist/ekt/launch_terminal.bat
vendored
13
dist/ekt/launch_terminal.bat
vendored
@ -1,13 +0,0 @@
|
|||||||
@echo off
|
|
||||||
set SEGATOOLS_CONFIG_PATH=.\segatools_terminal.ini
|
|
||||||
|
|
||||||
pushd %~dp0
|
|
||||||
|
|
||||||
start "AM Daemon" /min inject -d -k ekthook.dll ..\PackageBase\amdaemon.exe -c ..\PackageBase\config_terminal.json config_hook.json
|
|
||||||
inject -d -k ekthook.dll ekt.exe -terminal -logfile terminal.log -screen-fullscreen 1 -screen-width 1920 -screen-height 1080 -screen-quality Ultra -silent-crashes
|
|
||||||
|
|
||||||
taskkill /f /im amdaemon.exe > nul 2>&1
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo Game processes have terminated
|
|
||||||
pause
|
|
179
dist/ekt/segatools_satellite.ini
vendored
179
dist/ekt/segatools_satellite.ini
vendored
@ -1,179 +0,0 @@
|
|||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Path settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[vfs]
|
|
||||||
; Insert the path to the game AMFS directory here (contains ICF1 and ICF2)
|
|
||||||
amfs=
|
|
||||||
; Insert the path to the game Option directory here (contains Axxx directories)
|
|
||||||
option=
|
|
||||||
; Create an empty directory somewhere and insert the path here.
|
|
||||||
; This directory may be shared between multiple SEGA games.
|
|
||||||
; NOTE: This has nothing to do with Windows %APPDATA%.
|
|
||||||
appdata=
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Device settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[aime]
|
|
||||||
; Enable Aime card reader assembly emulation. Disable to use a real SEGA Aime
|
|
||||||
; reader.
|
|
||||||
enable=1
|
|
||||||
aimePath=DEVICE\aime.txt
|
|
||||||
|
|
||||||
; Virtual-key code. If this button is **held** then the emulated IC card reader
|
|
||||||
; emulates an IC card in its proximity. A variety of different IC cards can be
|
|
||||||
; emulated; the exact choice of card that is emulated depends on the presence or
|
|
||||||
; absence of the configured card ID files. Default is the Return key.
|
|
||||||
scan=0x0D
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Network settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[dns]
|
|
||||||
; Insert the hostname or IP address of the server you wish to use here.
|
|
||||||
; Note that 127.0.0.1, localhost etc are specifically rejected.
|
|
||||||
default=127.0.0.1
|
|
||||||
|
|
||||||
[netenv]
|
|
||||||
; Simulate an ideal LAN environment. This may interfere with head-to-head play.
|
|
||||||
; SEGA games are somewhat picky about their LAN environment, so leaving this
|
|
||||||
; setting enabled is recommended.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Board settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[keychip]
|
|
||||||
; Keychip serial number. Keychip serials observed in the wild follow this
|
|
||||||
; pattern: `A\d{2}(E|X)-(01|20)[ABCDU]\d{8}`.
|
|
||||||
id=A69E-01A88888888
|
|
||||||
|
|
||||||
; The /24 LAN subnet that the emulated keychip will tell the game to expect.
|
|
||||||
; If you disable netenv then you must set this to your LAN's IP subnet, and
|
|
||||||
; that subnet must start with 192.168.
|
|
||||||
subnet=192.168.189.0
|
|
||||||
|
|
||||||
; Override the game's four-character platform code (e.g. `AAV2` for Nu 2). This
|
|
||||||
; is actually supposed to be a separate three-character `platformId` and
|
|
||||||
; integer `modelType` setting, but they are combined here for convenience.
|
|
||||||
; 1 = Terminal (TM)
|
|
||||||
; 2 = Satellite (ST)
|
|
||||||
platformId=ACA2
|
|
||||||
|
|
||||||
[system]
|
|
||||||
; Enable ALLS system settings.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; LAN Install: If multiple machines are present on the same LAN then set
|
|
||||||
; this to 0 on exactly one machine and set this to 1 on all others.
|
|
||||||
dipsw1=0
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Misc. hooks settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[unity]
|
|
||||||
; Path to a .NET DLL that should run before the game. Useful for loading
|
|
||||||
; modding frameworks such as BepInEx.
|
|
||||||
targetAssembly=
|
|
||||||
|
|
||||||
[flatPanelReader]
|
|
||||||
; Enable the Y3 board emulation.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
[y3ws]
|
|
||||||
; Enable the Y3 websocket server.
|
|
||||||
enable=1
|
|
||||||
; Set the TCP port on which the Y3 websocket server runs.
|
|
||||||
port=3594
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; LED settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[led15093]
|
|
||||||
; Enable the 837-15093-06 board emulation.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Custom IO settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[aimeio]
|
|
||||||
; To use a custom card reader IO DLL enter its path here.
|
|
||||||
; Leave empty if you want to use Segatools built-in keyboard input.
|
|
||||||
path=
|
|
||||||
|
|
||||||
[ektio]
|
|
||||||
; To use a custom Eiketsu Taisen IO DLL enter its path here.
|
|
||||||
; Leave empty if you want to use Segatools built-in keyboard/gamepad input.
|
|
||||||
path=
|
|
||||||
|
|
||||||
[y3io]
|
|
||||||
; To use a custom Y3 IO DLL enter its path here.
|
|
||||||
; Leave empty if you want to use ... TBA ...
|
|
||||||
path=
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Input settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
; Keyboard bindings are as hexadecimal (prefixed with 0x) or decimal
|
|
||||||
; (not prefixed with 0x) virtual-key codes, a list of which can be found here:
|
|
||||||
;
|
|
||||||
; https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
|
|
||||||
;
|
|
||||||
; This is, admittedly, not the most user-friendly configuration method in the
|
|
||||||
; world. An improved solution will be provided later.
|
|
||||||
|
|
||||||
[io4]
|
|
||||||
; Test button virtual-key code. Default is the F1 key.
|
|
||||||
test=0x70
|
|
||||||
; Service button virtual-key code. Default is the F2 key.
|
|
||||||
service=0x71
|
|
||||||
; Keyboard button to increment coin counter. Default is the F3 key.
|
|
||||||
coin=0x72
|
|
||||||
|
|
||||||
; SW1. Default is the 4 key.
|
|
||||||
sw1=0x34
|
|
||||||
; SW2. Default is the 5 key.
|
|
||||||
sw2=0x35
|
|
||||||
|
|
||||||
; Input API selection for IO4 input emulator.
|
|
||||||
; For now only "keyboard" is supported.
|
|
||||||
mode=keyboard
|
|
||||||
|
|
||||||
[keyboard]
|
|
||||||
|
|
||||||
menu=0x41
|
|
||||||
start=0x42
|
|
||||||
stratagem=0x43
|
|
||||||
stratagem_lock=0x44
|
|
||||||
hougu=0x45
|
|
||||||
ryuuha=0x46
|
|
||||||
|
|
||||||
tenkey_0=0x60
|
|
||||||
tenkey_1=0x61
|
|
||||||
tenkey_2=0x62
|
|
||||||
tenkey_3=0x63
|
|
||||||
tenkey_4=0x64
|
|
||||||
tenkey_5=0x65
|
|
||||||
tenkey_6=0x66
|
|
||||||
tenkey_7=0x67
|
|
||||||
tenkey_8=0x68
|
|
||||||
tenkey_9=0x69
|
|
||||||
tenkey_clear=0x6E
|
|
||||||
tenkey_enter=0x0D
|
|
||||||
|
|
||||||
vol_up=0x21
|
|
||||||
vol_down=0x22
|
|
||||||
|
|
||||||
trackball_up=0x26
|
|
||||||
trackball_right=0x27
|
|
||||||
trackball_down=0x28
|
|
||||||
trackball_left=0x25
|
|
||||||
speed_modifier=10
|
|
149
dist/ekt/segatools_terminal.ini
vendored
149
dist/ekt/segatools_terminal.ini
vendored
@ -1,149 +0,0 @@
|
|||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Path settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[vfs]
|
|
||||||
; Insert the path to the game AMFS directory here (contains ICF1 and ICF2)
|
|
||||||
amfs=
|
|
||||||
; Insert the path to the game Option directory here (contains Axxx directories)
|
|
||||||
option=
|
|
||||||
; Create an empty directory somewhere and insert the path here.
|
|
||||||
; This directory may be shared between multiple SEGA games.
|
|
||||||
; NOTE: This has nothing to do with Windows %APPDATA%.
|
|
||||||
appdata=
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Device settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[aime]
|
|
||||||
; Enable Aime card reader assembly emulation. Disable to use a real SEGA Aime
|
|
||||||
; reader.
|
|
||||||
enable=1
|
|
||||||
aimePath=DEVICE\aime.txt
|
|
||||||
|
|
||||||
; Virtual-key code. If this button is **held** then the emulated IC card reader
|
|
||||||
; emulates an IC card in its proximity. A variety of different IC cards can be
|
|
||||||
; emulated; the exact choice of card that is emulated depends on the presence or
|
|
||||||
; absence of the configured card ID files. Default is the Return key.
|
|
||||||
scan=0x0D
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Network settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[dns]
|
|
||||||
; Insert the hostname or IP address of the server you wish to use here.
|
|
||||||
; Note that 127.0.0.1, localhost etc are specifically rejected.
|
|
||||||
default=127.0.0.1
|
|
||||||
|
|
||||||
[netenv]
|
|
||||||
; Simulate an ideal LAN environment. This may interfere with head-to-head play.
|
|
||||||
; SEGA games are somewhat picky about their LAN environment, so leaving this
|
|
||||||
; setting enabled is recommended.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Board settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[keychip]
|
|
||||||
; Keychip serial number. Keychip serials observed in the wild follow this
|
|
||||||
; pattern: `A\d{2}(E|X)-(01|20)[ABCDU]\d{8}`.
|
|
||||||
id=A69E-01A88888888
|
|
||||||
|
|
||||||
; The /24 LAN subnet that the emulated keychip will tell the game to expect.
|
|
||||||
; If you disable netenv then you must set this to your LAN's IP subnet, and
|
|
||||||
; that subnet must start with 192.168.
|
|
||||||
subnet=192.168.189.0
|
|
||||||
|
|
||||||
; Override the game's four-character platform code (e.g. `AAV2` for Nu 2). This
|
|
||||||
; is actually supposed to be a separate three-character `platformId` and
|
|
||||||
; integer `modelType` setting, but they are combined here for convenience.
|
|
||||||
; 1 = Terminal (TM)
|
|
||||||
; 2 = Satellite (ST)
|
|
||||||
platformId=ACA1
|
|
||||||
|
|
||||||
[system]
|
|
||||||
; Enable ALLS system settings.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; LAN Install: If multiple machines are present on the same LAN then set
|
|
||||||
; this to 0 on exactly one machine and set this to 1 on all others.
|
|
||||||
dipsw1=0
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Misc. hooks settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[unity]
|
|
||||||
; Enable Unity hook. This will allow you to run custom .NET code before the game
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; Path to a .NET DLL that should run before the game. Useful for loading
|
|
||||||
; modding frameworks such as BepInEx.
|
|
||||||
targetAssembly=
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; LED settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[led15093]
|
|
||||||
; Enable the 837-15093-06 board emulation.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Custom IO settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[aimeio]
|
|
||||||
; To use a custom card reader IO DLL enter its path here.
|
|
||||||
; Leave empty if you want to use Segatools built-in keyboard input.
|
|
||||||
path=
|
|
||||||
|
|
||||||
[ektio]
|
|
||||||
; To use a custom Eiketsu Taisen IO DLL enter its path here.
|
|
||||||
; Leave empty if you want to use Segatools built-in keyboard/gamepad input.
|
|
||||||
path=
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Input settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
; Keyboard bindings are as hexadecimal (prefixed with 0x) or decimal
|
|
||||||
; (not prefixed with 0x) virtual-key codes, a list of which can be found here:
|
|
||||||
;
|
|
||||||
; https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
|
|
||||||
;
|
|
||||||
; This is, admittedly, not the most user-friendly configuration method in the
|
|
||||||
; world. An improved solution will be provided later.
|
|
||||||
|
|
||||||
[io4]
|
|
||||||
; Test button virtual-key code. Default is the F1 key.
|
|
||||||
test=0x70
|
|
||||||
; Service button virtual-key code. Default is the F2 key.
|
|
||||||
service=0x71
|
|
||||||
; Keyboard button to increment coin counter. Default is the F3 key.
|
|
||||||
coin=0x72
|
|
||||||
|
|
||||||
; SW1. Default is the 4 key.
|
|
||||||
sw1=0x34
|
|
||||||
; SW2. Default is the 5 key.
|
|
||||||
sw2=0x35
|
|
||||||
|
|
||||||
; Input API selection for IO4 input emulator.
|
|
||||||
; For now only "keyboard" is supported.
|
|
||||||
mode=keyboard
|
|
||||||
|
|
||||||
[keyboard]
|
|
||||||
|
|
||||||
cancel=0x53
|
|
||||||
decide=0x41
|
|
||||||
|
|
||||||
up=0x26
|
|
||||||
right=0x27
|
|
||||||
down=0x28
|
|
||||||
left=0x25
|
|
||||||
|
|
||||||
left_2=0x4F
|
|
||||||
right_2=0x57
|
|
228
dist/sekito/card_player.html
vendored
228
dist/sekito/card_player.html
vendored
@ -1,228 +0,0 @@
|
|||||||
<!-- very basic thing, I can't do UX/CSS/design, don't blame me, I'm a network engineer lmao -->
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Taisen Card Field</title>
|
|
||||||
</head>
|
|
||||||
<style>
|
|
||||||
html, body {
|
|
||||||
width: 99%;
|
|
||||||
height: 99%;
|
|
||||||
}
|
|
||||||
.playfield {
|
|
||||||
width: 79%;
|
|
||||||
height: 100%;
|
|
||||||
float: left;
|
|
||||||
border: 1px solid black;
|
|
||||||
}
|
|
||||||
.card_menu {
|
|
||||||
width: 20%;
|
|
||||||
height: 100%;
|
|
||||||
border: 1px solid black;
|
|
||||||
overflow-x: hidden;
|
|
||||||
overflow-y: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
width: 200px;
|
|
||||||
transform: rotate(-90deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
#playfield .card {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
#status {
|
|
||||||
margin-bottom: 50px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
|
||||||
var VERSION = 1;
|
|
||||||
|
|
||||||
var socket;
|
|
||||||
var state = 0;
|
|
||||||
var game_id;
|
|
||||||
var cards = [];
|
|
||||||
var current_card_fetch = 0;
|
|
||||||
|
|
||||||
function send(obj){
|
|
||||||
if (!socket){ return; }
|
|
||||||
var data = JSON.stringify(obj);
|
|
||||||
console.log("Sending: " + data);
|
|
||||||
socket.send(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
function connect(){
|
|
||||||
socket = new WebSocket("ws://127.0.0.1:3594/y3io");
|
|
||||||
|
|
||||||
socket.onopen = function(e) {
|
|
||||||
document.getElementById("status").innerText = "Connected. Loading information...";
|
|
||||||
state = 0;
|
|
||||||
send({
|
|
||||||
version: VERSION,
|
|
||||||
command: "get_game_id"
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.onmessage = function(event) {
|
|
||||||
console.log("Received: " + event.data);
|
|
||||||
handle_response(JSON.parse(event.data));
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.onclose = function(event) {
|
|
||||||
state = -1;
|
|
||||||
document.getElementById("status").innerHTML = "Disconnected. <a href='javascript:window.location.reload();'>Reconnect</a>";
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.onerror = function(error) {
|
|
||||||
console.log(error);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function handle_response(obj){
|
|
||||||
if (!obj.success){
|
|
||||||
alert("Error receiving data while in state " + state + ": " + obj.error);
|
|
||||||
socket.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (state == 0){
|
|
||||||
game_id = obj.game_id;
|
|
||||||
document.getElementById("status").innerText = "Connected to "+game_id+". Loading cards...";
|
|
||||||
state = 1;
|
|
||||||
send({
|
|
||||||
version: VERSION,
|
|
||||||
command: "get_cards"
|
|
||||||
});
|
|
||||||
} else if (state == 1){
|
|
||||||
cards = obj.cards;
|
|
||||||
document.getElementById("status").innerText = "Connected to "+game_id+". Loading card images...";
|
|
||||||
document.getElementById("cards").innerHTML = "";
|
|
||||||
document.getElementById("playfield").innerHTML = "";
|
|
||||||
current_card_fetch = 0;
|
|
||||||
state = 2;
|
|
||||||
if (cards.length > 0){
|
|
||||||
fetch_next_card();
|
|
||||||
} else {
|
|
||||||
document.getElementById("status").innerText = "Connected to "+game_id+". No cards available.";
|
|
||||||
}
|
|
||||||
} else if (state == 2){
|
|
||||||
cards[current_card_fetch].image = obj.data;
|
|
||||||
document.getElementById("cards").innerHTML += "<img class='card' src='data:image/bmp;base64, "+obj.data+"' onclick='spawn_card("+current_card_fetch+");' />";
|
|
||||||
|
|
||||||
if (++current_card_fetch >= cards.length){
|
|
||||||
document.getElementById("status").innerText = "Connected to "+game_id+".";
|
|
||||||
state = 3;
|
|
||||||
} else {
|
|
||||||
fetch_next_card();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function fetch_next_card(){
|
|
||||||
var p = cards[current_card_fetch].path;
|
|
||||||
if (p.includes("holo")){
|
|
||||||
if (++current_card_fetch >= cards.length){
|
|
||||||
document.getElementById("status").innerText = "Connected to "+game_id+".";
|
|
||||||
state = 3;
|
|
||||||
} else {
|
|
||||||
fetch_next_card();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
send({
|
|
||||||
version: VERSION,
|
|
||||||
command: "get_card_image",
|
|
||||||
path: p
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function spawn_card(i){
|
|
||||||
if (state != 3){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById("playfield").innerHTML += "<img class='card' src='data:image/bmp;base64, "+cards[i].image+"' onmousedown='startMoving(event, this, "+i+");' />";
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_pos(i, x, y){
|
|
||||||
if (state != 3){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var panelHeight = 1272;
|
|
||||||
var panelWidth = 1260;
|
|
||||||
|
|
||||||
cards[i].x = panelHeight - ((y / window.screen.height) * panelHeight);
|
|
||||||
cards[i].y = panelWidth - ((x / window.screen.width) * panelWidth);
|
|
||||||
cards[i].rotation = 0;
|
|
||||||
|
|
||||||
|
|
||||||
var list = [];
|
|
||||||
for (var j = 0; j < cards.length; j++){
|
|
||||||
var c = cards[j];
|
|
||||||
if (c.x && c.y){
|
|
||||||
list.push({
|
|
||||||
card_id: c.card_id,
|
|
||||||
x: c.x,
|
|
||||||
y: c.y,
|
|
||||||
rotation: c.rotation
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
send({
|
|
||||||
version: VERSION,
|
|
||||||
command: "set_field",
|
|
||||||
cards: list
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<script>
|
|
||||||
var mousePosition;
|
|
||||||
var offset = [-75,-75];
|
|
||||||
var div;
|
|
||||||
var current_card = -1;
|
|
||||||
var isDown = false;
|
|
||||||
|
|
||||||
function startMoving(e, el, card){
|
|
||||||
div = el;
|
|
||||||
isDown = true;
|
|
||||||
current_card = card;
|
|
||||||
offset = [
|
|
||||||
div.offsetLeft - e.clientX,
|
|
||||||
div.offsetTop - e.clientY
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener('mouseup', function() {
|
|
||||||
isDown = false;
|
|
||||||
current_card = -1;
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
document.addEventListener('mousemove', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
if (isDown) {
|
|
||||||
mousePosition = {
|
|
||||||
|
|
||||||
x : event.clientX,
|
|
||||||
y : event.clientY
|
|
||||||
|
|
||||||
};
|
|
||||||
div.style.left = (mousePosition.x + offset[0]) + 'px';
|
|
||||||
div.style.top = (mousePosition.y + offset[1]) + 'px';
|
|
||||||
update_pos(current_card, event.clientX, event.clientY);
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
</script>
|
|
||||||
<body onload="connect();">
|
|
||||||
<div id="playfield" class="playfield">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="card_menu">
|
|
||||||
<div id="status">Please wait...</div>
|
|
||||||
<div id="cards">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
16
dist/sekito/config_hook.json
vendored
16
dist/sekito/config_hook.json
vendored
@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"common": {
|
|
||||||
"language": "english"
|
|
||||||
},
|
|
||||||
"network": {
|
|
||||||
"property": {
|
|
||||||
"dhcp": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"allnet_auth": {
|
|
||||||
"type": "1.0"
|
|
||||||
},
|
|
||||||
"aime": {
|
|
||||||
"firmware_path": []
|
|
||||||
}
|
|
||||||
}
|
|
15
dist/sekito/launch_satellite.bat
vendored
15
dist/sekito/launch_satellite.bat
vendored
@ -1,15 +0,0 @@
|
|||||||
@echo off
|
|
||||||
set SEGATOOLS_CONFIG_PATH=.\segatools_satellite.ini
|
|
||||||
|
|
||||||
pushd %~dp0
|
|
||||||
|
|
||||||
start "AM Daemon" /min inject_x64 -d -k sekitohook_x64.dll bin\amdaemon.exe -c bin\config_new.json -c bin\config_video_single.json -c bin\config_video_multi.json -c bin\config_input_sate.json -c bin\config_input_terminal.json -c bin\config_input_terminal_exp.json -c config_hook.json
|
|
||||||
|
|
||||||
inject_x86 -d -k sekitohook_x86.dll bin\appSate.exe
|
|
||||||
|
|
||||||
taskkill /f /im appSate.exe > nul 2>&1
|
|
||||||
taskkill /f /im amdaemon.exe > nul 2>&1
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo Game processes have terminated
|
|
||||||
pause
|
|
19
dist/sekito/launch_terminal.bat
vendored
19
dist/sekito/launch_terminal.bat
vendored
@ -1,19 +0,0 @@
|
|||||||
@echo off
|
|
||||||
set SEGATOOLS_CONFIG_PATH=.\segatools_terminal.ini
|
|
||||||
|
|
||||||
pushd %~dp0
|
|
||||||
|
|
||||||
start "AM Daemon" /min inject_x64 -d -k sekitohook_x64.dll bin\amdaemon.exe -c bin\config_new.json -c bin\config_video_single.json -c bin\config_video_multi.json -c bin\config_input_sate.json -c bin\config_input_terminal.json -c bin\config_input_terminal_exp.json -c config_hook.json
|
|
||||||
|
|
||||||
call bin\server\server_start.bat
|
|
||||||
|
|
||||||
inject_x86 -d -k sekitohook_x86.dll bin\appTerminal.exe
|
|
||||||
|
|
||||||
taskkill /f /im appTerminal.exe > nul 2>&1
|
|
||||||
taskkill /f /im amdaemon.exe > nul 2>&1
|
|
||||||
|
|
||||||
call bin\server\server_stop.bat
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo Game processes have terminated
|
|
||||||
pause
|
|
192
dist/sekito/segatools_satellite.ini
vendored
192
dist/sekito/segatools_satellite.ini
vendored
@ -1,192 +0,0 @@
|
|||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Path settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[vfs]
|
|
||||||
; Insert the path to the game AMFS directory here (contains ICF1 and ICF2)
|
|
||||||
amfs=
|
|
||||||
; Insert the path to the game Option directory here (contains Axxx directories)
|
|
||||||
option=
|
|
||||||
; Create an empty directory somewhere and insert the path here.
|
|
||||||
; This directory may be shared between multiple SEGA games.
|
|
||||||
; NOTE: This has nothing to do with Windows %APPDATA%.
|
|
||||||
appdata=
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Device settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[aime]
|
|
||||||
; Enable Aime card reader assembly emulation. Disable to use a real SEGA Aime
|
|
||||||
; reader.
|
|
||||||
enable=1
|
|
||||||
aimePath=DEVICE\aime.txt
|
|
||||||
|
|
||||||
; Virtual-key code. If this button is **held** then the emulated IC card reader
|
|
||||||
; emulates an IC card in its proximity. A variety of different IC cards can be
|
|
||||||
; emulated; the exact choice of card that is emulated depends on the presence or
|
|
||||||
; absence of the configured card ID files. Default is the Return key.
|
|
||||||
scan=0x0D
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Network settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[dns]
|
|
||||||
; Insert the hostname or IP address of the server you wish to use here.
|
|
||||||
; Note that 127.0.0.1, localhost etc are specifically rejected.
|
|
||||||
default=127.0.0.1
|
|
||||||
|
|
||||||
[netenv]
|
|
||||||
; Simulate an ideal LAN environment. This may interfere with head-to-head play.
|
|
||||||
; SEGA games are somewhat picky about their LAN environment, so leaving this
|
|
||||||
; setting enabled is recommended.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Board settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[keychip]
|
|
||||||
; Keychip serial number. Keychip serials observed in the wild follow this
|
|
||||||
; pattern: `A\d{2}(E|X)-(01|20)[ABCDU]\d{8}`.
|
|
||||||
id=A69E-01A88888888
|
|
||||||
|
|
||||||
; The /24 LAN subnet that the emulated keychip will tell the game to expect.
|
|
||||||
; If you disable netenv then you must set this to your LAN's IP subnet, and
|
|
||||||
; that subnet must start with 192.168.
|
|
||||||
subnet=192.168.189.0
|
|
||||||
|
|
||||||
; Override the game's four-character platform code (e.g. `AAV2` for Nu 2). This
|
|
||||||
; is actually supposed to be a separate three-character `platformId` and
|
|
||||||
; integer `modelType` setting, but they are combined here for convenience.
|
|
||||||
; 1 = Terminal (TM)
|
|
||||||
; 2 = Satellite (ST)
|
|
||||||
platformId=AAV2
|
|
||||||
|
|
||||||
[system]
|
|
||||||
; Enable ALLS system settings.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; LAN Install: If multiple machines are present on the same LAN then set
|
|
||||||
; this to 0 on exactly one machine and set this to 1 on all others.
|
|
||||||
dipsw1=0
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Misc. hooks settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[printer]
|
|
||||||
; Sinfonia CHC-C320 printer emulation setting.
|
|
||||||
enable=1
|
|
||||||
; Change the printer serial number here.
|
|
||||||
serial_no="5A-A123"
|
|
||||||
; Insert the path to the image output directory here.
|
|
||||||
printerOutPath="DEVICE\print"
|
|
||||||
|
|
||||||
[gfx]
|
|
||||||
; Enables the graphics hook.
|
|
||||||
enable=1
|
|
||||||
; Force the game to run windowed.
|
|
||||||
windowed=1
|
|
||||||
; Add a frame to the game window if running windowed.
|
|
||||||
framed=0
|
|
||||||
; Select the monitor to run the game on. (Fullscreen only, 0 =primary screen)
|
|
||||||
monitor=0
|
|
||||||
; Enable DPI awareness for the game process, preventing Windows from stretching the game window if a DPI scaling higher than 100% is used
|
|
||||||
dpiAware=1
|
|
||||||
|
|
||||||
[flatPanelReader]
|
|
||||||
; Enable the Y3 board emulation.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
[y3ws]
|
|
||||||
; Enable the Y3 websocket server.
|
|
||||||
enable=1
|
|
||||||
; Set the TCP port on which the Y3 websocket server runs.
|
|
||||||
port=3594
|
|
||||||
; Game ID used for clients.
|
|
||||||
gameId=SDDD
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; LED settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[led15093]
|
|
||||||
; Enable the 837-15093-06 board emulation.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Custom IO settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[aimeio]
|
|
||||||
; To use a custom card reader IO DLL enter its path here.
|
|
||||||
; Leave empty if you want to use Segatools built-in keyboard input.
|
|
||||||
path=
|
|
||||||
|
|
||||||
[ektio]
|
|
||||||
; To use a custom Eiketsu Taisen IO DLL enter its path here.
|
|
||||||
; Leave empty if you want to use Segatools built-in keyboard/gamepad input.
|
|
||||||
path=
|
|
||||||
|
|
||||||
[y3io]
|
|
||||||
; To use a custom Y3 IO DLL enter its path here.
|
|
||||||
; Leave empty if you want to use ... TBA ...
|
|
||||||
path=
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Input settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
; Keyboard bindings are as hexadecimal (prefixed with 0x) or decimal
|
|
||||||
; (not prefixed with 0x) virtual-key codes, a list of which can be found here:
|
|
||||||
;
|
|
||||||
; https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
|
|
||||||
;
|
|
||||||
; This is, admittedly, not the most user-friendly configuration method in the
|
|
||||||
; world. An improved solution will be provided later.
|
|
||||||
|
|
||||||
[io4]
|
|
||||||
; Test button virtual-key code. Default is the F1 key.
|
|
||||||
test=0x70
|
|
||||||
; Service button virtual-key code. Default is the F2 key.
|
|
||||||
service=0x71
|
|
||||||
; Keyboard button to increment coin counter. Default is the F3 key.
|
|
||||||
coin=0x72
|
|
||||||
|
|
||||||
; SW1. Default is the 4 key.
|
|
||||||
sw1=0x34
|
|
||||||
; SW2. Default is the 5 key.
|
|
||||||
sw2=0x35
|
|
||||||
|
|
||||||
; Input API selection for IO4 input emulator.
|
|
||||||
; For now only "keyboard" is supported.
|
|
||||||
mode=keyboard
|
|
||||||
|
|
||||||
[keyboard]
|
|
||||||
|
|
||||||
menu=0x41
|
|
||||||
start=0x42
|
|
||||||
stratagem=0x43
|
|
||||||
stratagem_lock=0x44
|
|
||||||
hougu=0x45
|
|
||||||
|
|
||||||
tenkey_0=0x60
|
|
||||||
tenkey_1=0x61
|
|
||||||
tenkey_2=0x62
|
|
||||||
tenkey_3=0x63
|
|
||||||
tenkey_4=0x64
|
|
||||||
tenkey_5=0x65
|
|
||||||
tenkey_6=0x66
|
|
||||||
tenkey_7=0x67
|
|
||||||
tenkey_8=0x68
|
|
||||||
tenkey_9=0x69
|
|
||||||
tenkey_clear=0x6E
|
|
||||||
tenkey_enter=0x0D
|
|
||||||
|
|
||||||
trackball_up=0x26
|
|
||||||
trackball_right=0x27
|
|
||||||
trackball_down=0x28
|
|
||||||
trackball_left=0x25
|
|
||||||
speed_modifier=10
|
|
154
dist/sekito/segatools_terminal.ini
vendored
154
dist/sekito/segatools_terminal.ini
vendored
@ -1,154 +0,0 @@
|
|||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Path settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[vfs]
|
|
||||||
; Insert the path to the game AMFS directory here (contains ICF1 and ICF2)
|
|
||||||
amfs=
|
|
||||||
; Insert the path to the game Option directory here (contains Axxx directories)
|
|
||||||
option=
|
|
||||||
; Create an empty directory somewhere and insert the path here.
|
|
||||||
; This directory may be shared between multiple SEGA games.
|
|
||||||
; NOTE: This has nothing to do with Windows %APPDATA%.
|
|
||||||
appdata=
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Device settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[aime]
|
|
||||||
; Enable Aime card reader assembly emulation. Disable to use a real SEGA Aime
|
|
||||||
; reader.
|
|
||||||
enable=1
|
|
||||||
aimePath=DEVICE\aime.txt
|
|
||||||
|
|
||||||
; Virtual-key code. If this button is **held** then the emulated IC card reader
|
|
||||||
; emulates an IC card in its proximity. A variety of different IC cards can be
|
|
||||||
; emulated; the exact choice of card that is emulated depends on the presence or
|
|
||||||
; absence of the configured card ID files. Default is the Return key.
|
|
||||||
scan=0x0D
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Network settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[dns]
|
|
||||||
; Insert the hostname or IP address of the server you wish to use here.
|
|
||||||
; Note that 127.0.0.1, localhost etc are specifically rejected.
|
|
||||||
default=127.0.0.1
|
|
||||||
|
|
||||||
[netenv]
|
|
||||||
; Simulate an ideal LAN environment. This may interfere with head-to-head play.
|
|
||||||
; SEGA games are somewhat picky about their LAN environment, so leaving this
|
|
||||||
; setting enabled is recommended.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Board settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[keychip]
|
|
||||||
; Keychip serial number. Keychip serials observed in the wild follow this
|
|
||||||
; pattern: `A\d{2}(E|X)-(01|20)[ABCDU]\d{8}`.
|
|
||||||
id=A69E-01A88888888
|
|
||||||
|
|
||||||
; The /24 LAN subnet that the emulated keychip will tell the game to expect.
|
|
||||||
; If you disable netenv then you must set this to your LAN's IP subnet, and
|
|
||||||
; that subnet must start with 192.168.
|
|
||||||
subnet=192.168.189.0
|
|
||||||
|
|
||||||
; Override the game's four-character platform code (e.g. `AAV2` for Nu 2). This
|
|
||||||
; is actually supposed to be a separate three-character `platformId` and
|
|
||||||
; integer `modelType` setting, but they are combined here for convenience.
|
|
||||||
; 1 = Terminal (TM)
|
|
||||||
; 2 = Satellite (ST)
|
|
||||||
platformId=AAV1
|
|
||||||
|
|
||||||
[system]
|
|
||||||
; Enable ALLS system settings.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; LAN Install: If multiple machines are present on the same LAN then set
|
|
||||||
; this to 0 on exactly one machine and set this to 1 on all others.
|
|
||||||
dipsw1=0
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Misc. hooks settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[gfx]
|
|
||||||
; Enables the graphics hook.
|
|
||||||
enable=1
|
|
||||||
; Force the game to run windowed.
|
|
||||||
windowed=1
|
|
||||||
; Add a frame to the game window if running windowed.
|
|
||||||
framed=0
|
|
||||||
; Select the monitor to run the game on. (Fullscreen only, 0 =primary screen)
|
|
||||||
monitor=0
|
|
||||||
; Enable DPI awareness for the game process, preventing Windows from stretching the game window if a DPI scaling higher than 100% is used
|
|
||||||
dpiAware=1
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; LED settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[led15093]
|
|
||||||
; Enable the 837-15093-06 board emulation.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Custom IO settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[aimeio]
|
|
||||||
; To use a custom card reader IO DLL enter its path here.
|
|
||||||
; Leave empty if you want to use Segatools built-in keyboard input.
|
|
||||||
path=
|
|
||||||
|
|
||||||
[ektio]
|
|
||||||
; To use a custom Eiketsu Taisen IO DLL enter its path here.
|
|
||||||
; Leave empty if you want to use Segatools built-in keyboard/gamepad input.
|
|
||||||
path=
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Input settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
; Keyboard bindings are as hexadecimal (prefixed with 0x) or decimal
|
|
||||||
; (not prefixed with 0x) virtual-key codes, a list of which can be found here:
|
|
||||||
;
|
|
||||||
; https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
|
|
||||||
;
|
|
||||||
; This is, admittedly, not the most user-friendly configuration method in the
|
|
||||||
; world. An improved solution will be provided later.
|
|
||||||
|
|
||||||
[io4]
|
|
||||||
; Test button virtual-key code. Default is the F1 key.
|
|
||||||
test=0x70
|
|
||||||
; Service button virtual-key code. Default is the F2 key.
|
|
||||||
service=0x71
|
|
||||||
; Keyboard button to increment coin counter. Default is the F3 key.
|
|
||||||
coin=0x72
|
|
||||||
|
|
||||||
; SW1. Default is the 4 key.
|
|
||||||
sw1=0x34
|
|
||||||
; SW2. Default is the 5 key.
|
|
||||||
sw2=0x35
|
|
||||||
|
|
||||||
; Input API selection for IO4 input emulator.
|
|
||||||
; For now only "keyboard" is supported.
|
|
||||||
mode=keyboard
|
|
||||||
|
|
||||||
[keyboard]
|
|
||||||
|
|
||||||
cancel=0x53
|
|
||||||
decide=0x41
|
|
||||||
reserve=0x45
|
|
||||||
|
|
||||||
up=0x26
|
|
||||||
right=0x27
|
|
||||||
down=0x28
|
|
||||||
left=0x25
|
|
||||||
|
|
||||||
left_2=0x4F
|
|
||||||
right_2=0x57
|
|
@ -576,12 +576,6 @@ Default: `01:02:03:04:05:06`
|
|||||||
The MAC address of the virtualized Ethernet adapter. The exact value shouldn't
|
The MAC address of the virtualized Ethernet adapter. The exact value shouldn't
|
||||||
ever matter.
|
ever matter.
|
||||||
|
|
||||||
### `broadcast`
|
|
||||||
|
|
||||||
Default: `255.255.255.255`
|
|
||||||
|
|
||||||
The UDP broadcast address that should be used if packets are being sent to the virtual keychip's subnet. This is used for cab-to-cab communication (Local Play, Satellite to Terminal, etc.). Depending on your network adapters (VPNs etc), sometimes you must explicitely specify your real LANs subnet.
|
|
||||||
|
|
||||||
## `[pcbid]`
|
## `[pcbid]`
|
||||||
|
|
||||||
Configure Windows host name virtualization. The ALLS-series platform no longer
|
Configure Windows host name virtualization. The ALLS-series platform no longer
|
||||||
@ -669,4 +663,21 @@ Enables the Thinca emulation. This will allow you to enable E-Money on compatibl
|
|||||||
|
|
||||||
Default: `1`
|
Default: `1`
|
||||||
|
|
||||||
Enables hooking of respective Thinca DLL functions to emulate the existence of E-Money. This cannot be used with a real E-Money server.
|
Enables hooking of respective Thinca DLL functions to emulate the existence of E-Money. This cannot be used with a real E-Money server.
|
||||||
|
|
||||||
|
## `[openssl]`
|
||||||
|
|
||||||
|
Configure the OpenSSL SHA extension bug hook.
|
||||||
|
|
||||||
|
### `enable`
|
||||||
|
|
||||||
|
Default: `1`
|
||||||
|
|
||||||
|
Enables the OpenSSL hook to fix the SHA extension bug on Intel CPUs.
|
||||||
|
|
||||||
|
### `override`
|
||||||
|
|
||||||
|
Default: `0`
|
||||||
|
|
||||||
|
Enables the override to always hook the OpenSSL env variable. By default the
|
||||||
|
hook is only applied to Intel CPUs with the SHA extension present.
|
||||||
|
@ -1,107 +0,0 @@
|
|||||||
# Taisen configuration settings
|
|
||||||
|
|
||||||
This file describes configuration settings specific to the Taisen series.
|
|
||||||
|
|
||||||
Keyboard binding settings use
|
|
||||||
[Virtual-Key Codes](https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes).
|
|
||||||
|
|
||||||
## `[ektio]` / `[sekitoio]`
|
|
||||||
|
|
||||||
Controls the input driver.
|
|
||||||
|
|
||||||
### `path`
|
|
||||||
|
|
||||||
Specify a path for a third-party input driver DLL. Default is empty
|
|
||||||
(use built-in keyboard IO emulation).
|
|
||||||
|
|
||||||
## `[flatPanelReader]`
|
|
||||||
|
|
||||||
Controls settings for the Flat Panel (a.k.a. Y3 Board)
|
|
||||||
|
|
||||||
### `enable`
|
|
||||||
|
|
||||||
Default: `1`
|
|
||||||
|
|
||||||
Whether or not to enable Flat Panel emulation. Disable to use a real board.
|
|
||||||
|
|
||||||
### `port_field`
|
|
||||||
|
|
||||||
Default: `10`
|
|
||||||
|
|
||||||
The COM port on which the emulated Flat Panel is connected to. This differs per game.
|
|
||||||
|
|
||||||
### `port_printer`
|
|
||||||
|
|
||||||
Default: `11`
|
|
||||||
|
|
||||||
The COM port on which the emulated Printer Camera is connected to. This only exists in Sangokushi.
|
|
||||||
|
|
||||||
### `dllVersion`
|
|
||||||
|
|
||||||
Default: `1`
|
|
||||||
|
|
||||||
The version of the emulated Y3CodeReader dll. Unsure if that is used anywhere.
|
|
||||||
|
|
||||||
### `firmVersion`
|
|
||||||
|
|
||||||
Default: `1`
|
|
||||||
|
|
||||||
The version of the emulated Y3CodeReader firmware. Unsure if that is used anywhere.
|
|
||||||
|
|
||||||
### `firmNameField`
|
|
||||||
|
|
||||||
Default: `SFPR`
|
|
||||||
|
|
||||||
The device name of the emulated Flat Panel. This should never need changing.
|
|
||||||
|
|
||||||
### `firmNamePrinter`
|
|
||||||
|
|
||||||
Default: `SPRT`
|
|
||||||
|
|
||||||
The device name of the emulated Printer Camera. This should never need changing.
|
|
||||||
|
|
||||||
### `targetCodeField`
|
|
||||||
|
|
||||||
Default: `SFR0`
|
|
||||||
|
|
||||||
The target name of the emulated Flat Panel. This should never need changing.
|
|
||||||
|
|
||||||
### `targetCodePrinter`
|
|
||||||
|
|
||||||
Default: `SPT0`
|
|
||||||
|
|
||||||
The target name of the emulated Printer Camera. This should never need changing.
|
|
||||||
|
|
||||||
## `[y3ws]`
|
|
||||||
|
|
||||||
Settings for the default implementation of setting cards on the Flat Panel remotely via websockets
|
|
||||||
|
|
||||||
### `enable`
|
|
||||||
|
|
||||||
Default: `1`
|
|
||||||
|
|
||||||
Enable the websocket server.
|
|
||||||
|
|
||||||
### `debug`
|
|
||||||
|
|
||||||
Default: `0`
|
|
||||||
|
|
||||||
Makes y3ws I/O very verbose. For debugging only. May lag the game.
|
|
||||||
|
|
||||||
### `port`
|
|
||||||
|
|
||||||
Default: `3594`
|
|
||||||
|
|
||||||
The TCP port the websocket server listens on.
|
|
||||||
|
|
||||||
### `gameId`
|
|
||||||
|
|
||||||
Default: `SDEY`
|
|
||||||
|
|
||||||
The game ID that the websocket server transmits, so clients can change their behaviour based on that (UI, etc.)
|
|
||||||
|
|
||||||
### `cardDirectory`
|
|
||||||
|
|
||||||
Default: `DEVICE\print`
|
|
||||||
|
|
||||||
The directory where printed card images are placed. Should be the same as in `[printer]`.
|
|
57
doc/y3ws.txt
57
doc/y3ws.txt
@ -1,57 +0,0 @@
|
|||||||
Y3WS websocket protocol for card I/O for the Taisen series by Haruka:
|
|
||||||
|
|
||||||
Default listening port: 3594 (san-go-ku-shi)
|
|
||||||
|
|
||||||
All packets are JSON and, unless otherwise specified contain these fields:
|
|
||||||
|
|
||||||
* Requests:
|
|
||||||
{"version": 1, "command": "..."}
|
|
||||||
|
|
||||||
* Responses:
|
|
||||||
{"version": 1, "success": <bool>, "error": <null/string>}
|
|
||||||
|
|
||||||
Commands:
|
|
||||||
|
|
||||||
- ping
|
|
||||||
|
|
||||||
Does nothing except answering with a success response.
|
|
||||||
|
|
||||||
|
|
||||||
- get_game_id
|
|
||||||
|
|
||||||
Extra response fields:
|
|
||||||
- game_id: <string>
|
|
||||||
|
|
||||||
Returns the current game ID that is being run (SDDD, SDGY).
|
|
||||||
|
|
||||||
|
|
||||||
- get_cards
|
|
||||||
|
|
||||||
Extra response fields:
|
|
||||||
- cards: <array of objects>
|
|
||||||
- card_id: <long>
|
|
||||||
- path: <string>
|
|
||||||
|
|
||||||
Returns all cards that the player has in possession.
|
|
||||||
|
|
||||||
|
|
||||||
- get_card_image
|
|
||||||
|
|
||||||
Extra request fields:
|
|
||||||
- path: <string>
|
|
||||||
Extra response fields:
|
|
||||||
- data: <base64 encoded string>
|
|
||||||
|
|
||||||
Returns the card image for the given path (format TBA).
|
|
||||||
|
|
||||||
|
|
||||||
- set_field
|
|
||||||
|
|
||||||
Extra request fields:
|
|
||||||
- array of objects
|
|
||||||
- card_id: <long>
|
|
||||||
- x: <float>
|
|
||||||
- y: <float>
|
|
||||||
- rotation: <float>
|
|
||||||
|
|
||||||
Sets the given cards onto the given positions on the field. Always replaces the entire board.
|
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include "hooklib/dvd.h"
|
#include "hooklib/dvd.h"
|
||||||
#include "hooklib/touch.h"
|
#include "hooklib/touch.h"
|
||||||
#include "hooklib/printer_chc.h"
|
#include "hooklib/printer.h"
|
||||||
|
|
||||||
#include "gfxhook/config.h"
|
#include "gfxhook/config.h"
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ void cm_hook_config_load(
|
|||||||
io4_config_load(&cfg->io4, filename);
|
io4_config_load(&cfg->io4, filename);
|
||||||
vfd_config_load(&cfg->vfd, filename);
|
vfd_config_load(&cfg->vfd, filename);
|
||||||
touch_screen_config_load(&cfg->touch, filename);
|
touch_screen_config_load(&cfg->touch, filename);
|
||||||
printer_chc_config_load(&cfg->printer, filename);
|
printer_config_load(&cfg->printer, filename);
|
||||||
cm_dll_config_load(&cfg->dll, filename);
|
cm_dll_config_load(&cfg->dll, filename);
|
||||||
unity_config_load(&cfg->unity, filename);
|
unity_config_load(&cfg->unity, filename);
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "hooklib/dvd.h"
|
#include "hooklib/dvd.h"
|
||||||
#include "hooklib/touch.h"
|
#include "hooklib/touch.h"
|
||||||
#include "hooklib/printer_chc.h"
|
#include "hooklib/printer.h"
|
||||||
|
|
||||||
#include "cmhook/cm-dll.h"
|
#include "cmhook/cm-dll.h"
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ struct cm_hook_config {
|
|||||||
struct vfd_config vfd;
|
struct vfd_config vfd;
|
||||||
struct cm_dll_config dll;
|
struct cm_dll_config dll;
|
||||||
struct touch_screen_config touch;
|
struct touch_screen_config touch;
|
||||||
struct printer_chc_config printer;
|
struct printer_config printer;
|
||||||
struct unity_config unity;
|
struct unity_config unity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ static DWORD CALLBACK cm_pre_startup(void)
|
|||||||
|
|
||||||
/* Hook external DLL APIs */
|
/* Hook external DLL APIs */
|
||||||
|
|
||||||
printer_chc_hook_init(&cm_hook_cfg.printer, 0, cm_hook_mod);
|
printer_hook_init(&cm_hook_cfg.printer, 0, cm_hook_mod);
|
||||||
|
|
||||||
/* Initialize emulation hooks */
|
/* Initialize emulation hooks */
|
||||||
|
|
||||||
|
@ -1,107 +0,0 @@
|
|||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "board/config.h"
|
|
||||||
|
|
||||||
#include "ekthook/config.h"
|
|
||||||
#include "ekthook/ekt-dll.h"
|
|
||||||
|
|
||||||
#include "hooklib/config.h"
|
|
||||||
|
|
||||||
#include "platform/config.h"
|
|
||||||
|
|
||||||
void led15093_config_load(struct led15093_config *cfg, const wchar_t *filename)
|
|
||||||
{
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
|
|
||||||
wchar_t tmpstr[16];
|
|
||||||
|
|
||||||
memset(cfg->board_number, ' ', sizeof(cfg->board_number));
|
|
||||||
memset(cfg->chip_number, ' ', sizeof(cfg->chip_number));
|
|
||||||
memset(cfg->boot_chip_number, ' ', sizeof(cfg->boot_chip_number));
|
|
||||||
|
|
||||||
cfg->enable = GetPrivateProfileIntW(L"led15093", L"enable", 1, filename);
|
|
||||||
cfg->port_no[0] = GetPrivateProfileIntW(L"led15093", L"portNo1", 0, filename);
|
|
||||||
cfg->port_no[1] = GetPrivateProfileIntW(L"led15093", L"portNo2", 0, filename);
|
|
||||||
cfg->high_baudrate = GetPrivateProfileIntW(L"led15093", L"highBaud", 0, filename);
|
|
||||||
cfg->fw_ver = GetPrivateProfileIntW(L"led15093", L"fwVer", 0xA0, filename);
|
|
||||||
cfg->fw_sum = GetPrivateProfileIntW(L"led15093", L"fwSum", 0xAA53, filename);
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"led15093",
|
|
||||||
L"boardNumber",
|
|
||||||
L"15093-06",
|
|
||||||
tmpstr,
|
|
||||||
_countof(tmpstr),
|
|
||||||
filename);
|
|
||||||
|
|
||||||
size_t n = wcstombs(cfg->board_number, tmpstr, sizeof(cfg->board_number));
|
|
||||||
for (int i = n; i < sizeof(cfg->board_number); i++)
|
|
||||||
{
|
|
||||||
cfg->board_number[i] = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"led15093",
|
|
||||||
L"chipNumber",
|
|
||||||
L"6710A",
|
|
||||||
tmpstr,
|
|
||||||
_countof(tmpstr),
|
|
||||||
filename);
|
|
||||||
|
|
||||||
n = wcstombs(cfg->chip_number, tmpstr, sizeof(cfg->chip_number));
|
|
||||||
for (int i = n; i < sizeof(cfg->chip_number); i++)
|
|
||||||
{
|
|
||||||
cfg->chip_number[i] = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"led15093",
|
|
||||||
L"bootChipNumber",
|
|
||||||
L"6709 ",
|
|
||||||
tmpstr,
|
|
||||||
_countof(tmpstr),
|
|
||||||
filename);
|
|
||||||
|
|
||||||
n = wcstombs(cfg->boot_chip_number, tmpstr, sizeof(cfg->boot_chip_number));
|
|
||||||
for (int i = n; i < sizeof(cfg->boot_chip_number); i++)
|
|
||||||
{
|
|
||||||
cfg->boot_chip_number[i] = ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ekt_dll_config_load(
|
|
||||||
struct ekt_dll_config *cfg,
|
|
||||||
const wchar_t *filename)
|
|
||||||
{
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"ektio",
|
|
||||||
L"path",
|
|
||||||
L"",
|
|
||||||
cfg->path,
|
|
||||||
_countof(cfg->path),
|
|
||||||
filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ekt_hook_config_load(
|
|
||||||
struct ekt_hook_config *cfg,
|
|
||||||
const wchar_t *filename)
|
|
||||||
{
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
|
|
||||||
platform_config_load(&cfg->platform, filename);
|
|
||||||
aime_config_load(&cfg->aime, filename);
|
|
||||||
io4_config_load(&cfg->io4, filename);
|
|
||||||
dvd_config_load(&cfg->dvd, filename);
|
|
||||||
led15093_config_load(&cfg->led15093, filename);
|
|
||||||
y3_config_load(&cfg->y3, filename);
|
|
||||||
printer_cx_config_load(&cfg->printer, filename);
|
|
||||||
unity_config_load(&cfg->unity, filename);
|
|
||||||
ekt_dll_config_load(&cfg->dll, filename);
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "board/sg-reader.h"
|
|
||||||
#include "board/config.h"
|
|
||||||
#include "board/led15093.h"
|
|
||||||
|
|
||||||
#include "ekthook/ekt-dll.h"
|
|
||||||
|
|
||||||
#include "hooklib/config.h"
|
|
||||||
#include "hooklib/dvd.h"
|
|
||||||
#include "hooklib/printer_cx.h"
|
|
||||||
|
|
||||||
#include "platform/config.h"
|
|
||||||
|
|
||||||
#include "unityhook/config.h"
|
|
||||||
|
|
||||||
struct ekt_hook_config {
|
|
||||||
struct platform_config platform;
|
|
||||||
struct aime_config aime;
|
|
||||||
struct io4_config io4;
|
|
||||||
struct dvd_config dvd;
|
|
||||||
struct led15093_config led15093;
|
|
||||||
struct y3_config y3;
|
|
||||||
struct ekt_dll_config dll;
|
|
||||||
struct unity_config unity;
|
|
||||||
struct printer_cx_config printer;
|
|
||||||
};
|
|
||||||
|
|
||||||
void ekt_dll_config_load(
|
|
||||||
struct ekt_dll_config *cfg,
|
|
||||||
const wchar_t *filename);
|
|
||||||
|
|
||||||
void ekt_hook_config_load(
|
|
||||||
struct ekt_hook_config *cfg,
|
|
||||||
const wchar_t *filename);
|
|
@ -1,181 +0,0 @@
|
|||||||
/*
|
|
||||||
"Eiketsu Taisen" (ekt) hook
|
|
||||||
|
|
||||||
Devices
|
|
||||||
|
|
||||||
USB: 837-15257-01 "Type 4" I/O Board
|
|
||||||
|
|
||||||
[Satellite]
|
|
||||||
|
|
||||||
USB: 630-00011 G-Printec CX-7000 Printer
|
|
||||||
COM2: 837-15093-06 LED Controller Board
|
|
||||||
COM3: 837-15396 "Gen 3" Aime Reader
|
|
||||||
COM4: 601-13160-01 "Flat Panel Reader" Y3CR BD SIE F720MM Board
|
|
||||||
|
|
||||||
[Terminal]
|
|
||||||
|
|
||||||
COM1: 837-15396 "Gen 3" Aime Reader
|
|
||||||
COM3: 837-15093-06 LED Controller Board
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "ekt-dll.h"
|
|
||||||
#include "board/sg-reader.h"
|
|
||||||
#include "board/led15093.h"
|
|
||||||
|
|
||||||
#include "hook/process.h"
|
|
||||||
#include "hook/iohook.h"
|
|
||||||
|
|
||||||
#include "hooklib/serial.h"
|
|
||||||
#include "hooklib/spike.h"
|
|
||||||
|
|
||||||
#include "ekthook/config.h"
|
|
||||||
#include "ekthook/io4.h"
|
|
||||||
#include "hooklib/printer_cx.h"
|
|
||||||
|
|
||||||
#include "platform/platform.h"
|
|
||||||
|
|
||||||
#include "unityhook/hook.h"
|
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
#include "util/env.h"
|
|
||||||
#include "hooklib/y3-dll.h"
|
|
||||||
#include "hooklib/y3.h"
|
|
||||||
|
|
||||||
static HMODULE ekt_hook_mod;
|
|
||||||
static process_entry_t ekt_startup;
|
|
||||||
static struct ekt_hook_config ekt_hook_cfg;
|
|
||||||
|
|
||||||
static void unity_hook_callback(HMODULE hmodule, const wchar_t* p) {
|
|
||||||
netenv_hook_apply_hooks(hmodule);
|
|
||||||
}
|
|
||||||
|
|
||||||
static DWORD CALLBACK ekt_pre_startup(void)
|
|
||||||
{
|
|
||||||
HRESULT hr;
|
|
||||||
bool is_terminal;
|
|
||||||
|
|
||||||
dprintf("--- Begin ekt_pre_startup ---\n");
|
|
||||||
|
|
||||||
/* Load config */
|
|
||||||
|
|
||||||
ekt_hook_config_load(&ekt_hook_cfg, get_config_path());
|
|
||||||
|
|
||||||
/* Hook Win32 APIs */
|
|
||||||
|
|
||||||
dvd_hook_init(&ekt_hook_cfg.dvd, ekt_hook_mod);
|
|
||||||
serial_hook_init();
|
|
||||||
|
|
||||||
/* Hook external DLL APIs */
|
|
||||||
|
|
||||||
hr = y3_hook_init(&ekt_hook_cfg.y3, ekt_hook_mod, get_config_path());
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
printer_cx_hook_init(&ekt_hook_cfg.printer, ekt_hook_mod);
|
|
||||||
|
|
||||||
/* Initialize emulation hooks */
|
|
||||||
|
|
||||||
hr = platform_hook_init(
|
|
||||||
&ekt_hook_cfg.platform,
|
|
||||||
"SDGY",
|
|
||||||
"ACA1",
|
|
||||||
ekt_hook_mod);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize Terminal/Satellite hooks */
|
|
||||||
if (strncmp(ekt_hook_cfg.platform.nusec.platform_id, "ACA1", 4) == 0) {
|
|
||||||
// Terminal
|
|
||||||
is_terminal = true;
|
|
||||||
} else if (strncmp(ekt_hook_cfg.platform.nusec.platform_id, "ACA2", 4) == 0) {
|
|
||||||
// Satellite
|
|
||||||
is_terminal = false;
|
|
||||||
} else {
|
|
||||||
// Unknown
|
|
||||||
dprintf("Unknown platform ID: %s\n", ekt_hook_cfg.platform.nusec.platform_id);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
// LED: terminal uses COM 3 and satellite use COM 2
|
|
||||||
unsigned int led_port_no[2] = {is_terminal ? 3 : 2, 0};
|
|
||||||
|
|
||||||
// AIME: terminal uses COM 1 and satellite use COM 3
|
|
||||||
unsigned int aime_port_no = is_terminal ? 1 : 3;
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = ekt_dll_init(&ekt_hook_cfg.dll, ekt_hook_mod);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = ekt_io4_hook_init(&ekt_hook_cfg.io4, is_terminal);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = led15093_hook_init(&ekt_hook_cfg.led15093,
|
|
||||||
ekt_dll.led_init, ekt_dll.led_set_leds, led_port_no);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = sg_reader_hook_init(&ekt_hook_cfg.aime, aime_port_no, 3,
|
|
||||||
ekt_hook_mod);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize Unity native plugin DLL hooks
|
|
||||||
|
|
||||||
There seems to be an issue with other DLL hooks if `LoadLibraryW` is
|
|
||||||
hooked earlier in the `ekthook` initialization. */
|
|
||||||
|
|
||||||
unity_hook_init(&ekt_hook_cfg.unity, ekt_hook_mod, unity_hook_callback);
|
|
||||||
|
|
||||||
/* Initialize debug helpers */
|
|
||||||
|
|
||||||
spike_hook_init(get_config_path());
|
|
||||||
|
|
||||||
dprintf("--- End ekt_pre_startup ---\n");
|
|
||||||
|
|
||||||
/* Jump to EXE start address */
|
|
||||||
|
|
||||||
return ekt_startup();
|
|
||||||
|
|
||||||
fail:
|
|
||||||
ExitProcess(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL WINAPI DllMain(HMODULE mod, DWORD cause, void *ctx)
|
|
||||||
{
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
if (cause != DLL_PROCESS_ATTACH) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ekt_hook_mod = mod;
|
|
||||||
|
|
||||||
hr = process_hijack_startup(ekt_pre_startup, &ekt_startup);
|
|
||||||
|
|
||||||
if (!SUCCEEDED(hr)) {
|
|
||||||
dprintf("Failed to hijack process startup: %x\n", (int) hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return SUCCEEDED(hr);
|
|
||||||
}
|
|
@ -1,118 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "ekthook/ekt-dll.h"
|
|
||||||
|
|
||||||
#include "util/dll-bind.h"
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
|
|
||||||
const struct dll_bind_sym ekt_dll_syms[] = {
|
|
||||||
{
|
|
||||||
.sym = "ekt_io_init",
|
|
||||||
.off = offsetof(struct ekt_dll, init),
|
|
||||||
}, {
|
|
||||||
.sym = "ekt_io_poll",
|
|
||||||
.off = offsetof(struct ekt_dll, poll),
|
|
||||||
}, {
|
|
||||||
.sym = "ekt_io_get_opbtns",
|
|
||||||
.off = offsetof(struct ekt_dll, get_opbtns),
|
|
||||||
}, {
|
|
||||||
.sym = "ekt_io_get_gamebtns",
|
|
||||||
.off = offsetof(struct ekt_dll, get_gamebtns),
|
|
||||||
}, {
|
|
||||||
.sym = "ekt_io_get_trackball_position",
|
|
||||||
.off = offsetof(struct ekt_dll, get_trackball_position),
|
|
||||||
}, {
|
|
||||||
.sym = "ekt_io_led_init",
|
|
||||||
.off = offsetof(struct ekt_dll, led_init),
|
|
||||||
}, {
|
|
||||||
.sym = "ekt_io_led_set_colors",
|
|
||||||
.off = offsetof(struct ekt_dll, led_set_leds),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ekt_dll ekt_dll;
|
|
||||||
|
|
||||||
// Copypasta DLL binding and diagnostic message boilerplate.
|
|
||||||
// Not much of this lends itself to being easily factored out. Also there
|
|
||||||
// will be a lot of API-specific branching code here eventually as new API
|
|
||||||
// versions get defined, so even though these functions all look the same
|
|
||||||
// now this won't remain the case forever.
|
|
||||||
|
|
||||||
HRESULT ekt_dll_init(const struct ekt_dll_config *cfg, HINSTANCE self)
|
|
||||||
{
|
|
||||||
uint16_t (*get_api_version)(void);
|
|
||||||
const struct dll_bind_sym *sym;
|
|
||||||
HINSTANCE owned;
|
|
||||||
HINSTANCE src;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(self != NULL);
|
|
||||||
|
|
||||||
if (cfg->path[0] != L'\0') {
|
|
||||||
owned = LoadLibraryW(cfg->path);
|
|
||||||
|
|
||||||
if (owned == NULL) {
|
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
||||||
dprintf("EKT IO: Failed to load IO DLL: %lx: %S\n",
|
|
||||||
hr,
|
|
||||||
cfg->path);
|
|
||||||
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintf("EKT IO: Using custom IO DLL: %S\n", cfg->path);
|
|
||||||
src = owned;
|
|
||||||
} else {
|
|
||||||
owned = NULL;
|
|
||||||
src = self;
|
|
||||||
}
|
|
||||||
|
|
||||||
get_api_version = (void *) GetProcAddress(src, "ekt_io_get_api_version");
|
|
||||||
|
|
||||||
if (get_api_version != NULL) {
|
|
||||||
ekt_dll.api_version = get_api_version();
|
|
||||||
} else {
|
|
||||||
ekt_dll.api_version = 0x0100;
|
|
||||||
dprintf("Custom IO DLL does not expose ekt_io_get_api_version, "
|
|
||||||
"assuming API version 1.0.\n"
|
|
||||||
"Please ask the developer to update their DLL.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ekt_dll.api_version >= 0x0200) {
|
|
||||||
hr = E_NOTIMPL;
|
|
||||||
dprintf("EKT IO: Custom IO DLL implements an unsupported "
|
|
||||||
"API version (%#04x). Please update Segatools.\n",
|
|
||||||
ekt_dll.api_version);
|
|
||||||
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
sym = ekt_dll_syms;
|
|
||||||
hr = dll_bind(&ekt_dll, src, &sym, _countof(ekt_dll_syms));
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
if (src != self) {
|
|
||||||
dprintf("EKT IO: Custom IO DLL does not provide function "
|
|
||||||
"\"%s\". Please contact your IO DLL's developer for "
|
|
||||||
"further assistance.\n",
|
|
||||||
sym->sym);
|
|
||||||
|
|
||||||
goto end;
|
|
||||||
} else {
|
|
||||||
dprintf("Internal error: could not reflect \"%s\"\n", sym->sym);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
owned = NULL;
|
|
||||||
|
|
||||||
end:
|
|
||||||
if (owned != NULL) {
|
|
||||||
FreeLibrary(owned);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include "ektio/ektio.h"
|
|
||||||
|
|
||||||
struct ekt_dll {
|
|
||||||
uint16_t api_version;
|
|
||||||
HRESULT (*init)(void);
|
|
||||||
HRESULT (*poll)(void);
|
|
||||||
void (*get_opbtns)(uint8_t *opbtn);
|
|
||||||
void (*get_gamebtns)(uint32_t *gamebtn);
|
|
||||||
void (*get_trackball_position)(uint16_t *x, uint16_t *y);
|
|
||||||
HRESULT (*led_init)(void);
|
|
||||||
void (*led_set_leds)(uint8_t board, uint8_t *rgb);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ekt_dll_config {
|
|
||||||
wchar_t path[MAX_PATH];
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct ekt_dll ekt_dll;
|
|
||||||
|
|
||||||
HRESULT ekt_dll_init(const struct ekt_dll_config *cfg, HINSTANCE self);
|
|
@ -1,61 +0,0 @@
|
|||||||
LIBRARY ekthook
|
|
||||||
|
|
||||||
EXPORTS
|
|
||||||
aime_io_get_api_version
|
|
||||||
aime_io_init
|
|
||||||
aime_io_led_set_color
|
|
||||||
aime_io_nfc_get_aime_id
|
|
||||||
aime_io_nfc_get_felica_id
|
|
||||||
aime_io_nfc_poll
|
|
||||||
ekt_io_get_api_version
|
|
||||||
ekt_io_get_gamebtns
|
|
||||||
ekt_io_get_opbtns
|
|
||||||
ekt_io_get_trackball_position
|
|
||||||
ekt_io_init
|
|
||||||
ekt_io_poll
|
|
||||||
ekt_io_led_init
|
|
||||||
ekt_io_led_set_colors
|
|
||||||
y3_io_get_api_version
|
|
||||||
y3_io_init
|
|
||||||
y3_io_close
|
|
||||||
y3_io_get_cards
|
|
||||||
API_DLLVersion @1
|
|
||||||
API_GetLastError @2
|
|
||||||
API_GetErrorMessage @3
|
|
||||||
API_Connect @4
|
|
||||||
API_Close @5
|
|
||||||
API_Start @6
|
|
||||||
API_Stop @7
|
|
||||||
API_GetFirmVersion @8
|
|
||||||
API_GetFirmName @9
|
|
||||||
API_GetTargetCode @10
|
|
||||||
API_GetStatus @11
|
|
||||||
API_GetCounter @12
|
|
||||||
API_ClearError @13
|
|
||||||
API_Reset @14
|
|
||||||
API_GetCardInfo @15
|
|
||||||
API_GetCardInfoCharSize @16
|
|
||||||
API_SetDevice @17
|
|
||||||
API_SetCommand @18
|
|
||||||
API_FirmwareUpdate @19
|
|
||||||
API_Calibration @20
|
|
||||||
API_GetCalibrationResult @21
|
|
||||||
API_GetProcTime @22
|
|
||||||
API_GetMemStatus @23
|
|
||||||
API_GetMemCounter @24
|
|
||||||
API_SetSysControl @25
|
|
||||||
API_GetSysControl @26
|
|
||||||
API_SetParameter @27
|
|
||||||
API_GetParameter @28
|
|
||||||
API_TestReset @29
|
|
||||||
API_DebugReset @30
|
|
||||||
API_GetBoardType @31
|
|
||||||
API_GetCardDataSize @32
|
|
||||||
API_GetFirmDate @33
|
|
||||||
API_SystemCommand @34
|
|
||||||
API_CalcCheckSum @35
|
|
||||||
API_GetCheckSumResult @36
|
|
||||||
API_BlockRead @37
|
|
||||||
API_GetBlockReadResult @38
|
|
||||||
API_BlockWrite @39
|
|
||||||
API_GetDebugParam @40
|
|
@ -1,223 +0,0 @@
|
|||||||
#include "io4.h"
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "board/io4.h"
|
|
||||||
|
|
||||||
#include "ekthook/ekt-dll.h"
|
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
|
|
||||||
static HRESULT ekt_io4_poll(void *ctx, struct io4_state *state);
|
|
||||||
static uint16_t coins;
|
|
||||||
|
|
||||||
static const struct io4_ops ekt_io4_ops = {
|
|
||||||
.poll = ekt_io4_poll,
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool io_is_terminal;
|
|
||||||
|
|
||||||
HRESULT ekt_io4_hook_init(const struct io4_config *cfg, bool is_terminal)
|
|
||||||
{
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
assert(ekt_dll.init != NULL);
|
|
||||||
|
|
||||||
hr = io4_hook_init(cfg, &ekt_io4_ops, NULL);
|
|
||||||
|
|
||||||
io_is_terminal = is_terminal;
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ekt_dll.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT ekt_io4_poll(void *ctx, struct io4_state *state)
|
|
||||||
{
|
|
||||||
uint8_t opbtn;
|
|
||||||
uint16_t x, y;
|
|
||||||
uint32_t gamebtn;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
assert(ekt_dll.poll != NULL);
|
|
||||||
assert(ekt_dll.get_opbtns != NULL);
|
|
||||||
assert(ekt_dll.get_gamebtns != NULL);
|
|
||||||
assert(ekt_dll.get_trackball_position != NULL);
|
|
||||||
|
|
||||||
memset(state, 0, sizeof(*state));
|
|
||||||
|
|
||||||
hr = ekt_dll.poll();
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
opbtn = 0;
|
|
||||||
gamebtn = 0;
|
|
||||||
x = 0;
|
|
||||||
y = 0;
|
|
||||||
|
|
||||||
ekt_dll.get_opbtns(&opbtn);
|
|
||||||
ekt_dll.get_gamebtns(&gamebtn);
|
|
||||||
ekt_dll.get_trackball_position(&x, &y);
|
|
||||||
|
|
||||||
if (opbtn & EKT_IO_OPBTN_TEST) {
|
|
||||||
state->buttons[0] |= IO4_BUTTON_TEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opbtn & EKT_IO_OPBTN_SERVICE) {
|
|
||||||
state->buttons[0] |= IO4_BUTTON_SERVICE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opbtn & EKT_IO_OPBTN_SW1) {
|
|
||||||
state->buttons[0] |= 1 << 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opbtn & EKT_IO_OPBTN_SW2) {
|
|
||||||
state->buttons[0] |= 1 << 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opbtn & EKT_IO_OPBTN_COIN) {
|
|
||||||
coins++;
|
|
||||||
}
|
|
||||||
state->chutes[0] = coins << 8;
|
|
||||||
|
|
||||||
if (!io_is_terminal) {
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_HOUGU) {
|
|
||||||
state->buttons[1] |= 1 << 14;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_RYUUHA) {
|
|
||||||
state->buttons[1] |= 1 << 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_MENU) {
|
|
||||||
state->buttons[0] |= 1 << 13;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_START) {
|
|
||||||
state->buttons[0] |= 1 << 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_STRATAGEM) {
|
|
||||||
state->buttons[1] |= 1 << 15;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_STRATAGEM_LOCK) {
|
|
||||||
state->buttons[1] |= 1 << 13;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_VOL_DOWN) {
|
|
||||||
state->buttons[1] |= 1 << 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_VOL_UP) {
|
|
||||||
state->buttons[1] |= 1 << 11;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_NUMPAD_0) {
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_C2 : EKT_NUMPAD_TERM_C2;
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_R4 : EKT_NUMPAD_TERM_R4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_NUMPAD_1) {
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_C1 : EKT_NUMPAD_TERM_C1;
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_R1 : EKT_NUMPAD_TERM_R1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_NUMPAD_2) {
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_C2 : EKT_NUMPAD_TERM_C2;
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_R1 : EKT_NUMPAD_TERM_R1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_NUMPAD_3) {
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_C3 : EKT_NUMPAD_TERM_C3;
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_R1 : EKT_NUMPAD_TERM_R1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_NUMPAD_4) {
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_C1 : EKT_NUMPAD_TERM_C1;
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_R2 : EKT_NUMPAD_TERM_R2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_NUMPAD_5) {
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_C2 : EKT_NUMPAD_TERM_C2;
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_R2 : EKT_NUMPAD_TERM_R2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_NUMPAD_6) {
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_C3 : EKT_NUMPAD_TERM_C3;
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_R2 : EKT_NUMPAD_TERM_R2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_NUMPAD_7) {
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_C1 : EKT_NUMPAD_TERM_C1;
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_R3 : EKT_NUMPAD_TERM_R3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_NUMPAD_8) {
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_C2 : EKT_NUMPAD_TERM_C2;
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_R3 : EKT_NUMPAD_TERM_R3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_NUMPAD_9) {
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_C3 : EKT_NUMPAD_TERM_C3;
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_R3 : EKT_NUMPAD_TERM_R3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_NUMPAD_CLEAR) {
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_C1 : EKT_NUMPAD_TERM_C1;
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_R4 : EKT_NUMPAD_TERM_R4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_NUMPAD_ENTER) {
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_C3 : EKT_NUMPAD_TERM_C3;
|
|
||||||
state->buttons[0] |= !io_is_terminal ? EKT_NUMPAD_SATE_R4 : EKT_NUMPAD_TERM_R4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (io_is_terminal) {
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_TERMINAL_CANCEL) {
|
|
||||||
state->buttons[1] |= 1 << 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_TERMINAL_DECIDE) {
|
|
||||||
state->buttons[1] |= 1 << 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_TERMINAL_LEFT) {
|
|
||||||
state->buttons[0] |= 1 << 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_TERMINAL_UP) {
|
|
||||||
state->buttons[0] |= 1 << 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_TERMINAL_RIGHT) {
|
|
||||||
state->buttons[0] |= 1 << 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_TERMINAL_DOWN) {
|
|
||||||
state->buttons[0] |= 1 << 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_TERMINAL_LEFT_2) {
|
|
||||||
state->buttons[1] |= 1 << 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & EKT_IO_GAMEBTN_TERMINAL_RIGHT_2) {
|
|
||||||
state->buttons[1] |= 1 << 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
state->spinners[2] = x;
|
|
||||||
state->spinners[3] = y;
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include "board/io4.h"
|
|
||||||
|
|
||||||
enum {
|
|
||||||
EKT_NUMPAD_SATE_R1 = 1 << 1,
|
|
||||||
EKT_NUMPAD_SATE_R2 = 1 << 0,
|
|
||||||
EKT_NUMPAD_SATE_R3 = 1 << 15,
|
|
||||||
EKT_NUMPAD_SATE_R4 = 1 << 14,
|
|
||||||
EKT_NUMPAD_SATE_C1 = 1 << 12,
|
|
||||||
EKT_NUMPAD_SATE_C2 = 1 << 11,
|
|
||||||
EKT_NUMPAD_SATE_C3 = 1 << 10,
|
|
||||||
EKT_NUMPAD_TERM_R1 = 1 << 1,
|
|
||||||
EKT_NUMPAD_TERM_R2 = 1 << 0,
|
|
||||||
EKT_NUMPAD_TERM_R3 = 1 << 15,
|
|
||||||
EKT_NUMPAD_TERM_R4 = 1 << 14,
|
|
||||||
EKT_NUMPAD_TERM_C1 = 1 << 13,
|
|
||||||
EKT_NUMPAD_TERM_C2 = 1 << 12,
|
|
||||||
EKT_NUMPAD_TERM_C3 = 1 << 11,
|
|
||||||
};
|
|
||||||
|
|
||||||
HRESULT ekt_io4_hook_init(const struct io4_config *cfg, bool is_terminal);
|
|
@ -1,31 +0,0 @@
|
|||||||
shared_library(
|
|
||||||
'ekthook',
|
|
||||||
name_prefix : '',
|
|
||||||
include_directories : inc,
|
|
||||||
implicit_include_directories : false,
|
|
||||||
vs_module_defs : 'ekthook.def',
|
|
||||||
dependencies : [
|
|
||||||
capnhook.get_variable('hook_dep'),
|
|
||||||
capnhook.get_variable('hooklib_dep')
|
|
||||||
],
|
|
||||||
link_with : [
|
|
||||||
aimeio_lib,
|
|
||||||
board_lib,
|
|
||||||
ektio_lib,
|
|
||||||
hooklib_lib,
|
|
||||||
jvs_lib,
|
|
||||||
platform_lib,
|
|
||||||
unityhook_lib,
|
|
||||||
util_lib,
|
|
||||||
y3io_lib,
|
|
||||||
],
|
|
||||||
sources : [
|
|
||||||
'config.c',
|
|
||||||
'config.h',
|
|
||||||
'dllmain.c',
|
|
||||||
'ekt-dll.c',
|
|
||||||
'ekt-dll.h',
|
|
||||||
'io4.c',
|
|
||||||
'io4.h',
|
|
||||||
],
|
|
||||||
)
|
|
@ -1,10 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "ektio/ektio.h"
|
|
||||||
|
|
||||||
struct ekt_io_backend {
|
|
||||||
void (*get_gamebtns)(uint32_t *gamebtn);
|
|
||||||
void (*get_trackball)(uint16_t *x, uint16_t *y);
|
|
||||||
};
|
|
@ -1,77 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "ektio/config.h"
|
|
||||||
|
|
||||||
#include <xinput.h>
|
|
||||||
|
|
||||||
|
|
||||||
void ekt_kb_config_load(
|
|
||||||
struct ekt_kb_config *cfg,
|
|
||||||
const wchar_t *filename) {
|
|
||||||
|
|
||||||
cfg->vk_menu = GetPrivateProfileIntW(L"keyboard", L"menu", 'A', filename);
|
|
||||||
cfg->vk_start = GetPrivateProfileIntW(L"keyboard", L"start", 'S', filename);
|
|
||||||
cfg->vk_stratagem = GetPrivateProfileIntW(L"keyboard", L"stratagem", 'D', filename);
|
|
||||||
cfg->vk_stratagem_lock = GetPrivateProfileIntW(L"keyboard", L"stratagem_lock", 'F', filename);
|
|
||||||
cfg->vk_hougu = GetPrivateProfileIntW(L"keyboard", L"hougu", 'G', filename);
|
|
||||||
cfg->vk_ryuuha = GetPrivateProfileIntW(L"keyboard", L"ryuuha", 'H', filename);
|
|
||||||
|
|
||||||
cfg->vk_tenkey_0 = GetPrivateProfileIntW(L"keyboard", L"tenkey_0", VK_NUMPAD0, filename);
|
|
||||||
cfg->vk_tenkey_1 = GetPrivateProfileIntW(L"keyboard", L"tenkey_1", VK_NUMPAD1, filename);
|
|
||||||
cfg->vk_tenkey_2 = GetPrivateProfileIntW(L"keyboard", L"tenkey_2", VK_NUMPAD2, filename);
|
|
||||||
cfg->vk_tenkey_3 = GetPrivateProfileIntW(L"keyboard", L"tenkey_3", VK_NUMPAD3, filename);
|
|
||||||
cfg->vk_tenkey_4 = GetPrivateProfileIntW(L"keyboard", L"tenkey_4", VK_NUMPAD4, filename);
|
|
||||||
cfg->vk_tenkey_5 = GetPrivateProfileIntW(L"keyboard", L"tenkey_5", VK_NUMPAD5, filename);
|
|
||||||
cfg->vk_tenkey_6 = GetPrivateProfileIntW(L"keyboard", L"tenkey_6", VK_NUMPAD6, filename);
|
|
||||||
cfg->vk_tenkey_7 = GetPrivateProfileIntW(L"keyboard", L"tenkey_7", VK_NUMPAD7, filename);
|
|
||||||
cfg->vk_tenkey_8 = GetPrivateProfileIntW(L"keyboard", L"tenkey_8", VK_NUMPAD8, filename);
|
|
||||||
cfg->vk_tenkey_9 = GetPrivateProfileIntW(L"keyboard", L"tenkey_9", VK_NUMPAD9, filename);
|
|
||||||
cfg->vk_tenkey_clear = GetPrivateProfileIntW(L"keyboard", L"tenkey_clear", VK_DECIMAL, filename);
|
|
||||||
cfg->vk_tenkey_enter = GetPrivateProfileIntW(L"keyboard", L"tenkey_enter", VK_RETURN, filename);
|
|
||||||
|
|
||||||
cfg->vk_vol_down = GetPrivateProfileIntW(L"keyboard", L"vol_down", VK_NEXT, filename);
|
|
||||||
cfg->vk_vol_up = GetPrivateProfileIntW(L"keyboard", L"vol_up", VK_PRIOR, filename);
|
|
||||||
|
|
||||||
cfg->vk_terminal_decide = GetPrivateProfileIntW(L"keyboard", L"decide", 'A', filename);
|
|
||||||
cfg->vk_terminal_cancel = GetPrivateProfileIntW(L"keyboard", L"cancel", 'S', filename);
|
|
||||||
cfg->vk_terminal_up = GetPrivateProfileIntW(L"keyboard", L"up", VK_UP, filename);
|
|
||||||
cfg->vk_terminal_right = GetPrivateProfileIntW(L"keyboard", L"right", VK_RIGHT, filename);
|
|
||||||
cfg->vk_terminal_down = GetPrivateProfileIntW(L"keyboard", L"down", VK_DOWN, filename);
|
|
||||||
cfg->vk_terminal_left = GetPrivateProfileIntW(L"keyboard", L"left", VK_LEFT, filename);
|
|
||||||
cfg->vk_terminal_left_2 = GetPrivateProfileIntW(L"keyboard", L"left2", 'Q', filename);
|
|
||||||
cfg->vk_terminal_right_2 = GetPrivateProfileIntW(L"keyboard", L"right2", 'W', filename);
|
|
||||||
|
|
||||||
cfg->x_down = GetPrivateProfileIntW(L"keyboard", L"trackball_left", VK_LEFT, filename);
|
|
||||||
cfg->x_up = GetPrivateProfileIntW(L"keyboard", L"trackball_right", VK_RIGHT, filename);
|
|
||||||
cfg->y_down = GetPrivateProfileIntW(L"keyboard", L"trackball_up", VK_UP, filename);
|
|
||||||
cfg->y_up = GetPrivateProfileIntW(L"keyboard", L"trackball_down", VK_DOWN, filename);
|
|
||||||
cfg->speed = GetPrivateProfileIntW(L"keyboard", L"speed_modifier", 1, filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ekt_io_config_load(
|
|
||||||
struct ekt_io_config *cfg,
|
|
||||||
const wchar_t *filename)
|
|
||||||
{
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
|
|
||||||
cfg->vk_test = GetPrivateProfileIntW(L"io4", L"test", '1', filename);
|
|
||||||
cfg->vk_service = GetPrivateProfileIntW(L"io4", L"service", '2', filename);
|
|
||||||
cfg->vk_coin = GetPrivateProfileIntW(L"io4", L"coin", '3', filename);
|
|
||||||
cfg->vk_sw1 = GetPrivateProfileIntW(L"io4", L"sw1", '4', filename);
|
|
||||||
cfg->vk_sw2 = GetPrivateProfileIntW(L"io4", L"sw2", '5', filename);
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"io4",
|
|
||||||
L"mode",
|
|
||||||
L"keyboard",
|
|
||||||
cfg->mode,
|
|
||||||
_countof(cfg->mode),
|
|
||||||
filename);
|
|
||||||
|
|
||||||
ekt_kb_config_load(&cfg->kb, filename);
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
struct ekt_kb_config {
|
|
||||||
uint8_t vk_menu;
|
|
||||||
uint8_t vk_start;
|
|
||||||
uint8_t vk_stratagem;
|
|
||||||
uint8_t vk_stratagem_lock;
|
|
||||||
uint8_t vk_hougu;
|
|
||||||
uint8_t vk_ryuuha;
|
|
||||||
|
|
||||||
uint8_t vk_tenkey_0;
|
|
||||||
uint8_t vk_tenkey_1;
|
|
||||||
uint8_t vk_tenkey_2;
|
|
||||||
uint8_t vk_tenkey_3;
|
|
||||||
uint8_t vk_tenkey_4;
|
|
||||||
uint8_t vk_tenkey_5;
|
|
||||||
uint8_t vk_tenkey_6;
|
|
||||||
uint8_t vk_tenkey_7;
|
|
||||||
uint8_t vk_tenkey_8;
|
|
||||||
uint8_t vk_tenkey_9;
|
|
||||||
uint8_t vk_tenkey_clear;
|
|
||||||
uint8_t vk_tenkey_enter;
|
|
||||||
|
|
||||||
uint8_t vk_vol_down;
|
|
||||||
uint8_t vk_vol_up;
|
|
||||||
|
|
||||||
uint8_t vk_terminal_up;
|
|
||||||
uint8_t vk_terminal_right;
|
|
||||||
uint8_t vk_terminal_down;
|
|
||||||
uint8_t vk_terminal_left;
|
|
||||||
uint8_t vk_terminal_left_2;
|
|
||||||
uint8_t vk_terminal_right_2;
|
|
||||||
uint8_t vk_terminal_cancel;
|
|
||||||
uint8_t vk_terminal_decide;
|
|
||||||
|
|
||||||
uint8_t x_down;
|
|
||||||
uint8_t x_up;
|
|
||||||
uint8_t y_down;
|
|
||||||
uint8_t y_up;
|
|
||||||
uint8_t speed;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ekt_io_config {
|
|
||||||
uint8_t vk_test;
|
|
||||||
uint8_t vk_service;
|
|
||||||
uint8_t vk_coin;
|
|
||||||
uint8_t vk_sw1;
|
|
||||||
uint8_t vk_sw2;
|
|
||||||
|
|
||||||
wchar_t mode[12];
|
|
||||||
struct ekt_kb_config kb;
|
|
||||||
};
|
|
||||||
|
|
||||||
void ekt_kb_config_load(struct ekt_kb_config *cfg, const wchar_t *filename);
|
|
||||||
void ekt_io_config_load(
|
|
||||||
struct ekt_io_config *cfg,
|
|
||||||
const wchar_t *filename);
|
|
@ -1,108 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
#include <xinput.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "ektio/ektio.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "keyboard.h"
|
|
||||||
#include "ektio/config.h"
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
#include "util/env.h"
|
|
||||||
#include "util/str.h"
|
|
||||||
|
|
||||||
static uint8_t ekt_opbtn;
|
|
||||||
static uint32_t ekt_gamebtn;
|
|
||||||
static uint8_t ekt_stick_x;
|
|
||||||
static uint8_t ekt_stick_y;
|
|
||||||
static struct ekt_io_config ekt_io_cfg;
|
|
||||||
static const struct ekt_io_backend* ekt_io_backend;
|
|
||||||
static bool ekt_io_coin;
|
|
||||||
|
|
||||||
uint16_t ekt_io_get_api_version(void) {
|
|
||||||
return 0x0100;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT ekt_io_init(void) {
|
|
||||||
ekt_io_config_load(&ekt_io_cfg, get_config_path());
|
|
||||||
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
if (wstr_ieq(ekt_io_cfg.mode, L"keyboard")) {
|
|
||||||
hr = ekt_kb_init(&ekt_io_cfg.kb, &ekt_io_backend);
|
|
||||||
} else {
|
|
||||||
hr = E_INVALIDARG;
|
|
||||||
dprintf("EKT IO: Invalid IO mode \"%S\", use keyboard\n",
|
|
||||||
ekt_io_cfg.mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT ekt_io_poll(void) {
|
|
||||||
assert(ekt_io_backend != NULL);
|
|
||||||
|
|
||||||
ekt_opbtn = 0;
|
|
||||||
ekt_gamebtn = 0;
|
|
||||||
ekt_stick_x = 0;
|
|
||||||
ekt_stick_y = 0;
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(ekt_io_cfg.vk_test) & 0x8000) {
|
|
||||||
ekt_opbtn |= EKT_IO_OPBTN_TEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(ekt_io_cfg.vk_service) & 0x8000) {
|
|
||||||
ekt_opbtn |= EKT_IO_OPBTN_SERVICE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(ekt_io_cfg.vk_sw1) & 0x8000) {
|
|
||||||
ekt_opbtn |= EKT_IO_OPBTN_SW1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(ekt_io_cfg.vk_sw2) & 0x8000) {
|
|
||||||
ekt_opbtn |= EKT_IO_OPBTN_SW2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(ekt_io_cfg.vk_coin) & 0x8000) {
|
|
||||||
if (!ekt_io_coin) {
|
|
||||||
ekt_io_coin = true;
|
|
||||||
ekt_opbtn |= EKT_IO_OPBTN_COIN;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ekt_io_coin = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ekt_io_get_opbtns(uint8_t* opbtn) {
|
|
||||||
if (opbtn != NULL) {
|
|
||||||
*opbtn = ekt_opbtn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ekt_io_get_gamebtns(uint32_t* btn) {
|
|
||||||
assert(ekt_io_backend != NULL);
|
|
||||||
assert(btn != NULL);
|
|
||||||
|
|
||||||
ekt_io_backend->get_gamebtns(btn);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ekt_io_get_trackball_position(uint16_t* stick_x, uint16_t* stick_y) {
|
|
||||||
assert(ekt_io_backend != NULL);
|
|
||||||
assert(stick_x != NULL);
|
|
||||||
assert(stick_y != NULL);
|
|
||||||
|
|
||||||
ekt_io_backend->get_trackball(stick_x, stick_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT ekt_io_led_init(void) {
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ekt_io_led_set_colors(uint8_t board, uint8_t* rgb) {
|
|
||||||
return;
|
|
||||||
}
|
|
@ -1,106 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
enum {
|
|
||||||
EKT_IO_OPBTN_TEST = 0x01,
|
|
||||||
EKT_IO_OPBTN_SERVICE = 0x02,
|
|
||||||
EKT_IO_OPBTN_COIN = 0x04,
|
|
||||||
EKT_IO_OPBTN_SW1 = 0x08,
|
|
||||||
EKT_IO_OPBTN_SW2 = 0x10,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
EKT_IO_GAMEBTN_MENU = 0x01,
|
|
||||||
EKT_IO_GAMEBTN_START = 0x02,
|
|
||||||
EKT_IO_GAMEBTN_STRATAGEM = 0x04,
|
|
||||||
EKT_IO_GAMEBTN_STRATAGEM_LOCK = 0x08,
|
|
||||||
EKT_IO_GAMEBTN_HOUGU = 0x10,
|
|
||||||
EKT_IO_GAMEBTN_RYUUHA = 0x20,
|
|
||||||
EKT_IO_GAMEBTN_NUMPAD_0 = 0x100,
|
|
||||||
EKT_IO_GAMEBTN_NUMPAD_1 = 0x200,
|
|
||||||
EKT_IO_GAMEBTN_NUMPAD_2 = 0x400,
|
|
||||||
EKT_IO_GAMEBTN_NUMPAD_3 = 0x800,
|
|
||||||
EKT_IO_GAMEBTN_NUMPAD_4 = 0x1000,
|
|
||||||
EKT_IO_GAMEBTN_NUMPAD_5 = 0x2000,
|
|
||||||
EKT_IO_GAMEBTN_NUMPAD_6 = 0x4000,
|
|
||||||
EKT_IO_GAMEBTN_NUMPAD_7 = 0x8000,
|
|
||||||
EKT_IO_GAMEBTN_NUMPAD_8 = 0x10000,
|
|
||||||
EKT_IO_GAMEBTN_NUMPAD_9 = 0x20000,
|
|
||||||
EKT_IO_GAMEBTN_NUMPAD_CLEAR = 0x40000,
|
|
||||||
EKT_IO_GAMEBTN_NUMPAD_ENTER = 0x80000,
|
|
||||||
EKT_IO_GAMEBTN_VOL_UP = 0x100000,
|
|
||||||
EKT_IO_GAMEBTN_VOL_DOWN = 0x200000,
|
|
||||||
EKT_IO_GAMEBTN_TERMINAL_LEFT = 0x400000,
|
|
||||||
EKT_IO_GAMEBTN_TERMINAL_UP = 0x800000,
|
|
||||||
EKT_IO_GAMEBTN_TERMINAL_RIGHT = 0x1000000,
|
|
||||||
EKT_IO_GAMEBTN_TERMINAL_DOWN = 0x2000000,
|
|
||||||
EKT_IO_GAMEBTN_TERMINAL_LEFT_2 = 0x4000000,
|
|
||||||
EKT_IO_GAMEBTN_TERMINAL_RIGHT_2 = 0x8000000,
|
|
||||||
EKT_IO_GAMEBTN_TERMINAL_DECIDE = 0x10000000,
|
|
||||||
EKT_IO_GAMEBTN_TERMINAL_CANCEL = 0x20000000,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Get the version of the Eiketsu Taisen IO API that this DLL supports. This
|
|
||||||
function should return a positive 16-bit integer, where the high byte is
|
|
||||||
the major version and the low byte is the minor version (as defined by the
|
|
||||||
Semantic Versioning standard).
|
|
||||||
|
|
||||||
The latest API version as of this writing is 0x0100. */
|
|
||||||
|
|
||||||
uint16_t ekt_io_get_api_version(void);
|
|
||||||
|
|
||||||
/* Initialize the IO DLL. This is the second function that will be called on
|
|
||||||
your DLL, after ekt_io_get_api_version.
|
|
||||||
|
|
||||||
All subsequent calls to this API may originate from arbitrary threads.
|
|
||||||
|
|
||||||
Minimum API version: 0x0100 */
|
|
||||||
|
|
||||||
HRESULT ekt_io_init(void);
|
|
||||||
|
|
||||||
/* Send any queued outputs (of which there are currently none, though this may
|
|
||||||
change in subsequent API versions) and retrieve any new inputs.
|
|
||||||
|
|
||||||
Minimum API version: 0x0100 */
|
|
||||||
|
|
||||||
HRESULT ekt_io_poll(void);
|
|
||||||
|
|
||||||
/* Get the state of the cabinet's operator buttons as of the last poll. See
|
|
||||||
EKT_IO_OPBTN enum above: this contains bit mask definitions for button
|
|
||||||
states returned in *opbtn. All buttons are active-high.
|
|
||||||
|
|
||||||
Minimum API version: 0x0100 */
|
|
||||||
|
|
||||||
void ekt_io_get_opbtns(uint8_t *opbtn);
|
|
||||||
|
|
||||||
/* Get the state of the cabinet's gameplay buttons as of the last poll. See
|
|
||||||
EKT_IO_GAMEBTN enum above: this contains bit mask definitions for button
|
|
||||||
states returned in *gamebtn. All buttons are active-high.
|
|
||||||
|
|
||||||
Minimum API version: 0x0100 */
|
|
||||||
|
|
||||||
void ekt_io_get_gamebtns(uint32_t *gamebtn);
|
|
||||||
|
|
||||||
/* Get the position of the trackball as of the last poll.
|
|
||||||
|
|
||||||
Minimum API version: 0x0100 */
|
|
||||||
|
|
||||||
void ekt_io_get_trackball_position(uint16_t *stick_x, uint16_t *stick_y);
|
|
||||||
|
|
||||||
/* Initialize LED emulation. This function will be called before any
|
|
||||||
other ekt_io_led_*() function calls.
|
|
||||||
|
|
||||||
All subsequent calls may originate from arbitrary threads and some may
|
|
||||||
overlap with each other. Ensuring synchronization inside your IO DLL is
|
|
||||||
your responsibility. */
|
|
||||||
|
|
||||||
HRESULT ekt_io_led_init(void);
|
|
||||||
|
|
||||||
/* Update the RGB LEDs.
|
|
||||||
|
|
||||||
Exact layout is TBD. */
|
|
||||||
|
|
||||||
void ekt_io_led_set_colors(uint8_t board, uint8_t *rgb);
|
|
@ -1,176 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#include "ektio/backend.h"
|
|
||||||
#include "ektio/config.h"
|
|
||||||
#include "ektio/ektio.h"
|
|
||||||
#include "ektio/keyboard.h"
|
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
|
|
||||||
static void ekt_kb_get_gamebtns(uint32_t* gamebtn_out);
|
|
||||||
static void ekt_kb_get_trackball(uint16_t* x, uint16_t* y);
|
|
||||||
|
|
||||||
static const struct ekt_io_backend ekt_kb_backend = {
|
|
||||||
.get_gamebtns = ekt_kb_get_gamebtns,
|
|
||||||
.get_trackball = ekt_kb_get_trackball
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint16_t current_x;
|
|
||||||
static uint16_t current_y;
|
|
||||||
|
|
||||||
static struct ekt_kb_config config;
|
|
||||||
|
|
||||||
HRESULT ekt_kb_init(const struct ekt_kb_config* cfg, const struct ekt_io_backend** backend) {
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(backend != NULL);
|
|
||||||
|
|
||||||
dprintf("Keyboard: Using keyboard input\n");
|
|
||||||
*backend = &ekt_kb_backend;
|
|
||||||
config = *cfg;
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ekt_kb_get_gamebtns(uint32_t* gamebtn_out) {
|
|
||||||
assert(gamebtn_out != NULL);
|
|
||||||
|
|
||||||
uint32_t gamebtn = 0;
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_hougu) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_HOUGU;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_menu) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_MENU;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_start) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_START;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_stratagem) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_STRATAGEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_stratagem_lock) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_STRATAGEM_LOCK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_ryuuha) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_RYUUHA;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_0) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_NUMPAD_0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_1) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_NUMPAD_1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_2) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_NUMPAD_2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_3) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_NUMPAD_3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_4) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_NUMPAD_4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_5) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_NUMPAD_5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_6) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_NUMPAD_6;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_7) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_NUMPAD_7;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_8) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_NUMPAD_8;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_9) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_NUMPAD_9;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_clear) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_NUMPAD_CLEAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_enter) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_NUMPAD_ENTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_vol_down) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_VOL_DOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_vol_up) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_VOL_UP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_terminal_cancel) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_TERMINAL_CANCEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_terminal_decide) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_TERMINAL_DECIDE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_terminal_up) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_TERMINAL_UP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_terminal_right) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_TERMINAL_RIGHT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_terminal_down) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_TERMINAL_DOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_terminal_left) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_TERMINAL_LEFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_terminal_left_2) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_TERMINAL_LEFT_2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_terminal_right_2) & 0x8000) {
|
|
||||||
gamebtn |= EKT_IO_GAMEBTN_TERMINAL_RIGHT_2;
|
|
||||||
}
|
|
||||||
|
|
||||||
*gamebtn_out = gamebtn;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ekt_kb_get_trackball(uint16_t* x, uint16_t* y) {
|
|
||||||
assert(x != NULL);
|
|
||||||
assert(y != NULL);
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.x_down) & 0x8000) {
|
|
||||||
current_x -= config.speed;
|
|
||||||
} else if (GetAsyncKeyState(config.x_up) & 0x8000) {
|
|
||||||
current_x += config.speed;
|
|
||||||
}
|
|
||||||
if (GetAsyncKeyState(config.y_down) & 0x8000) {
|
|
||||||
current_y += config.speed;
|
|
||||||
} else if (GetAsyncKeyState(config.y_up) & 0x8000) {
|
|
||||||
current_y -= config.speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
*x = current_x;
|
|
||||||
*y = current_y;
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include "ektio/backend.h"
|
|
||||||
#include "ektio/config.h"
|
|
||||||
|
|
||||||
HRESULT ekt_kb_init(const struct ekt_kb_config *cfg, const struct ekt_io_backend **backend);
|
|
@ -1,18 +0,0 @@
|
|||||||
ektio_lib = static_library(
|
|
||||||
'ektio',
|
|
||||||
name_prefix : '',
|
|
||||||
include_directories : inc,
|
|
||||||
implicit_include_directories : false,
|
|
||||||
dependencies : [
|
|
||||||
xinput_lib,
|
|
||||||
],
|
|
||||||
sources : [
|
|
||||||
'ektio.c',
|
|
||||||
'ektio.h',
|
|
||||||
'config.c',
|
|
||||||
'config.h',
|
|
||||||
'backend.h',
|
|
||||||
'keyboard.c',
|
|
||||||
'keyboard.h',
|
|
||||||
],
|
|
||||||
)
|
|
@ -120,7 +120,7 @@ void fgo_hook_config_load(
|
|||||||
io4_config_load(&cfg->io4, filename);
|
io4_config_load(&cfg->io4, filename);
|
||||||
vfd_config_load(&cfg->vfd, filename);
|
vfd_config_load(&cfg->vfd, filename);
|
||||||
touch_screen_config_load(&cfg->touch, filename);
|
touch_screen_config_load(&cfg->touch, filename);
|
||||||
printer_chc_config_load(&cfg->printer, filename);
|
printer_config_load(&cfg->printer, filename);
|
||||||
fgo_deck_config_load(&cfg->deck, filename);
|
fgo_deck_config_load(&cfg->deck, filename);
|
||||||
ftdi_config_load(&cfg->ftdi, filename);
|
ftdi_config_load(&cfg->ftdi, filename);
|
||||||
led15093_config_load(&cfg->led15093, filename);
|
led15093_config_load(&cfg->led15093, filename);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include "hooklib/dvd.h"
|
#include "hooklib/dvd.h"
|
||||||
#include "hooklib/touch.h"
|
#include "hooklib/touch.h"
|
||||||
#include "hooklib/printer_chc.h"
|
#include "hooklib/printer.h"
|
||||||
|
|
||||||
#include "gfxhook/config.h"
|
#include "gfxhook/config.h"
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ struct fgo_hook_config {
|
|||||||
struct io4_config io4;
|
struct io4_config io4;
|
||||||
struct vfd_config vfd;
|
struct vfd_config vfd;
|
||||||
struct touch_screen_config touch;
|
struct touch_screen_config touch;
|
||||||
struct printer_chc_config printer;
|
struct printer_config printer;
|
||||||
struct deck_config deck;
|
struct deck_config deck;
|
||||||
struct ftdi_config ftdi;
|
struct ftdi_config ftdi;
|
||||||
struct led15093_config led15093;
|
struct led15093_config led15093;
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include "hooklib/dll.h"
|
#include "hooklib/dll.h"
|
||||||
#include "hooklib/dvd.h"
|
#include "hooklib/dvd.h"
|
||||||
#include "hooklib/touch.h"
|
#include "hooklib/touch.h"
|
||||||
#include "hooklib/printer_chc.h"
|
#include "hooklib/printer.h"
|
||||||
#include "hooklib/createprocess.h"
|
#include "hooklib/createprocess.h"
|
||||||
#include "hooklib/serial.h"
|
#include "hooklib/serial.h"
|
||||||
#include "hooklib/spike.h"
|
#include "hooklib/spike.h"
|
||||||
@ -81,7 +81,7 @@ static DWORD CALLBACK fgo_pre_startup(void)
|
|||||||
|
|
||||||
/* Hook external DLL APIs */
|
/* Hook external DLL APIs */
|
||||||
|
|
||||||
printer_chc_hook_init(&fgo_hook_cfg.printer, 4, fgo_hook_mod);
|
printer_hook_init(&fgo_hook_cfg.printer, 4, fgo_hook_mod);
|
||||||
if (fgo_hook_cfg.printer.enable) {
|
if (fgo_hook_cfg.printer.enable) {
|
||||||
dll_hook_push(fgo_hook_mod, L"C330Ausb.dll");
|
dll_hook_push(fgo_hook_mod, L"C330Ausb.dll");
|
||||||
dll_hook_push(fgo_hook_mod, L"C330AFWDLusb.dll");
|
dll_hook_push(fgo_hook_mod, L"C330AFWDLusb.dll");
|
||||||
|
@ -126,7 +126,7 @@ void kemono_hook_config_load(
|
|||||||
vfd_config_load(&cfg->vfd, filename);
|
vfd_config_load(&cfg->vfd, filename);
|
||||||
kemono_dll_config_load(&cfg->dll, filename);
|
kemono_dll_config_load(&cfg->dll, filename);
|
||||||
unity_config_load(&cfg->unity, filename);
|
unity_config_load(&cfg->unity, filename);
|
||||||
printer_chc_config_load(&cfg->printer, filename);
|
printer_config_load(&cfg->printer, filename);
|
||||||
amex_config_load(&cfg->amex, filename);
|
amex_config_load(&cfg->amex, filename);
|
||||||
led15093_config_load(&cfg->led15093, filename);
|
led15093_config_load(&cfg->led15093, filename);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ struct kemono_hook_config {
|
|||||||
struct vfd_config vfd;
|
struct vfd_config vfd;
|
||||||
struct kemono_dll_config dll;
|
struct kemono_dll_config dll;
|
||||||
struct unity_config unity;
|
struct unity_config unity;
|
||||||
struct printer_chc_config printer;
|
struct printer_config printer;
|
||||||
struct amex_config amex;
|
struct amex_config amex;
|
||||||
struct led15093_config led15093;
|
struct led15093_config led15093;
|
||||||
};
|
};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include "hook/iohook.h"
|
#include "hook/iohook.h"
|
||||||
#include "hook/process.h"
|
#include "hook/process.h"
|
||||||
#include "hook/table.h"
|
#include "hook/table.h"
|
||||||
#include "hooklib/printer_chc.h"
|
#include "hooklib/printer.h"
|
||||||
#include "hooklib/serial.h"
|
#include "hooklib/serial.h"
|
||||||
#include "hooklib/spike.h"
|
#include "hooklib/spike.h"
|
||||||
#include "kemonohook/config.h"
|
#include "kemonohook/config.h"
|
||||||
@ -65,7 +65,7 @@ static DWORD CALLBACK kemono_pre_startup(void) {
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
printer_chc_hook_init(&kemono_hook_cfg.printer, 0, kemono_hook_mod);
|
printer_hook_init(&kemono_hook_cfg.printer, 0, kemono_hook_mod);
|
||||||
printer_set_dimensions(720, 1028); // printer doesn't call setimageformat
|
printer_set_dimensions(720, 1028); // printer doesn't call setimageformat
|
||||||
|
|
||||||
/* Initialize emulation hooks */
|
/* Initialize emulation hooks */
|
||||||
|
@ -1,112 +0,0 @@
|
|||||||
#include "amex/config.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "board/config.h"
|
|
||||||
#include "gfxhook/config.h"
|
|
||||||
|
|
||||||
#include "sekitohook/config.h"
|
|
||||||
#include "sekitohook/sekito-dll.h"
|
|
||||||
|
|
||||||
#include "hooklib/config.h"
|
|
||||||
|
|
||||||
#include "platform/config.h"
|
|
||||||
|
|
||||||
void led15093_config_load(struct led15093_config *cfg, const wchar_t *filename)
|
|
||||||
{
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
|
|
||||||
wchar_t tmpstr[16];
|
|
||||||
|
|
||||||
memset(cfg->board_number, ' ', sizeof(cfg->board_number));
|
|
||||||
memset(cfg->chip_number, ' ', sizeof(cfg->chip_number));
|
|
||||||
memset(cfg->boot_chip_number, ' ', sizeof(cfg->boot_chip_number));
|
|
||||||
|
|
||||||
cfg->enable = GetPrivateProfileIntW(L"led15093", L"enable", 1, filename);
|
|
||||||
cfg->port_no[0] = GetPrivateProfileIntW(L"led15093", L"portNo1", 0, filename);
|
|
||||||
cfg->port_no[1] = GetPrivateProfileIntW(L"led15093", L"portNo2", 0, filename);
|
|
||||||
cfg->high_baudrate = GetPrivateProfileIntW(L"led15093", L"highBaud", 0, filename);
|
|
||||||
cfg->fw_ver = GetPrivateProfileIntW(L"led15093", L"fwVer", 0xA0, filename);
|
|
||||||
cfg->fw_sum = GetPrivateProfileIntW(L"led15093", L"fwSum", 0xAA53, filename);
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"led15093",
|
|
||||||
L"boardNumber",
|
|
||||||
L"15093-06",
|
|
||||||
tmpstr,
|
|
||||||
_countof(tmpstr),
|
|
||||||
filename);
|
|
||||||
|
|
||||||
size_t n = wcstombs(cfg->board_number, tmpstr, sizeof(cfg->board_number));
|
|
||||||
for (int i = n; i < sizeof(cfg->board_number); i++)
|
|
||||||
{
|
|
||||||
cfg->board_number[i] = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"led15093",
|
|
||||||
L"chipNumber",
|
|
||||||
L"6710A",
|
|
||||||
tmpstr,
|
|
||||||
_countof(tmpstr),
|
|
||||||
filename);
|
|
||||||
|
|
||||||
n = wcstombs(cfg->chip_number, tmpstr, sizeof(cfg->chip_number));
|
|
||||||
for (int i = n; i < sizeof(cfg->chip_number); i++)
|
|
||||||
{
|
|
||||||
cfg->chip_number[i] = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"led15093",
|
|
||||||
L"bootChipNumber",
|
|
||||||
L"6709 ",
|
|
||||||
tmpstr,
|
|
||||||
_countof(tmpstr),
|
|
||||||
filename);
|
|
||||||
|
|
||||||
n = wcstombs(cfg->boot_chip_number, tmpstr, sizeof(cfg->boot_chip_number));
|
|
||||||
for (int i = n; i < sizeof(cfg->boot_chip_number); i++)
|
|
||||||
{
|
|
||||||
cfg->boot_chip_number[i] = ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sekito_dll_config_load(
|
|
||||||
struct sekito_dll_config *cfg,
|
|
||||||
const wchar_t *filename)
|
|
||||||
{
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"sekitoio",
|
|
||||||
L"path",
|
|
||||||
L"",
|
|
||||||
cfg->path,
|
|
||||||
_countof(cfg->path),
|
|
||||||
filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void sekito_hook_config_load(
|
|
||||||
struct sekito_hook_config *cfg,
|
|
||||||
const wchar_t *filename)
|
|
||||||
{
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
|
|
||||||
platform_config_load(&cfg->platform, filename);
|
|
||||||
aime_config_load(&cfg->aime, filename);
|
|
||||||
io4_config_load(&cfg->io4, filename);
|
|
||||||
dvd_config_load(&cfg->dvd, filename);
|
|
||||||
led15093_config_load(&cfg->led15093, filename);
|
|
||||||
y3_config_load(&cfg->y3, filename);
|
|
||||||
printer_chc_config_load(&cfg->printer, filename);
|
|
||||||
sekito_dll_config_load(&cfg->dll, filename);
|
|
||||||
gfx_config_load(&cfg->gfx, filename);
|
|
||||||
amex_config_load(&cfg->amex, filename);
|
|
||||||
amvideo_config_load(&cfg->amvideo, filename);
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "amex/amex.h"
|
|
||||||
#include "board/sg-reader.h"
|
|
||||||
#include "board/config.h"
|
|
||||||
#include "board/led15093.h"
|
|
||||||
#include "gfxhook/gfx.h"
|
|
||||||
|
|
||||||
#include "sekitohook/sekito-dll.h"
|
|
||||||
|
|
||||||
#include "hooklib/config.h"
|
|
||||||
#include "hooklib/dvd.h"
|
|
||||||
#include "hooklib/printer_chc.h"
|
|
||||||
|
|
||||||
#include "platform/config.h"
|
|
||||||
|
|
||||||
|
|
||||||
struct sekito_hook_config {
|
|
||||||
struct platform_config platform;
|
|
||||||
struct aime_config aime;
|
|
||||||
struct io4_config io4;
|
|
||||||
struct dvd_config dvd;
|
|
||||||
struct led15093_config led15093;
|
|
||||||
struct y3_config y3;
|
|
||||||
struct sekito_dll_config dll;
|
|
||||||
struct printer_chc_config printer;
|
|
||||||
struct gfx_config gfx;
|
|
||||||
struct amex_config amex;
|
|
||||||
struct amvideo_config amvideo;
|
|
||||||
};
|
|
||||||
|
|
||||||
void sekito_dll_config_load(
|
|
||||||
struct sekito_dll_config *cfg,
|
|
||||||
const wchar_t *filename);
|
|
||||||
|
|
||||||
void sekito_hook_config_load(
|
|
||||||
struct sekito_hook_config *cfg,
|
|
||||||
const wchar_t *filename);
|
|
@ -1,185 +0,0 @@
|
|||||||
/*
|
|
||||||
"Sangokushi Taisen" (sekito) hook
|
|
||||||
|
|
||||||
Devices
|
|
||||||
|
|
||||||
USB: 837-14572 "Type 3" I/O Board
|
|
||||||
COM12: 837-15084 "Gen 2" Aime Reader
|
|
||||||
|
|
||||||
[Satellite]
|
|
||||||
|
|
||||||
USB: Sinfonia CHC-C320 Printer
|
|
||||||
COM1: 837-15093-06 LED Controller Board
|
|
||||||
COM10: 601-13160-01 "Flat Panel Reader" Y3CR BD SIE F720MM Board
|
|
||||||
COM11: Printer Camera
|
|
||||||
|
|
||||||
[Terminal]
|
|
||||||
|
|
||||||
COM1: 837-15084 "Gen 2" Aime Reader
|
|
||||||
COM11: 837-15093-06 LED Controller Board
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "sekito-dll.h"
|
|
||||||
#include "amex/amex.h"
|
|
||||||
#include "board/sg-reader.h"
|
|
||||||
#include "board/led15093.h"
|
|
||||||
#include "gfxhook/gfx.h"
|
|
||||||
|
|
||||||
#include "hook/process.h"
|
|
||||||
#include "hook/iohook.h"
|
|
||||||
#include "hooklib/dll.h"
|
|
||||||
|
|
||||||
#include "hooklib/serial.h"
|
|
||||||
#include "hooklib/spike.h"
|
|
||||||
|
|
||||||
#include "sekitohook/config.h"
|
|
||||||
#include "sekitohook/jvs.h"
|
|
||||||
|
|
||||||
#include "platform/platform.h"
|
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
#include "util/env.h"
|
|
||||||
#include "hooklib/y3.h"
|
|
||||||
|
|
||||||
static HMODULE sekito_hook_mod;
|
|
||||||
static process_entry_t sekito_startup;
|
|
||||||
static struct sekito_hook_config sekito_hook_cfg;
|
|
||||||
|
|
||||||
static DWORD CALLBACK sekito_pre_startup(void)
|
|
||||||
{
|
|
||||||
HRESULT hr;
|
|
||||||
bool is_terminal;
|
|
||||||
|
|
||||||
dprintf("--- Begin sekito_pre_startup ---\n");
|
|
||||||
|
|
||||||
/* Load config */
|
|
||||||
|
|
||||||
sekito_hook_config_load(&sekito_hook_cfg, get_config_path());
|
|
||||||
|
|
||||||
/* Hook Win32 APIs */
|
|
||||||
|
|
||||||
dvd_hook_init(&sekito_hook_cfg.dvd, sekito_hook_mod);
|
|
||||||
gfx_hook_init(&sekito_hook_cfg.gfx);
|
|
||||||
serial_hook_init();
|
|
||||||
sekito_io_init();
|
|
||||||
|
|
||||||
/* Hook external DLL APIs */
|
|
||||||
|
|
||||||
hr = y3_hook_init(&sekito_hook_cfg.y3, sekito_hook_mod, get_config_path());
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
printer_chc_hook_init(&sekito_hook_cfg.printer, 0, sekito_hook_mod);
|
|
||||||
if (sekito_hook_cfg.printer.enable) {
|
|
||||||
dll_hook_push(sekito_hook_mod, L"C320Ausb.dll");
|
|
||||||
dll_hook_push(sekito_hook_mod, L"C320AFWDLusb.dll");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize emulation hooks */
|
|
||||||
|
|
||||||
hr = platform_hook_init(
|
|
||||||
&sekito_hook_cfg.platform,
|
|
||||||
"SDDD",
|
|
||||||
"AAV2",
|
|
||||||
sekito_hook_mod);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize Terminal/Satellite hooks */
|
|
||||||
if (strncmp(sekito_hook_cfg.platform.nusec.platform_id, "AAV1", 4) == 0) {
|
|
||||||
// Terminal
|
|
||||||
is_terminal = true;
|
|
||||||
} else if (strncmp(sekito_hook_cfg.platform.nusec.platform_id, "AAV2", 4) == 0) {
|
|
||||||
// Satellite
|
|
||||||
is_terminal = false;
|
|
||||||
} else {
|
|
||||||
// Unknown
|
|
||||||
dprintf("Unknown platform ID: %s\n", sekito_hook_cfg.platform.nusec.platform_id);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
// LED: terminal uses COM 11 and satellite use COM 1
|
|
||||||
unsigned int led_port_no[2] = {is_terminal ? 11 : 1, 0};
|
|
||||||
|
|
||||||
hr = sekito_dll_init(&sekito_hook_cfg.dll, sekito_hook_mod);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = led15093_hook_init(&sekito_hook_cfg.led15093,
|
|
||||||
sekito_dll.led_init, sekito_dll.led_set_leds, led_port_no);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = sg_reader_hook_init(&sekito_hook_cfg.aime, 12, 2,
|
|
||||||
sekito_hook_mod);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_terminal) {
|
|
||||||
hr = sg_reader_hook_init(&sekito_hook_cfg.aime, 1, 2,
|
|
||||||
sekito_hook_mod);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sekito_jvs_set_terminal(is_terminal);
|
|
||||||
hr = amex_hook_init(&sekito_hook_cfg.amex, sekito_jvs_init);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = amvideo_hook_init(&sekito_hook_cfg.amvideo, sekito_hook_mod);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize debug helpers */
|
|
||||||
|
|
||||||
spike_hook_init(get_config_path());
|
|
||||||
|
|
||||||
dprintf("--- End sekito_pre_startup ---\n");
|
|
||||||
|
|
||||||
/* Jump to EXE start address */
|
|
||||||
|
|
||||||
return sekito_startup();
|
|
||||||
|
|
||||||
fail:
|
|
||||||
ExitProcess(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL WINAPI DllMain(HMODULE mod, DWORD cause, void *ctx)
|
|
||||||
{
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
if (cause != DLL_PROCESS_ATTACH) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
sekito_hook_mod = mod;
|
|
||||||
|
|
||||||
hr = process_hijack_startup(sekito_pre_startup, &sekito_startup);
|
|
||||||
|
|
||||||
if (!SUCCEEDED(hr)) {
|
|
||||||
dprintf("Failed to hijack process startup: %x\n", (int) hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return SUCCEEDED(hr);
|
|
||||||
}
|
|
@ -1,258 +0,0 @@
|
|||||||
#include "jvs.h"
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "amex/jvs.h"
|
|
||||||
|
|
||||||
#include "board/io3.h"
|
|
||||||
|
|
||||||
#include "sekitohook/config.h"
|
|
||||||
|
|
||||||
#include "jvs/jvs-bus.h"
|
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
|
|
||||||
static void sekito_jvs_read_switches(void* ctx, struct io3_switch_state* out);
|
|
||||||
|
|
||||||
static void sekito_jvs_read_coin_counter(
|
|
||||||
void* ctx,
|
|
||||||
uint8_t slot_no,
|
|
||||||
uint16_t* out);
|
|
||||||
|
|
||||||
static void sekito_jvs_read_rotary(
|
|
||||||
void* ctx,
|
|
||||||
uint16_t* rotary,
|
|
||||||
uint8_t nrotary);
|
|
||||||
|
|
||||||
static const struct io3_ops sekito_jvs_io3_ops = {
|
|
||||||
.read_switches = sekito_jvs_read_switches,
|
|
||||||
.read_rotarys = sekito_jvs_read_rotary,
|
|
||||||
.read_coin_counter = sekito_jvs_read_coin_counter,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct io3 sekito_jvs_io3;
|
|
||||||
|
|
||||||
static bool io_is_terminal;
|
|
||||||
|
|
||||||
HRESULT sekito_jvs_init(struct jvs_node** out) {
|
|
||||||
assert(out != NULL);
|
|
||||||
|
|
||||||
dprintf("JVS I/O: Starting JVS\n");
|
|
||||||
|
|
||||||
io3_init(&sekito_jvs_io3, NULL, &sekito_jvs_io3_ops, NULL);
|
|
||||||
*out = io3_to_jvs_node(&sekito_jvs_io3);
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sekito_jvs_set_terminal(bool is_terminal) {
|
|
||||||
dprintf("JVS I/O: Terminal: %d\n", is_terminal);
|
|
||||||
io_is_terminal = is_terminal;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sekito_jvs_read_switches(void* ctx, struct io3_switch_state* out) {
|
|
||||||
assert(out != NULL);
|
|
||||||
|
|
||||||
uint8_t opbtn;
|
|
||||||
uint32_t gamebtn;
|
|
||||||
|
|
||||||
assert(sekito_dll.poll != NULL);
|
|
||||||
assert(sekito_dll.get_opbtns != NULL);
|
|
||||||
assert(sekito_dll.get_gamebtns != NULL);
|
|
||||||
|
|
||||||
memset(out, 0, sizeof(*out));
|
|
||||||
|
|
||||||
sekito_dll.poll();
|
|
||||||
|
|
||||||
opbtn = 0;
|
|
||||||
gamebtn = 0;
|
|
||||||
|
|
||||||
sekito_dll.get_opbtns(&opbtn);
|
|
||||||
sekito_dll.get_gamebtns(&gamebtn);
|
|
||||||
|
|
||||||
if (opbtn & SEKITO_IO_OPBTN_TEST) {
|
|
||||||
out->system = 0x80;
|
|
||||||
} else {
|
|
||||||
out->system = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opbtn & SEKITO_IO_OPBTN_SERVICE) {
|
|
||||||
out->p1 |= 1 << 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opbtn & SEKITO_IO_OPBTN_SW1) {
|
|
||||||
out->p1 |= 1 << 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opbtn & SEKITO_IO_OPBTN_SW2) {
|
|
||||||
out->p1 |= 1 << 11;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opbtn & SEKITO_IO_OPBTN_COIN) {
|
|
||||||
out->p1 |= 1 << 14;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!io_is_terminal) {
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_HOUGU) {
|
|
||||||
out->p2 |= 1 << 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_MENU) {
|
|
||||||
out->p2 |= 1 << 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_START) {
|
|
||||||
out->p1 |= 1 << 15;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_STRATAGEM) {
|
|
||||||
out->p2 |= 1 << 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_STRATAGEM_LOCK) {
|
|
||||||
out->p2 |= 1 << 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
out->p1 |= 0 << 2; // card_sensor
|
|
||||||
out->p2 |= 1 << 2; // open_sensor
|
|
||||||
out->p2 |= 1 << 3; // lock
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_NUMPAD_0) {
|
|
||||||
out->p1 |= SEKITO_NUMPAD_C2;
|
|
||||||
out->p1 |= SEKITO_NUMPAD_R4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_NUMPAD_1) {
|
|
||||||
out->p1 |= SEKITO_NUMPAD_C1;
|
|
||||||
out->p1 |= SEKITO_NUMPAD_R1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_NUMPAD_2) {
|
|
||||||
out->p1 |= SEKITO_NUMPAD_C2;
|
|
||||||
out->p1 |= SEKITO_NUMPAD_R1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_NUMPAD_3) {
|
|
||||||
out->p1 |= SEKITO_NUMPAD_C3;
|
|
||||||
out->p1 |= SEKITO_NUMPAD_R1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_NUMPAD_4) {
|
|
||||||
out->p1 |= SEKITO_NUMPAD_C1;
|
|
||||||
out->p1 |= SEKITO_NUMPAD_R2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_NUMPAD_5) {
|
|
||||||
out->p1 |= SEKITO_NUMPAD_C2;
|
|
||||||
out->p1 |= SEKITO_NUMPAD_R2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_NUMPAD_6) {
|
|
||||||
out->p1 |= SEKITO_NUMPAD_C3;
|
|
||||||
out->p1 |= SEKITO_NUMPAD_R2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_NUMPAD_7) {
|
|
||||||
out->p1 |= SEKITO_NUMPAD_C1;
|
|
||||||
out->p1 |= SEKITO_NUMPAD_R3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_NUMPAD_8) {
|
|
||||||
out->p1 |= SEKITO_NUMPAD_C2;
|
|
||||||
out->p1 |= SEKITO_NUMPAD_R3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_NUMPAD_9) {
|
|
||||||
out->p1 |= SEKITO_NUMPAD_C3;
|
|
||||||
out->p1 |= SEKITO_NUMPAD_R3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_NUMPAD_CLEAR) {
|
|
||||||
out->p1 |= SEKITO_NUMPAD_C1;
|
|
||||||
out->p1 |= SEKITO_NUMPAD_R4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_NUMPAD_ENTER) {
|
|
||||||
out->p1 |= SEKITO_NUMPAD_C3;
|
|
||||||
out->p1 |= SEKITO_NUMPAD_R4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (io_is_terminal) {
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_TERMINAL_CANCEL) {
|
|
||||||
out->p2 |= 1 << 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_TERMINAL_DECIDE) {
|
|
||||||
out->p2 |= 1 << 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_TERMINAL_LEFT) {
|
|
||||||
out->p1 |= 1 << 11;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_TERMINAL_UP) {
|
|
||||||
out->p1 |= 1 << 13;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_TERMINAL_RIGHT) {
|
|
||||||
out->p1 |= 1 << 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_TERMINAL_DOWN) {
|
|
||||||
out->p1 |= 1 << 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_TERMINAL_LEFT_2) {
|
|
||||||
out->p2 |= 1 << 11;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_TERMINAL_RIGHT_2) {
|
|
||||||
out->p2 |= 1 << 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamebtn & SEKITO_IO_GAMEBTN_TERMINAL_RESERVE) {
|
|
||||||
out->p2 |= 1 << 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sekito_jvs_read_rotary(
|
|
||||||
void* ctx,
|
|
||||||
uint16_t* rotary,
|
|
||||||
uint8_t nrotary) {
|
|
||||||
assert(rotary != NULL);
|
|
||||||
assert(sekito_dll.get_trackball_position != NULL);
|
|
||||||
|
|
||||||
uint16_t x, y;
|
|
||||||
|
|
||||||
x = 0;
|
|
||||||
y = 0;
|
|
||||||
|
|
||||||
sekito_dll.get_trackball_position(&x, &y);
|
|
||||||
|
|
||||||
if (nrotary >= 4) {
|
|
||||||
rotary[2] = x;
|
|
||||||
rotary[3] = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sekito_jvs_read_coin_counter(
|
|
||||||
void* ctx,
|
|
||||||
uint8_t slot_no,
|
|
||||||
uint16_t* out) {
|
|
||||||
if (slot_no > 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// unused(!)
|
|
||||||
*out = 0;
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include "jvs/jvs-bus.h"
|
|
||||||
|
|
||||||
enum {
|
|
||||||
SEKITO_NUMPAD_R1 = 1 << 9,
|
|
||||||
SEKITO_NUMPAD_R2 = 1 << 8,
|
|
||||||
SEKITO_NUMPAD_R3 = 1 << 7,
|
|
||||||
SEKITO_NUMPAD_R4 = 1 << 6,
|
|
||||||
SEKITO_NUMPAD_C1 = 1 << 5,
|
|
||||||
SEKITO_NUMPAD_C2 = 1 << 4,
|
|
||||||
SEKITO_NUMPAD_C3 = 1 << 3
|
|
||||||
};
|
|
||||||
|
|
||||||
HRESULT sekito_jvs_init(struct jvs_node **root);
|
|
||||||
void sekito_jvs_set_terminal(bool is_terminal);
|
|
@ -1,32 +0,0 @@
|
|||||||
shared_library(
|
|
||||||
'sekitohook',
|
|
||||||
name_prefix : '',
|
|
||||||
include_directories : inc,
|
|
||||||
implicit_include_directories : false,
|
|
||||||
vs_module_defs : 'sekitohook.def',
|
|
||||||
dependencies : [
|
|
||||||
capnhook.get_variable('hook_dep'),
|
|
||||||
capnhook.get_variable('hooklib_dep')
|
|
||||||
],
|
|
||||||
link_with : [
|
|
||||||
aimeio_lib,
|
|
||||||
amex_lib,
|
|
||||||
board_lib,
|
|
||||||
hooklib_lib,
|
|
||||||
gfxhook_lib,
|
|
||||||
jvs_lib,
|
|
||||||
platform_lib,
|
|
||||||
sekitoio_lib,
|
|
||||||
util_lib,
|
|
||||||
y3io_lib,
|
|
||||||
],
|
|
||||||
sources : [
|
|
||||||
'config.c',
|
|
||||||
'config.h',
|
|
||||||
'dllmain.c',
|
|
||||||
'jvs.c',
|
|
||||||
'jvs.h',
|
|
||||||
'sekito-dll.c',
|
|
||||||
'sekito-dll.h',
|
|
||||||
],
|
|
||||||
)
|
|
@ -1,118 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "sekitohook/sekito-dll.h"
|
|
||||||
|
|
||||||
#include "util/dll-bind.h"
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
|
|
||||||
const struct dll_bind_sym sekito_dll_syms[] = {
|
|
||||||
{
|
|
||||||
.sym = "sekito_io_init",
|
|
||||||
.off = offsetof(struct sekito_dll, init),
|
|
||||||
}, {
|
|
||||||
.sym = "sekito_io_poll",
|
|
||||||
.off = offsetof(struct sekito_dll, poll),
|
|
||||||
}, {
|
|
||||||
.sym = "sekito_io_get_opbtns",
|
|
||||||
.off = offsetof(struct sekito_dll, get_opbtns),
|
|
||||||
}, {
|
|
||||||
.sym = "sekito_io_get_gamebtns",
|
|
||||||
.off = offsetof(struct sekito_dll, get_gamebtns),
|
|
||||||
}, {
|
|
||||||
.sym = "sekito_io_get_trackball_position",
|
|
||||||
.off = offsetof(struct sekito_dll, get_trackball_position),
|
|
||||||
}, {
|
|
||||||
.sym = "sekito_io_led_init",
|
|
||||||
.off = offsetof(struct sekito_dll, led_init),
|
|
||||||
}, {
|
|
||||||
.sym = "sekito_io_led_set_colors",
|
|
||||||
.off = offsetof(struct sekito_dll, led_set_leds),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sekito_dll sekito_dll;
|
|
||||||
|
|
||||||
// Copypasta DLL binding and diagnostic message boilerplate.
|
|
||||||
// Not much of this lends itself to being easily factored out. Also there
|
|
||||||
// will be a lot of API-specific branching code here eventually as new API
|
|
||||||
// versions get defined, so even though these functions all look the same
|
|
||||||
// now this won't remain the case forever.
|
|
||||||
|
|
||||||
HRESULT sekito_dll_init(const struct sekito_dll_config *cfg, HINSTANCE self)
|
|
||||||
{
|
|
||||||
uint16_t (*get_api_version)(void);
|
|
||||||
const struct dll_bind_sym *sym;
|
|
||||||
HINSTANCE owned;
|
|
||||||
HINSTANCE src;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(self != NULL);
|
|
||||||
|
|
||||||
if (cfg->path[0] != L'\0') {
|
|
||||||
owned = LoadLibraryW(cfg->path);
|
|
||||||
|
|
||||||
if (owned == NULL) {
|
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
||||||
dprintf("Sekito IO: Failed to load IO DLL: %lx: %S\n",
|
|
||||||
hr,
|
|
||||||
cfg->path);
|
|
||||||
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintf("Sekito IO: Using custom IO DLL: %S\n", cfg->path);
|
|
||||||
src = owned;
|
|
||||||
} else {
|
|
||||||
owned = NULL;
|
|
||||||
src = self;
|
|
||||||
}
|
|
||||||
|
|
||||||
get_api_version = (void *) GetProcAddress(src, "sekito_io_get_api_version");
|
|
||||||
|
|
||||||
if (get_api_version != NULL) {
|
|
||||||
sekito_dll.api_version = get_api_version();
|
|
||||||
} else {
|
|
||||||
sekito_dll.api_version = 0x0100;
|
|
||||||
dprintf("Custom IO DLL does not expose sekito_io_get_api_version, "
|
|
||||||
"assuming API version 1.0.\n"
|
|
||||||
"Please ask the developer to update their DLL.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sekito_dll.api_version >= 0x0200) {
|
|
||||||
hr = E_NOTIMPL;
|
|
||||||
dprintf("Sekito IO: Custom IO DLL implements an unsupported "
|
|
||||||
"API version (%#04x). Please update Segatools.\n",
|
|
||||||
sekito_dll.api_version);
|
|
||||||
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
sym = sekito_dll_syms;
|
|
||||||
hr = dll_bind(&sekito_dll, src, &sym, _countof(sekito_dll_syms));
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
if (src != self) {
|
|
||||||
dprintf("Sekito IO: Custom IO DLL does not provide function "
|
|
||||||
"\"%s\". Please contact your IO DLL's developer for "
|
|
||||||
"further assistance.\n",
|
|
||||||
sym->sym);
|
|
||||||
|
|
||||||
goto end;
|
|
||||||
} else {
|
|
||||||
dprintf("Internal error: could not reflect \"%s\"\n", sym->sym);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
owned = NULL;
|
|
||||||
|
|
||||||
end:
|
|
||||||
if (owned != NULL) {
|
|
||||||
FreeLibrary(owned);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include "sekitoio/sekitoio.h"
|
|
||||||
|
|
||||||
struct sekito_dll {
|
|
||||||
uint16_t api_version;
|
|
||||||
HRESULT (*init)(void);
|
|
||||||
HRESULT (*poll)(void);
|
|
||||||
void (*get_opbtns)(uint8_t *opbtn);
|
|
||||||
void (*get_gamebtns)(uint32_t *gamebtn);
|
|
||||||
void (*get_trackball_position)(uint16_t *x, uint16_t *y);
|
|
||||||
HRESULT (*led_init)(void);
|
|
||||||
void (*led_set_leds)(uint8_t board, uint8_t *rgb);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sekito_dll_config {
|
|
||||||
wchar_t path[MAX_PATH];
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct sekito_dll sekito_dll;
|
|
||||||
|
|
||||||
HRESULT sekito_dll_init(const struct sekito_dll_config *cfg, HINSTANCE self);
|
|
@ -1,65 +0,0 @@
|
|||||||
LIBRARY sekitohook
|
|
||||||
|
|
||||||
EXPORTS
|
|
||||||
aime_io_get_api_version
|
|
||||||
aime_io_init
|
|
||||||
aime_io_led_set_color
|
|
||||||
aime_io_nfc_get_aime_id
|
|
||||||
aime_io_nfc_get_felica_id
|
|
||||||
aime_io_nfc_poll
|
|
||||||
sekito_io_get_api_version
|
|
||||||
sekito_io_get_gamebtns
|
|
||||||
sekito_io_get_opbtns
|
|
||||||
sekito_io_get_trackball_position
|
|
||||||
sekito_io_init
|
|
||||||
sekito_io_poll
|
|
||||||
sekito_io_led_init
|
|
||||||
sekito_io_led_set_colors
|
|
||||||
y3_io_get_api_version
|
|
||||||
y3_io_init
|
|
||||||
y3_io_close
|
|
||||||
y3_io_get_cards
|
|
||||||
amDllVideoClose
|
|
||||||
amDllVideoGetVBiosVersion
|
|
||||||
amDllVideoOpen
|
|
||||||
amDllVideoSetResolution
|
|
||||||
API_DLLVersion @1
|
|
||||||
API_GetLastError @2
|
|
||||||
API_GetErrorMessage @3
|
|
||||||
API_Connect @4
|
|
||||||
API_Close @5
|
|
||||||
API_Start @6
|
|
||||||
API_Stop @7
|
|
||||||
API_GetFirmVersion @8
|
|
||||||
API_GetFirmName @9
|
|
||||||
API_GetTargetCode @10
|
|
||||||
API_GetStatus @11
|
|
||||||
API_GetCounter @12
|
|
||||||
API_ClearError @13
|
|
||||||
API_Reset @14
|
|
||||||
API_GetCardInfo @15
|
|
||||||
API_GetCardInfoCharSize @16
|
|
||||||
API_SetDevice @17
|
|
||||||
API_SetCommand @18
|
|
||||||
API_FirmwareUpdate @19
|
|
||||||
API_Calibration @20
|
|
||||||
API_GetCalibrationResult @21
|
|
||||||
API_GetProcTime @22
|
|
||||||
API_GetMemStatus @23
|
|
||||||
API_GetMemCounter @24
|
|
||||||
API_SetSysControl @25
|
|
||||||
API_GetSysControl @26
|
|
||||||
API_SetParameter @27
|
|
||||||
API_GetParameter @28
|
|
||||||
API_TestReset @29
|
|
||||||
API_DebugReset @30
|
|
||||||
API_GetBoardType @31
|
|
||||||
API_GetCardDataSize @32
|
|
||||||
API_GetFirmDate @33
|
|
||||||
API_SystemCommand @34
|
|
||||||
API_CalcCheckSum @35
|
|
||||||
API_GetCheckSumResult @36
|
|
||||||
API_BlockRead @37
|
|
||||||
API_GetBlockReadResult @38
|
|
||||||
API_BlockWrite @39
|
|
||||||
API_GetDebugParam @40
|
|
@ -1,10 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "sekitoio/sekitoio.h"
|
|
||||||
|
|
||||||
struct sekito_io_backend {
|
|
||||||
void (*get_gamebtns)(uint32_t *gamebtn);
|
|
||||||
void (*get_trackball)(uint16_t *x, uint16_t *y);
|
|
||||||
};
|
|
@ -1,74 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "sekitoio/config.h"
|
|
||||||
|
|
||||||
#include <xinput.h>
|
|
||||||
|
|
||||||
|
|
||||||
void sekito_kb_config_load(
|
|
||||||
struct sekito_kb_config *cfg,
|
|
||||||
const wchar_t *filename) {
|
|
||||||
|
|
||||||
cfg->vk_menu = GetPrivateProfileIntW(L"keyboard", L"menu", 'A', filename);
|
|
||||||
cfg->vk_start = GetPrivateProfileIntW(L"keyboard", L"start", 'S', filename);
|
|
||||||
cfg->vk_stratagem = GetPrivateProfileIntW(L"keyboard", L"stratagem", 'D', filename);
|
|
||||||
cfg->vk_stratagem_lock = GetPrivateProfileIntW(L"keyboard", L"stratagem_lock", 'F', filename);
|
|
||||||
cfg->vk_hougu = GetPrivateProfileIntW(L"keyboard", L"hougu", 'G', filename);
|
|
||||||
|
|
||||||
cfg->vk_tenkey_0 = GetPrivateProfileIntW(L"keyboard", L"tenkey_0", VK_NUMPAD0, filename);
|
|
||||||
cfg->vk_tenkey_1 = GetPrivateProfileIntW(L"keyboard", L"tenkey_1", VK_NUMPAD1, filename);
|
|
||||||
cfg->vk_tenkey_2 = GetPrivateProfileIntW(L"keyboard", L"tenkey_2", VK_NUMPAD2, filename);
|
|
||||||
cfg->vk_tenkey_3 = GetPrivateProfileIntW(L"keyboard", L"tenkey_3", VK_NUMPAD3, filename);
|
|
||||||
cfg->vk_tenkey_4 = GetPrivateProfileIntW(L"keyboard", L"tenkey_4", VK_NUMPAD4, filename);
|
|
||||||
cfg->vk_tenkey_5 = GetPrivateProfileIntW(L"keyboard", L"tenkey_5", VK_NUMPAD5, filename);
|
|
||||||
cfg->vk_tenkey_6 = GetPrivateProfileIntW(L"keyboard", L"tenkey_6", VK_NUMPAD6, filename);
|
|
||||||
cfg->vk_tenkey_7 = GetPrivateProfileIntW(L"keyboard", L"tenkey_7", VK_NUMPAD7, filename);
|
|
||||||
cfg->vk_tenkey_8 = GetPrivateProfileIntW(L"keyboard", L"tenkey_8", VK_NUMPAD8, filename);
|
|
||||||
cfg->vk_tenkey_9 = GetPrivateProfileIntW(L"keyboard", L"tenkey_9", VK_NUMPAD9, filename);
|
|
||||||
cfg->vk_tenkey_clear = GetPrivateProfileIntW(L"keyboard", L"tenkey_clear", VK_DECIMAL, filename);
|
|
||||||
cfg->vk_tenkey_enter = GetPrivateProfileIntW(L"keyboard", L"tenkey_enter", VK_RETURN, filename);
|
|
||||||
|
|
||||||
cfg->vk_terminal_decide = GetPrivateProfileIntW(L"keyboard", L"decide", 'A', filename);
|
|
||||||
cfg->vk_terminal_cancel = GetPrivateProfileIntW(L"keyboard", L"cancel", 'S', filename);
|
|
||||||
cfg->vk_terminal_up = GetPrivateProfileIntW(L"keyboard", L"up", VK_UP, filename);
|
|
||||||
cfg->vk_terminal_right = GetPrivateProfileIntW(L"keyboard", L"right", VK_RIGHT, filename);
|
|
||||||
cfg->vk_terminal_down = GetPrivateProfileIntW(L"keyboard", L"down", VK_DOWN, filename);
|
|
||||||
cfg->vk_terminal_left = GetPrivateProfileIntW(L"keyboard", L"left", VK_LEFT, filename);
|
|
||||||
cfg->vk_terminal_left_2 = GetPrivateProfileIntW(L"keyboard", L"left2", 'Q', filename);
|
|
||||||
cfg->vk_terminal_right_2 = GetPrivateProfileIntW(L"keyboard", L"right2", 'W', filename);
|
|
||||||
cfg->vk_terminal_reserve = GetPrivateProfileIntW(L"keyboard", L"reserve", 'E', filename);
|
|
||||||
|
|
||||||
cfg->x_down = GetPrivateProfileIntW(L"keyboard", L"trackball_left", VK_LEFT, filename);
|
|
||||||
cfg->x_up = GetPrivateProfileIntW(L"keyboard", L"trackball_right", VK_RIGHT, filename);
|
|
||||||
cfg->y_down = GetPrivateProfileIntW(L"keyboard", L"trackball_up", VK_UP, filename);
|
|
||||||
cfg->y_up = GetPrivateProfileIntW(L"keyboard", L"trackball_down", VK_DOWN, filename);
|
|
||||||
cfg->speed = GetPrivateProfileIntW(L"keyboard", L"speed_modifier", 1, filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sekito_io_config_load(
|
|
||||||
struct sekito_io_config *cfg,
|
|
||||||
const wchar_t *filename)
|
|
||||||
{
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
|
|
||||||
cfg->vk_test = GetPrivateProfileIntW(L"io4", L"test", '1', filename);
|
|
||||||
cfg->vk_service = GetPrivateProfileIntW(L"io4", L"service", '2', filename);
|
|
||||||
cfg->vk_coin = GetPrivateProfileIntW(L"io4", L"coin", '3', filename);
|
|
||||||
cfg->vk_sw1 = GetPrivateProfileIntW(L"io4", L"sw1", '4', filename);
|
|
||||||
cfg->vk_sw2 = GetPrivateProfileIntW(L"io4", L"sw2", '5', filename);
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"io4",
|
|
||||||
L"mode",
|
|
||||||
L"keyboard",
|
|
||||||
cfg->mode,
|
|
||||||
_countof(cfg->mode),
|
|
||||||
filename);
|
|
||||||
|
|
||||||
sekito_kb_config_load(&cfg->kb, filename);
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
struct sekito_kb_config {
|
|
||||||
uint8_t vk_menu;
|
|
||||||
uint8_t vk_start;
|
|
||||||
uint8_t vk_stratagem;
|
|
||||||
uint8_t vk_stratagem_lock;
|
|
||||||
uint8_t vk_hougu;
|
|
||||||
|
|
||||||
uint8_t vk_tenkey_0;
|
|
||||||
uint8_t vk_tenkey_1;
|
|
||||||
uint8_t vk_tenkey_2;
|
|
||||||
uint8_t vk_tenkey_3;
|
|
||||||
uint8_t vk_tenkey_4;
|
|
||||||
uint8_t vk_tenkey_5;
|
|
||||||
uint8_t vk_tenkey_6;
|
|
||||||
uint8_t vk_tenkey_7;
|
|
||||||
uint8_t vk_tenkey_8;
|
|
||||||
uint8_t vk_tenkey_9;
|
|
||||||
uint8_t vk_tenkey_clear;
|
|
||||||
uint8_t vk_tenkey_enter;
|
|
||||||
|
|
||||||
uint8_t vk_terminal_up;
|
|
||||||
uint8_t vk_terminal_right;
|
|
||||||
uint8_t vk_terminal_down;
|
|
||||||
uint8_t vk_terminal_left;
|
|
||||||
uint8_t vk_terminal_left_2;
|
|
||||||
uint8_t vk_terminal_right_2;
|
|
||||||
uint8_t vk_terminal_reserve;
|
|
||||||
uint8_t vk_terminal_cancel;
|
|
||||||
uint8_t vk_terminal_decide;
|
|
||||||
|
|
||||||
uint8_t x_down;
|
|
||||||
uint8_t x_up;
|
|
||||||
uint8_t y_down;
|
|
||||||
uint8_t y_up;
|
|
||||||
uint8_t speed;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sekito_io_config {
|
|
||||||
uint8_t vk_test;
|
|
||||||
uint8_t vk_service;
|
|
||||||
uint8_t vk_coin;
|
|
||||||
uint8_t vk_sw1;
|
|
||||||
uint8_t vk_sw2;
|
|
||||||
|
|
||||||
wchar_t mode[12];
|
|
||||||
struct sekito_kb_config kb;
|
|
||||||
};
|
|
||||||
|
|
||||||
void sekito_kb_config_load(struct sekito_kb_config *cfg, const wchar_t *filename);
|
|
||||||
void sekito_io_config_load(
|
|
||||||
struct sekito_io_config *cfg,
|
|
||||||
const wchar_t *filename);
|
|
@ -1,168 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#include "sekitoio/backend.h"
|
|
||||||
#include "sekitoio/config.h"
|
|
||||||
#include "sekitoio/sekitoio.h"
|
|
||||||
#include "sekitoio/keyboard.h"
|
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
|
|
||||||
static void sekito_kb_get_gamebtns(uint32_t* gamebtn_out);
|
|
||||||
static void sekito_kb_get_trackball(uint16_t* x, uint16_t* y);
|
|
||||||
|
|
||||||
static const struct sekito_io_backend sekito_kb_backend = {
|
|
||||||
.get_gamebtns = sekito_kb_get_gamebtns,
|
|
||||||
.get_trackball = sekito_kb_get_trackball
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint16_t current_x;
|
|
||||||
static uint16_t current_y;
|
|
||||||
|
|
||||||
static struct sekito_kb_config config;
|
|
||||||
|
|
||||||
HRESULT sekito_kb_init(const struct sekito_kb_config* cfg, const struct sekito_io_backend** backend) {
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(backend != NULL);
|
|
||||||
|
|
||||||
dprintf("Keyboard: Using keyboard input\n");
|
|
||||||
*backend = &sekito_kb_backend;
|
|
||||||
config = *cfg;
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sekito_kb_get_gamebtns(uint32_t* gamebtn_out) {
|
|
||||||
assert(gamebtn_out != NULL);
|
|
||||||
|
|
||||||
uint32_t gamebtn = 0;
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_hougu) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_HOUGU;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_menu) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_MENU;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_start) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_START;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_stratagem) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_STRATAGEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_stratagem_lock) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_STRATAGEM_LOCK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_0) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_NUMPAD_0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_1) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_NUMPAD_1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_2) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_NUMPAD_2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_3) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_NUMPAD_3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_4) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_NUMPAD_4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_5) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_NUMPAD_5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_6) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_NUMPAD_6;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_7) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_NUMPAD_7;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_8) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_NUMPAD_8;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_9) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_NUMPAD_9;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_clear) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_NUMPAD_CLEAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_tenkey_enter) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_NUMPAD_ENTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_terminal_cancel) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_TERMINAL_CANCEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_terminal_decide) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_TERMINAL_DECIDE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_terminal_up) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_TERMINAL_UP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_terminal_right) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_TERMINAL_RIGHT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_terminal_down) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_TERMINAL_DOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_terminal_left) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_TERMINAL_LEFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_terminal_left_2) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_TERMINAL_LEFT_2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_terminal_right_2) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_TERMINAL_RIGHT_2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.vk_terminal_reserve) & 0x8000) {
|
|
||||||
gamebtn |= SEKITO_IO_GAMEBTN_TERMINAL_RESERVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*gamebtn_out = gamebtn;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sekito_kb_get_trackball(uint16_t* x, uint16_t* y) {
|
|
||||||
assert(x != NULL);
|
|
||||||
assert(y != NULL);
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(config.x_down) & 0x8000) {
|
|
||||||
current_x -= config.speed;
|
|
||||||
} else if (GetAsyncKeyState(config.x_up) & 0x8000) {
|
|
||||||
current_x += config.speed;
|
|
||||||
}
|
|
||||||
if (GetAsyncKeyState(config.y_down) & 0x8000) {
|
|
||||||
current_y += config.speed;
|
|
||||||
} else if (GetAsyncKeyState(config.y_up) & 0x8000) {
|
|
||||||
current_y -= config.speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
*x = current_x;
|
|
||||||
*y = current_y;
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include "sekitoio/backend.h"
|
|
||||||
#include "sekitoio/config.h"
|
|
||||||
|
|
||||||
HRESULT sekito_kb_init(const struct sekito_kb_config *cfg, const struct sekito_io_backend **backend);
|
|
@ -1,18 +0,0 @@
|
|||||||
sekitoio_lib = static_library(
|
|
||||||
'sekitoio',
|
|
||||||
name_prefix : '',
|
|
||||||
include_directories : inc,
|
|
||||||
implicit_include_directories : false,
|
|
||||||
dependencies : [
|
|
||||||
xinput_lib,
|
|
||||||
],
|
|
||||||
sources : [
|
|
||||||
'config.c',
|
|
||||||
'config.h',
|
|
||||||
'backend.h',
|
|
||||||
'keyboard.c',
|
|
||||||
'keyboard.h',
|
|
||||||
'sekitoio.c',
|
|
||||||
'sekitoio.h',
|
|
||||||
],
|
|
||||||
)
|
|
@ -1,108 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
#include <xinput.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "sekitoio/sekitoio.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "keyboard.h"
|
|
||||||
#include "sekitoio/config.h"
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
#include "util/env.h"
|
|
||||||
#include "util/str.h"
|
|
||||||
|
|
||||||
static uint8_t sekito_opbtn;
|
|
||||||
static uint32_t sekito_gamebtn;
|
|
||||||
static uint8_t sekito_stick_x;
|
|
||||||
static uint8_t sekito_stick_y;
|
|
||||||
static struct sekito_io_config sekito_io_cfg;
|
|
||||||
static const struct sekito_io_backend* sekito_io_backend;
|
|
||||||
static bool sekito_io_coin;
|
|
||||||
|
|
||||||
uint16_t sekito_io_get_api_version(void) {
|
|
||||||
return 0x0100;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT sekito_io_init(void) {
|
|
||||||
sekito_io_config_load(&sekito_io_cfg, get_config_path());
|
|
||||||
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
if (wstr_ieq(sekito_io_cfg.mode, L"keyboard")) {
|
|
||||||
hr = sekito_kb_init(&sekito_io_cfg.kb, &sekito_io_backend);
|
|
||||||
} else {
|
|
||||||
hr = E_INVALIDARG;
|
|
||||||
dprintf("Sekito IO: Invalid IO mode \"%S\", use keyboard\n",
|
|
||||||
sekito_io_cfg.mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT sekito_io_poll(void) {
|
|
||||||
assert(sekito_io_backend != NULL);
|
|
||||||
|
|
||||||
sekito_opbtn = 0;
|
|
||||||
sekito_gamebtn = 0;
|
|
||||||
sekito_stick_x = 0;
|
|
||||||
sekito_stick_y = 0;
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(sekito_io_cfg.vk_test) & 0x8000) {
|
|
||||||
sekito_opbtn |= SEKITO_IO_OPBTN_TEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(sekito_io_cfg.vk_service) & 0x8000) {
|
|
||||||
sekito_opbtn |= SEKITO_IO_OPBTN_SERVICE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(sekito_io_cfg.vk_sw1) & 0x8000) {
|
|
||||||
sekito_opbtn |= SEKITO_IO_OPBTN_SW1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(sekito_io_cfg.vk_sw2) & 0x8000) {
|
|
||||||
sekito_opbtn |= SEKITO_IO_OPBTN_SW2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(sekito_io_cfg.vk_coin) & 0x8000) {
|
|
||||||
if (!sekito_io_coin) {
|
|
||||||
sekito_io_coin = true;
|
|
||||||
sekito_opbtn |= SEKITO_IO_OPBTN_COIN;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sekito_io_coin = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sekito_io_get_opbtns(uint8_t* opbtn) {
|
|
||||||
if (opbtn != NULL) {
|
|
||||||
*opbtn = sekito_opbtn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sekito_io_get_gamebtns(uint32_t* btn) {
|
|
||||||
assert(sekito_io_backend != NULL);
|
|
||||||
assert(btn != NULL);
|
|
||||||
|
|
||||||
sekito_io_backend->get_gamebtns(btn);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sekito_io_get_trackball_position(uint16_t* stick_x, uint16_t* stick_y) {
|
|
||||||
assert(sekito_io_backend != NULL);
|
|
||||||
assert(stick_x != NULL);
|
|
||||||
assert(stick_y != NULL);
|
|
||||||
|
|
||||||
sekito_io_backend->get_trackball(stick_x, stick_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT sekito_io_led_init(void) {
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sekito_io_led_set_colors(uint8_t board, uint8_t* rgb) {
|
|
||||||
return;
|
|
||||||
}
|
|
@ -1,104 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
enum {
|
|
||||||
SEKITO_IO_OPBTN_TEST = 0x01,
|
|
||||||
SEKITO_IO_OPBTN_SERVICE = 0x02,
|
|
||||||
SEKITO_IO_OPBTN_COIN = 0x04,
|
|
||||||
SEKITO_IO_OPBTN_SW1 = 0x08,
|
|
||||||
SEKITO_IO_OPBTN_SW2 = 0x10,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
SEKITO_IO_GAMEBTN_MENU = 0x01,
|
|
||||||
SEKITO_IO_GAMEBTN_START = 0x02,
|
|
||||||
SEKITO_IO_GAMEBTN_STRATAGEM = 0x04,
|
|
||||||
SEKITO_IO_GAMEBTN_STRATAGEM_LOCK = 0x08,
|
|
||||||
SEKITO_IO_GAMEBTN_HOUGU = 0x10,
|
|
||||||
SEKITO_IO_GAMEBTN_NUMPAD_0 = 0x100,
|
|
||||||
SEKITO_IO_GAMEBTN_NUMPAD_1 = 0x200,
|
|
||||||
SEKITO_IO_GAMEBTN_NUMPAD_2 = 0x400,
|
|
||||||
SEKITO_IO_GAMEBTN_NUMPAD_3 = 0x800,
|
|
||||||
SEKITO_IO_GAMEBTN_NUMPAD_4 = 0x1000,
|
|
||||||
SEKITO_IO_GAMEBTN_NUMPAD_5 = 0x2000,
|
|
||||||
SEKITO_IO_GAMEBTN_NUMPAD_6 = 0x4000,
|
|
||||||
SEKITO_IO_GAMEBTN_NUMPAD_7 = 0x8000,
|
|
||||||
SEKITO_IO_GAMEBTN_NUMPAD_8 = 0x10000,
|
|
||||||
SEKITO_IO_GAMEBTN_NUMPAD_9 = 0x20000,
|
|
||||||
SEKITO_IO_GAMEBTN_NUMPAD_CLEAR = 0x40000,
|
|
||||||
SEKITO_IO_GAMEBTN_NUMPAD_ENTER = 0x80000,
|
|
||||||
SEKITO_IO_GAMEBTN_TERMINAL_LEFT = 0x400000,
|
|
||||||
SEKITO_IO_GAMEBTN_TERMINAL_UP = 0x800000,
|
|
||||||
SEKITO_IO_GAMEBTN_TERMINAL_RIGHT = 0x1000000,
|
|
||||||
SEKITO_IO_GAMEBTN_TERMINAL_DOWN = 0x2000000,
|
|
||||||
SEKITO_IO_GAMEBTN_TERMINAL_LEFT_2 = 0x4000000,
|
|
||||||
SEKITO_IO_GAMEBTN_TERMINAL_RIGHT_2 = 0x8000000,
|
|
||||||
SEKITO_IO_GAMEBTN_TERMINAL_DECIDE = 0x10000000,
|
|
||||||
SEKITO_IO_GAMEBTN_TERMINAL_CANCEL = 0x20000000,
|
|
||||||
SEKITO_IO_GAMEBTN_TERMINAL_RESERVE = 0x40000000,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Get the version of the Eiketsu Taisen IO API that this DLL supports. This
|
|
||||||
function should return a positive 16-bit integer, where the high byte is
|
|
||||||
the major version and the low byte is the minor version (as defined by the
|
|
||||||
Semantic Versioning standard).
|
|
||||||
|
|
||||||
The latest API version as of this writing is 0x0100. */
|
|
||||||
|
|
||||||
uint16_t sekito_io_get_api_version(void);
|
|
||||||
|
|
||||||
/* Initialize the IO DLL. This is the second function that will be called on
|
|
||||||
your DLL, after sekito_io_get_api_version.
|
|
||||||
|
|
||||||
All subsequent calls to this API may originate from arbitrary threads.
|
|
||||||
|
|
||||||
Minimum API version: 0x0100 */
|
|
||||||
|
|
||||||
HRESULT sekito_io_init(void);
|
|
||||||
|
|
||||||
/* Send any queued outputs (of which there are currently none, though this may
|
|
||||||
change in subsequent API versions) and retrieve any new inputs.
|
|
||||||
|
|
||||||
Minimum API version: 0x0100 */
|
|
||||||
|
|
||||||
HRESULT sekito_io_poll(void);
|
|
||||||
|
|
||||||
/* Get the state of the cabinet's operator buttons as of the last poll. See
|
|
||||||
SEKITO_IO_OPBTN enum above: this contains bit mask definitions for button
|
|
||||||
states returned in *opbtn. All buttons are active-high.
|
|
||||||
|
|
||||||
Minimum API version: 0x0100 */
|
|
||||||
|
|
||||||
void sekito_io_get_opbtns(uint8_t *opbtn);
|
|
||||||
|
|
||||||
/* Get the state of the cabinet's gameplay buttons as of the last poll. See
|
|
||||||
SEKITO_IO_GAMEBTN enum above: this contains bit mask definitions for button
|
|
||||||
states returned in *gamebtn. All buttons are active-high.
|
|
||||||
|
|
||||||
Minimum API version: 0x0100 */
|
|
||||||
|
|
||||||
void sekito_io_get_gamebtns(uint32_t *gamebtn);
|
|
||||||
|
|
||||||
/* Get the position of the trackball as of the last poll.
|
|
||||||
|
|
||||||
Minimum API version: 0x0100 */
|
|
||||||
|
|
||||||
void sekito_io_get_trackball_position(uint16_t *stick_x, uint16_t *stick_y);
|
|
||||||
|
|
||||||
/* Initialize LED emulation. This function will be called before any
|
|
||||||
other sekito_io_led_*() function calls.
|
|
||||||
|
|
||||||
All subsequent calls may originate from arbitrary threads and some may
|
|
||||||
overlap with each other. Ensuring synchronization inside your IO DLL is
|
|
||||||
your responsibility. */
|
|
||||||
|
|
||||||
HRESULT sekito_io_led_init(void);
|
|
||||||
|
|
||||||
/* Update the RGB LEDs.
|
|
||||||
|
|
||||||
Exact layout is TBD. */
|
|
||||||
|
|
||||||
void sekito_io_led_set_colors(uint8_t board, uint8_t *rgb);
|
|
@ -97,7 +97,6 @@ bcrypt_lib = cc.find_library('bcrypt')
|
|||||||
|
|
||||||
inc = include_directories('common', 'games')
|
inc = include_directories('common', 'games')
|
||||||
capnhook = subproject('capnhook')
|
capnhook = subproject('capnhook')
|
||||||
cwinwebsocket = subproject('cwinwebsocket')
|
|
||||||
|
|
||||||
subdir('common/amex')
|
subdir('common/amex')
|
||||||
subdir('common/iccard')
|
subdir('common/iccard')
|
||||||
@ -107,7 +106,6 @@ subdir('common/jvs')
|
|||||||
subdir('common/platform')
|
subdir('common/platform')
|
||||||
subdir('common/util')
|
subdir('common/util')
|
||||||
subdir('common/aimeio')
|
subdir('common/aimeio')
|
||||||
subdir('common/y3io')
|
|
||||||
|
|
||||||
subdir('common/gfxhook')
|
subdir('common/gfxhook')
|
||||||
subdir('common/unityhook')
|
subdir('common/unityhook')
|
||||||
@ -127,8 +125,6 @@ subdir('games/tokyoio')
|
|||||||
subdir('games/fgoio')
|
subdir('games/fgoio')
|
||||||
subdir('games/kemonoio')
|
subdir('games/kemonoio')
|
||||||
subdir('games/apm3io')
|
subdir('games/apm3io')
|
||||||
subdir('games/sekitoio')
|
|
||||||
subdir('games/ektio')
|
|
||||||
|
|
||||||
subdir('games/chunihook')
|
subdir('games/chunihook')
|
||||||
subdir('games/divahook')
|
subdir('games/divahook')
|
||||||
@ -146,5 +142,3 @@ subdir('games/tokyohook')
|
|||||||
subdir('games/fgohook')
|
subdir('games/fgohook')
|
||||||
subdir('games/kemonohook')
|
subdir('games/kemonohook')
|
||||||
subdir('games/apm3hook')
|
subdir('games/apm3hook')
|
||||||
subdir('games/ekthook')
|
|
||||||
subdir('games/sekitohook')
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user