code:
#include "colmatch.h"

#define FASTPALCOLDEPTH 256
#define FASTPALRIGHTSHIFT 3
#define FASTPALRGBDIST (FASTPALCOLDEPTH*2+1)
static int32_t rdist[FASTPALRGBDIST], gdist[FASTPALRGBDIST], bdist[FASTPALRGBDIST];
#define FASTPALGRIDSIZ (FASTPALCOLDEPTH>>FASTPALRIGHTSHIFT)
static char colhere[((FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)+7)>>3];
static char colhead[(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)];
static int32_t colnext[256];
#define FASTPALCOLDIST (1<<FASTPALRIGHTSHIFT)
#define FASTPALCOLDISTMASK (FASTPALCOLDIST-1)
static uint8_t coldist[FASTPALCOLDIST];
static int32_t colscan[27];

static uint8_t const * colmatch_palette;

#define pow2char(x) (1u << (x))

//
// paletteInitClosestColor
//
void paletteInitClosestColorScale(int32_t rscale, int32_t gscale, int32_t bscale)
{
    int32_t j = 0;
    for (bssize_t i=256; i>=0; i--)
    {
        //j = (i-64)*(i-64);
        rdist[i] = rdist[FASTPALCOLDEPTH*2-i] = j*rscale;
        gdist[i] = gdist[FASTPALCOLDEPTH*2-i] = j*gscale;
        bdist[i] = bdist[FASTPALCOLDEPTH*2-i] = j*bscale;
        j += FASTPALRGBDIST-(i<<1);
    }
}
void paletteInitClosestColorMap(uint8_t const * const pal)
{
    Bmemset(colhere,0,sizeof(colhere));
    Bmemset(colhead,0,sizeof(colhead));

    colmatch_palette = pal;

    char const *pal1 = (char const *)&pal[768-3];
    for (bssize_t i=255; i>=0; i--,pal1-=3)
    {
        int32_t const j = (pal1[0]>>FASTPALRIGHTSHIFT)*FASTPALGRIDSIZ*FASTPALGRIDSIZ
            + (pal1[1]>>FASTPALRIGHTSHIFT)*FASTPALGRIDSIZ + (pal1[2]>>FASTPALRIGHTSHIFT)
            + FASTPALGRIDSIZ*FASTPALGRIDSIZ + FASTPALGRIDSIZ + 1;
        if (bitmap_test(colhere, j)) colnext[i] = colhead[j]; else colnext[i] = -1;
        colhead[j] = i;
        bitmap_set(colhere, j);
    }

    paletteFlushClosestColor();
}
void paletteInitClosestColorGrid(void)
{
    int i = 0;
    int32_t x, y, z;
    for (x=-FASTPALGRIDSIZ*FASTPALGRIDSIZ; x<=FASTPALGRIDSIZ*FASTPALGRIDSIZ; x+=FASTPALGRIDSIZ*FASTPALGRIDSIZ)
        for (y=-FASTPALGRIDSIZ; y<=FASTPALGRIDSIZ; y+=FASTPALGRIDSIZ)
            for (z=-1; z<=1; z++)
                colscan[i++] = x+y+z;
    i = colscan[13]; colscan[13] = colscan[26]; colscan[26] = i;

    for (i = 0; i < FASTPALCOLDIST/2; i++)
        coldist[i] = i;
    for (; i < FASTPALCOLDIST; i++)
        coldist[i] = FASTPALCOLDIST-i;
}

#define COLRESULTSIZ 4096

static uint32_t colmatchresults[COLRESULTSIZ];
static int32_t numcolmatchresults;

void paletteFlushClosestColor(void)
{
    Bmemset(colmatchresults, 0, COLRESULTSIZ * sizeof(uint32_t));
    numcolmatchresults = 0;
}

// Finds a color index in [0 .. lastokcol] closest to (r, g, b).
// <lastokcol> must be in [0 .. 255].
int32_t paletteGetClosestColorWithBlacklist(int32_t const r, int32_t const g, int32_t const b, int32_t const lastokcol, uint8_t const * const blacklist)
{
#ifdef DEBUGGINGAIDS
    Bassert(lastokcol >= 0 && lastokcol <= 255);
#endif

    uint32_t const col = r | (g<<8) | (b<<16);

    int mindist = -1;

    int const k = (numcolmatchresults > COLRESULTSIZ) ? COLRESULTSIZ : numcolmatchresults;

    if (!numcolmatchresults) goto skip;

    if (col == (colmatchresults[(numcolmatchresults-1) & (COLRESULTSIZ-1)] & 0x00ffffff))
        return colmatchresults[(numcolmatchresults-1) & (COLRESULTSIZ-1)]>>24;

    int i;

    for (i = 0; i <= k-4; i+=4)
    {
        if (col == (colmatchresults[i]   & 0x00ffffff)) { mindist = i; break; }
        if (col == (colmatchresults[i+1] & 0x00ffffff)) { mindist = i+1; break; }
        if (col == (colmatchresults[i+2] & 0x00ffffff)) { mindist = i+2; break; }
        if (col == (colmatchresults[i+3] & 0x00ffffff)) { mindist = i+3; break; }
    }

    if (mindist == -1)
    for (; i < k; i++)
        if (col == (colmatchresults[i] & 0x00ffffff)) { mindist = i; break; }

    if (mindist != -1)
    {
        uint32_t const idx = colmatchresults[mindist]>>24;
        if (idx <= (unsigned)lastokcol && (blacklist == nullptr || !bitmap_test(blacklist, idx)))
            return idx;
    }

skip:
    i = paletteGetClosestColorWithBlacklistNoCache(r, g, b, lastokcol, blacklist);
    colmatchresults[numcolmatchresults++ & (COLRESULTSIZ-1)] = col | (i << 24);
    return i;
}

int32_t paletteGetClosestColorWithBlacklistNoCache(int32_t r, int32_t g, int32_t b, int32_t const lastokcol, uint8_t const * const blacklist)
{
#ifdef DEBUGGINGAIDS
    Bassert(lastokcol >= 0 && lastokcol <= 255);
#endif

    int const j = (r>>FASTPALRIGHTSHIFT)*FASTPALGRIDSIZ*FASTPALGRIDSIZ
        + (g>>FASTPALRIGHTSHIFT)*FASTPALGRIDSIZ + (b>>FASTPALRIGHTSHIFT)
        + FASTPALGRIDSIZ*FASTPALGRIDSIZ
        + FASTPALGRIDSIZ + 1;

    int const minrdist = rdist[coldist[r&FASTPALCOLDISTMASK]+FASTPALCOLDEPTH];
    int const mingdist = gdist[coldist[g&FASTPALCOLDISTMASK]+FASTPALCOLDEPTH];
    int const minbdist = bdist[coldist[b&FASTPALCOLDISTMASK]+FASTPALCOLDEPTH];

    int mindist = min(minrdist, mingdist);
    mindist = min(mindist, minbdist) + 1;

    r = FASTPALCOLDEPTH-r, g = FASTPALCOLDEPTH-g, b = FASTPALCOLDEPTH-b;

    int retcol = -1;

    for (bssize_t k=26; k>=0; k--)
    {
        int i = colscan[k]+j;

        if (!bitmap_test(colhere, i))
            continue;

        i = colhead[i];

        do
        {
            char const * const pal1 = (char const *)&colmatch_palette[i*3];
            int dist = gdist[pal1[1]+g];

            if (dist >= mindist || i > lastokcol || (blacklist != nullptr && bitmap_test(blacklist, i))) continue;
            if ((dist += rdist[pal1[0]+r]) >= mindist) continue;
            if ((dist += bdist[pal1[2]+b]) >= mindist) continue;

            mindist = dist;
            retcol = i;
        }
        while ((i = colnext[i]) >= 0);
    }

    if (retcol >= 0)
        return retcol;

    mindist = INT32_MAX;

    for (bssize_t i = 0; i <= lastokcol; ++i)
    {
        if (blacklist != nullptr && bitmap_test(blacklist, i))
            continue;

        char const * const pal1 = (char const *)&colmatch_palette[i*3];
        int dist = gdist[pal1[1]+g];

        if (dist >= mindist) continue;
        if ((dist += rdist[pal1[0]+r]) >= mindist) continue;
        if ((dist += bdist[pal1[2]+b]) >= mindist) continue;

        mindist = dist;
        retcol = i;
    }

    return retcol;
}


code:
#include "compat.h"
#include "build.h"
#include "scriptfile.h"
#include "cache1d.h"
#include "kplib.h"
#include "baselayer.h"

#include "common.h"

#include "vfs.h"

void PrintBuildInfo(void)
{
    buildprint(
        "Built ", s_buildTimestamp, ", "

#if defined __INTEL_COMPILER
        "ICC ", __INTEL_COMPILER / 100, ".", __INTEL_COMPILER % 100, " " __INTEL_COMPILER_BUILD_DATE " (" __VERSION__ ")"
#elif defined __clang__
        "clang "
# ifdef DEBUGGINGAIDS
        __clang_version__
# else
        , __clang_major__, ".", __clang_minor__, ".", __clang_patchlevel__,
# endif
#elif defined _MSC_VER
        "MSVC ",
# if defined _MSC_FULL_VER
            _MSC_FULL_VER / 10000000, ".", _MSC_FULL_VER % 10000000 / 100000, ".", _MSC_FULL_VER % 100000, ".", _MSC_BUILD,
# else
            _MSC_VER / 100, ".", _MSC_VER % 100,
# endif
#elif defined __GNUC__
        "GCC "
# ifdef DEBUGGINGAIDS
            __VERSION__
# else
            , __GNUC__, ".", __GNUC_MINOR__,
#  if defined __GNUC_PATCHLEVEL__
            ".", __GNUC_PATCHLEVEL__,
#  endif
# endif
#else
        "Unknown"
#endif
        ", "
#ifdef BITNESS64
        "64"
#else
        "32"
#endif
        "-bit"
#if B_BIG_ENDIAN == 1
        " big-endian"
#endif
        );

    // TODO: architecture, OS, maybe build and feature settings
}

// def/clipmap handling

// g_defNamePtr can ONLY point to a malloc'd block (length BMAX_PATH)
char *g_defNamePtr = NULL;

void clearDefNamePtr(void)
{
    Xfree(g_defNamePtr);
    // g_defNamePtr assumed to be assigned to right after
}

GrowArray<char *> g_defModules;

#ifdef HAVE_CLIPSHAPE_FEATURE
GrowArray<char *> g_clipMapFiles;
#endif

void G_AddDef(const char *buffer)
{
    clearDefNamePtr();
    g_defNamePtr = dup_filename(buffer);
    LOG_F(INFO, "Using .def file %s",g_defNamePtr);
}

void G_AddDefModule(const char *buffer)
{
    g_defModules.append(Xstrdup(buffer));
}

#ifdef HAVE_CLIPSHAPE_FEATURE
void G_AddClipMap(const char *buffer)
{
    g_clipMapFiles.append(Xstrdup(buffer));
}
#endif

//////////

int32_t getatoken(scriptfile *sf, const tokenlist *tl, int32_t ntokens)
{
    char *tok;
    int32_t i;

    if (!sf) return T_ERROR;
    tok = scriptfile_gettoken(sf);
    if (!tok) return T_EOF;

    for (i=ntokens-1; i>=0; i--)
    {
        if (!Bstrcasecmp(tok, tl[i].text))
            return tl[i].tokenid;
    }
    return T_ERROR;
}

