// Utils.cpp -- Low-level helpers: game directory, memory patching
#include "Utils.h"
#include "Logger.h"

void GetGameDir(char* buffer, int size) {
    GetModuleFileNameA(NULL, buffer, size);
    char* lastSlash = strrchr(buffer, '\\');
    if (lastSlash) *(lastSlash + 1) = '\0';
}

void FloatToHex(float value, char* outBuf) {
    unsigned char* b = (unsigned char*)&value;
    sprintf(outBuf, "%02X %02X %02X %02X", b[0], b[1], b[2], b[3]);
}

void WriteFloat(DWORD address, float value) {
    float before = *(float*)address;
    char hexBefore[16], hexAfter[16], hexIntended[16];
    FloatToHex(before, hexBefore);
    FloatToHex(value, hexIntended);
    LogFmtIf("  WriteFloat @ 0x%08X  before: %.6f (%s)  ->  intended: %.6f (%s)",
        address, before, hexBefore, value, hexIntended);

    DWORD oldProt;
    if (!VirtualProtect((LPVOID)address, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProt)) {
        LogFmtIf("  ERROR: VirtualProtect failed at 0x%08X (GLE=%lu)", address, GetLastError());
        return;
    }
    *(float*)address = value;
    VirtualProtect((LPVOID)address, sizeof(float), oldProt, &oldProt);

    float after = *(float*)address;
    FloatToHex(after, hexAfter);
    if (after == value) LogFmtIf("  OK:    write confirmed  after: %.6f (%s)", after, hexAfter);
    else                LogFmtIf("  WARN:  readback mismatch! after: %.6f (%s)", after, hexAfter);
}

void WriteBytes(DWORD address, const BYTE* patch, SIZE_T len) {
    char hexBefore[64] = { 0 }, hexAfter[64] = { 0 }, hexIntended[64] = { 0 };
    const BYTE* src = (const BYTE*)address;
    for (SIZE_T i = 0; i < len; ++i) {
        char tmp[4];
        sprintf(tmp, "%02X ", src[i]);   strncat(hexBefore, tmp, sizeof(hexBefore) - strlen(hexBefore) - 1);
        sprintf(tmp, "%02X ", patch[i]); strncat(hexIntended, tmp, sizeof(hexIntended) - strlen(hexIntended) - 1);
    }
    LogFmtIf("  WriteBytes @ 0x%08X  len: %u  before: %s->  intended: %s",
        address, (unsigned)len, hexBefore, hexIntended);

    DWORD oldProt;
    if (!VirtualProtect((LPVOID)address, len, PAGE_EXECUTE_READWRITE, &oldProt)) {
        LogFmtIf("  ERROR: VirtualProtect failed at 0x%08X (GLE=%lu)", address, GetLastError());
        return;
    }
    memcpy((LPVOID)address, patch, len);
    VirtualProtect((LPVOID)address, len, oldProt, &oldProt);

    src = (const BYTE*)address;
    BOOL ok = TRUE;
    for (SIZE_T i = 0; i < len; ++i) {
        char tmp[4];
        sprintf(tmp, "%02X ", src[i]); strncat(hexAfter, tmp, sizeof(hexAfter) - strlen(hexAfter) - 1);
        if (src[i] != patch[i]) ok = FALSE;
    }
    if (ok) LogFmtIf("  OK:    write confirmed  after:  %s", hexAfter);
    else    LogFmtIf("  WARN:  readback mismatch! after: %s", hexAfter);
}
