1
0
mirror of synced 2024-11-27 17:00:53 +01:00

Add card reading?

This commit is contained in:
BroGamer 2022-08-15 19:29:54 +12:00
parent b6c0fe457f
commit 8dfbf5c2da
6 changed files with 140 additions and 47 deletions

2
.gitignore vendored
View File

@ -2,3 +2,5 @@ x86_64-pc-windows
*.o *.o
*.dll *.dll
*.7z *.7z
.cache
compile_commands.json

View File

@ -31,13 +31,13 @@ ${TARGET}/%.o: %.c
.PHONY: SDL .PHONY: SDL
SDL: SDL:
@mkdir -p SDL/${SDL_TARGET} @mkdir -p SDL/${SDL_TARGET}
@cd SDL/${SDL_TARGET} && ../configure --build=x86_64-linux-gnu --host=${SDL_TARGET} --disable-sdl2-config --disable-shared --enable-assertions=release --enable-directx --enable-haptic @#cd SDL/${SDL_TARGET} && ../configure --build=x86_64-linux-gnu --host=${SDL_TARGET} --disable-sdl2-config --disable-shared --enable-assertions=release --enable-directx --enable-haptic
@make -s -C SDL/${SDL_TARGET} @make -s -C SDL/${SDL_TARGET}
.PHONY: ${OUT} .PHONY: ${OUT}
${OUT}: dirs ${DEPS} ${OBJ} ${OUT}: dirs ${DEPS} ${OBJ}
@echo LINK $@ @echo LINK $@
@${CC} ${CFLAGS} -o ${TARGET}/$@.dll ${OBJ} ${LDFLAGS} ${LIBS} @bear -- ${CC} ${CFLAGS} -o ${TARGET}/$@.dll ${OBJ} ${LDFLAGS} ${LIBS}
.PHONY: fmt .PHONY: fmt
fmt: fmt:

View File

@ -26,6 +26,6 @@ options:
@${CC} -c ${CFLAGS} $< -o $@ @${CC} -c ${CFLAGS} $< -o $@
.PHONY: ${OUT} .PHONY: ${OUT}
${OUT}: dirs ${DEPS} ${OBJ} ${OUT}: dirs ${OBJ}
@echo LINK $@ @echo LINK $@
@${CC} ${CFLAGS} -o ../../${TARGET}/$@.dll ${OBJ} ${EXTERN_OBJ} ${LDFLAGS} ${LIBS} @${CC} ${CFLAGS} -o ../../${TARGET}/$@.dll ${OBJ} ${EXTERN_OBJ} ${LDFLAGS} ${LIBS}

View File