//////////

int32_t G_CheckCmdSwitch(int32_t argc, char const * const * argv, const char *str)
{
    int32_t i;
    for (i=0; i<argc; i++)
    {
        if (str && !Bstrcasecmp(argv[i], str))
            return 1;
    }

    return 0;
}

// returns: 1 if file could be opened, 0 else
int32_t testkopen(const char *filename, char searchfirst)
{
    buildvfs_kfd fd = kopen4load(filename, searchfirst);
    if (fd != buildvfs_kfd_invalid)
        kclose(fd);
    return (fd != buildvfs_kfd_invalid);
}

// checks from path and in ZIPs, returns 1 if NOT found
int32_t check_file_exist(const char *fn)
{
#ifdef USE_PHYSFS
    return !PHYSFS_exists(fn);
#else
    int32_t opsm = pathsearchmode;
    char *tfn;

    pathsearchmode = 1;
    if (findfrompath(fn,&tfn) < 0)
    {
        char buf[BMAX_PATH];

        Bstrcpy(buf,fn);
        kzfindfilestart(buf);
        if (!kzfindfile(buf))
        {
            LOG_F(ERROR, "File %s not found", fn);
            pathsearchmode = opsm;
            return 1;
        }
    }
    else Xfree(tfn);
    pathsearchmode = opsm;

    return 0;
#endif
}

//// FILE NAME / DIRECTORY LISTS ////
void fnlist_clearnames(fnlist_t *fnl)
{
    klistfree(fnl->finddirs);
    klistfree(fnl->findfiles);

    fnl->finddirs = fnl->findfiles = NULL;
    fnl->numfiles = fnl->numdirs = 0;
}

// dirflags, fileflags:
//  -1 means "don't get dirs/files",
//  otherwise ORed to flags for respective klistpath
int32_t fnlist_getnames(fnlist_t *fnl, const char *dirname, const char *pattern,
                        int32_t dirflags, int32_t fileflags)
{
    BUILDVFS_FIND_REC *r;

    fnlist_clearnames(fnl);

    if (dirflags != -1)
        fnl->finddirs = klistpath(dirname, "*", BUILDVFS_FIND_DIR|dirflags);
    if (fileflags != -1)
        fnl->findfiles = klistpath(dirname, pattern, BUILDVFS_FIND_FILE|fileflags);

    for (r=fnl->finddirs; r; r=r->next)
        fnl->numdirs++;
    for (r=fnl->findfiles; r; r=r->next)
        fnl->numfiles++;

    return 0;
}

////

// Copy FN to WBUF and append an extension if it's not there, which is checked
// case-insensitively.
// Returns: 1 if not all characters could be written to WBUF, 0 else.
int32_t maybe_append_ext(char *wbuf, int32_t wbufsiz, const char *fn, const char *ext)
{
    const int32_t slen=Bstrlen(fn), extslen=Bstrlen(ext);
    const int32_t haveext = (slen>=extslen && Bstrcasecmp(&fn[slen-extslen], ext)==0);

    Bassert((intptr_t)wbuf != (intptr_t)fn);  // no aliasing

    // If 'fn' has no extension suffixed, append one.
    return (Bsnprintf(wbuf, wbufsiz, "%s%s", fn, haveext ? "" : ext) >= wbufsiz);
}

int32_t ldist(const void *s1, const void *s2)
{
    auto sp1 = (vec2_t const *)s1;
    auto sp2 = (vec2_t const *)s2;
    return sepldist(sp1->x - sp2->x, sp1->y - sp2->y)
        + (enginecompatibilitymode != ENGINE_EDUKE32);
}

int32_t dist(const void *s1, const void *s2)
{
    auto sp1 = (vec3_t const *)s1;
    auto sp2 = (vec3_t const *)s2;
    return sepdist(sp1->x - sp2->x, sp1->y - sp2->y, sp1->z - sp2->z);
}

int32_t FindDistance2D(int32_t x, int32_t y)
{
    return sepldist(x, y);
}

int32_t FindDistance3D(int32_t x, int32_t y, int32_t z)
{
    return sepdist(x, y, z);
}

// Clear OSD background
void COMMON_clearbackground(int numcols, int numrows)
{
    UNREFERENCED_PARAMETER(numcols);

# ifdef USE_OPENGL
    if (videoGetRenderMode() >= REND_POLYMOST && in3dmode())
    {
//        glPushAttrib(GL_FOG_BIT);
        polymost_setFogEnabled(false);
        polymost_useColorOnly(true);

        polymostSet2dView();
        glColor4f(0.f, 0.f, 0.f, 0.67f);
        buildgl_setEnabled(GL_BLEND);
        glRecti(0, 0, xdim, 8*numrows+8);
        glColor4f(0.f, 0.f, 0.f, 1.f);
        glRecti(0, 8*numrows+4, xdim, 8*numrows+8);

//        glPopAttrib();
        polymost_useColorOnly(false);
        polymost_setFogEnabled(true);

        return;
    }
# endif

    CLEARLINES2D(0, min(ydim, numrows*8+8), blackcol*0x01010101);
}

#if defined _WIN32 && !defined EDUKE32_STANDALONE
# define NEED_SHLWAPI_H
# include "windows_inc.h"
# ifndef KEY_WOW64_64KEY
#  define KEY_WOW64_64KEY 0x0100
# endif
# ifndef KEY_WOW64_32KEY
#  define KEY_WOW64_32KEY 0x0200
# endif

int Paths_ReadRegistryValue(char const * const SubKey, char const * const Value, char * const Output, DWORD * OutputSize)
{
    // KEY_WOW64_32KEY gets us around Wow6432Node on 64-bit builds
    REGSAM const wow64keys[] = { KEY_WOW64_32KEY, KEY_WOW64_64KEY };

    for (auto &wow64key : wow64keys)
    {
        HKEY hkey;
        LONG keygood = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NULL, 0, KEY_READ | wow64key, &hkey);

        if (keygood != ERROR_SUCCESS)
            continue;

        LONG retval = SHGetValueA(hkey, SubKey, Value, NULL, Output, OutputSize);

        RegCloseKey(hkey);

        if (retval == ERROR_SUCCESS)
            return 1;
    }

    return 0;
}
#endif

// A bare-bones "parser" for Valve's KeyValues VDF format.
// There is no guarantee this will function properly with ill-formed files (i.e. unbalanced or improper).
static void KeyValues_SkipWhitespace(char *& buf, char * const bufend)
{
    while (1)
    {
        while (buf < bufend && (buf[0] == ' ' || buf[0] == '\n' || buf[0] == '\r' || buf[0] == '\t'))
            ++buf;

        // comments
        if (buf + 2 < bufend && buf[0] == '/' && buf[1] == '/')
        {
            buf += 2;

            while (buf < bufend && buf[0] != '\n' && buf[0] != '\r')
                ++buf;

            continue;
        }

        break;
    }
}
static void KeyValues_SkipToEndOfNormalizedToken(char *& buf, char * const bufend)
{
    ++buf;
    while (buf < bufend && buf[0] != '\0')
        ++buf;
    while (buf < bufend && buf[0] == '\0')
        ++buf;
}
static void KeyValues_SkipToEndOfQuotedToken(char *& buf, char * const bufend)
{
    ++buf;
    while (buf < bufend)
    {
        if (buf + 2 < bufend && buf[0] == '\\' && buf[1] == '"')
            buf += 2;
        else if (buf[0] == '"')
        {
            ++buf;
            break;
        }
        else
            ++buf;
    }
}
static void KeyValues_SkipToEndOfUnquotedToken(char *& buf, char * const bufend)
{
    while (buf < bufend && buf[0] != ' ' && buf[0] != '\n' && buf[0] != '\r' && buf[0] != '\t' && buf[0] != '\0')
        ++buf;
}
static void KeyValues_SkipNextWhatever(char *& buf, char * const bufend)
{
    KeyValues_SkipWhitespace(buf, bufend);

    if (buf >= bufend)
        return;

    if (buf[0] == '{')
    {
        ++buf;

        do
            KeyValues_SkipNextWhatever(buf, bufend);
        while (buf < bufend && buf[0] != '}');

        if (buf < bufend)
            ++buf;
    }
    else if (buf[0] == '\0')
        KeyValues_SkipToEndOfNormalizedToken(buf, bufend);
    else if (buf[0] == '"')
        KeyValues_SkipToEndOfQuotedToken(buf, bufend);
    else if (buf[0] != '}')
        KeyValues_SkipToEndOfUnquotedToken(buf, bufend);

    KeyValues_SkipWhitespace(buf, bufend);
}
static char * KeyValues_NormalizeToken(char *& buf, char * const bufend)
{
    if (buf >= bufend)
        return bufend;

    char * token = buf;

    if (buf[0] == '"')
    {
        buf[0] = '\0';
        KeyValues_SkipToEndOfQuotedToken(buf, bufend);
        buf[-1] = '\0';

        ++token;

        // account for escape sequences
        const char * readseeker = token;
        char * writeseeker = token;
        while (readseeker < buf)
        {
            if (readseeker[0] == '\\')
                ++readseeker;

            writeseeker[0] = readseeker[0];

            ++writeseeker;
            ++readseeker;
        }
        if (writeseeker < buf)
            memset(writeseeker, '\0', buf - writeseeker);
    }
    else if (buf[0] == '\0')
    {
        KeyValues_SkipToEndOfNormalizedToken(buf, bufend);
        ++token;
    }
    else
    {
        KeyValues_SkipToEndOfUnquotedToken(buf, bufend);
        buf[0] = '\0';
    }

    return token;
}
static void KeyValues_SeekToKey(char *& buf, char * const bufend, const char * token)
{
    KeyValues_SkipWhitespace(buf, bufend);

    if (buf >= bufend || buf[0] == '}') // end of scope
        return;

    char * ParentKey = KeyValues_NormalizeToken(buf, bufend);
    while (buf < bufend && Bstrcasecmp(ParentKey, token) != 0)
    {
        KeyValues_SkipNextWhatever(buf, bufend);
        ParentKey = KeyValues_NormalizeToken(buf, bufend);
    }

    KeyValues_SkipWhitespace(buf, bufend);
}
static char * KeyValues_GetValue(char *& buf, char * const bufend)
{
    KeyValues_SkipWhitespace(buf, bufend);

    if (buf >= bufend)
        return nullptr;

    return KeyValues_NormalizeToken(buf, bufend);
}

