diff --git a/board/sg-nfc-cmd.h b/board/sg-nfc-cmd.h index 604783b..08923fd 100644 --- a/board/sg-nfc-cmd.h +++ b/board/sg-nfc-cmd.h @@ -11,10 +11,10 @@ enum { SG_NFC_CMD_RADIO_OFF = 0x41, SG_NFC_CMD_POLL = 0x42, SG_NFC_CMD_MIFARE_SELECT_TAG = 0x43, - SG_NFC_CMD_MIFARE_SET_KEY_A = 0x50, + SG_NFC_CMD_MIFARE_SET_KEY_AIME = 0x50, SG_NFC_CMD_MIFARE_AUTHENTICATE_A = 0x51, SG_NFC_CMD_MIFARE_READ_BLOCK = 0x52, - SG_NFC_CMD_MIFARE_SET_KEY_B = 0x54, + SG_NFC_CMD_MIFARE_SET_KEY_BANA = 0x54, SG_NFC_CMD_MIFARE_AUTHENTICATE_B = 0x55, SG_NFC_CMD_TO_UPDATE_MODE = 0x60, SG_NFC_CMD_SEND_HEX_DATA = 0x61, diff --git a/board/sg-nfc.c b/board/sg-nfc.c index 19a6ad6..49309f8 100644 --- a/board/sg-nfc.c +++ b/board/sg-nfc.c @@ -189,7 +189,7 @@ static HRESULT sg_nfc_dispatch( &req->felica_encap, &res->felica_encap); - case SG_NFC_CMD_MIFARE_AUTHENTICATE: + case SG_NFC_CMD_MIFARE_AUTHENTICATE_A: case SG_NFC_CMD_SEND_HEX_DATA: return sg_nfc_cmd_send_hex_data(nfc, &req->simple, &res->simple); diff --git a/cmhook/dllmain.c b/cmhook/dllmain.c index ac54a9d..7020f75 100644 --- a/cmhook/dllmain.c +++ b/cmhook/dllmain.c @@ -101,7 +101,7 @@ static DWORD CALLBACK cm_pre_startup(void) There seems to be an issue with other DLL hooks if `LoadLibraryW` is hooked earlier in the `cmhook` initialization. */ - unity_hook_init(&cm_hook_cfg.unity, cm_hook_mod); + unity_hook_init(&cm_hook_cfg.unity, cm_hook_mod, NULL); /* Initialize debug helpers */ diff --git a/dist/kemono/segatools.ini b/dist/kemono/segatools.ini new file mode 100644 index 0000000..7bb293e --- /dev/null +++ b/dist/kemono/segatools.ini @@ -0,0 +1,145 @@ +; ----------------------------------------------------------------------------- +; 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 + +[vfd] +; Enable VFD emulation (currently just stubbed). Disable to use a real VFD +; GP1232A02A FUTABA assembly. +enable=1 + +; ----------------------------------------------------------------------------- +; 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 its LAN environment, so leaving this +; setting enabled is recommended. +enable=1 +; The final octet of the local host's IP address on the virtualized subnet (so, +; if the keychip subnet is `192.168.32.0` and this value is set to `11`, then the +; local host's virtualized LAN IP is `192.168.32.11`). +addrSuffix=11 + +; ----------------------------------------------------------------------------- +; Board settings +; ----------------------------------------------------------------------------- + +[keychip] +; 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.172.0 + +[gpio] +; Emulated Nu DIP switch for Distribution Server setting. +; +; If multiple machines are present on the same LAN then set this to 1 on +; exactly one machine and set this to 0 on all others. +dipsw1=1 + +; Chassis Test button virtual-key code. Default is the 4 key. +test=0x34 +; Chassis Service button virtual-key code. Default is the 5 key. +service=0x35 + +; ----------------------------------------------------------------------------- +; Misc. hook 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= + +[printer] +; Sinfonia CHC-C300 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" + +; ----------------------------------------------------------------------------- +; LED settings +; ----------------------------------------------------------------------------- + +[led15093] +; 837-15093-06 LED board emulation setting. +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= + +[kemonoio] +; To use a custom Kemono IO DLL enter its path here. +; Leave empty if you want to use Segatools built-in keyboard input. +path= + +; ----------------------------------------------------------------------------- +; Input settings +; ----------------------------------------------------------------------------- + +; Keyboard bindings are specified 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. + +[io3] +; Test button virtual-key code. Default is the 1 key. +test=0x31 +; Service button virtual-key code. Default is the 2 key. +service=0x32 +; Keyboard button to increment coin counter. Default is the 3 key. +coin=0x33 + +; Analog lever (which is actually just four buttons, and not real analog input, default: Arrow keys) +left=0x25 +right=0x27 +up=0x26 +down=0x28 + +; Controller face buttons (default A, S, D) +red=0x41 +green=0x53 +blue=0x44 + +; Menu confirmation key (default RETURN) +start=0x0D \ No newline at end of file diff --git a/dist/kemono/start.bat b/dist/kemono/start.bat new file mode 100644 index 0000000..7f3bfa9 --- /dev/null +++ b/dist/kemono/start.bat @@ -0,0 +1,12 @@ +@echo off + +pushd %~dp0 + +start "AM Daemon" /min cmd /C timeout 10 ^& inject_x64 -d -k kemonohook_x64.dll ../amdaemon.exe -f -c ../config.json" +inject_x86 -d -k kemonohook_x86.dll Parade -screen-fullscreen 0 -popupwindow -screen-width 720 -screen-height 1280 -silent-crashes + +taskkill /f /im amdaemon.exe > nul 2>&1 + +echo. +echo Game processes have terminated +pause \ No newline at end of file diff --git a/hooklib/printer.c b/hooklib/printer.c index 7ce0ee0..3ea4e70 100644 --- a/hooklib/printer.c +++ b/hooklib/printer.c @@ -11,6 +11,7 @@ #include "hooklib/printer.h" +#include #include #include #include @@ -60,44 +61,44 @@ static uint8_t STATUS = 0; /* C3XXFWDLusb API hooks */ -int fwdlusb_open(uint16_t *rResult); -void fwdlusb_close(); -int fwdlusb_listupPrinter(uint8_t *rIdArray); -int fwdlusb_listupPrinterSN(uint64_t *rSerialArray); -int fwdlusb_selectPrinter(uint8_t printerId, uint16_t *rResult); -int fwdlusb_selectPrinterSN(uint64_t printerSN, uint16_t *rResult); -int fwdlusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen); -int fwdlusb_status(uint16_t *rResult); -int fwdlusb_statusAll(uint8_t *idArray, uint16_t *rResultArray); -int fwdlusb_resetPrinter(uint16_t *rResult); -int fwdlusb_updateFirmware(uint8_t update, LPCSTR filename, uint16_t *rResult); -int fwdlusb_getFirmwareInfo(uint8_t update, LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult); -int fwdlusb_MakeThread(uint16_t maxCount); -int fwdlusb_ReleaseThread(uint16_t *rResult); -int fwdlusb_AttachThreadCount(uint16_t *rCount, uint16_t *rMaxCount); -int fwdlusb_getErrorLog(uint16_t index, uint8_t *rData, uint16_t *rResult); +__stdcall int fwdlusb_open(uint16_t *rResult); +__stdcall void fwdlusb_close(); +__stdcall int fwdlusb_listupPrinter(uint8_t *rIdArray); +__stdcall int fwdlusb_listupPrinterSN(uint64_t *rSerialArray); +__stdcall int fwdlusb_selectPrinter(uint8_t printerId, uint16_t *rResult); +__stdcall int fwdlusb_selectPrinterSN(uint64_t printerSN, uint16_t *rResult); +__stdcall int fwdlusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen); +__stdcall int fwdlusb_status(uint16_t *rResult); +__stdcall int fwdlusb_statusAll(uint8_t *idArray, uint16_t *rResultArray); +__stdcall int fwdlusb_resetPrinter(uint16_t *rResult); +__stdcall int fwdlusb_updateFirmware(uint8_t update, LPCSTR filename, uint16_t *rResult); +__stdcall int fwdlusb_getFirmwareInfo(uint8_t update, LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult); +__stdcall int fwdlusb_MakeThread(uint16_t maxCount); +__stdcall int fwdlusb_ReleaseThread(uint16_t *rResult); +__stdcall int fwdlusb_AttachThreadCount(uint16_t *rCount, uint16_t *rMaxCount); +__stdcall int fwdlusb_getErrorLog(uint16_t index, uint8_t *rData, uint16_t *rResult); /* C3XXusb API hooks */ -int chcusb_MakeThread(uint16_t maxCount); -int chcusb_open(uint16_t *rResult); -void chcusb_close(); -int chcusb_ReleaseThread(uint16_t *rResult); -int chcusb_listupPrinter(uint8_t *rIdArray); -int chcusb_listupPrinterSN(uint64_t *rSerialArray); -int chcusb_selectPrinter(uint8_t printerId, uint16_t *rResult); -int chcusb_selectPrinterSN(uint64_t printerSN, uint16_t *rResult); -int chcusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen); -int chcusb_imageformat( +__stdcall int chcusb_MakeThread(uint16_t maxCount); +__stdcall int chcusb_open(uint16_t *rResult); +__stdcall void chcusb_close(); +__stdcall int chcusb_ReleaseThread(uint16_t *rResult); +__stdcall int chcusb_listupPrinter(uint8_t *rIdArray); +__stdcall int chcusb_listupPrinterSN(uint64_t *rSerialArray); +__stdcall int chcusb_selectPrinter(uint8_t printerId, uint16_t *rResult); +__stdcall int chcusb_selectPrinterSN(uint64_t printerSN, uint16_t *rResult); +__stdcall int chcusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen); +__stdcall int chcusb_imageformat( uint16_t format, uint16_t ncomp, uint16_t depth, uint16_t width, uint16_t height, uint16_t *rResult); -int chcusb_setmtf(int32_t *mtf); -int chcusb_makeGamma(uint16_t k, uint8_t *intoneR, uint8_t *intoneG, uint8_t *intoneB); -int chcusb_setIcctable( +__thiscall int chcusb_setmtf(int32_t *mtf); +__stdcall int chcusb_makeGamma(uint16_t k, uint8_t *intoneR, uint8_t *intoneG, uint8_t *intoneB); +__stdcall int chcusb_setIcctable( LPCSTR icc1, LPCSTR icc2, uint16_t intents, @@ -108,40 +109,42 @@ int chcusb_setIcctable( uint8_t *outtoneG, uint8_t *outtoneB, uint16_t *rResult); -int chcusb_copies(uint16_t copies, uint16_t *rResult); -int chcusb_status(uint16_t *rResult); -int chcusb_statusAll(uint8_t *idArray, uint16_t *rResultArray); -int chcusb_startpage(uint16_t postCardState, uint16_t *pageId, uint16_t *rResult); -int chcusb_endpage(uint16_t *rResult); -int chcusb_write(uint8_t *data, uint32_t *writeSize, uint16_t *rResult); -int chcusb_writeLaminate(uint8_t *data, uint32_t *writeSize, uint16_t *rResult); -int chcusb_writeHolo(uint8_t *data, uint32_t *writeSize, uint16_t *rResult); -int chcusb_setPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult); -int chcusb_getGamma(LPCSTR filename, uint8_t *r, uint8_t *g, uint8_t *b, uint16_t *rResult); -int chcusb_getMtf(LPCSTR filename, int32_t *mtf, uint16_t *rResult); -int chcusb_cancelCopies(uint16_t pageId, uint16_t *rResult); -int chcusb_setPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, uint16_t *rResult); -int chcusb_getPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, uint16_t *rResult); -int chcusb_blinkLED(uint16_t *rResult); -int chcusb_resetPrinter(uint16_t *rResult); -int chcusb_AttachThreadCount(uint16_t *rCount, uint16_t *rMaxCount); -int chcusb_getPrintIDStatus(uint16_t pageId, uint8_t *rBuffer, uint16_t *rResult); -int chcusb_setPrintStandby(uint16_t position, uint16_t *rResult); -int chcusb_testCardFeed(uint16_t mode, uint16_t times, uint16_t *rResult); -int chcusb_exitCard(uint16_t *rResult); -int chcusb_getCardRfidTID(uint8_t *rCardTID, uint16_t *rResult); -int chcusb_commCardRfidReader(uint8_t *sendData, uint8_t *rRecvData, uint32_t sendSize, uint32_t *rRecvSize, uint16_t *rResult); -int chcusb_updateCardRfidReader(uint8_t *data, uint32_t size, uint16_t *rResult); -int chcusb_getErrorLog(uint16_t index, uint8_t *rData, uint16_t *rResult); -int chcusb_getErrorStatus(uint16_t *rBuffer); -int chcusb_setCutList(uint8_t *rData, uint16_t *rResult); -int chcusb_setLaminatePattern(uint16_t index, uint8_t *rData, uint16_t *rResult); -int chcusb_color_adjustment(LPCSTR filename, int32_t a2, int32_t a3, int16_t a4, int16_t a5, int64_t a6, int64_t a7, uint16_t *rResult); -int chcusb_color_adjustmentEx(int32_t a1, int32_t a2, int32_t a3, int16_t a4, int16_t a5, int64_t a6, int64_t a7, uint16_t *rResult); -int chcusb_getEEPROM(uint8_t index, uint8_t *rData, uint16_t *rResult); -int chcusb_setParameter(uint8_t a1, uint32_t a2, uint16_t *rResult); -int chcusb_getParameter(uint8_t a1, uint8_t *a2, uint16_t *rResult); -int chcusb_universal_command(int32_t a1, uint8_t a2, int32_t a3, uint8_t *a4, uint16_t *rResult); +__stdcall int chcusb_copies(uint16_t copies, uint16_t *rResult); +__stdcall int chcusb_status(uint16_t *rResult); +__stdcall int chcusb_statusAll(uint8_t *idArray, uint16_t *rResultArray); +__stdcall int chcusb_startpage(uint16_t postCardState, uint16_t *pageId, uint16_t *rResult); +__stdcall int chcusb_startpage_300(uint16_t postCardState, uint16_t *rResult); +__stdcall int chcusb_endpage(uint16_t *rResult); +__stdcall int chcusb_write(uint8_t *data, uint32_t *writeSize, uint16_t *rResult); +__stdcall int chcusb_writeLaminate(uint8_t *data, uint32_t *writeSize, uint16_t *rResult); +__stdcall int chcusb_writeHolo(uint8_t *data, uint32_t *writeSize, uint16_t *rResult); +__stdcall int chcusb_setPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult); +__stdcall int chcusb_getGamma(LPCSTR filename, uint8_t *r, uint8_t *g, uint8_t *b, uint16_t *rResult); +__stdcall int chcusb_getMtf(LPCSTR filename, int32_t *mtf, uint16_t *rResult); +__stdcall int chcusb_cancelCopies(uint16_t pageId, uint16_t *rResult); +__stdcall int chcusb_setPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, uint16_t *rResult); +__stdcall int chcusb_getPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, uint16_t *rResult); +__stdcall int chcusb_blinkLED(uint16_t *rResult); +__stdcall int chcusb_resetPrinter(uint16_t *rResult); +__stdcall int chcusb_AttachThreadCount(uint16_t *rCount, uint16_t *rMaxCount); +__stdcall int chcusb_getPrintIDStatus(uint16_t pageId, uint8_t *rBuffer, uint16_t *rResult); +__stdcall int chcusb_setPrintStandby(uint16_t position, uint16_t *rResult); +__stdcall int chcusb_setPrintStandby_300(uint16_t *rResult); +__stdcall int chcusb_testCardFeed(uint16_t mode, uint16_t times, uint16_t *rResult); +__stdcall int chcusb_exitCard(uint16_t *rResult); +__stdcall int chcusb_getCardRfidTID(uint8_t *rCardTID, uint16_t *rResult); +__stdcall int chcusb_commCardRfidReader(uint8_t *sendData, uint8_t *rRecvData, uint32_t sendSize, uint32_t *rRecvSize, uint16_t *rResult); +__stdcall int chcusb_updateCardRfidReader(uint8_t *data, uint32_t size, uint16_t *rResult); +__stdcall int chcusb_getErrorLog(uint16_t index, uint8_t *rData, uint16_t *rResult); +__stdcall int chcusb_getErrorStatus(uint16_t *rBuffer); +__stdcall int chcusb_setCutList(uint8_t *rData, uint16_t *rResult); +__stdcall int chcusb_setLaminatePattern(uint16_t index, uint8_t *rData, uint16_t *rResult); +__stdcall int chcusb_color_adjustment(LPCSTR filename, int32_t a2, int32_t a3, int16_t a4, int16_t a5, int64_t a6, int64_t a7, uint16_t *rResult); +__stdcall int chcusb_color_adjustmentEx(int32_t a1, int32_t a2, int32_t a3, int16_t a4, int16_t a5, int64_t a6, int64_t a7, uint16_t *rResult); +__stdcall int chcusb_getEEPROM(uint8_t index, uint8_t *rData, uint16_t *rResult); +__stdcall int chcusb_setParameter(uint8_t a1, uint32_t a2, uint16_t *rResult); +__stdcall int chcusb_getParameter(uint8_t a1, uint8_t *a2, uint16_t *rResult); +__stdcall int chcusb_universal_command(int32_t a1, uint8_t a2, int32_t a3, uint8_t *a4, uint16_t *rResult); /* PrintDLL API hooks */ @@ -491,7 +494,7 @@ static const struct hook_symbol C300usb_hooks[] = { }, { .name = "chcusb_startpage", .ordinal = 0x0011, - .patch = chcusb_startpage, + .patch = chcusb_startpage_300, .link = NULL }, { .name = "chcusb_endpage", @@ -561,7 +564,7 @@ static const struct hook_symbol C300usb_hooks[] = { }, { .name = "chcusb_setPrintStandby", .ordinal = 0x001f, - .patch = chcusb_setPrintStandby, + .patch = chcusb_setPrintStandby_300, .link = NULL }, { .name = "chcusb_testCardFeed", @@ -1619,7 +1622,7 @@ static HRESULT deck_frame_encode_byte(struct iobuf *dest, uint8_t byte) { // C3XXFWDLusb stubs -int fwdlusb_open(uint16_t *rResult) { +__stdcall int fwdlusb_open(uint16_t *rResult) { dprintf("Printer: C3XXFWDLusb: %s\n", __func__); *rResult = 0; return 1; @@ -1627,33 +1630,33 @@ int fwdlusb_open(uint16_t *rResult) { void fwdlusb_close() {} -int fwdlusb_listupPrinter(uint8_t *rIdArray) { +__stdcall int fwdlusb_listupPrinter(uint8_t *rIdArray) { dprintf("Printer: C3XXFWDLusb: %s\n", __func__); memset(rIdArray, 0xFF, 0x80); rIdArray[0] = idNumber; return 1; } -int fwdlusb_listupPrinterSN(uint64_t *rSerialArray) { +__stdcall int fwdlusb_listupPrinterSN(uint64_t *rSerialArray) { dprintf("Printer: C3XXFWDLusb: %s\n", __func__); memset(rSerialArray, 0xFF, 0x400); rSerialArray[0] = serialNo; return 1; } -int fwdlusb_selectPrinter(uint8_t printerId, uint16_t *rResult) { +__stdcall int fwdlusb_selectPrinter(uint8_t printerId, uint16_t *rResult) { dprintf("Printer: C3XXFWDLusb: %s\n", __func__); *rResult = 0; return 1; } -int fwdlusb_selectPrinterSN(uint64_t printerSN, uint16_t *rResult) { +__stdcall int fwdlusb_selectPrinterSN(uint64_t printerSN, uint16_t *rResult) { dprintf("Printer: C3XXFWDLusb: %s\n", __func__); *rResult = 0; return 1; } -int fwdlusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen) { +__stdcall int fwdlusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen) { dprintf("Printer: C3XXFWDLusb: %s\n", __func__); switch (tagNumber) { case 0: // getPaperInfo @@ -1734,13 +1737,13 @@ int fwdlusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen) return 1; } -int fwdlusb_status(uint16_t *rResult) { +__stdcall int fwdlusb_status(uint16_t *rResult) { dprintf("Printer: C3XXFWDLusb: %s\n", __func__); *rResult = 0; return 1; } -int fwdlusb_statusAll(uint8_t *idArray, uint16_t *rResultArray) { +__stdcall int fwdlusb_statusAll(uint8_t *idArray, uint16_t *rResultArray) { dprintf("Printer: C3XXFWDLusb: %s\n", __func__); for (int i = 0; *(uint8_t *)(idArray + i) != 255 && i < 128; ++i) { *(uint16_t *)(rResultArray + 2 * i) = 0; @@ -1749,13 +1752,13 @@ int fwdlusb_statusAll(uint8_t *idArray, uint16_t *rResultArray) { return 1; } -int fwdlusb_resetPrinter(uint16_t *rResult) { +__stdcall int fwdlusb_resetPrinter(uint16_t *rResult) { dprintf("Printer: C3XXFWDLusb: %s\n", __func__); *rResult = 0; return 1; } -int fwdlusb_getFirmwareVersion(uint8_t *buffer, int size) { +__stdcall int fwdlusb_getFirmwareVersion(uint8_t *buffer, int size) { int8_t a; uint32_t b = 0; for (int32_t i = 0; i < size; ++i) { @@ -1776,7 +1779,7 @@ int fwdlusb_getFirmwareVersion(uint8_t *buffer, int size) { return b; } -int fwdlusb_updateFirmware_main(uint8_t update, LPCSTR filename, uint16_t *rResult) { +__stdcall int fwdlusb_updateFirmware_main(uint8_t update, LPCSTR filename, uint16_t *rResult) { DWORD result; HANDLE fwFile = NULL; DWORD bytesWritten = 0; @@ -1825,7 +1828,7 @@ int fwdlusb_updateFirmware_main(uint8_t update, LPCSTR filename, uint16_t *rResu return result; } -int fwdlusb_updateFirmware_dsp(uint8_t update, LPCSTR filename, uint16_t *rResult) { +__stdcall int fwdlusb_updateFirmware_dsp(uint8_t update, LPCSTR filename, uint16_t *rResult) { DWORD result; HANDLE fwFile = NULL; DWORD bytesWritten = 0; @@ -1874,7 +1877,7 @@ int fwdlusb_updateFirmware_dsp(uint8_t update, LPCSTR filename, uint16_t *rResul return result; } -int fwdlusb_updateFirmware_param(uint8_t update, LPCSTR filename, uint16_t *rResult) { +__stdcall int fwdlusb_updateFirmware_param(uint8_t update, LPCSTR filename, uint16_t *rResult) { DWORD result; HANDLE fwFile = NULL; DWORD bytesWritten = 0; @@ -1923,7 +1926,7 @@ int fwdlusb_updateFirmware_param(uint8_t update, LPCSTR filename, uint16_t *rRes return result; } -int fwdlusb_updateFirmware(uint8_t update, LPCSTR filename, uint16_t *rResult) { +__stdcall int fwdlusb_updateFirmware(uint8_t update, LPCSTR filename, uint16_t *rResult) { dprintf("Printer: C3XXFWDLusb: %s\n", __func__); if (update == 1) { return fwdlusb_updateFirmware_main(update, filename, rResult); @@ -1937,7 +1940,7 @@ int fwdlusb_updateFirmware(uint8_t update, LPCSTR filename, uint16_t *rResult) { } } -int fwdlusb_getFirmwareInfo_main(LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) { +__stdcall int fwdlusb_getFirmwareInfo_main(LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) { DWORD result; if (filename) { @@ -1973,7 +1976,7 @@ int fwdlusb_getFirmwareInfo_main(LPCSTR filename, uint8_t *rBuffer, uint32_t *rL return result; } -int fwdlusb_getFirmwareInfo_dsp(LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) { +__stdcall int fwdlusb_getFirmwareInfo_dsp(LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) { DWORD result; if (filename) { @@ -2009,7 +2012,7 @@ int fwdlusb_getFirmwareInfo_dsp(LPCSTR filename, uint8_t *rBuffer, uint32_t *rLe return result; } -int fwdlusb_getFirmwareInfo_param(LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) { +__stdcall int fwdlusb_getFirmwareInfo_param(LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) { DWORD result; if (filename) { @@ -2045,7 +2048,7 @@ int fwdlusb_getFirmwareInfo_param(LPCSTR filename, uint8_t *rBuffer, uint32_t *r return result; } -int fwdlusb_getFirmwareInfo(uint8_t update, LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) { +__stdcall int fwdlusb_getFirmwareInfo(uint8_t update, LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) { dprintf("Printer: C3XXFWDLusb: %s(update: %d, filename: %s)\n", __func__, update, filename); if (!rBuffer) { *rLen = 38; @@ -2064,25 +2067,25 @@ int fwdlusb_getFirmwareInfo(uint8_t update, LPCSTR filename, uint8_t *rBuffer, u } } -int fwdlusb_MakeThread(uint16_t maxCount) { +__stdcall int fwdlusb_MakeThread(uint16_t maxCount) { dprintf("Printer: C3XXFWDLusb: %s\n", __func__); return 1; } -int fwdlusb_ReleaseThread(uint16_t *rResult) { +__stdcall int fwdlusb_ReleaseThread(uint16_t *rResult) { dprintf("Printer: C3XXFWDLusb: %s\n", __func__); *rResult = 0; return 1; } -int fwdlusb_AttachThreadCount(uint16_t *rCount, uint16_t *rMaxCount) { +__stdcall int fwdlusb_AttachThreadCount(uint16_t *rCount, uint16_t *rMaxCount) { dprintf("Printer: C3XXFWDLusb: %s\n", __func__); *rCount = 0; *rMaxCount = 1; return 1; } -int fwdlusb_getErrorLog(uint16_t index, uint8_t *rData, uint16_t *rResult) { +__stdcall int fwdlusb_getErrorLog(uint16_t index, uint8_t *rData, uint16_t *rResult) { dprintf("Printer: C3XXFWDLusb: %s\n", __func__); *rResult = 0; return 1; @@ -2090,12 +2093,12 @@ int fwdlusb_getErrorLog(uint16_t index, uint8_t *rData, uint16_t *rResult) { // C3XXusb stubs -int chcusb_MakeThread(uint16_t maxCount) { +__stdcall int chcusb_MakeThread(uint16_t maxCount) { dprintf("Printer: C3XXusb: %s\n", __func__); return 1; } -int chcusb_open(uint16_t *rResult) { +__stdcall int chcusb_open(uint16_t *rResult) { // Seed random for card id generation srand(time(NULL)); generate_rfid(); @@ -2109,38 +2112,38 @@ void chcusb_close() { dprintf("Printer: C3XXusb: %s\n", __func__); } -int chcusb_ReleaseThread(uint16_t *rResult) { +__stdcall int chcusb_ReleaseThread(uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); return 1; } -int chcusb_listupPrinter(uint8_t *rIdArray) { +__stdcall int chcusb_listupPrinter(uint8_t *rIdArray) { dprintf("Printer: C3XXusb: %s\n", __func__); memset(rIdArray, 0xFF, 0x80); rIdArray[0] = idNumber; return 1; } -int chcusb_listupPrinterSN(uint64_t *rSerialArray) { +__stdcall int chcusb_listupPrinterSN(uint64_t *rSerialArray) { dprintf("Printer: C3XXusb: %s\n", __func__); memset(rSerialArray, 0xFF, 0x400); rSerialArray[0] = serialNo; return 1; } -int chcusb_selectPrinter(uint8_t printerId, uint16_t *rResult) { +__stdcall int chcusb_selectPrinter(uint8_t printerId, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); *rResult = 0; return 1; } -int chcusb_selectPrinterSN(uint64_t printerSN, uint16_t *rResult) { +__stdcall int chcusb_selectPrinterSN(uint64_t printerSN, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); *rResult = 0; return 1; } -int chcusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen) { +__stdcall int chcusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen) { // dprintf("Printer: C3XXusb: %s\n", __func__); switch (tagNumber) { @@ -2239,6 +2242,8 @@ int chcusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen) *rLen = 1; if (awaitingCardExit) *rBuffer = 0xF0; + else if (STATUS == 1) + *rBuffer = 1; else *rBuffer = 0; break; @@ -2294,7 +2299,7 @@ int chcusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen) return 1; } -int chcusb_imageformat( +__stdcall int chcusb_imageformat( uint16_t format, uint16_t ncomp, uint16_t depth, @@ -2310,14 +2315,14 @@ int chcusb_imageformat( return 1; } -int chcusb_setmtf(int32_t *mtf) { +__thiscall int chcusb_setmtf(int32_t *mtf) { dprintf("Printer: C3XXusb: %s\n", __func__); memcpy(MTF, mtf, sizeof(MTF)); return 1; } -int chcusb_makeGamma(uint16_t k, uint8_t *intoneR, uint8_t *intoneG, uint8_t *intoneB) { +__stdcall int chcusb_makeGamma(uint16_t k, uint8_t *intoneR, uint8_t *intoneG, uint8_t *intoneB) { dprintf("Printer: C3XXusb: %s\n", __func__); uint8_t tone; @@ -2348,7 +2353,7 @@ int chcusb_makeGamma(uint16_t k, uint8_t *intoneR, uint8_t *intoneG, uint8_t *in return 1; } -int chcusb_setIcctable( +__stdcall int chcusb_setIcctable( LPCSTR icc1, LPCSTR icc2, uint16_t intents, @@ -2361,32 +2366,34 @@ int chcusb_setIcctable( uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); - for (int i = 0; i < 256; ++i) { - intoneR[i] = i; - intoneG[i] = i; - intoneB[i] = i; - outtoneR[i] = i; - outtoneG[i] = i; - outtoneB[i] = i; + if (intoneR != NULL && intoneG != NULL && intoneB != NULL && outtoneR != NULL && outtoneG != NULL && outtoneB != NULL) { + for (int i = 0; i < 256; ++i) { + intoneR[i] = i; + intoneG[i] = i; + intoneB[i] = i; + outtoneR[i] = i; + outtoneG[i] = i; + outtoneB[i] = i; + } } *rResult = 0; return 1; } -int chcusb_copies(uint16_t copies, uint16_t *rResult) { +__stdcall int chcusb_copies(uint16_t copies, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); *rResult = 0; return 1; } -int chcusb_status(uint16_t *rResult) { +__stdcall int chcusb_status(uint16_t *rResult) { // dprintf("Printer: C3XXusb: %s\n", __func__); *rResult = 0; return 1; } -int chcusb_statusAll(uint8_t *idArray, uint16_t *rResultArray) { +__stdcall int chcusb_statusAll(uint8_t *idArray, uint16_t *rResultArray) { dprintf("Printer: C3XXusb: %s\n", __func__); for (int i = 0; *(uint8_t *)(idArray + i) != 255 && i < 128; ++i) { @@ -2396,7 +2403,7 @@ int chcusb_statusAll(uint8_t *idArray, uint16_t *rResultArray) { return 1; } -int chcusb_startpage(uint16_t postCardState, uint16_t *pageId, uint16_t *rResult) { +__stdcall int chcusb_startpage(uint16_t postCardState, uint16_t *pageId, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); STATUS = 2; @@ -2406,7 +2413,16 @@ int chcusb_startpage(uint16_t postCardState, uint16_t *pageId, uint16_t *rResult return 1; } -int chcusb_endpage(uint16_t *rResult) { +__stdcall int chcusb_startpage_300(uint16_t postCardState, uint16_t *rResult) { + dprintf("Printer: C300usb: %s\n", __func__); + + STATUS = 2; + + *rResult = 0; + return 1; +} + +__stdcall int chcusb_endpage(uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); awaitingCardExit = true; @@ -2415,7 +2431,7 @@ int chcusb_endpage(uint16_t *rResult) { return 1; } -int chcusb_write(uint8_t *data, uint32_t *writeSize, uint16_t *rResult) { +__stdcall int chcusb_write(uint8_t *data, uint32_t *writeSize, uint16_t *rResult) { SYSTEMTIME t; GetLocalTime(&t); @@ -2439,7 +2455,7 @@ int chcusb_write(uint8_t *data, uint32_t *writeSize, uint16_t *rResult) { return 1; } -int chcusb_writeLaminate(uint8_t *data, uint32_t *writeSize, uint16_t *rResult) { +__stdcall int chcusb_writeLaminate(uint8_t *data, uint32_t *writeSize, uint16_t *rResult) { SYSTEMTIME t; GetLocalTime(&t); @@ -2458,7 +2474,7 @@ int chcusb_writeLaminate(uint8_t *data, uint32_t *writeSize, uint16_t *rResult) return 1; } -int chcusb_writeHolo(uint8_t *data, uint32_t *writeSize, uint16_t *rResult) { +__stdcall int chcusb_writeHolo(uint8_t *data, uint32_t *writeSize, uint16_t *rResult) { SYSTEMTIME t; GetLocalTime(&t); @@ -2477,7 +2493,7 @@ int chcusb_writeHolo(uint8_t *data, uint32_t *writeSize, uint16_t *rResult) { return 1; } -int chcusb_setPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) { +__stdcall int chcusb_setPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); switch (tagNumber) { @@ -2495,7 +2511,7 @@ int chcusb_setPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen, return 1; } -int chcusb_getGamma(LPCSTR filename, uint8_t *r, uint8_t *g, uint8_t *b, uint16_t *rResult) { +__stdcall int chcusb_getGamma(LPCSTR filename, uint8_t *r, uint8_t *g, uint8_t *b, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); for (int i = 0; i < 256; ++i) { @@ -2508,7 +2524,7 @@ int chcusb_getGamma(LPCSTR filename, uint8_t *r, uint8_t *g, uint8_t *b, uint16_ return 1; } -int chcusb_getMtf(LPCSTR filename, int32_t *mtf, uint16_t *rResult) { +__stdcall int chcusb_getMtf(LPCSTR filename, int32_t *mtf, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); HANDLE hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); @@ -2545,13 +2561,13 @@ int chcusb_getMtf(LPCSTR filename, int32_t *mtf, uint16_t *rResult) { return 1; } -int chcusb_cancelCopies(uint16_t pageId, uint16_t *rResult) { +__stdcall int chcusb_cancelCopies(uint16_t pageId, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); *rResult = 0; return 1; } -int chcusb_setPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, uint16_t *rResult) { +__stdcall int chcusb_setPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); if ((type > 0 && type < 3) && (number > 0 && number < 3)) { CURVE[type][number] = *data; @@ -2560,7 +2576,7 @@ int chcusb_setPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, u return 1; } -int chcusb_getPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, uint16_t *rResult) { +__stdcall int chcusb_getPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); if ((type > 0 && type < 3) && (number > 0 && number < 3)) { *data = CURVE[type][number]; @@ -2569,26 +2585,26 @@ int chcusb_getPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, u return 1; } -int chcusb_blinkLED(uint16_t *rResult) { +__stdcall int chcusb_blinkLED(uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); *rResult = 0; return 1; } -int chcusb_resetPrinter(uint16_t *rResult) { +__stdcall int chcusb_resetPrinter(uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); *rResult = 0; return 1; } -int chcusb_AttachThreadCount(uint16_t *rCount, uint16_t *rMaxCount) { +__stdcall int chcusb_AttachThreadCount(uint16_t *rCount, uint16_t *rMaxCount) { dprintf("Printer: C3XXusb: %s\n", __func__); *rCount = 0; *rMaxCount = 1; return 1; } -int chcusb_getPrintIDStatus(uint16_t pageId, uint8_t *rBuffer, uint16_t *rResult) { +__stdcall int chcusb_getPrintIDStatus(uint16_t pageId, uint8_t *rBuffer, uint16_t *rResult) { // dprintf("Printer: C3XXusb: %s\n", __func__); memset(rBuffer, 0, 8); @@ -2606,7 +2622,7 @@ int chcusb_getPrintIDStatus(uint16_t pageId, uint8_t *rBuffer, uint16_t *rResult return 1; } -int chcusb_setPrintStandby(uint16_t position, uint16_t *rResult) { +__stdcall int chcusb_setPrintStandby(uint16_t position, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); if (STATUS == 0) @@ -2622,13 +2638,29 @@ int chcusb_setPrintStandby(uint16_t position, uint16_t *rResult) { return 1; } -int chcusb_testCardFeed(uint16_t mode, uint16_t times, uint16_t *rResult) { +__stdcall int chcusb_setPrintStandby_300(uint16_t *rResult) { + dprintf("Printer: C300usb: %s\n", __func__); + + *rResult = 0; + if (awaitingCardExit){ // 300 does not use exitCard, so reset this for getPrinterInfo. + awaitingCardExit = false; + STATUS = 1; + } + if (STATUS == 0) + { + STATUS = 1; + } + + return 1; +} + +__stdcall int chcusb_testCardFeed(uint16_t mode, uint16_t times, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); *rResult = 0; return 1; } -int chcusb_exitCard(uint16_t *rResult) { +__stdcall int chcusb_exitCard(uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); awaitingCardExit = false; @@ -2638,7 +2670,7 @@ int chcusb_exitCard(uint16_t *rResult) { return 1; } -int chcusb_getCardRfidTID(uint8_t *rCardTID, uint16_t *rResult) { +__stdcall int chcusb_getCardRfidTID(uint8_t *rCardTID, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); memcpy(rCardTID, cardRFID, sizeof(cardRFID)); @@ -2646,7 +2678,7 @@ int chcusb_getCardRfidTID(uint8_t *rCardTID, uint16_t *rResult) { return 1; } -int chcusb_commCardRfidReader(uint8_t *sendData, uint8_t *rRecvData, uint32_t sendSize, uint32_t *rRecvSize, uint16_t *rResult) { +__stdcall int chcusb_commCardRfidReader(uint8_t *sendData, uint8_t *rRecvData, uint32_t sendSize, uint32_t *rRecvSize, uint16_t *rResult) { uint8_t off; dprintf("Printer: C3XXusb: %s\n", __func__); @@ -2709,67 +2741,67 @@ int chcusb_commCardRfidReader(uint8_t *sendData, uint8_t *rRecvData, uint32_t se return 1; } -int chcusb_updateCardRfidReader(uint8_t *data, uint32_t size, uint16_t *rResult) { +__stdcall int chcusb_updateCardRfidReader(uint8_t *data, uint32_t size, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); *rResult = 0; return 1; } -int chcusb_getErrorLog(uint16_t index, uint8_t *rData, uint16_t *rResult) { +__stdcall int chcusb_getErrorLog(uint16_t index, uint8_t *rData, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); *rResult = 0; return 1; } -int chcusb_getErrorStatus(uint16_t *rBuffer) { +__stdcall int chcusb_getErrorStatus(uint16_t *rBuffer) { dprintf("Printer: C3XXusb: %s\n", __func__); memset(rBuffer, 0, 0x80); return 1; } -int chcusb_setCutList(uint8_t *rData, uint16_t *rResult) { +__stdcall int chcusb_setCutList(uint8_t *rData, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); *rResult = 0; return 1; } -int chcusb_setLaminatePattern(uint16_t index, uint8_t *rData, uint16_t *rResult) { +__stdcall int chcusb_setLaminatePattern(uint16_t index, uint8_t *rData, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); *rResult = 0; return 1; } -int chcusb_color_adjustment(LPCSTR filename, int32_t a2, int32_t a3, int16_t a4, int16_t a5, int64_t a6, int64_t a7, uint16_t *rResult) { +__stdcall int chcusb_color_adjustment(LPCSTR filename, int32_t a2, int32_t a3, int16_t a4, int16_t a5, int64_t a6, int64_t a7, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); *rResult = 0; return 1; } -int chcusb_color_adjustmentEx(int32_t a1, int32_t a2, int32_t a3, int16_t a4, int16_t a5, int64_t a6, int64_t a7, uint16_t *rResult) { +__stdcall int chcusb_color_adjustmentEx(int32_t a1, int32_t a2, int32_t a3, int16_t a4, int16_t a5, int64_t a6, int64_t a7, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); *rResult = 0; return 1; } -int chcusb_getEEPROM(uint8_t index, uint8_t *rData, uint16_t *rResult) { +__stdcall int chcusb_getEEPROM(uint8_t index, uint8_t *rData, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); *rResult = 0; return 1; } -int chcusb_setParameter(uint8_t a1, uint32_t a2, uint16_t *rResult) { +__stdcall int chcusb_setParameter(uint8_t a1, uint32_t a2, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); *rResult = 0; return 1; } -int chcusb_getParameter(uint8_t a1, uint8_t *a2, uint16_t *rResult) { +__stdcall int chcusb_getParameter(uint8_t a1, uint8_t *a2, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); *rResult = 0; return 1; } -int chcusb_universal_command(int32_t a1, uint8_t a2, int32_t a3, uint8_t *a4, uint16_t *rResult) { +__stdcall int chcusb_universal_command(int32_t a1, uint8_t a2, int32_t a3, uint8_t *a4, uint16_t *rResult) { dprintf("Printer: C3XXusb: %s\n", __func__); *rResult = 0; return 1; @@ -3282,3 +3314,8 @@ DWORD WriteArrayToFile(LPCSTR lpOutputFilePath, LPVOID lpDataTemp, DWORD nDataSi #endif } + +void printer_set_dimensions(int width, int height){ + WIDTH = width; + HEIGHT = height; +} \ No newline at end of file diff --git a/hooklib/printer.h b/hooklib/printer.h index 229cff7..1a39fe8 100644 --- a/hooklib/printer.h +++ b/hooklib/printer.h @@ -15,3 +15,4 @@ struct printer_config { void printer_hook_init(const struct printer_config *cfg, int rfid_port_no, HINSTANCE self); void printer_hook_insert_hooks(HMODULE target); +void printer_set_dimensions(int width, int height); \ No newline at end of file diff --git a/kemonohook/config.c b/kemonohook/config.c new file mode 100644 index 0000000..d1097be --- /dev/null +++ b/kemonohook/config.c @@ -0,0 +1,105 @@ +#include +#include + +#include "amex/config.h" + +#include "board/config.h" + +#include "hooklib/config.h" +#include "hooklib/dvd.h" + +#include "kemonohook/config.h" + +#include "platform/config.h" + +void kemono_dll_config_load( + struct kemono_dll_config *cfg, + const wchar_t *filename) { + assert(cfg != NULL); + assert(filename != NULL); + + GetPrivateProfileStringW( + L"kemonoio", + L"path", + L"", + cfg->path, + _countof(cfg->path), + filename); +} + +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 = GetPrivateProfileIntW(L"led15093", L"portNo", 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-04", + 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"6704 ", + 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"6704 ", + 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 kemono_hook_config_load( + struct kemono_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); + dvd_config_load(&cfg->dvd, filename); + vfd_config_load(&cfg->vfd, filename); + kemono_dll_config_load(&cfg->dll, filename); + unity_config_load(&cfg->unity, filename); + printer_config_load(&cfg->printer, filename); + amex_config_load(&cfg->amex, filename); + led15093_config_load(&cfg->led15093, filename); +} diff --git a/kemonohook/config.h b/kemonohook/config.h new file mode 100644 index 0000000..bf76cff --- /dev/null +++ b/kemonohook/config.h @@ -0,0 +1,36 @@ +#pragma once + +#include + +#include "amex/amex.h" + +#include "board/config.h" +#include "board/led15093.h" + +#include "hooklib/dvd.h" + +#include "kemonohook/kemono-dll.h" + +#include "platform/config.h" + +#include "unityhook/config.h" + +struct kemono_hook_config { + struct platform_config platform; + struct aime_config aime; + struct dvd_config dvd; + struct vfd_config vfd; + struct kemono_dll_config dll; + struct unity_config unity; + struct printer_config printer; + struct amex_config amex; + struct led15093_config led15093; +}; + +void kemono_dll_config_load( + struct kemono_dll_config *cfg, + const wchar_t *filename); + +void kemono_hook_config_load( + struct kemono_hook_config *cfg, + const wchar_t *filename); diff --git a/kemonohook/dllmain.c b/kemonohook/dllmain.c new file mode 100644 index 0000000..736da4e --- /dev/null +++ b/kemonohook/dllmain.c @@ -0,0 +1,121 @@ +#include + +#include "board/io4.h" +#include "board/sg-reader.h" +#include "board/vfd.h" + +#include "hook/process.h" +#include "hook/table.h" +#include "hook/iohook.h" + +#include "hooklib/printer.h" +#include "hooklib/serial.h" +#include "hooklib/spike.h" + +#include "kemonohook/config.h" +#include "kemonohook/hooks.h" +#include "kemonohook/jvs.h" +#include "kemonohook/kemono-dll.h" + +#include "platform/platform.h" + +#include "unityhook/hook.h" + +#include "util/dprintf.h" + +static HMODULE kemono_hook_mod; +static process_entry_t kemono_startup; +static struct kemono_hook_config kemono_hook_cfg; + +static DWORD CALLBACK kemono_pre_startup(void) { + HRESULT hr; + + dprintf("--- Begin kemono_pre_startup ---\n"); + + /* Load config */ + + kemono_hook_config_load(&kemono_hook_cfg, L".\\segatools.ini"); + + /* Hook Win32 APIs */ + + dvd_hook_init(&kemono_hook_cfg.dvd, kemono_hook_mod); + serial_hook_init(); + printer_hook_init(&kemono_hook_cfg.printer, 0, kemono_hook_mod); + printer_set_dimensions(720, 1028); + + /* Initialize emulation hooks */ + + hr = platform_hook_init( + &kemono_hook_cfg.platform, + "SDFL", + "AAW1", + kemono_hook_mod); + + if (FAILED(hr)) { + goto fail; + } + + hr = sg_reader_hook_init(&kemono_hook_cfg.aime, 1, 1, kemono_hook_mod); + + if (FAILED(hr)) { + goto fail; + } + + hr = kemono_dll_init(&kemono_hook_cfg.dll, kemono_hook_mod); + + if (FAILED(hr)) { + goto fail; + } + + hr = amex_hook_init(&kemono_hook_cfg.amex, kemono_jvs_init); + + if (FAILED(hr)) { + goto fail; + } + + hr = led15093_hook_init(&kemono_hook_cfg.led15093, kemono_dll.led_init, kemono_dll.led_set_leds, 10, 1, 1, 2); + + if (FAILED(hr)) { + goto fail; + } + + kemono_extra_hooks_init(); + + /* Initialize Unity native plugin DLL hooks + + There seems to be an issue with other DLL hooks if `LoadLibraryW` is + hooked earlier in the `kemonohook` initialization. */ + + unity_hook_init(&kemono_hook_cfg.unity, kemono_hook_mod, kemono_extra_hooks_load); + + /* Initialize debug helpers */ + + spike_hook_init(L".\\segatools.ini"); + + dprintf("--- End kemono_pre_startup ---\n"); + + /* Jump to EXE start address */ + + return kemono_startup(); + + fail: + ExitProcess(EXIT_FAILURE); +} + +BOOL WINAPI DllMain(HMODULE mod, DWORD cause, void *ctx) { + HRESULT hr; + + if (cause != DLL_PROCESS_ATTACH) { + return TRUE; + } + + kemono_hook_mod = mod; + + hr = process_hijack_startup(kemono_pre_startup, &kemono_startup); + + if (!SUCCEEDED(hr)) { + dprintf("Failed to hijack process startup: %x\n", (int) hr); + } + + return SUCCEEDED(hr); +} diff --git a/kemonohook/hooks.c b/kemonohook/hooks.c new file mode 100644 index 0000000..51fc0d0 --- /dev/null +++ b/kemonohook/hooks.c @@ -0,0 +1,59 @@ +#include "hook/iohook.h" +#include "hook/procaddr.h" +#include "hook/table.h" + +#include "hooklib/serial.h" + +#include "kemonohook/hooks.h" + +#include "util/dprintf.h" + +static BOOL WINAPI hook_GetVersionExW(LPOSVERSIONINFOW lpVersionInformation); + +static int (WINAPI *next_GetVersionExW)(LPOSVERSIONINFOW lpVersionInformation); + +static const struct hook_symbol kemono_kernel32_syms[] = { + { + .name = "GetVersionExW", + .patch = hook_GetVersionExW, + .link = (void **) &next_GetVersionExW, + } +}; + +void kemono_extra_hooks_init(){ +} + +void kemono_extra_hooks_load(HMODULE mod, const wchar_t* target_module) { + + // Workaround for AmManager.checkTarget:Environment.GetEnvironmentVariable("USERNAME") + SetEnvironmentVariableA("USERNAME", "AppUser"); + + // Workaround for AmManager.checkTarget, expects OS version to be 6.2 or 6.3 + hook_table_apply( + mod, + "kernel32.dll", + kemono_kernel32_syms, + _countof(kemono_kernel32_syms)); + + // needed for LED COM port + // FIXME: SerialPortAPI.dll seems to be loaded twice? this causes a crash + /*if (_wcsicmp(L"SerialPortAPI.dll", target_module) == 0) { + iohook_apply_hooks(mod); + serial_hook_apply_hooks(mod); + dprintf("Kemono: Loaded I/O hooks for serial port\n"); + }*/ + +} + +static BOOL WINAPI hook_GetVersionExW(LPOSVERSIONINFOW lpVersionInformation) { + int result = next_GetVersionExW(lpVersionInformation); + + if (result) { + lpVersionInformation->dwMajorVersion = 6; + lpVersionInformation->dwMinorVersion = 2; + lpVersionInformation->dwBuildNumber = 0; + dprintf("Kemono: GetVersionExW hook hit\n"); + } + + return result; +} \ No newline at end of file diff --git a/kemonohook/hooks.h b/kemonohook/hooks.h new file mode 100644 index 0000000..a778e5b --- /dev/null +++ b/kemonohook/hooks.h @@ -0,0 +1,5 @@ +#pragma once + +void kemono_extra_hooks_init(); + +void kemono_extra_hooks_load(HMODULE mod, const wchar_t* target_module); \ No newline at end of file diff --git a/kemonohook/jvs.c b/kemonohook/jvs.c new file mode 100644 index 0000000..ae9f0f8 --- /dev/null +++ b/kemonohook/jvs.c @@ -0,0 +1,133 @@ +#include + +#include +#include +#include +#include + +#include "amex/jvs.h" + +#include "board/io3.h" + +#include "kemonohook/kemono-dll.h" + +#include "jvs/jvs-bus.h" + +#include "util/dprintf.h" + +struct kemono_jvs_ir_mask { + uint16_t p1; + uint16_t p2; +}; + +static void kemono_jvs_read_switches(void *ctx, struct io3_switch_state *out); +static void kemono_jvs_read_coin_counter( + void *ctx, + uint8_t slot_no, + uint16_t *out); + +static const struct io3_ops kemono_jvs_io3_ops = { + .read_switches = kemono_jvs_read_switches, + .read_coin_counter = kemono_jvs_read_coin_counter, +}; + +static struct io3 kemono_jvs_io3; + +HRESULT kemono_jvs_init(struct jvs_node **out) +{ + HRESULT hr; + + assert(out != NULL); + assert(kemono_dll.init != NULL); + + dprintf("JVS I/O: Starting IO backend\n"); + hr = kemono_dll.init(); + + if (FAILED(hr)) { + dprintf("JVS I/O: Backend error, I/O disconnected: %x\n", (int) hr); + + return hr; + } + + io3_init(&kemono_jvs_io3, NULL, &kemono_jvs_io3_ops, NULL); + *out = io3_to_jvs_node(&kemono_jvs_io3); + + return S_OK; +} + +static void kemono_jvs_read_switches(void *ctx, struct io3_switch_state *out) +{ + const struct kemono_jvs_ir_mask *masks; + uint16_t opbtn; + uint16_t pbtn; + size_t i; + + assert(out != NULL); + assert(kemono_dll.poll != NULL); + + opbtn = 0; + pbtn = 0; + + kemono_dll.poll(&opbtn, &pbtn); + + out->system = 0x00; + out->p1 = 0x0000; + out->p2 = 0x0000; + + if (opbtn & KEMONO_IO_OPBTN_TEST) { + out->system |= 1 << 7; + } + + if (opbtn & KEMONO_IO_OPBTN_SERVICE) { + out->p1 |= 1 << 14; + } + + if (pbtn & KEMONO_IO_GAMEBTN_UP) { + out->p1 |= 1 << 13; + } + + if (pbtn & KEMONO_IO_GAMEBTN_DOWN) { + out->p1 |= 1 << 12; + } + + if (pbtn & KEMONO_IO_GAMEBTN_LEFT) { + out->p1 |= 1 << 11; + } + + if (pbtn & KEMONO_IO_GAMEBTN_RIGHT) { + out->p1 |= 1 << 10; + } + + if (pbtn & KEMONO_IO_GAMEBTN_R) { + out->p1 |= 1 << 9; + } + + if (pbtn & KEMONO_IO_GAMEBTN_G) { + out->p1 |= 1 << 7; + } + + if (pbtn & KEMONO_IO_GAMEBTN_B) { + out->p1 |= 1 << 8; + } + + if (pbtn & KEMONO_IO_GAMEBTN_START) { + out->p1 |= 1 << 15; + } + + +} + +static void kemono_jvs_read_coin_counter( + void *ctx, + uint8_t slot_no, + uint16_t *out) +{ + assert(out != NULL); + assert(kemono_dll.jvs_read_coin_counter != NULL); + + if (slot_no > 0) { + return; + } + + kemono_dll.jvs_read_coin_counter(out); +} diff --git a/kemonohook/jvs.h b/kemonohook/jvs.h new file mode 100644 index 0000000..359138b --- /dev/null +++ b/kemonohook/jvs.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +#include "jvs/jvs-bus.h" + +HRESULT kemono_jvs_init(struct jvs_node **root); diff --git a/kemonohook/kemono-dll.c b/kemonohook/kemono-dll.c new file mode 100644 index 0000000..8fbb447 --- /dev/null +++ b/kemonohook/kemono-dll.c @@ -0,0 +1,115 @@ +#include + +#include +#include + +#include "kemonohook/kemono-dll.h" + +#include "util/dll-bind.h" +#include "util/dprintf.h" + +const struct dll_bind_sym kemono_dll_syms[] = { + { + .sym = "kemono_io_init", + .off = offsetof(struct kemono_dll, init), + }, + { + .sym = "kemono_io_poll", + .off = offsetof(struct kemono_dll, poll), + }, + { + .sym = "kemono_io_jvs_read_coin_counter", + .off = offsetof(struct kemono_dll, jvs_read_coin_counter), + }, + { + .sym = "kemono_io_led_init", + .off = offsetof(struct kemono_dll, led_init), + }, + { + .sym = "kemono_io_led_set_colors", + .off = offsetof(struct kemono_dll, led_set_leds), + } +}; + +struct kemono_dll kemono_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 kemono_dll_init(const struct kemono_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("Kemono IO: Failed to load IO DLL: %lx: %S\n", + hr, + cfg->path); + + goto end; + } + + dprintf("Kemono IO: Using custom IO DLL: %S\n", cfg->path); + src = owned; + } else { + owned = NULL; + src = self; + } + + get_api_version = (void *) GetProcAddress(src, "kemono_io_get_api_version"); + + if (get_api_version != NULL) { + kemono_dll.api_version = get_api_version(); + } else { + kemono_dll.api_version = 0x0100; + dprintf("Custom IO DLL does not expose kemono_io_get_api_version, " + "assuming API version 1.0.\n" + "Please ask the developer to update their DLL.\n"); + } + + if (kemono_dll.api_version >= 0x0200) { + hr = E_NOTIMPL; + dprintf("Kemono IO: Custom IO DLL implements an unsupported " + "API version (%#04x). Please update Segatools.\n", + kemono_dll.api_version); + + goto end; + } + + sym = kemono_dll_syms; + hr = dll_bind(&kemono_dll, src, &sym, _countof(kemono_dll_syms)); + + if (FAILED(hr)) { + if (src != self) { + dprintf("Kemono 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; +} diff --git a/kemonohook/kemono-dll.h b/kemonohook/kemono-dll.h new file mode 100644 index 0000000..3ab7506 --- /dev/null +++ b/kemonohook/kemono-dll.h @@ -0,0 +1,27 @@ +#pragma once + +#include + +#include "kemonoio/kemonoio.h" + +struct kemono_dll { + uint16_t api_version; + + HRESULT (*init)(void); + + HRESULT (*poll)(uint16_t *ops, uint16_t *player); + + void (*jvs_read_coin_counter)(uint16_t *coins); + + HRESULT (*led_init)(void); + + void (*led_set_leds)(uint8_t board, uint8_t *rgb); +}; + +struct kemono_dll_config { + wchar_t path[MAX_PATH]; +}; + +extern struct kemono_dll kemono_dll; + +HRESULT kemono_dll_init(const struct kemono_dll_config *cfg, HINSTANCE self); diff --git a/kemonohook/kemonohook.def b/kemonohook/kemonohook.def new file mode 100644 index 0000000..c28d512 --- /dev/null +++ b/kemonohook/kemonohook.def @@ -0,0 +1,82 @@ +LIBRARY kemonohook + +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 + amDllVideoClose @2 + amDllVideoGetVBiosVersion @4 + amDllVideoOpen @1 + amDllVideoSetResolution @3 + kemono_io_get_api_version + kemono_io_jvs_read_coin_counter + kemono_io_init + kemono_io_poll + kemono_io_led_init + kemono_io_led_set_colors + fwdlusb_open + fwdlusb_close + fwdlusb_listupPrinter + fwdlusb_listupPrinterSN + fwdlusb_selectPrinter + fwdlusb_selectPrinterSN + fwdlusb_getPrinterInfo + fwdlusb_status + fwdlusb_statusAll + fwdlusb_resetPrinter + fwdlusb_updateFirmware + fwdlusb_getFirmwareInfo + fwdlusb_MakeThread + fwdlusb_ReleaseThread + fwdlusb_AttachThreadCount + fwdlusb_getErrorLog + chcusb_MakeThread + chcusb_open + chcusb_close + chcusb_ReleaseThread + chcusb_listupPrinter + chcusb_listupPrinterSN + chcusb_selectPrinter + chcusb_selectPrinterSN + chcusb_getPrinterInfo + chcusb_imageformat + chcusb_setmtf + chcusb_makeGamma + chcusb_setIcctable + chcusb_copies + chcusb_status + chcusb_statusAll + chcusb_startpage + chcusb_endpage + chcusb_write + chcusb_writeLaminate + chcusb_writeHolo + chcusb_setPrinterInfo + chcusb_getGamma + chcusb_getMtf + chcusb_cancelCopies + chcusb_setPrinterToneCurve + chcusb_getPrinterToneCurve + chcusb_blinkLED + chcusb_resetPrinter + chcusb_AttachThreadCount + chcusb_getPrintIDStatus + chcusb_setPrintStandby + chcusb_testCardFeed + chcusb_exitCard + chcusb_getCardRfidTID + chcusb_commCardRfidReader + chcusb_updateCardRfidReader + chcusb_getErrorLog + chcusb_getErrorStatus + chcusb_setCutList + chcusb_setLaminatePattern + chcusb_color_adjustment + chcusb_color_adjustmentEx + chcusb_getEEPROM + chcusb_setParameter + chcusb_getParameter + chcusb_universal_command diff --git a/kemonohook/meson.build b/kemonohook/meson.build new file mode 100644 index 0000000..78538dd --- /dev/null +++ b/kemonohook/meson.build @@ -0,0 +1,34 @@ +shared_library( + 'kemonohook', + name_prefix : '', + include_directories : inc, + implicit_include_directories : false, + vs_module_defs : 'kemonohook.def', + c_pch : '../precompiled.h', + dependencies : [ + capnhook.get_variable('hook_dep'), + capnhook.get_variable('hooklib_dep'), + ], + link_with : [ + aimeio_lib, + amex_lib, + board_lib, + hooklib_lib, + jvs_lib, + kemonoio_lib, + platform_lib, + unityhook_lib, + util_lib, + ], + sources : [ + 'config.c', + 'config.h', + 'dllmain.c', + 'hooks.c', + 'hooks.h', + 'jvs.c', + 'jvs.h', + 'kemono-dll.c', + 'kemono-dll.h', + ], +) diff --git a/kemonoio/config.c b/kemonoio/config.c new file mode 100644 index 0000000..88afa5d --- /dev/null +++ b/kemonoio/config.c @@ -0,0 +1,28 @@ +#include + +#include +#include +#include + +#include "kemonoio/config.h" + +void kemono_io_config_load( + struct kemono_io_config *cfg, + const wchar_t *filename) { + + assert(cfg != NULL); + assert(filename != NULL); + + cfg->vk_test = GetPrivateProfileIntW(L"io3", L"test", '1', filename); + cfg->vk_service = GetPrivateProfileIntW(L"io3", L"service", '2', filename); + cfg->vk_coin = GetPrivateProfileIntW(L"io3", L"coin", '3', filename); + + cfg->vk_left = GetPrivateProfileIntW(L"io3", L"left", VK_LEFT, filename); + cfg->vk_right = GetPrivateProfileIntW(L"io3", L"right", VK_RIGHT, filename); + cfg->vk_up = GetPrivateProfileIntW(L"io3", L"up", VK_UP, filename); + cfg->vk_down = GetPrivateProfileIntW(L"io3", L"down", VK_DOWN, filename); + cfg->vk_red = GetPrivateProfileIntW(L"io3", L"red", 'A', filename); + cfg->vk_green = GetPrivateProfileIntW(L"io3", L"green", 'S', filename); + cfg->vk_blue = GetPrivateProfileIntW(L"io3", L"blue", 'D', filename); + cfg->vk_start = GetPrivateProfileIntW(L"io3", L"start", VK_RETURN, filename); +} diff --git a/kemonoio/config.h b/kemonoio/config.h new file mode 100644 index 0000000..f2c36f3 --- /dev/null +++ b/kemonoio/config.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include + +#include + +struct kemono_io_config { + uint8_t vk_test; + uint8_t vk_service; + uint8_t vk_coin; + + uint8_t vk_left; + uint8_t vk_right; + uint8_t vk_up; + uint8_t vk_down; + uint8_t vk_red; + uint8_t vk_green; + uint8_t vk_blue; + uint8_t vk_start; +}; + +void kemono_io_config_load( + struct kemono_io_config *cfg, + const wchar_t *filename); diff --git a/kemonoio/kemonoio.c b/kemonoio/kemonoio.c new file mode 100644 index 0000000..8d4033c --- /dev/null +++ b/kemonoio/kemonoio.c @@ -0,0 +1,104 @@ +#include + +#include +#include +#include + +#include "kemonoio/kemonoio.h" +#include "kemonoio/config.h" + +static uint8_t kemono_opbtn; +static uint16_t kemono_pbtn; +static uint16_t kemono_io_coins; +static struct kemono_io_config kemono_io_cfg; +static bool kemono_io_coin; + +uint16_t kemono_io_get_api_version(void) { + return 0x0100; +} + +HRESULT kemono_io_init(void) { + kemono_io_config_load(&kemono_io_cfg, L".\\segatools.ini"); + + kemono_io_coins = 0; + + return S_OK; +} + +HRESULT kemono_io_poll(uint16_t *ops, uint16_t *player) { + kemono_opbtn = 0; + kemono_pbtn = 0; + + if (GetAsyncKeyState(kemono_io_cfg.vk_test) & 0x8000) { + kemono_opbtn |= KEMONO_IO_OPBTN_TEST; + } + + if (GetAsyncKeyState(kemono_io_cfg.vk_service) & 0x8000) { + kemono_opbtn |= KEMONO_IO_OPBTN_SERVICE; + } + + if (kemono_io_cfg.vk_coin && + (GetAsyncKeyState(kemono_io_cfg.vk_coin) & 0x8000)) { + if (!kemono_io_coin) { + kemono_io_coin = true; + kemono_io_coins++; + } + } else { + kemono_io_coin = false; + } + + if (GetAsyncKeyState(kemono_io_cfg.vk_up)) { + kemono_pbtn |= KEMONO_IO_GAMEBTN_UP; + } + + if (GetAsyncKeyState(kemono_io_cfg.vk_down)) { + kemono_pbtn |= KEMONO_IO_GAMEBTN_DOWN; + } + + if (GetAsyncKeyState(kemono_io_cfg.vk_left)) { + kemono_pbtn |= KEMONO_IO_GAMEBTN_LEFT; + } + + if (GetAsyncKeyState(kemono_io_cfg.vk_right)) { + kemono_pbtn |= KEMONO_IO_GAMEBTN_RIGHT; + } + + if (GetAsyncKeyState(kemono_io_cfg.vk_red)) { + kemono_pbtn |= KEMONO_IO_GAMEBTN_R; + } + + if (GetAsyncKeyState(kemono_io_cfg.vk_green)) { + kemono_pbtn |= KEMONO_IO_GAMEBTN_G; + } + + if (GetAsyncKeyState(kemono_io_cfg.vk_blue)) { + kemono_pbtn |= KEMONO_IO_GAMEBTN_B; + } + + if (GetAsyncKeyState(kemono_io_cfg.vk_start)) { + kemono_pbtn |= KEMONO_IO_GAMEBTN_START; + } + + if (ops != NULL) { + *ops = kemono_opbtn; + } + if (player != NULL) { + *player = kemono_pbtn; + } + + return S_OK; +} + +void kemono_io_jvs_read_coin_counter(uint16_t *out) { + assert(out != NULL); + + *out = kemono_io_coins; +} + +HRESULT kemono_io_led_init(void) { + return S_OK; +} + +void kemono_io_led_set_colors(uint8_t board, uint8_t *rgb) { + +} \ No newline at end of file diff --git a/kemonoio/kemonoio.h b/kemonoio/kemonoio.h new file mode 100644 index 0000000..c014857 --- /dev/null +++ b/kemonoio/kemonoio.h @@ -0,0 +1,53 @@ +#pragma once + +#include + +#include + +enum { + KEMONO_IO_OPBTN_TEST = 0x01, + KEMONO_IO_OPBTN_SERVICE = 0x02 +}; + +enum { + KEMONO_IO_GAMEBTN_UP = 0x01, + KEMONO_IO_GAMEBTN_DOWN = 0x02, + KEMONO_IO_GAMEBTN_LEFT = 0x04, + KEMONO_IO_GAMEBTN_RIGHT = 0x08, + KEMONO_IO_GAMEBTN_R = 0x10, + KEMONO_IO_GAMEBTN_G = 0x20, + KEMONO_IO_GAMEBTN_B = 0x40, + KEMONO_IO_GAMEBTN_START = 0x80 +}; + +/* Get the version of the Kemono 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 kemono_io_get_api_version(void); + +/* Initialize the IO DLL. This is the second function that will be called on + your DLL, after kemono_io_get_api_version. + + All subsequent calls to this API may originate from arbitrary threads. + + Minimum API version: 0x0100 */ + +HRESULT kemono_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 kemono_io_poll(uint16_t* ops, uint16_t* player); + +/* Read the current state of the coin counter. This value should be incremented + for every coin detected by the coin acceptor mechanism. This count does not + need to persist beyond the lifetime of the process. + + Minimum API version: 0x0100 */ +void kemono_io_jvs_read_coin_counter(uint16_t *out); diff --git a/kemonoio/meson.build b/kemonoio/meson.build new file mode 100644 index 0000000..3dcc27c --- /dev/null +++ b/kemonoio/meson.build @@ -0,0 +1,13 @@ +kemonoio_lib = static_library( + 'kemonoio_lib', + name_prefix : '', + include_directories : inc, + implicit_include_directories : false, + c_pch : '../precompiled.h', + sources : [ + 'kemonoio.c', + 'kemonoio.h', + 'config.c', + 'config.h', + ], +) diff --git a/mai2hook/dllmain.c b/mai2hook/dllmain.c index 02f32a4..ac14649 100644 --- a/mai2hook/dllmain.c +++ b/mai2hook/dllmain.c @@ -102,7 +102,7 @@ static DWORD CALLBACK mai2_pre_startup(void) There seems to be an issue with other DLL hooks if `LoadLibraryW` is hooked earlier in the `mai2hook` initialization. */ - unity_hook_init(&mai2_hook_cfg.unity, mai2_hook_mod); + unity_hook_init(&mai2_hook_cfg.unity, mai2_hook_mod, NULL); /* Initialize debug helpers */ diff --git a/meson.build b/meson.build index c5b3d40..129a387 100644 --- a/meson.build +++ b/meson.build @@ -110,6 +110,7 @@ subdir('mercuryio') subdir('cxbio') subdir('tokyoio') subdir('fgoio') +subdir('kemonoio') subdir('chunihook') subdir('divahook') @@ -126,3 +127,4 @@ subdir('mercuryhook') subdir('cxbhook') subdir('tokyohook') subdir('fgohook') +subdir('kemonohook') diff --git a/mu3hook/dllmain.c b/mu3hook/dllmain.c index bab6c0b..e991b40 100644 --- a/mu3hook/dllmain.c +++ b/mu3hook/dllmain.c @@ -110,7 +110,7 @@ static DWORD CALLBACK mu3_pre_startup(void) There seems to be an issue with other DLL hooks if `LoadLibraryW` is hooked earlier in the `mu3hook` initialization. */ - unity_hook_init(&mu3_hook_cfg.unity, mu3_hook_mod); + unity_hook_init(&mu3_hook_cfg.unity, mu3_hook_mod, NULL); /* Initialize debug helpers */ diff --git a/platform/vfs.c b/platform/vfs.c index 26e4d34..e49ad5b 100644 --- a/platform/vfs.c +++ b/platform/vfs.c @@ -34,11 +34,11 @@ static HRESULT vfs_path_hook_option( static HRESULT vfs_reg_read_amfs(void *bytes, uint32_t *nbytes); static HRESULT vfs_reg_read_appdata(void *bytes, uint32_t *nbytes); -static wchar_t* hook_System_getAppRootPath(); -static wchar_t* (*next_System_getAppRootPath)(); +static __thiscall wchar_t* hook_System_getAppRootPath(); +static __thiscall wchar_t* (*next_System_getAppRootPath)(); -static wchar_t* hook_AppImage_getOptionMountRootPath(); -static wchar_t* (*next_AppImage_getOptionMountRootPath)(); +static __thiscall wchar_t* hook_AppImage_getOptionMountRootPath(); +static __thiscall wchar_t* (*next_AppImage_getOptionMountRootPath)(); static const struct hook_symbol amdaemon_syms[] = { { @@ -510,7 +510,7 @@ static HRESULT vfs_reg_read_appdata(void *bytes, uint32_t *nbytes) return reg_hook_read_wstr(bytes, nbytes, L"Y:\\"); } -static wchar_t* hook_System_getAppRootPath() +static __thiscall wchar_t* hook_System_getAppRootPath() { wchar_t *path = malloc(sizeof(wchar_t) * MAX_PATH); wcscpy_s(path, MAX_PATH, vfs_config.appdata); @@ -520,7 +520,7 @@ static wchar_t* hook_System_getAppRootPath() return path; } -static wchar_t* hook_AppImage_getOptionMountRootPath() +static __thiscall wchar_t* hook_AppImage_getOptionMountRootPath() { wchar_t *path = malloc(sizeof(wchar_t) * MAX_PATH); wcscpy_s(path, MAX_PATH, vfs_config.option); diff --git a/unityhook/hook.c b/unityhook/hook.c index 0058ec1..63816f3 100644 --- a/unityhook/hook.c +++ b/unityhook/hook.c @@ -39,6 +39,8 @@ static const size_t target_modules_len = _countof(target_modules); static void dll_hook_insert_hooks(HMODULE target); +static unity_hook_callback_func hook_load_callback; + static HMODULE WINAPI hook_LoadLibraryW(const wchar_t *name); static HMODULE (WINAPI *next_LoadLibraryW)(const wchar_t *name); static HMODULE WINAPI hook_LoadLibraryExW(const wchar_t *name, HANDLE hFile, DWORD dwFlags); @@ -57,7 +59,7 @@ static const struct hook_symbol unity_kernel32_syms[] = { }; -void unity_hook_init(const struct unity_config *cfg, HINSTANCE self) { +void unity_hook_init(const struct unity_config *cfg, HINSTANCE self, unity_hook_callback_func callback) { assert(cfg != NULL); if (!cfg->enable) { @@ -71,6 +73,8 @@ void unity_hook_init(const struct unity_config *cfg, HINSTANCE self) { memcpy(&unity_config, cfg, sizeof(*cfg)); dll_hook_insert_hooks(NULL); + hook_load_callback = callback; + unity_hook_initted = true; dprintf("Unity: Hook enabled.\n"); } @@ -144,6 +148,9 @@ static HMODULE WINAPI hook_LoadLibraryW(const wchar_t *name) reg_hook_insert_hooks(result); clock_hook_insert_hooks(result); proc_addr_insert_hooks(result); + if (hook_load_callback != NULL){ + hook_load_callback(result, target_module); + } // Not needed? // serial_hook_apply_hooks(result); diff --git a/unityhook/hook.h b/unityhook/hook.h index 684868c..7be6044 100644 --- a/unityhook/hook.h +++ b/unityhook/hook.h @@ -4,4 +4,6 @@ #include "config.h" -void unity_hook_init(const struct unity_config *cfg, HINSTANCE self); +typedef void (*unity_hook_callback_func)(HMODULE, const wchar_t*); + +void unity_hook_init(const struct unity_config *cfg, HINSTANCE self, unity_hook_callback_func callback);