@ -9,51 +9,73 @@ HOOK_DYNAMIC (u32, __stdcall, XinputSetState, u32 index, void *state) { return E
HOOK_DYNAMIC (u32, __stdcall, XinputGetCapabilites, u32 index, u32 flags, void *state) { return ERROR_DEVICE_NOT_CONNECTED; } HOOK_DYNAMIC (u32, __stdcall, XinputGetCapabilites, u32 index, u32 flags, void *state) { return ERROR_DEVICE_NOT_CONNECTED; }
// bnusio stuff // bnusio stuff
RETURN_FALSE (i64, __stdcall, bnusio_ClearSram) RETURN_FALSE (i64, __stdcall, bnusio_ClearSram);
RETURN_FALSE (i64, __stdcall, bnusio_Close) RETURN_FALSE (i64, __stdcall, bnusio_Close);
RETURN_FALSE (i64, __fastcall, bnusio_Communication, i32 a1) RETURN_FALSE (i64, __fastcall, bnusio_Communication, i32 a1);
RETURN_FALSE (i64, __fastcall, bnusio_DecService, i32 a1, u16 a2) RETURN_FALSE (i64, __fastcall, bnusio_DecService, i32 a1, u16 a2);
RETURN_FALSE (void *, __fastcall, bnusio_GetBuffer, u16 a1, i64 a2, i16 a3) RETURN_FALSE (void *, __fastcall, bnusio_GetBuffer, u16 a1, i64 a2, i16 a3);
RETURN_FALSE (i64, __fastcall, bnusio_GetCDOut, u8 a1) RETURN_FALSE (i64, __fastcall, bnusio_GetCDOut, u8 a1);
RETURN_FALSE (void *, __fastcall, bnusio_GetCoinError, i32 a1) RETURN_FALSE (void *, __fastcall, bnusio_GetCoinError, i32 a1);
RETURN_FALSE (i64, __fastcall, bnusio_GetCoinLock, u8 a1) RETURN_FALSE (i64, __fastcall, bnusio_GetCoinLock, u8 a1);
RETURN_FALSE (u64, __stdcall, bnusio_GetEncoder) RETURN_FALSE (u64, __stdcall, bnusio_GetEncoder);
RETURN_FALSE (void *, __stdcall, bnusio_GetExpansionMode) RETURN_FALSE (void *, __stdcall, bnusio_GetExpansionMode);
void *__stdcall bnusio_GetFirmwareVersion () { return (void *)(u16)126; } void *__stdcall bnusio_GetFirmwareVersion () { return (void *)(u16)126; }
RETURN_FALSE (u8, __stdcall, bnusio_GetGout, u8 a1) RETURN_FALSE (u8, __stdcall, bnusio_GetGout, u8 a1);
RETURN_FALSE (i64, __stdcall, bnusio_GetHopOut, u8 a1) RETURN_FALSE (i64, __stdcall, bnusio_GetHopOut, u8 a1);
RETURN_FALSE (char *, __stdcall, bnusio_GetIoBoardName) RETURN_FALSE (char *, __stdcall, bnusio_GetIoBoardName);
RETURN_FALSE (u16, __fastcall, bnusio_GetRegisterU16, i16 a1) RETURN_FALSE (u16, __fastcall, bnusio_GetRegisterU16, i16 a1);
RETURN_FALSE (u8, __fastcall, bnusio_GetRegisterU8, u16 a1) RETURN_FALSE (u8, __fastcall, bnusio_GetRegisterU8, u16 a1);
RETURN_FALSE (void *, __fastcall, bnusio_GetService, i32 a1) RETURN_FALSE (void *, __fastcall, bnusio_GetService, i32 a1);
RETURN_FALSE (void *, __fastcall, bnusio_GetServiceError, i32 a1) RETURN_FALSE (void *, __fastcall, bnusio_GetServiceError, i32 a1);
RETURN_FALSE (u16, __fastcall, bnusio_GetStatusU16, u16 a1) RETURN_FALSE (u16, __fastcall, bnusio_GetStatusU16, u16 a1);
RETURN_FALSE (u8, __fastcall, bnusio_GetStatusU8, u16 a1) RETURN_FALSE (u8, __fastcall, bnusio_GetStatusU8, u16 a1);
RETURN_FALSE (u64, __stdcall, bnusio_GetSwIn64) RETURN_FALSE (u64, __stdcall, bnusio_GetSwIn64);
RETURN_FALSE (void *, __stdcall, bnusio_GetSystemError) RETURN_FALSE (void *, __stdcall, bnusio_GetSystemError);
RETURN_FALSE (u8, __stdcall, bnusio_IsConnected) RETURN_FALSE (u8, __stdcall, bnusio_IsConnected);
RETURN_FALSE (u8, __stdcall, bnusio_IsWideUsio) RETURN_FALSE (u8, __stdcall, bnusio_IsWideUsio);
RETURN_FALSE (i64, __stdcall, bnusio_Open) RETURN_FALSE (i64, __stdcall, bnusio_Open);
RETURN_FALSE (i32, __stdcall, bnusio_ResetIoBoard) RETURN_FALSE (i32, __stdcall, bnusio_ResetIoBoard);
RETURN_FALSE (i64, __fastcall, bnusio_SetBuffer, u16 a1, i32 a2, i16 a3) RETURN_FALSE (i64, __fastcall, bnusio_SetBuffer, u16 a1, i32 a2, i16 a3);
RETURN_FALSE (i64, __fastcall, bnusio_SetCDOut, u8 a1, u8 a2) RETURN_FALSE (i64, __fastcall, bnusio_SetCDOut, u8 a1, u8 a2);
RETURN_FALSE (i64, __fastcall, bnusio_SetCoinLock, u8 a1, u8 a2) RETURN_FALSE (i64, __fastcall, bnusio_SetCoinLock, u8 a1, u8 a2);
RETURN_FALSE (i64, __fastcall, bnusio_SetExpansionMode, i16 a1) RETURN_FALSE (i64, __fastcall, bnusio_SetExpansionMode, i16 a1);
RETURN_FALSE (i64, __fastcall, bnusio_SetGout, u8 a1, u8 a2) RETURN_FALSE (i64, __fastcall, bnusio_SetGout, u8 a1, u8 a2);
RETURN_FALSE (i64, __fastcall, bnusio_SetHopOut, u8 a1, u8 a2) RETURN_FALSE (i64, __fastcall, bnusio_SetHopOut, u8 a1, u8 a2);
RETURN_FALSE (i64, __fastcall, bnusio_SetHopperLimit, u16 a1, i16 a2) RETURN_FALSE (i64, __fastcall, bnusio_SetHopperLimit, u16 a1, i16 a2);
RETURN_FALSE (i64, __fastcall, bnusio_SetHopperRequest, u16 a1, i16 a2) RETURN_FALSE (i64, __fastcall, bnusio_SetHopperRequest, u16 a1, i16 a2);
RETURN_FALSE (void *, __fastcall, bnusio_SetPLCounter, i16 a1) RETURN_FALSE (void *, __fastcall, bnusio_SetPLCounter, i16 a1);
RETURN_FALSE (i64, __fastcall, bnusio_SetRegisterU16, u16 a1, u16 a2) RETURN_FALSE (i64, __fastcall, bnusio_SetRegisterU16, u16 a1, u16 a2);
RETURN_FALSE (i64, __fastcall, bnusio_SetRegisterU8, u16 a1, u8 a2) RETURN_FALSE (i64, __fastcall, bnusio_SetRegisterU8, u16 a1, u8 a2);
RETURN_FALSE (i64, __fastcall, bnusio_SetSystemError, i16 a1) RETURN_FALSE (i64, __fastcall, bnusio_SetSystemError, i16 a1);
RETURN_FALSE (i64, __fastcall, bnusio_SramRead, i32 a1, u8 a2, i32 a3, u16 a4) RETURN_FALSE (i64, __fastcall, bnusio_SramRead, i32 a1, u8 a2, i32 a3, u16 a4);
RETURN_FALSE (i64, __fastcall, bnusio_SramWrite, i32 a1, u8 a2, i32 a3, u16 a4) RETURN_FALSE (i64, __fastcall, bnusio_SramWrite, i32 a1, u8 a2, i32 a3, u16 a4);
RETURN_FALSE (i64, __stdcall, bnusio_ResetCoin) RETURN_FALSE (i64, __stdcall, bnusio_ResetCoin);
RETURN_FALSE (i64, __fastcall, bnusio_DecCoin, i32 a1, u16 a2) RETURN_FALSE (i64, __fastcall, bnusio_DecCoin, i32 a1, u16 a2);
HOOK_DYNAMIC (i64, __stdcall, UsbFinderInitialize) { return 0; } HOOK_DYNAMIC (i64, __stdcall, UsbFinderInitialize) { return 0; }
HOOK_DYNAMIC (i64, __stdcall, UsbFinderRelease) { return 0; } HOOK_DYNAMIC (i64, __stdcall, UsbFinderRelease) { return 0; }
HOOK_DYNAMIC (i64, __fastcall, UsbFinderGetSerialNumber, i32 a1, i64 a2) { return 1; } HOOK_DYNAMIC (i64, __fastcall, UsbFinderGetSerialNumber, i32 a1, char *a2) {
strcpy (a2, "284111080001");
return 0;
}
HOOK_DYNAMIC (u64, __stdcall, bngrw_DevReset) { return 1; }
HOOK_DYNAMIC (u64, __stdcall, bngrw_ReadMifare) { return 0xffffff9c; }
HOOK_DYNAMIC (void, __stdcall, bngrw_fin) { return; }
HOOK_DYNAMIC (u64, __stdcall, bngrw_GetFwVersion) { return 0; }
HOOK_DYNAMIC (u64, __stdcall, bngrw_GetStationID) { return 0; }
HOOK_DYNAMIC (u64, __stdcall, bngrw_GetRetryCount) { return 0; }
HOOK_DYNAMIC (u64, __stdcall, bngrw_Init) { return 0; }
HOOK_DYNAMIC (i32, __stdcall, bngrw_IsCmdExec) { return -1; }
HOOK_DYNAMIC (u64, __stdcall, bngrw_ReqAction) { return 1; }
HOOK_DYNAMIC (u64, __stdcall, bngrw_ReqAiccAuth) { return 1; }
HOOK_DYNAMIC (u64, __stdcall, bngrw_ReqBeep) { return 1; }
HOOK_DYNAMIC (i32, __stdcall, bngrw_ReqCancel, u32 a1) { return a1 > 7 ? -100 : 1; }
HOOK_DYNAMIC (u64, __stdcall, bngrw_ReqFwCleanup) { return 1; }
HOOK_DYNAMIC (u64, __stdcall, bngrw_ReqFwVersionUp) { return 1; }
HOOK_DYNAMIC (i32, __stdcall, bngrw_ReqLatchID, u32 a1) { return a1 < 8 ? -100 : 1; }
HOOK_DYNAMIC (u64, __stdcall, bngrw_ReqLed) { return 1; }
HOOK_DYNAMIC (i32, __stdcall, bngrw_ReqSendMail, u32 a1, u32 a2, u32 a3, u64 a4, u64 a5) { return a1 < 8 && a5 ? 1 : -100; }
HOOK_DYNAMIC (i32, __stdcall, bngrw_ReqSendUrl, u32 a1, u32 a2, u32 a3, u64 a4, u64 a5) { return a1 < 8 && a5 ? 1 : -100; }
HOOK_DYNAMIC (u64, __stdcall, bngrw_ReqSetLedPower) { return 0; }
void void
init_boilerplate () { init_boilerplate () {
@ -64,5 +86,25 @@ init_boilerplate () {
INSTALL_HOOK_DYNAMIC (UsbFinderInitialize, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderInitialize")); INSTALL_HOOK_DYNAMIC (UsbFinderInitialize, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderInitialize"));
INSTALL_HOOK_DYNAMIC (UsbFinderRelease, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderRelease")); INSTALL_HOOK_DYNAMIC (UsbFinderRelease, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderRelease"));
INSTALL_HOOK_DYNAMIC (UsbFinderGetSerialNumber, PROC_ADDRESS ("nbamUsbFinderGetSerialNumber.dll", "nbamUsbFinderRelease")); INSTALL_HOOK_DYNAMIC (UsbFinderGetSerialNumber, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderGetSerialNumber"));
INSTALL_HOOK_DYNAMIC (bngrw_DevReset, PROC_ADDRESS ("bngrw.dll", "BngRwDevReset"));
INSTALL_HOOK_DYNAMIC (bngrw_ReadMifare, PROC_ADDRESS ("bngrw.dll", "BngRwReadMifareAllBlock"));
INSTALL_HOOK_DYNAMIC (bngrw_fin, PROC_ADDRESS ("bngrw.dll", "BngRwFin"));
INSTALL_HOOK_DYNAMIC (bngrw_GetFwVersion, PROC_ADDRESS ("bngrw.dll", "BngRwGetFwVersion"));
INSTALL_HOOK_DYNAMIC (bngrw_GetStationID, PROC_ADDRESS ("bngrw.dll", "BngRwGetStationID"));
INSTALL_HOOK_DYNAMIC (bngrw_GetRetryCount, PROC_ADDRESS ("bngrw.dll", "BngRwGetTotalRetryCount"));
INSTALL_HOOK_DYNAMIC (bngrw_Init, PROC_ADDRESS ("bngrw.dll", "BngRwInit"));
INSTALL_HOOK_DYNAMIC (bngrw_IsCmdExec, PROC_ADDRESS ("bngrw.dll", "BngRwIsCmdExec"));
INSTALL_HOOK_DYNAMIC (bngrw_ReqAction, PROC_ADDRESS ("bngrw.dll", "BngRwReqAction"));
INSTALL_HOOK_DYNAMIC (bngrw_ReqAiccAuth, PROC_ADDRESS ("bngrw.dll", "BngRwReqAiccAuth"));
INSTALL_HOOK_DYNAMIC (bngrw_ReqBeep, PROC_ADDRESS ("bngrw.dll", "BngRwReqBeep"));
INSTALL_HOOK_DYNAMIC (bngrw_ReqCancel, PROC_ADDRESS ("bngrw.dll", "BngRwReqCancel"));
INSTALL_HOOK_DYNAMIC (bngrw_ReqFwCleanup, PROC_ADDRESS ("bngrw.dll", "BngRwReqFwCleanup"));
INSTALL_HOOK_DYNAMIC (bngrw_ReqFwVersionUp, PROC_ADDRESS ("bngrw.dll", "BngRwReqFwVersionUp"));
INSTALL_HOOK_DYNAMIC (bngrw_ReqLatchID, PROC_ADDRESS ("bngrw.dll", "BngRwReqLatchID"));
INSTALL_HOOK_DYNAMIC (bngrw_ReqLed, PROC_ADDRESS ("bngrw.dll", "BngRwReqLed"));
INSTALL_HOOK_DYNAMIC (bngrw_ReqSendMail, PROC_ADDRESS ("bngrw.dll", "BngRwReqSendMailTo"));
INSTALL_HOOK_DYNAMIC (bngrw_ReqSendUrl, PROC_ADDRESS ("bngrw.dll", "BngRwReqSendUrlTo"));
INSTALL_HOOK_DYNAMIC (bngrw_ReqSetLedPower, PROC_ADDRESS ("bngrw.dll", "BngRwReqSetLedPower"));
} }

View File

@ -6,6 +6,9 @@ bool testEnabled = false;
u16 drumMax = 0xFFFF; u16 drumMax = 0xFFFF;
u16 drumMin = 0xFFFF; u16 drumMin = 0xFFFF;
typedef i32 (*callbackAttach) (i32, i32, i32 *);
typedef void (*callbackTouch) (i32, i32, u8[168], u64);
#define ON_HIT(bind) IsButtonTapped (bind) ? drumMax == drumMin ? drumMax : (u16)(rand () % drumMax + drumMin) : 0 #define ON_HIT(bind) IsButtonTapped (bind) ? drumMax == drumMin ? drumMax : (u16)(rand () % drumMax + drumMin) : 0
Keybindings EXIT = { .keycodes = { VK_ESCAPE } }; Keybindings EXIT = { .keycodes = { VK_ESCAPE } };
@ -85,6 +88,11 @@ u16 __fastcall bnusio_GetCoin (i32 a1) {
return coin_count; return coin_count;
} }
callbackAttach attach;
i32 *attachData;
callbackTouch touch;
u64 touchData;
u32 __stdcall bnusio_GetSwIn () { u32 __stdcall bnusio_GetSwIn () {
u32 sw = 0; u32 sw = 0;
sw |= (u32)testEnabled << 7; sw |= (u32)testEnabled << 7;
@ -92,14 +100,49 @@ u32 __stdcall bnusio_GetSwIn () {
sw |= (u32)IsButtonDown (DEBUG_DOWN) << 12; sw |= (u32)IsButtonDown (DEBUG_DOWN) << 12;
sw |= (u32)IsButtonDown (DEBUG_UP) << 13; sw |= (u32)IsButtonDown (DEBUG_UP) << 13;
sw |= (u32)IsButtonDown (SERVICE) << 14; sw |= (u32)IsButtonDown (SERVICE) << 14;
if (attach != 0) {
attach (0, 0, attachData);
attach = 0;
}
if (touch != 0) {
u8 data[168]
= { 0x01, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x2E, 0x58, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x5C, 0x97, 0x44, 0xF0, 0x88, 0x04, 0x00, 0x43, 0x26, 0x2C, 0x33, 0x00, 0x04,
0x06, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x42, 0x47, 0x49, 0x43, 0x36,
0x00, 0x00, 0xFA, 0xE9, 0x69, 0x00, 0xF6, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
memcpy (data + 0x2C, "7F5C9744F111111143262C3300040610", 34);
memcpy (data + 0x50, "30764352518498791337", 22);
touch (0, 0, data, touchData);
touch = 0;
}
return sw; return sw;
} }
HOOK_DYNAMIC (u64, __stdcall, bngrw_attach, i32 a1, char *a2, i32 a3, i32 a4, callbackAttach callback, i32 *a6) {
attach = callback;
attachData = a6;
return 1;
}
HOOK_DYNAMIC (i32, __stdcall, bngrw_reqWaitTouch, u32 a1, i32 a2, u32 a3, callbackTouch callback, u64 a5) {
if (!GetAsyncKeyState (VK_RETURN)) return -1;
touch = callback;
touchData = a5;
return 1;
}
i32 __stdcall DllMain (HMODULE mod, DWORD cause, void *ctx) { i32 __stdcall DllMain (HMODULE mod, DWORD cause, void *ctx) {
if (cause == DLL_PROCESS_DETACH) DisposePoll (); if (cause == DLL_PROCESS_DETACH) DisposePoll ();
if (cause != DLL_PROCESS_ATTACH) return true; if (cause != DLL_PROCESS_ATTACH) return true;
init_boilerplate (); init_boilerplate ();
INSTALL_HOOK_DYNAMIC (bngrw_attach, PROC_ADDRESS ("bngrw.dll", "BngRwAttach"));
INSTALL_HOOK_DYNAMIC (bngrw_reqWaitTouch, PROC_ADDRESS ("bngrw.dll", "BngRwReqWaitTouch"));
// Set current directory to the directory of the executable // Set current directory to the directory of the executable
// Find all files in the plugins directory that end with .dll // Find all files in the plugins directory that end with .dll
@ -120,7 +163,11 @@ i32 __stdcall DllMain (HMODULE mod, DWORD cause, void *ctx) {
wcscat (filePath, L"/plugins/"); wcscat (filePath, L"/plugins/");
wcscat (filePath, fd.cFileName); wcscat (filePath, fd.cFileName);
HMODULE hModule = LoadLibraryW (filePath); HMODULE hModule = LoadLibraryW (filePath);
if (!hModule) { MessageBoxW (NULL, L"Failed to load plugin", fd.cFileName, MB_ICONERROR); } if (!hModule) {
wchar_t buf[128];
swprintf (buf, 128, L"Failed to load plugin %d", GetLastError ());
MessageBoxW (NULL, buf, fd.cFileName, MB_ICONERROR);
}
} while (FindNextFileW (hFind, &fd)); } while (FindNextFileW (hFind, &fd));
FindClose (hFind); FindClose (hFind);
} }

View File

@ -87,6 +87,8 @@ typedef uint64_t u64;
#define COUNTOFARR(arr) sizeof (arr) / sizeof (arr[0]) #define COUNTOFARR(arr) sizeof (arr) / sizeof (arr[0])
#define RETURN_FALSE(returnType, callingConvention, functionName, ...) \ #define RETURN_FALSE(returnType, callingConvention, functionName, ...) \
returnType callingConvention functionName (__VA_ARGS__) { return 0; } returnType callingConvention functionName (__VA_ARGS__) { return 0; }
#define RETURN_TRUE(returnType, callingConvention, functionName, ...) \
returnType callingConvention functionName (__VA_ARGS__) { return 1; }
#define INFO_COLOUR FOREGROUND_GREEN #define INFO_COLOUR FOREGROUND_GREEN
#define WARNING_COLOUR (FOREGROUND_RED | FOREGROUND_GREEN) #define WARNING_COLOUR (FOREGROUND_RED | FOREGROUND_GREEN)