void Paths_ParseSteamLibraryVDF(const char * fn, PathsParseFunc func)
{
    buildvfs_fd const fd = buildvfs_open_read(fn);
    if (fd == buildvfs_fd_invalid)
        return;

    int32_t size = buildvfs_length(fd);
    if (size <= 0)
        return;

    auto const bufstart = (char *)Xmalloc(size+1);
    char * buf = bufstart;
    auto readsize = (int32_t)buildvfs_read(fd, buf, size);
    buildvfs_close(fd);
    if (readsize != size)
        LOG_F(WARNING, "Read %d bytes from %s, expected %d", readsize, fn, size);

    char * const bufend = buf + readsize;
    bufend[0] = '\0';

    KeyValues_SeekToKey(buf, bufend, "LibraryFolders");
    if (buf < bufend && buf[0] == '{')
    {
        ++buf;

        for (int i = 1; ; ++i)
        {
            char * seeker = buf;
            char key[24];
            snprintf(key, ARRAY_SIZE(key), "%d", i);
            KeyValues_SeekToKey(seeker, bufend, key);
            if (seeker >= bufend || seeker[0] == '}')
                break;

            if (seeker[0] == '{')
            {
                ++seeker;
                KeyValues_SeekToKey(seeker, bufend, "path");
                if (seeker >= bufend || seeker[0] == '}' || seeker[0] == '{')
                    break;
            }

            char * value = KeyValues_GetValue(seeker, bufend);
            if (value == nullptr)
                break;

            func(value);
        }
    }

    Xfree(bufstart);
}

void Paths_ParseXDGDesktopFile(const char * fn, PathsParseFunc func)
{
    buildvfs_fd const fd = buildvfs_open_read(fn);
    if (fd == buildvfs_fd_invalid)
        return;

    int32_t size = buildvfs_length(fd);
    if (size <= 0)
        return;

    auto const bufstart = (char *)Xmalloc(size+1);
    char * buf = bufstart;
    auto readsize = (int32_t)buildvfs_read(fd, buf, size);
    buildvfs_close(fd);
    if (readsize != size)
        LOG_F(WARNING, "Read %d bytes from %s, expected %d", readsize, fn, size);

    char * const bufend = buf + readsize;
    bufend[0] = '\0';

    static char const s_PathEquals[] = "Path=";

    while (buf < bufend)
    {
        if (Bstrncmp(buf, s_PathEquals, ARRAY_SIZE(s_PathEquals)-1) == 0)
        {
            const char * path = buf += ARRAY_SIZE(s_PathEquals)-1;

            while (buf < bufend && *buf != '\n')
                ++buf;
            *buf = '\0';

            func(path);

            break;
        }

        while (buf < bufend && *buf++ != '\n') { }
    }

    Xfree(bufstart);
}

void Paths_ParseXDGDesktopFilesFromGOG(const char * homepath, const char * game, PathsParseFunc func)
{
    static char const * const locations[] = { ".local/share/applications", "Desktop" };
    char buf[BMAX_PATH];

    for (char const * location : locations)
    {
        Bsnprintf(buf, sizeof(buf), "%s/%s/gog_com-%s_1.desktop", homepath, location, game);
        Paths_ParseXDGDesktopFile(buf, func);
    }
}

repo_name: orochi/nblood

license: mit


code:
// Made possible by the Build Engine linking exception.

#if defined _WIN32 || defined __linux__ || defined EDUKE32_OSX
# define VW_ENABLED
#endif

#ifdef VW_ENABLED
# define VOIDWRAP_RUNTIMELINK
# include "voidwrap_steam.h"
#endif

#include "build.h"
#include "communityapi.h"

#ifdef VW_ENABLED

static bool steamworks_enabled;
static VW_LIBHANDLE wrapper_handle;

#ifdef _WIN32
# ifdef _WIN64
static char const wrapper_lib[] = "voidwrap_steam_x64.dll";
# else
static char const wrapper_lib[] = "voidwrap_steam_x86.dll";
# endif
#else
static char const wrapper_lib[] = "libvoidwrap_steam.so";
#endif

#ifdef VWSCREENSHOT
static void steam_callback_screenshotrequested()
{
    DLOG_F(INFO, "Voidwrap: preparing screenshot for Steam.");
    videoCaptureScreen("steam0000.png", 0);
}

#if 0
static void steam_callback_screenshotready(int32_t result)
{
    DLOG_F(INFO, "Voidwrap: screenshot ready: %d", result);
}
#endif
#endif

static void steam_callback_printdebug(char const * str)
{
    UNREFERENCED_PARAMETER(str);
    DLOG_F(INFO, "%s: %s", wrapper_lib, str);
}
#endif

void communityapiInit()
{
#ifdef VW_ENABLED
    DLOG_F(INFO, "Voidwrap: found %s", wrapper_lib);

    wrapper_handle = Voidwrap_LoadLibrary(wrapper_lib);

    if (wrapper_handle == nullptr)
    {
#ifdef _WIN32
        DLOG_F(ERROR, "Voidwrap: failed loading %s.", wrapper_lib);
#else
        DLOG_F(ERROR, "Voidwrap: failed loading %s: dlopen error: %s", wrapper_lib, dlerror());
#endif
        return;
    }

    Voidwrap_Steam_Init = (VW_BOOL)Voidwrap_GetSymbol(wrapper_handle, "Voidwrap_Steam_Init");
    Voidwrap_Steam_Shutdown = (VW_VOID)Voidwrap_GetSymbol(wrapper_handle, "Voidwrap_Steam_Shutdown");
    Voidwrap_Steam_RunCallbacks = (VW_VOID)Voidwrap_GetSymbol(wrapper_handle, "Voidwrap_Steam_RunCallbacks");

    if (nullptr != (Voidwrap_Steam_SetCallback_PrintDebug = (VW_SETCALLBACK_VOID_CONSTCHARPTR)Voidwrap_GetSymbol(wrapper_handle, "Voidwrap_Steam_SetCallback_PrintDebug")))
        Voidwrap_Steam_SetCallback_PrintDebug(steam_callback_printdebug);

    Voidwrap_Steam_UnlockAchievement = (VW_VOID_CONSTCHARPTR)Voidwrap_GetSymbol(wrapper_handle, "Voidwrap_Steam_UnlockAchievement");
    Voidwrap_Steam_SetStat = (VW_VOID_CONSTCHARPTR_INT32)Voidwrap_GetSymbol(wrapper_handle, "Voidwrap_Steam_SetStat");
    Voidwrap_Steam_ResetStats = (VW_VOID)Voidwrap_GetSymbol(wrapper_handle, "Voidwrap_Steam_ResetStats");
    Voidwrap_Steam_SetRichPresence = (VW_VOID_CONSTCHARPTR_CONSTCHARPTR)Voidwrap_GetSymbol(wrapper_handle, "Voidwrap_Steam_SetRichPresence");
    Voidwrap_Steam_ClearRichPresence = (VW_VOID)Voidwrap_GetSymbol(wrapper_handle, "Voidwrap_Steam_ClearRichPresence");
#ifdef VWSCREENSHOT
    Voidwrap_Steam_SendScreenshot = (VW_BOOL_SCREENSHOT)Voidwrap_GetSymbol(wrapper_handle, "Voidwrap_Steam_SendScreenshot");
    Voidwrap_Steam_SetCallback_ScreenshotRequested = (VW_SETCALLBACK_VOID)Voidwrap_GetSymbol(wrapper_handle, "Voidwrap_Steam_SetCallback_ScreenshotRequested");
    Voidwrap_Steam_SetCallback_ScreenshotRequested(steam_callback_screenshotrequested);
#if 0
    Voidwrap_Steam_SetCallback_ScreenshotReady = (VW_SETCALLBACK_VOID_INT32)Voidwrap_GetSymbol(wrapper_handle, "Voidwrap_Steam_SetCallback_ScreenshotReady");
    Voidwrap_Steam_SetCallback_ScreenshotReady(steam_callback_screenshotready);
#endif
#endif

    if (Voidwrap_Steam_Init == nullptr || Voidwrap_Steam_RunCallbacks == nullptr)
    {
        DLOG_F(ERROR, "Voidwrap: fatal error: required symbols are missing.");
        return;
    }
    else if (!Voidwrap_Steam_Init())
    {
        DLOG_F(WARNING, "Voidwrap: Steamworks initialization failed.");
        return;
    }

    DLOG_F(INFO, "Voidwrap: Steamworks initialized.");

    steamworks_enabled = true;
#endif
}

void communityapiShutdown()
{
#ifdef VW_ENABLED
    if (!steamworks_enabled)
        return;

    if (nullptr == Voidwrap_Steam_Shutdown)
        return;

    Voidwrap_Steam_Shutdown();
#endif
}

void communityapiRunCallbacks()
{
#ifdef VW_ENABLED
    if (!steamworks_enabled)
        return;

    Voidwrap_Steam_RunCallbacks();
#endif
}

bool communityapiEnabled()
{
#ifdef VW_ENABLED
    return steamworks_enabled;
#else
    return false;
#endif
}

char const *communityApiGetPlatformName()
{
#ifdef VW_ENABLED
    return "Steam";
#else
    return NULL;
#endif
}

void communityapiUnlockAchievement(char const * id)
{
#ifdef VW_ENABLED
    if (!steamworks_enabled)
        return;

    if (nullptr == Voidwrap_Steam_UnlockAchievement)
        return;

    Voidwrap_Steam_UnlockAchievement(id);
#else
    UNREFERENCED_PARAMETER(id);
#endif
}

void communityapiSetStat(char const * id, int32_t value)
{
#ifdef VW_ENABLED
    if (!steamworks_enabled)
        return;

    if (nullptr == Voidwrap_Steam_SetStat)
        return;

    Voidwrap_Steam_SetStat(id, value);
#else
    UNREFERENCED_PARAMETER(id);
    UNREFERENCED_PARAMETER(value);
#endif
}

void communityapiResetStats()
{
#ifdef VW_ENABLED
    if (!steamworks_enabled)
        return;

    if (nullptr == Voidwrap_Steam_ResetStats)
        return;

    Voidwrap_Steam_ResetStats();
#endif
}

void communityapiSetRichPresence(char const * key, char const * str)
{
#ifdef VW_ENABLED
    if (!steamworks_enabled)
        return;

    if (nullptr == Voidwrap_Steam_SetRichPresence)
        return;

    Voidwrap_Steam_SetRichPresence(key, str);
#else
    UNREFERENCED_PARAMETER(str);
#endif
}

void communityapiClearRichPresence(void)
{
#ifdef VW_ENABLED
    if (!steamworks_enabled)
        return;

    if (nullptr == Voidwrap_Steam_ClearRichPresence)
        return;

    Voidwrap_Steam_ClearRichPresence();
#endif
}

#ifdef VWSCREENSHOT
void communityapiSendScreenshot(char * filename)
{
#ifdef VW_ENABLED
    if (!steamworks_enabled)
        return;

    char fullpath[BMAX_PATH];
    buildvfs_getcwd(fullpath, sizeof(fullpath));
    Bstrcat(fullpath, "/");
    Bstrcat(fullpath, filename);

    DVLOG_F(LOG_DEBUG, "Steam screenshot path: %s", fullpath);

    Voidwrap_Steam_SendScreenshot(fullpath, xdim, ydim);
#else
    UNREFERENCED_PARAMETER(filename);
#endif
}
#endif


code:
/*
 * Playing-field leveler for Build
 */

#define LIBDIVIDE_BODY
#include "compat.h"

#ifdef _WIN32
# define NEED_SHLOBJ_H
# include "windows_inc.h"
#elif __APPLE__
# include "osxbits.h"
#endif

#ifndef USE_PHYSFS
#if defined(_MSC_VER)
# include <io.h>
#else
# include <dirent.h>
#endif
#endif

#if defined __linux || defined EDUKE32_BSD
# include <libgen.h> // for dirname()
#endif
#if defined EDUKE32_BSD
# include <limits.h> // for PATH_MAX
# include <sys/sysctl.h> // for sysctl() to get path to executable
#endif

#include "baselayer.h"
#include "vfs.h"

////////// PANICKING ALLOCATION FUNCTIONS //////////

static void (*g_MemErrHandler)(int32_t line, const char *file, const char *func);

#ifdef __cplusplus
extern "C"
{
#endif
#ifdef DEBUGGINGAIDS
const char *g_MemErrFunc = "???";
const char *g_MemErrFile = "???";
int32_t g_MemErrLine;
#endif
char *_xstrdup(const char *s) { return xstrdup(s); }
void *_xmalloc(bsize_t const size) { return xmalloc(size); }
void *_xcalloc(bsize_t const nmemb, bsize_t const size) { return xcalloc(nmemb, size); }
void *_xrealloc(void *const ptr, bsize_t const size) { return xrealloc(ptr, size); }
void *_xaligned_alloc(bsize_t const alignment, bsize_t const size) { return xaligned_alloc(alignment, size); }
void *_xaligned_calloc(bsize_t const alignment, bsize_t const count, bsize_t const size) { return xaligned_calloc(alignment, count, size); }
void  _xfree(void *const ptr) { xfree(ptr); }
void  _xaligned_free(void *const ptr) { xaligned_free(ptr); }
#ifdef __cplusplus
}
#endif

void handle_memerr(void)
{
    debug_break();

    if (g_MemErrHandler)
    {
#ifdef DEBUGGINGAIDS
        g_MemErrHandler(g_MemErrLine, g_MemErrFile, g_MemErrFunc);
#else
        g_MemErrHandler(0, "???", "???");
#endif
    }

    Bexit(EXIT_FAILURE);
    EDUKE32_UNREACHABLE_SECTION(return nullptr);
}

void set_memerr_handler(void (*handlerfunc)(int32_t, const char *, const char *)) { g_MemErrHandler = handlerfunc; }
sm_allocator g_sm_heap;

//
// Stuff which must be a function
//
char *Bgethomedir(void)
{
#ifdef _WIN32
    int32_t loaded = 0;
    auto hShell32 = GetModuleHandle("shell32.dll");

    if (hShell32 == NULL)
    {
        hShell32 = LoadLibrary("shell32.dll");
        loaded = 1;
    }

    if (hShell32 == NULL)
        return NULL;

    using SHGSFPA_t = BOOL (WINAPI *)(HWND, LPTSTR, int, BOOL);
    auto aSHGetSpecialFolderPathA = (SHGSFPA_t)(void (*)(void))GetProcAddress(hShell32, "SHGetSpecialFolderPathA");

    if (aSHGetSpecialFolderPathA != NULL)
    {
        TCHAR appdata[MAX_PATH];

        if (SUCCEEDED(aSHGetSpecialFolderPathA(NULL, appdata, CSIDL_APPDATA, FALSE)))
        {
            if (loaded)
                FreeLibrary(hShell32);
            return Xstrdup(appdata);
        }
    }

    if (loaded)
        FreeLibrary(hShell32);
    return NULL;
#elif defined EDUKE32_OSX
    return osx_gethomedir();
#elif defined(GEKKO)
    // return current drive's name
    char *drv, cwd[BMAX_PATH] = {0};
    buildvfs_getcwd(cwd, BMAX_PATH);
    drv = strchr(cwd, ':');
    if (drv)
        drv[1] = '\0';
    return Xstrdup(cwd);
#else
    char *e = getenv("HOME");
    if (!e) return NULL;
    return Xstrdup(e);
#endif
}

char *Bgetappdir(void)
{
    char *dir = NULL;

#ifdef _WIN32
    TCHAR appdir[MAX_PATH];

    if (GetModuleFileName(NULL, appdir, MAX_PATH) > 0) {
        // trim off the filename
        char *slash = Bstrrchr(appdir, '\\');
        if (slash) slash[0] = 0;
        dir = Xstrdup(appdir);
    }

#elif defined EDUKE32_OSX
    dir = osx_getappdir();
#elif defined __FreeBSD__
    // the sysctl should also work when /proc/ is not mounted (which seems to
    // be common on FreeBSD), so use it..
    char   buf[PATH_MAX] = {0};
    int    name[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
    size_t len     = sizeof(buf) - 1;
    int    ret     = sysctl(name, ARRAY_SIZE(name), buf, &len, NULL, 0);

    if (ret == 0 && buf[0] != '\0')
    {
        // again, remove executable name with dirname()
        // on FreeBSD dirname() seems to use some internal buffer
        dir = Xstrdup(dirname(buf));
    }
#elif defined __linux || defined EDUKE32_BSD
    char buf[PATH_MAX] = {0};
    char buf2[PATH_MAX] = {0};
#  ifdef __linux
    Bsnprintf(buf, sizeof(buf), "/proc/%d/exe", getpid());
#  else // the BSDs.. except for FreeBSD which has a sysctl
    Bsnprintf(buf, sizeof(buf), "/proc/%d/file", getpid());
#  endif
    int len = readlink(buf, buf2, sizeof(buf2));
    if (len != -1) {
        // remove executable name with dirname(3)
        // on Linux, dirname() will modify buf2 (cutting off executable name) and return it
        // on FreeBSD it seems to use some internal buffer instead.. anyway, just strdup()
        dir = Xstrdup(dirname(buf2));
    }
#endif

    return dir;
}

int32_t Bcorrectfilename(char *filename, int32_t removefn)
{
    char *fn = Xstrdup(filename);
    char *tokarr[64], *first, *next = NULL;

    for (first=fn; *first; first++)
    {
#ifdef _WIN32
        if (*first == '\\') *first = '/';
#endif
    }

    int leadslash = (*fn == '/');
    int trailslash = (first>fn && first[-1] == '/');
    int ntok = 0;

    first = fn;
    do
    {
        char *token = Bstrtoken(first, "/", &next, 1);
        first = NULL;
        if (!token) break;
        else if (token[0] == 0) continue;
        else if (token[0] == '.' && token[1] == 0) continue;
        else if (token[0] == '.' && token[1] == '.' && token[2] == 0) ntok = max(0,ntok-1);
        else tokarr[ntok++] = token;
    }
    while (1);

    if (!trailslash && removefn) { ntok = max(0,ntok-1); trailslash = 1; }
    if (ntok == 0 && trailslash && leadslash) trailslash = 0;

    first = filename;
    if (leadslash) *(first++) = '/';
    for (int i=0; i<ntok; i++)
    {
        if (i>0) *(first++) = '/';
        for (char *token=tokarr[i]; *token; token++)
            *(first++) = *token;
    }
    if (trailslash) *(first++) = '/';
    *(first++) = 0;

    Xfree(fn);
    return 0;
}

#ifndef USE_PHYSFS
int32_t Bcanonicalisefilename(char *filename, int32_t removefn)
{
    char cwd[BMAX_PATH];
    char *fnp = filename;

#ifdef _WIN32
    int drv = 0;

    if (filename[0] && filename[1] == ':')
    {
        // filename is prefixed with a drive
        drv = toupper(filename[0]) - 'A' + 1;
        fnp += 2;
    }

    if (!_getdcwd(drv, cwd, sizeof(cwd)))
        return -1;

    for (char *p = cwd; *p; p++)
        if (*p == '\\')
            *p = '/';
#else
    if (!buildvfs_getcwd(cwd, sizeof(cwd)))
        return -1;
#endif

    char *p = Bstrrchr(cwd, '/');
    if (!p || p[1])
        Bstrcat(cwd, "/");

    char fn[BMAX_PATH];
    Bstrcpy(fn, fnp);

#ifdef _WIN32
    for (p = fn; *p; p++)
        if (*p == '\\')
            *p = '/';
#endif

    if (fn[0] != '/')
    {
        // we are dealing with a path relative to the current directory
        Bstrcpy(filename, cwd);
        Bstrcat(filename, fn);
    }
    else
    {
#ifdef _WIN32
        filename[0] = cwd[0];
        filename[1] = ':';
        filename[2] = 0;
        Bstrcat(filename, fn);
#else
        Bstrcpy(filename, fn);
#endif
    }
    fnp = filename;
#ifdef _WIN32
    fnp += 2;  // skip the drive
#endif
    UNREFERENCED_PARAMETER(removefn);  // change the call below to use removefn instead of 1?
    return Bcorrectfilename(fnp, 1);
}
#endif

char *Bgetsystemdrives(void)
{
#ifdef _WIN32
    char *str, *p;
    DWORD drv, mask;
    int32_t number = 0;

    drv = GetLogicalDrives();
    if (drv == 0)
        return NULL;

    for (mask = 1; mask < 0x8000000l; mask <<= 1)
    {
        if ((drv & mask) == 0)
            continue;
        number++;
    }

    str = p = (char *)Xmalloc(1 + (3 * number));
    number = 0;
    for (mask = 1; mask < 0x8000000l; mask <<= 1, number++)
    {
        if ((drv & mask) == 0)
            continue;
        *(p++) = 'A' + number;
        *(p++) = ':';
        *(p++) = 0;
    }
    *(p++) = 0;

    return str;
#else
    // Perhaps have Unix OS's put /, /home/user, and /mnt/* in the "drives" list?
    return NULL;
#endif
}

#ifndef USE_PHYSFS
typedef struct
{
#ifdef _MSC_VER
    intptr_t dir;
    struct _finddata_t fid;
#else
    DIR *dir;
#endif
    struct Bdirent info;
    int32_t status;
    char name[1];
} BDIR_real;

BDIR *Bopendir(const char *name)
{
    BDIR_real *dirr;
#ifdef _MSC_VER
    char *t, *tt;
    t = (char *)Xmalloc(Bstrlen(name) + 1 + 4);
#endif

    dirr = (BDIR_real *)Xmalloc(sizeof(BDIR_real) + Bstrlen(name));

#ifdef _MSC_VER
    Bstrcpy(t, name);
    tt = t + Bstrlen(name) - 1;
    while (*tt == ' ' && tt > t) tt--;
    if (*tt != '/' && *tt != '\\')
        *(++tt) = '/';
    *(++tt) = '*';
    *(++tt) = '.';
    *(++tt) = '*';
    *(++tt) = 0;

    dirr->dir = _findfirst(t, &dirr->fid);
    Xfree(t);
    if (dirr->dir == -1)
    {
        Xfree(dirr);
        return NULL;
    }
#else
    dirr->dir = opendir(name);
    if (dirr->dir == NULL)
    {
        Xfree(dirr);
        return NULL;
    }
#endif

    dirr->status = 0;
    Bstrcpy(dirr->name, name);

    return (BDIR *)dirr;
}

struct Bdirent *Breaddir(BDIR *dir)
{
    BDIR_real *dirr = (BDIR_real *)dir;

#ifdef _MSC_VER
    if (dirr->status > 0)
    {
        if (_findnext(dirr->dir, &dirr->fid) != 0)
        {
            dirr->status = -1;
            return NULL;
        }
    }
    dirr->info.namlen = Bstrlen(dirr->fid.name);
    dirr->info.name = dirr->fid.name;
    dirr->status++;
#else
    struct dirent *de = readdir(dirr->dir);
    if (de == NULL)
    {
        dirr->status = -1;
        return NULL;
    }
    else
    {
        dirr->status++;
    }
    dirr->info.namlen = Bstrlen(de->d_name);
    dirr->info.name = de->d_name;
#endif
    dirr->info.mode = 0;
    dirr->info.size = 0;
    dirr->info.mtime = 0;

    char *fn = (char *)Xmalloc(Bstrlen(dirr->name) + 1 + dirr->info.namlen + 1);
    Bsprintf(fn, "%s/%s", dirr->name, dirr->info.name);

#ifdef USE_PHYSFS
    PHYSFS_Stat st;
    if (PHYSFS_stat(fn, &st))
    {
        // dirr->info.mode = TODO;
        dirr->info.size = st.filesize;
        dirr->info.mtime = st.modtime;
    }
#else
    struct Bstat st;
    if (!Bstat(fn, &st))
    {
        dirr->info.mode = st.st_mode;
        dirr->info.size = st.st_size;
        dirr->info.mtime = st.st_mtime;
    }
#endif

    Xfree(fn);

    return &dirr->info;
}

int32_t Bclosedir(BDIR *dir)
{
    BDIR_real *dirr = (BDIR_real *)dir;

#ifdef _MSC_VER
    _findclose(dirr->dir);
#else
    closedir(dirr->dir);
#endif
    Xfree(dirr);

    return 0;
}
#endif

char *Bstrtoken(char *s, const char *delim, char **ptrptr, int chop)
{
    if (!ptrptr)
        return NULL;

    char *p = s ? s : *ptrptr;

    if (!p)
        return NULL;

    while (*p != 0 && Bstrchr(delim, *p)) p++;

    if (*p == 0)
    {
        *ptrptr = NULL;
        return NULL;
    }

    char * const start = p;

    while (*p != 0 && !Bstrchr(delim, *p)) p++;

    if (*p == 0)
        *ptrptr = NULL;
    else
    {
        if (chop)
            *(p++) = 0;
        *ptrptr = p;
    }

    return start;
}

char *Bstrtolower(char *str)
{
    if (!str)
        return NULL;

    int len = Bstrlen(str);

    if (len <= 0)
        return str;

    int i = 0;

    do
    {
        *(str + i) = Btolower(*(str + i));
        i++;
    } while (--len);

    return str;
}

//Brute-force case-insensitive, slash-insensitive, * and ? wildcard matcher
//Returns: 1:matches, 0:doesn't match
#ifndef WITHKPLIB
extern char toupperlookup[256];

static int32_t wildmatch(const char *match, const char *wild)
{
    do
    {
        if (*match && (toupperlookup[*wild] == toupperlookup[*match] || *wild == '?'))
        {
            wild++, match++;
            continue;
        }
        else if ((*match|*wild) == '\0')
            return 1;
        else if (*wild == '*')
        {
            do { wild++; } while (*wild == '*');
            do
            {
                if (*wild == '\0')
                    return 1;
                while (*match && toupperlookup[*match] != toupperlookup[*wild]) match++;
                if (*match && *(match+1) && toupperlookup[*(match+1)] != toupperlookup[*(wild+1)])
                {
                    match++;
                    continue;
                }
                break;
            }
            while (1);
            if (toupperlookup[*match] == toupperlookup[*wild])
                continue;
        }
        return 0;
    }
    while (1);
}
#endif

#if !defined(_WIN32)
char *Bstrlwr(char *s)
{
    if (!s) return s;
    char *t = s;
    while (*t) { *t = Btolower(*t); t++; }
    return s;
}

char *Bstrupr(char *s)
{
    if (!s) return s;
    char *t = s;
    while (*t) { *t = Btoupper(*t); t++; }
    return s;
}
#endif

#define BMAXPAGESIZE 16384

int Bgetpagesize(void)
{
    static int pageSize = -1;

    if (pageSize == -1)
    {
#ifdef _WIN32
        SYSTEM_INFO system_info;
        GetSystemInfo(&system_info);
        pageSize = system_info.dwPageSize;
#else
        pageSize = sysconf(_SC_PAGESIZE);
#endif
    }

    return (unsigned)pageSize < BMAXPAGESIZE ? pageSize : BMAXPAGESIZE;
}

//
// Bgetsysmemsize() -- gets the amount of system memory in the machine
//
#ifdef _WIN32
typedef BOOL (WINAPI *aGlobalMemoryStatusExType)(LPMEMORYSTATUSEX);
#endif

size_t Bgetsysmemsize(void)
{
    size_t siz = UINT32_MAX;

#ifdef _WIN32
    HMODULE lib = LoadLibrary("KERNEL32.DLL");

    if (lib)
    {
        aGlobalMemoryStatusExType aGlobalMemoryStatusEx =
            (aGlobalMemoryStatusExType)(void (*)(void))GetProcAddress(lib, "GlobalMemoryStatusEx");

        if (aGlobalMemoryStatusEx)
        {
            //WinNT
            MEMORYSTATUSEX memst;
            memst.dwLength = sizeof(MEMORYSTATUSEX);
            if (aGlobalMemoryStatusEx(&memst))
                siz = min<decltype(memst.ullTotalPhys)>(SIZE_MAX, memst.ullTotalPhys);
        }

        if (!aGlobalMemoryStatusEx || siz == 0)
        {
            LOG_F(ERROR, "Couldn't determine system memory size with GlobalMemoryStatusEx()!");
            siz = UINT32_MAX;
        }

        FreeLibrary(lib);
    }
    else
        LOG_F(ERROR, "Unable to load KERNEL32.DLL.");

#elif (defined(_SC_PAGE_SIZE) || defined(_SC_PAGESIZE)) && defined(_SC_PHYS_PAGES) && !defined(GEKKO)
#ifdef _SC_PAGE_SIZE
    int64_t const scpagesiz = sysconf(_SC_PAGE_SIZE);
#else
    int64_t const scpagesiz = sysconf(_SC_PAGESIZE);
#endif
    int64_t const scphyspages = sysconf(_SC_PHYS_PAGES);

    if (scpagesiz >= 0 && scphyspages >= 0)
        siz = (size_t)min<uint64_t>(SIZE_MAX, scpagesiz * scphyspages);

    //initprintf("Bgetsysmemsize(): %d pages of %d bytes, %d bytes of system memory\n",
    //		scphyspages, scpagesiz, siz);

#endif

    return siz;
}

#ifdef GEKKO
int access(const char *pathname, int mode)
{
    struct stat st;
    if (stat(pathname, &st)==-1)
        return -1;

    // TODO: Check mode against st_mode
    UNREFERENCED_PARAMETER(mode);

    return 0;
}
#endif


code:
// Evil and Nasty Configuration File Reader for KenBuild
// by Jonathon Fowler

#include "compat.h"
#include "build.h"
#include "editor.h"
#include "osd.h"
#include "cache1d.h"
#include "baselayer.h"
#include "renderlayer.h"

#include "vfs.h"

static double clampd(double d, double mind, double maxd)
{
    if (d != d || d<mind)
        d = mind;
    else if (d>maxd)
        d = maxd;
    return d;
}

static int32_t readconfig(buildvfs_FILE fp, const char *key, char *value, uint32_t len)
{
    char buf[1000], *k, *v, *eq;
    int32_t x=0;

    if (len < 1) return 0;

    buildvfs_rewind(fp);

    while (1)
    {
        if (!buildvfs_fgets(buf, 1000, fp)) return 0;

        if (buf[0] == ';') continue;

        eq = Bstrchr(buf, '=');
        if (!eq) continue;

        k = buf;
        v = eq+1;

        while (*k == ' ' || *k == '\t') k++;
        *(eq--) = 0;
        while ((*eq == ' ' || *eq == '\t') && eq>=k) *(eq--) = 0;

        if (Bstrcasecmp(k, key)) continue;

        while (*v == ' ' || *v == '\t') v++;
        eq = v + Bstrlen(v)-1;

        while ((*eq == ' ' || *eq == '\t' || *eq == '\r' || *eq == '\n') && eq>=v) *(eq--) = 0;

        value[--len] = 0;
        do value[x] = v[x]; while (v[x++] != 0 && len-- > 0);

        return x-1;
    }
}

extern int16_t brightness;
extern char default_buildkeys[NUMBUILDKEYS];
static char *const keys = default_buildkeys;
static int32_t default_grid=9;
extern int32_t AmbienceToggle, MixRate;
extern int32_t ParentalLock;

/*
 * SETUP.DAT
 * 0      = video mode (0:chained 1:vesa 2:screen buffered 3/4/5:tseng/paradise/s3 6:red-blue)
 * 1      = sound (0:none)
 * 2      = music (0:none)
 * 3      = input (0:keyboard 1:+mouse)
 * 4      = multiplayer (0:single 1-4:com 5-11:ipx)
 * 5&0xf0 = com speed
 * 5&0x0f = com irq
 * 6&0xf0 = chained y-res
 * 6&0x0f = chained x-res or vesa mode
 * 7&0xf0 = sound samplerate
 * 7&0x01 = sound quality
 * 7&0x02 = 8/16 bit
 * 7&0x04 = mono/stereo
 *
 * bytes 8 to 26 are key settings:
 * 0      = Forward (0xc8)
 * 1      = Backward (0xd0)
 * 2      = Turn left (0xcb)
 * 3      = Turn right (0xcd)
 * 4      = Run (0x2a)
 * 5      = Strafe (0x9d)
 * 6      = Fire (0x1d)
 * 7      = Use (0x39)
 * 8      = Stand high (0x1e)
 * 9      = Stand low (0x2c)
 * 10     = Look up (0xd1)
 * 11     = Look down (0xc9)
 * 12     = Strafe left (0x33)
 * 13     = Strafe right (0x34)
 * 14     = 2D/3D switch (0x9c)
 * 15     = View cycle (0x1c)
 * 16     = 2D Zoom in (0xd)
 * 17     = 2D Zoom out (0xc)
 * 18     = Chat (0xf)
 */

int32_t loadsetup(const char *fn)
{
    buildvfs_FILE fp;
#define VL 1024
    char val[VL];
    int32_t i;

    if ((fp = buildvfs_fopen_read(fn)) == NULL) return -1;

    if (readconfig(fp, "usecwd", val, VL) > 0) g_useCwd = (atoi_safe(val) != 0);
    if (readconfig(fp, "forcesetup", val, VL) > 0) forcesetup = (atoi_safe(val) != 0);
    if (readconfig(fp, "fullscreen", val, VL) > 0) fullscreen = (atoi_safe(val) != 0);

    if (readconfig(fp, "xdim", val, VL) > 0) xdim = atoi_safe(val);
    if (readconfig(fp, "ydim", val, VL) > 0) ydim = atoi_safe(val);

    if (readconfig(fp, "bpp", val, VL) > 0) bppgame = atoi_safe(val);

    if (readconfig(fp, "editorgridextent", val, VL) > 0)
    {
        int32_t tmp = atoi_safe(val);
        editorgridextent = clamp(tmp, 65536, BXY_MAX);
    }

    if (readconfig(fp, "grid", val, VL) > 0)
    {
        grid = atoi_safe(val);
        default_grid = grid;
        autogrid = (grid==9);
        grid = clamp(grid, 0, 8);
    }
#ifdef POLYMER
    if (readconfig(fp, "rendmode", val, VL) > 0) { i = atoi_safe(val); glrendmode = i; }
#endif
    if (readconfig(fp, "vid_gamma", val, VL) > 0) g_videoGamma = clampd(Bstrtod(val, NULL), 0.0, 10.0);
    if (readconfig(fp, "vid_brightness", val, VL) > 0) g_videoBrightness = clampd(Bstrtod(val, NULL), -10.0, 10.0);
    if (readconfig(fp, "vid_contrast", val, VL) > 0) g_videoContrast = clampd(Bstrtod(val, NULL), 0.0, 10.0);
#ifdef RENDERTYPEWIN
    if (readconfig(fp, "maxrefreshfreq", val, VL) > 0) maxrefreshfreq = atoi_safe(val);
#endif
#ifdef USE_OPENGL
    if (readconfig(fp, "lazytileselector", val, VL) > 0) g_lazy_tileselector = !!atoi_safe(val);
#endif
    if (readconfig(fp, "gameexecutable", val, VL) > 0)
        Bstrcpy(game_executable, val);

#if 1
    if (readconfig(fp, "keyforward", val, VL) > 0) keys[BK_MOVEFORWARD] = Bstrtol(val, NULL, 16);
    if (readconfig(fp, "keybackward", val, VL) > 0) keys[BK_MOVEBACKWARD] = Bstrtol(val, NULL, 16);
    if (readconfig(fp, "keyturnleft", val, VL) > 0) keys[BK_TURNLEFT] = Bstrtol(val, NULL, 16);
    if (readconfig(fp, "keyturnright", val, VL) > 0) keys[BK_TURNRIGHT] = Bstrtol(val, NULL, 16);
    if (readconfig(fp, "keyrun", val, VL) > 0) keys[BK_RUN] = Bstrtol(val, NULL, 16);
    if (readconfig(fp, "keystrafe", val, VL) > 0) keys[BK_STRAFE] = Bstrtol(val, NULL, 16);
//    if (readconfig(fp, "keyfire", val, VL) > 0) keys[BK_SHOOT] = Bstrtol(val, NULL, 16);
//    if (readconfig(fp, "keyuse", val, VL) > 0) keys[BK_OPEN] = Bstrtol(val, NULL, 16);
    if (readconfig(fp, "keystandhigh", val, VL) > 0) keys[BK_MOVEUP] = Bstrtol(val, NULL, 16);
    if (readconfig(fp, "keystandlow", val, VL) > 0) keys[BK_MOVEDOWN] = Bstrtol(val, NULL, 16);
//    if (readconfig(fp, "keylookup", val, VL) > 0) keys[BK_LOOKUP] = Bstrtol(val, NULL, 16);
//    if (readconfig(fp, "keylookdown", val, VL) > 0) keys[BK_LOOKDOWN] = Bstrtol(val, NULL, 16);
//    if (readconfig(fp, "keystrafeleft", val, VL) > 0) keys[BK_STRAFELEFT] = Bstrtol(val, NULL, 16);
//    if (readconfig(fp, "keystraferight", val, VL) > 0) keys[BK_STRAFERIGHT] = Bstrtol(val, NULL, 16);
    if (readconfig(fp, "key2dmode", val, VL) > 0) keys[BK_MODE2D_3D] = Bstrtol(val, NULL, 16);
//    if (readconfig(fp, "keyviewcycle", val, VL) > 0) keys[BK_PLAYERVIEW] = Bstrtol(val, NULL, 16);
//    if (readconfig(fp, "key2dzoomin", val, VL) > 0) keys[BK_ZOOMIN] = Bstrtol(val, NULL, 16);
//    if (readconfig(fp, "key2dzoomout", val, VL) > 0) keys[BK_ZOOMOUT] = Bstrtol(val, NULL, 16);
//    if (readconfig(fp, "keychat", val, VL) > 0) keys[BK_MESSAGE] = Bstrtol(val, NULL, 16);
#endif

    if (readconfig(fp, "windowposx", val, VL) > 0)
    {
        int32_t x = atoi_safe(val);

        if (readconfig(fp, "windowposy", val, VL) > 0)
        {
            g_windowPos = { x, atoi_safe(val) };
            g_windowPosValid = true;
        }
    }

    if (readconfig(fp, "keyconsole", val, VL) > 0)
    {
        keys[BK_CONSOLE] = Bstrtol(val, NULL, 16);
        OSD_CaptureKey(keys[BK_CONSOLE]);
    }

    if (readconfig(fp, "mousesensitivity", val, VL) > 0) msens = Bstrtod(val, NULL);

    if (readconfig(fp, "mousenavigation", val, VL) > 0) unrealedlook = !!atoi_safe(val);

    if (readconfig(fp, "mousenavigationaccel", val, VL) > 0) pk_uedaccel = atoi_safe(val);

    if (readconfig(fp, "quickmapcycling", val, VL) > 0) quickmapcycling = !!atoi_safe(val);

    if (readconfig(fp, "sideview_reversehorizrot", val, VL) > 0) sideview_reversehrot = !!atoi_safe(val);
    if (readconfig(fp, "revertCTRL", val, VL) > 0) revertCTRL = !!atoi_safe(val);

    if (readconfig(fp, "scrollamount", val, VL) > 0) scrollamount = atoi_safe(val);

    if (readconfig(fp, "turnaccel", val, VL) > 0) pk_turnaccel = atoi_safe(val);

    if (readconfig(fp, "turndecel", val, VL) > 0) pk_turndecel = atoi_safe(val);

    if (readconfig(fp, "autosavesec", val, VL) > 0) autosave = max(0, atoi_safe(val));
    if (readconfig(fp, "autocorruptchecksec", val, VL) > 0) autocorruptcheck = max(0, atoi_safe(val));
    if (readconfig(fp, "corruptcheck_noalreadyrefd", val, VL) > 0)
        corruptcheck_noalreadyrefd = !!atoi_safe(val);
    if (readconfig(fp, "corruptcheck_game_duke3d", val, VL) > 0)
        corruptcheck_game_duke3d = !!atoi_safe(val);
    if (readconfig(fp, "corruptcheck_heinum", val, VL) > 0)
        corruptcheck_heinum = clamp(atoi_safe(val), 0, 2);
    if (readconfig(fp, "fixmaponsave_sprites", val, VL) > 0)
        fixmaponsave_sprites = !!atoi_safe(val);
    if (readconfig(fp, "keeptexturestretch", val, VL) > 0)
        keeptexturestretch = !!atoi_safe(val);

    if (readconfig(fp, "showheightindicators", val, VL) > 0)
        showheightindicators = clamp(atoi_safe(val), 0, 2);
    if (readconfig(fp, "showambiencesounds", val, VL) > 0)
        showambiencesounds = clamp(atoi_safe(val), 0, 2);

    if (readconfig(fp, "pathsearchmode", val, VL) > 0)
        pathsearchmode = clamp(atoi_safe(val), 0, 1);

    if (readconfig(fp, "pointhighlightdist", val, VL) > 0)
        pointhighlightdist = atoi_safe(val);

    if (readconfig(fp, "linehighlightdist", val, VL) > 0)
        linehighlightdist = atoi_safe(val);

    if (readconfig(fp, "2d3dmode", val, VL) > 0)
        m32_2d3dmode = clamp(atoi_safe(val), 0, 1);

    if (readconfig(fp, "2d3dsize", val, VL) > 0)
        m32_2d3dsize = clamp(atoi_safe(val), 3, 5);

    if (readconfig(fp, "2d3d_x", val, VL) > 0)
        m32_2d3d.x = clamp(atoi_safe(val), 0, 0xffff);

    if (readconfig(fp, "2d3d_y", val, VL) > 0)
        m32_2d3d.y = clamp(atoi_safe(val), 0, 0xffff);

    if (readconfig(fp, "3dundo", val, VL) > 0)
        m32_3dundo = !!atoi_safe(val);

    if (readconfig(fp, "autogray", val, VL) > 0)
        autogray = !!atoi_safe(val);
//    if (readconfig(fp, "showinnergray", val, VL) > 0)
//        showinnergray = !!atoi_safe(val);

    if (readconfig(fp, "graphicsmode", val, VL) > 0)
        graphicsmode = clamp(atoi_safe(val), 0, 2);

    if (readconfig(fp, "upscalefactor", val, VL) > 0)
        upscalefactor = clamp(atoi_safe(val), 1, 3);

    if (readconfig(fp, "samplerate", val, VL) > 0) MixRate = clamp(atoi_safe(val), 8000, 48000);
    if (readconfig(fp, "ambiencetoggle", val, VL) > 0) AmbienceToggle = !!atoi_safe(val);
    if (readconfig(fp, "parlock", val, VL) > 0) ParentalLock = !!atoi_safe(val);

    if (readconfig(fp, "osdtryscript", val, VL) > 0) m32_osd_tryscript = !!atoi_safe(val);

    if (readconfig(fp, "remap", val, VL) > 0)
    {
        char *p=val;
        uint32_t v1,v2;

        while (*p)
        {
            if (!sscanf(p,"%x",&v1))break;
            if ((p=strchr(p,'-'))==0)break;
            p++;
            if (!sscanf(p,"%x",&v2))break;
            g_keyRemapTable[v1]=v2;
            LOG_F(INFO, "Remap %X key to %X",v1,v2);
            if ((p=strchr(p,','))==0)break;
            p++;
        }
    }

    // load m32script history
    for (i=0; i<SCRIPTHISTSIZ; i++)
    {
        Bsprintf(val, "hist%d", i);
        if (readconfig(fp, val, val, VL) <= 0)
            break;

        scripthist[i] = Xstrdup(val);
    }

    scripthistend = i;

    // copy script history into OSD history
    for (i=0; i<min(scripthistend, osd->history.maxlines); i++)
    {
        DO_FREE_AND_NULL(osd->history.buf[i]);
        OSD_SetHistory(i, scripthist[scripthistend-1-i]);

        osd->history.lines++;
        osd->history.total++;
    }

    scripthistend %= SCRIPTHISTSIZ;

    buildvfs_fclose(fp);

    return 0;
}

void writesettings(void) // save binds and aliases to <cfgname>_m32_settings.cfg
{
    buildvfs_FILE fp;
    char *ptr = Xstrdup(setupfilename);
    char tempbuf[128];

    if (!Bstrcmp(setupfilename, defaultsetupfilename))
        Bsprintf(tempbuf, "m32_settings.cfg");
    else Bsprintf(tempbuf, "%s_m32_settings.cfg", strtok(ptr, "."));

    fp = buildvfs_fopen_write(tempbuf);

    if (fp)
    {
        Bfprintf(fp,"// this file is automatically generated by %s\n", AppProperName);

        OSD_WriteAliases(fp);
        OSD_WriteCvars(fp);

        buildvfs_fclose(fp);

        if (!Bstrcmp(setupfilename, defaultsetupfilename))
            OSD_Printf("Wrote m32_settings.cfg\n");
        else OSD_Printf("Wrote %s_m32_settings.cfg\n",ptr);

        Xfree(ptr);
        return;
    }

    if (!Bstrcmp(setupfilename, defaultsetupfilename))
        OSD_Printf("Error writing m32_settings.cfg: %s\n", strerror(errno));
    else OSD_Printf("Error writing %s_m32_settings.cfg: %s\n",ptr,strerror(errno));

    Xfree(ptr);
}

int32_t writesetup(const char *fn)
{
    buildvfs_FILE fp;
    int32_t i,j,first=1;

    fp = buildvfs_fopen_write(fn);
    if (!fp) return -1;

    Bfprintf(fp,
             ";; NOTE: key-value pairs ending in a trailing ';;' will NOT be read from this\n"
             ";; file, but from m32_settings.cfg, potentially under a different name.\n"
             "\n"
             "; Always show configuration options on startup\n"
             ";   0 - No\n"
             ";   1 - Yes\n"
             "forcesetup = %d\n"
             "\n"
             "; Restrict operation to the current working directory only\n"
             ";   0 - No\n"
             ";   1 - Yes\n"
             "usecwd = %d\n"
             "\n"
             "; Video mode selection\n"
             ";   0 - Windowed\n"
             ";   1 - Fullscreen\n"
             "fullscreen = %d\n"
             "\n"
             "; Video resolution\n"
             "xdim = %d\n"
             "ydim = %d\n"
             "upscalefactor = %d\n"
             "\n"
             "; 3D-mode colour depth\n"
             "bpp = %d\n"
             "\n"
#ifdef USE_OPENGL
             "vsync = %d ;;\n"
             "\n"
#endif
#ifdef POLYMER
             "; Rendering mode\n"
             "rendmode = %d\n"
             "\n"
#endif
             "; Grid limits\n"
             "editorgridextent = %d\n"
             "; Startup grid size (0-8, 9 is automatic)\n"
             "grid = %d\n"
             "\n"
#ifdef USE_OPENGL
             ";; OpenGL mode options\n"
             "usemodels = %d ;;\n"
             "usehightile = %d ;;\n"
             "; Enabling lazytileselector allows the tile display to interrupt\n"
             "; drawing hightiles so you can quickly browse without waiting\n"
             "; for all of them to load. Set to 0 if you experience flickering.\n"
             "lazytileselector = %d\n"
             "; glusetexcache: 0:no, 1:yes, 2:compressed\n"
             "; For best performance, keep this setting in sync with EDuke32\n"
             "glusetexcache = %d ;;\n"
             "glusememcache = %d ;;\n"
             "gltexfiltermode = %d ;;\n"
             "glanisotropy = %d ;;\n"
             "r_downsize = %d ;;\n"
             "r_texcompr = %d ;;\n"
             "r_shadescale = %g ;;\n"
             "r_usenewshading = %d ;;\n"
             "r_usetileshades = %d ;;\n"
# ifdef POLYMER
             "r_pr_artmapping = %d ;;\n"
# endif
             "\n"
#endif
             "; Use new aspect determination code? (classic/Polymost)\n"
             "r_usenewaspect = %d ;;\n"
#ifndef RENDERTYPEWIN
             "; Screen aspect for fullscreen, in the form WWHH (e.g. 1609 for 16:9).\n"
             "; A value of 0 means to assume that the pixel aspect is square.\n"
             "r_screenxy = %d ;;\n"
#endif
             "\n"

#ifdef RENDERTYPEWIN
             "; Maximum OpenGL mode refresh rate (Windows only, in Hertz)\n"
             "maxrefreshfreq = %d\n"
             "\n"
#endif
             "; Window position\n"
             "windowposx = %d\n"
             "windowposy = %d\n"
             "\n"
             "; 3D mode brightness setting\n"
             "vid_gamma = %g\n"
             "vid_brightness = %g\n"
             "vid_contrast = %g\n"
             "\n"
             "; Game executable used for map testing\n"
             "gameexecutable = %s\n"
             "\n"
#if 0
             "; Sound sample frequency\n"
             ";   0 - 6 KHz\n"
             ";   1 - 8 KHz\n"
             ";   2 - 11.025 KHz\n"
             ";   3 - 16 KHz\n"
             ";   4 - 22.05 KHz\n"
             ";   5 - 32 KHz\n"
             ";   6 - 44.1 KHz\n"
             "samplerate = %d\n"
             "\n"
             "; Music playback\n"
             ";   0 - Off\n"
             ";   1 - On\n"
             "music = %d\n"
             "\n"
#endif
             "; Mouse sensitivity\n"
             "mousesensitivity = %g\n"
             "\n"
             "; Mouse navigation\n"
             ";   0 - No\n"
             ";   1 - Yes\n"
             "mousenavigation = %d\n"
             "\n"
             "; Mouse navigation acceleration\n"
             "mousenavigationaccel = %d\n"
             "\n"
             "; Quick map cycling (SHIFT)+CTRL+X\n"
             ";   0 - No\n"
             ";   1 - Yes\n"
             "quickmapcycling = %d\n"
             "\n"
             "; Reverse meaning of Q and W keys in side view mode\n"
             "sideview_reversehorizrot = %d\n"
             "\n"
             "; Revert CTRL for tile selction\n"
             ";   0 - WHEEL:scrolling, CTRL+WHEEL:zooming\n"
             ";   1 - CTRL+WHEEL:scrolling, WHEEL:zooming\n"
             "revertCTRL = %d\n"
             "\n"
             "; Scroll amount for WHEEL in the tile selection\n"
             "scrollamount = %d\n"
             "\n"
             "; Turning acceleration+declaration\n"
             "turnaccel = %d\n"
             "\n"
             "; Turning deceleration\n"
             "turndecel = %d\n"
             "\n"
             "; Autosave map interval (seconds)\n"
             "autosavesec = %d\n"
             "\n"
             "; Auto corruption check interval (seconds)\n"
             "autocorruptchecksec = %d\n"
             "\n"
             "; Ignore 'already referenced wall' warnings\n"
             "corruptcheck_noalreadyrefd = %d\n"
             "\n"
             "; Flag Duke3D issues\n"
             "corruptcheck_game_duke3d = %d\n"
             "\n"
             "; Auto-correct inconsistent ceilingstat/floorstat bit 2 and .heinum?\n"
             "; Set to 2, also warn on 'corruptcheck'.\n"
             "corruptcheck_heinum = %d\n"
             "\n"
             "; Fix sprite sectnums when saving a map or entering 3D mode\n"
             "fixmaponsave_sprites = %d\n"
             "\n"
             "; Keep texture stretching when dragging wall vertices\n"
             "keeptexturestretch = %d\n"
             "\n"
             "; Height indicators (0:none, 1:only 2-sided&different, 2:all)\n"
             "showheightindicators = %d\n"
             "\n"
             "; Ambience sound circles (0:none, 1:only in current sector, 2:all)\n"
             "showambiencesounds = %d\n"
             "\n"
             "; Default filesystem mode\n"
             "pathsearchmode = %d\n"
             "\n"
             "; Experimental 2d/3d hybrid mode\n"
             "2d3dmode = %d\n"
             "2d3dsize = %d\n"
             "2d3d_x = %d\n"
             "2d3d_y = %d\n"
             "\n"
             "; Enable undo in 3d mode\n"
             "3dundo = %d\n"
             "\n"
             "; Point and line highlight/selection distances\n"
             "pointhighlightdist = %d\n"
             "linehighlightdist = %d\n"
             "\n"
             "; TROR: Automatic grayout of plain (non-extended) sectors,\n"
             ";       toggled with Ctrl-A:\n"
             "autogray = %d\n"
//             "; TROR: Show inner gray walls, toggled with Ctrl-Alt-A:\n"
//             "showinnergray = %d\n"
             "\n"
             "; 2D mode display type (0:classic, 1:textured, 2:textured/animated)\n"
             "graphicsmode = %d\n"
             "\n"
             "; Sample rate in Hz\n"
             "samplerate = %d\n"
             "; Ambient sounds in 3D mode (0:off, 1:on)\n"
             "ambiencetoggle = %d\n"
             "parlock = %d\n"
             "\n"
             "; Try executing m32script on invalid command in the OSD? This makes\n"
             "; typing m32script commands into the OSD directly possible.\n"
             "osdtryscript = %d\n"
             "\n"
#if 1
             "; Key Settings\n"
             ";  Here's a map of all the keyboard scan codes: NOTE: values are listed in hex!\n"
             "; +---------------------------------------------------------------------------------------------+\n"
             "; | 01   3B  3C  3D  3E   3F  40  41  42   43  44  57  58          46                           |\n"
             "; |ESC   F1  F2  F3  F4   F5  F6  F7  F8   F9 F10 F11 F12        SCROLL                         |\n"
             "; |                                                                                |\n"
             "; |29  02  03  04  05  06  07  08  09  0A  0B  0C  0D   0E     D2  C7  C9      45  B5  37  4A   |\n"
             "; | ` '1' '2' '3' '4' '5' '6' '7' '8' '9' '0'  -   =  BACK    INS HOME PGUP  NUMLK KP/ KP* KP-  |\n"
             "; |                                                                                |\n"
             "; | 0F  10  11  12  13  14  15  16  17  18  19  1A  1B  2B     D3  CF  D1      47  48  49  4E   |\n"
             "; |TAB  Q   W   E   R   T   Y   U   I   O   P   [   ]    \\    DEL END PGDN    KP7 KP8 KP9 KP+   |\n"
             "; |                                                                                |\n"
             "; | 3A   1E  1F  20  21  22  23  24  25  26  27  28     1C                     4B  4C  4D       |\n"
             "; |CAPS  A   S   D   F   G   H   J   K   L   ;   '   ENTER                    KP4 KP5 KP6    9C |\n"
             "; |                                                                                KPENTER|\n"
             "; |  2A    2C  2D  2E  2F  30  31  32  33  34  35    36            C8          4F  50  51       |\n"
             "; |LSHIFT  Z   X   C   V   B   N   M   ,   .   /   RSHIFT          UP         KP1 KP2 KP3       |\n"
             "; |                                                                                |\n"
             "; | 1D     38              39                  B8     9D       CB  D0   CD      52    53        |\n"
             "; |LCTRL  LALT           SPACE                RALT   RCTRL   LEFT DOWN RIGHT    KP0    KP.      |\n"
             "; +---------------------------------------------------------------------------------------------+\n"
             "\n"
             "keyforward = %X\n"
             "keybackward = %X\n"
             "keyturnleft = %X\n"
             "keyturnright = %X\n"
             "keyrun = %X\n"
             "keystrafe = %X\n"
//             "keyfire = %X\n"
//             "keyuse = %X\n"
             "keystandhigh = %X\n"
             "keystandlow = %X\n"
//             "keylookup = %X\n"
//             "keylookdown = %X\n"
//             "keystrafeleft = %X\n"
//             "keystraferight = %X\n"
             "key2dmode = %X\n"
//             "keyviewcycle = %X\n"
//             "key2dzoomin = %X\n"
//             "key2dzoomout = %X\n"
//             "keychat = %X\n"
#endif
//             "; Console key scancode, in hex\n"
             "keyconsole = %X\n"
             "\n"
             "; This option allows you to remap keys in case some of them are not available\n"
             "; (like on a notebook). It has to be a comma-separated list of SOURCE-TARGET\n"
             "; scancode values, looked up in the keyboard map above. This also means that\n"
             "; the key positions count, not their labels for non-US keyboards.\n"
             ";\n"
             "; Example:\n"
             ";  1. Map the backslash key (0x2B) to KPENTER (9C), since portable devices\n"
             ";     often don't have the latter\n"
             ";  2. make KP0 (0x52) function as KP5 (0x4C), countering the inability to pan\n"
             ";     using Shift-KP5-KP8/2 in 3D mode\n"
             "; remap = 2B-9C,52-4C\n"
             "remap = ",

             forcesetup, g_useCwd, fullscreen, xres, yres, upscalefactor, bppgame,
#ifdef USE_OPENGL
             vsync,
#endif
#ifdef POLYMER
             glrendmode,
#endif
             editorgridextent, clamp(default_grid, 0, 9),
#ifdef USE_OPENGL
             usemodels, usehightile, g_lazy_tileselector,
             glusetexcache, glusememcache, gltexfiltermode, glanisotropy,r_downsize,glusetexcompr,
             shadescale, r_usenewshading, r_usetileshades,
# ifdef POLYMER
             pr_artmapping,
# endif
#endif
             r_usenewaspect,
#ifndef RENDERTYPEWIN
             r_screenxy,
#else
             maxrefreshfreq,
#endif
             g_windowPos.x, g_windowPos.y,
             vid_gamma_3d>=0?vid_gamma_3d:g_videoGamma,
             vid_brightness_3d>=0?vid_brightness_3d:g_videoBrightness,
             vid_contrast_3d>=0?vid_contrast_3d:g_videoContrast,
             game_executable,
#if 0
             option[7]>>4, option[2],
#endif
             msens, unrealedlook, pk_uedaccel, quickmapcycling,
             sideview_reversehrot,
             revertCTRL,scrollamount,pk_turnaccel,pk_turndecel,autosave,autocorruptcheck,
             corruptcheck_noalreadyrefd, corruptcheck_game_duke3d,
             corruptcheck_heinum, fixmaponsave_sprites, keeptexturestretch,
             showheightindicators,showambiencesounds,pathsearchmode,
             m32_2d3dmode,m32_2d3dsize,m32_2d3d.x, m32_2d3d.y,
             m32_3dundo,
             pointhighlightdist, linehighlightdist,
             autogray, //showinnergray,
             graphicsmode,
             MixRate,AmbienceToggle,ParentalLock, !!m32_osd_tryscript,

             keys[BK_MOVEFORWARD],
             keys[BK_MOVEBACKWARD],
             keys[BK_TURNLEFT],
             keys[BK_TURNRIGHT],
             keys[BK_RUN],
             keys[BK_STRAFE],
//             keys[BK_SHOOT],
//             keys[BK_OPEN],
             keys[BK_MOVEUP],
             keys[BK_MOVEDOWN],
//             keys[BK_LOOKUP],
//             keys[BK_LOOKDOWN],
//             keys[BK_STRAFELEFT],
//             keys[BK_STRAFERIGHT],
             keys[BK_MODE2D_3D],
//             keys[BK_PLAYERVIEW],
//             keys[BK_ZOOMIN],
//             keys[BK_ZOOMOUT],
//             keys[BK_MESSAGE],
             keys[BK_CONSOLE]
            );

    for (i=0; i<256; i++)
        if (g_keyRemapTable[i]!=i)
        {
            Bfprintf(fp,first?"%02X-%02X":",%02X-%02X",i,g_keyRemapTable[i]);
            first=0;
        }
    Bfprintf(fp,"\n\n");

    // save m32script history
    Bfprintf(fp,"; Mapster32-script history\n");
    first = 1;
    for (i=scripthistend, j=0; first || i!=scripthistend; i=(i+1)%SCRIPTHISTSIZ, first=0)
    {
        if (scripthist[i])
            Bfprintf(fp, "hist%d = %s\n", j++, scripthist[i]);
    }

    buildvfs_fclose(fp);

    writesettings();

    return 0;
}


code:
#include "baselayer.h"
#include "build_cpuid.h"
#include "compat.h"
#include "osd.h"

cpuinfo_t cpu;

#if defined EDUKE32_CPU_X86

#ifdef _WIN32
# include <intrin.h>
#else
# include <cpuid.h>
#endif

static char g_cpuVendorIDString[16];
static char g_cpuBrandString[48];

void sysReadCPUID()
{
    int32_t regs[4];

#ifdef _WIN32
    __cpuid(regs, 0);
#else
    __cpuid(0, regs[0], regs[1], regs[2], regs[3]);
#endif

    // CPUID returns things out of order...
    Bmemcpy(g_cpuVendorIDString,   regs+1, 4);
    Bmemcpy(g_cpuVendorIDString+8, regs+2, 4);
    Bmemcpy(g_cpuVendorIDString+4, regs+3, 4);
    g_cpuVendorIDString[12] = '\0';

    DVLOG_F(LOG_DEBUG, "CPUID Vendor ID: %s", g_cpuVendorIDString);

    cpu.vendorIDString = g_cpuVendorIDString;

    if (!Bstrcmp(g_cpuVendorIDString, "GenuineIntel"))
        cpu.type = CPU_INTEL;
    else if (!Bstrcmp(g_cpuVendorIDString, "AuthenticAMD"))
        cpu.type = CPU_AMD;
    else
        cpu.type = CPU_UNKNOWN;

#ifdef _WIN32
    __cpuid(regs, 0x80000000);
#else
    __cpuid(0x80000000, regs[0], regs[1], regs[2], regs[3]);
#endif

    auto const subleaves = (unsigned)regs[0];

    if (subleaves >= 0x80000004)
    {
#ifdef _WIN32
        __cpuid((int *)g_cpuBrandString,   0x80000002);
        __cpuid((int *)g_cpuBrandString+4, 0x80000003);
        __cpuid((int *)g_cpuBrandString+8, 0x80000004);
#else
        __cpuid(0x80000002, *(int *)&g_cpuBrandString[0], *(int *)&g_cpuBrandString[4],
                            *(int *)&g_cpuBrandString[8], *(int *)&g_cpuBrandString[12]);
        __cpuid(0x80000003, *(int *)&g_cpuBrandString[16], *(int *)&g_cpuBrandString[20],
                            *(int *)&g_cpuBrandString[24], *(int *)&g_cpuBrandString[28]);
        __cpuid(0x80000004, *(int *)&g_cpuBrandString[32], *(int *)&g_cpuBrandString[36],
                            *(int *)&g_cpuBrandString[40], *(int *)&g_cpuBrandString[44]);
#endif
        LOG_F(INFO, "CPU: %s", g_cpuBrandString);
        cpu.brandString = g_cpuBrandString;

        if (subleaves >= 0x80000007)
        {
#ifdef _WIN32
            __cpuid(regs, 0x80000007);
#else
            __cpuid(0x80000007, regs[0], regs[1], regs[2], regs[3]);
#endif
            cpu.features.invariant_tsc = (regs[3] & (1 << 8)) != 0;
        }
    }
}
#else

void sysReadCPUID() { }

#endif  // EDUKE32_CPU_X86


code:
// based on http://create.stephan-brumme.com/crc32/Crc32.cpp, zlib license

#include "compat.h"
#include "crc32.h"

uint32_t Bcrc32(const void* data, int length, uint32_t crc)
{
    const uint32_t* current = (const uint32_t*) data;
    uint8_t const * currentChar;
    crc = ~crc;

#ifdef BITNESS64
    // process eight bytes at once (Slicing-by-8)
    while (length >= 8)
    {
#if B_BIG_ENDIAN != 0
        uint32_t one = *current ^ B_SWAP32(crc);
        uint32_t two = *(current+1);
        crc  = crc32table[0][two       & 0xFF] ^
               crc32table[1][(two>> 8) & 0xFF] ^
               crc32table[2][(two>>16) & 0xFF] ^
               crc32table[3][(two>>24) & 0xFF] ^
               crc32table[4][one       & 0xFF] ^
               crc32table[5][(one>> 8) & 0xFF] ^
               crc32table[6][(one>>16) & 0xFF] ^
               crc32table[7][(one>>24) & 0xFF];
#else
        uint32_t one = *current ^ crc;
        uint32_t two = *(current+1);
        crc  = crc32table[0][(two>>24) & 0xFF] ^
               crc32table[1][(two>>16) & 0xFF] ^
               crc32table[2][(two>> 8) & 0xFF] ^
               crc32table[3][two       & 0xFF] ^
               crc32table[4][(one>>24) & 0xFF] ^
               crc32table[5][(one>>16) & 0xFF] ^
               crc32table[6][(one>> 8) & 0xFF] ^
               crc32table[7][one       & 0xFF];
#endif
        current += 2;
        length -= 8;
    }
#else
    // process four bytes at once (Slicing-by-4)
    while (length >= 4)
    {
#if B_BIG_ENDIAN != 0
        uint32_t one = *current++ ^ B_SWAP32(crc);
        crc  = crc32table[0][one       & 0xFF] ^
               crc32table[1][(one>> 8) & 0xFF] ^
               crc32table[2][(one>>16) & 0xFF] ^
               crc32table[3][(one>>24) & 0xFF];
#else
        uint32_t one = *current++ ^ crc;
        crc  = crc32table[0][(one>>24) & 0xFF] ^
               crc32table[1][(one>>16) & 0xFF] ^
               crc32table[2][(one>> 8) & 0xFF] ^
               crc32table[3][one       & 0xFF];
#endif

        length -= 4;
    }
#endif

    currentChar = (uint8_t const *) current;
    // remaining 1 to 7 bytes (standard algorithm)
    while (length-- > 0)
        crc = (crc >> 8) ^ crc32table[0][(crc & 0xFF) ^ *currentChar++];

    return ~crc;
}

#ifdef BITNESS64
uint32_t crc32table[8][256];
#else
uint32_t crc32table[4][256];
#endif

void initcrc32table(void)
{
    int i;
    for (i = 0; i <= 0xFF; i++)
    {
      uint32_t j, crc = i;
      for (j = 0; j < 8; j++)
        crc = (crc >> 1) ^ ((crc & 1) * POLY);
      crc32table[0][i] = crc;
    }

    for (i = 0; i <= 0xFF; i++)
    {
      crc32table[1][i] = (crc32table[0][i] >> 8) ^ crc32table[0][crc32table[0][i] & 0xFF];
      crc32table[2][i] = (crc32table[1][i] >> 8) ^ crc32table[0][crc32table[1][i] & 0xFF];
      crc32table[3][i] = (crc32table[2][i] >> 8) ^ crc32table[0][crc32table[2][i] & 0xFF];

#ifdef BITNESS64
      crc32table[4][i] = (crc32table[3][i] >> 8) ^ crc32table[0][crc32table[3][i] & 0xFF];
      crc32table[5][i] = (crc32table[4][i] >> 8) ^ crc32table[0][crc32table[4][i] & 0xFF];
      crc32table[6][i] = (crc32table[5][i] >> 8) ^ crc32table[0][crc32table[5][i] & 0xFF];
      crc32table[7][i] = (crc32table[6][i] >> 8) ^ crc32table[0][crc32table[6][i] & 0xFF];
#endif
    }
}