Subversion Repositories eduke32

Rev

Rev 8710 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
99 terminx 1
#include "baselayer.h"
2
 
3291 helixhorne 3
#include "a.h"
8147 terminx 4
#include "build.h"
6807 terminx 5
#include "cache1d.h"
8094 hendricks2 6
#include "communityapi.h"
8147 terminx 7
#include "compat.h"
8
#include "osd.h"
9
#include "polymost.h"
10
#include "renderlayer.h"
1488 terminx 11
 
6827 terminx 12
// video
6826 terminx 13
#ifdef _WIN32
8174 terminx 14
#include "winbits.h"
6826 terminx 15
extern "C"
16
{
17
    __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 0x00000001;
18
    __declspec(dllexport) DWORD NvOptimusEnablement                = 0x00000001;
19
}
20
#endif // _WIN32
21
 
8060 terminx 22
int32_t g_borderless=2;
6827 terminx 23
 
1652 terminx 24
// input
6827 terminx 25
char    inputdevices = 0;
4853 hendricks2 26
 
6827 terminx 27
char    keystatus[NUMKEYS];
28
char    g_keyFIFO[KEYFIFOSIZ];
29
char    g_keyAsciiFIFO[KEYFIFOSIZ];
8429 hendricks2 30
uint8_t g_keyFIFOpos;
6827 terminx 31
uint8_t g_keyFIFOend;
32
uint8_t g_keyAsciiPos;
33
uint8_t g_keyAsciiEnd;
34
char    g_keyRemapTable[NUMKEYS];
35
char    g_keyNameTable[NUMKEYS][24];
4853 hendricks2 36
 
8716 terminx 37
int32_t r_maxfps = -1;
38
int32_t r_maxfpsoffset;
39
uint64_t g_frameDelay;
40
 
6827 terminx 41
void (*keypresscallback)(int32_t, int32_t);
4853 hendricks2 42
 
6827 terminx 43
void keySetCallback(void (*callback)(int32_t, int32_t)) { keypresscallback = callback; }
1652 terminx 44
 
6827 terminx 45
int32_t keyGetState(int32_t key) { return keystatus[g_keyRemapTable[key]]; }
1819 plagman 46
 
6827 terminx 47
void keySetState(int32_t key, int32_t state)
4269 hendricks2 48
{
6827 terminx 49
    keystatus[g_keyRemapTable[key]] = state;
4749 terminx 50
 
1762 terminx 51
    if (state)
1652 terminx 52
    {
6827 terminx 53
        g_keyFIFO[g_keyFIFOend] = g_keyRemapTable[key];
54
        g_keyFIFO[(g_keyFIFOend+1)&(KEYFIFOSIZ-1)] = state;
55
        g_keyFIFOend = ((g_keyFIFOend+2)&(KEYFIFOSIZ-1));
1652 terminx 56
    }
57
}
58
 
8429 hendricks2 59
char keyGetScan(void)
60
{
61
    if (g_keyFIFOpos == g_keyFIFOend)
62
        return 0;
63
 
64
    char const c    = g_keyFIFO[g_keyFIFOpos];
65
    g_keyFIFOpos = ((g_keyFIFOpos + 2) & (KEYFIFOSIZ - 1));
66
 
67
    return c;
68
}
69
 
70
void keyFlushScans(void)
71
{
72
    Bmemset(&g_keyFIFO,0,sizeof(g_keyFIFO));
73
    g_keyFIFOpos = g_keyFIFOend = 0;
74
}
75
 
1652 terminx 76
//
6827 terminx 77
// character-based input functions
1652 terminx 78
//
6827 terminx 79
char keyGetChar(void)
1652 terminx 80
{
6827 terminx 81
    if (g_keyAsciiPos == g_keyAsciiEnd)
1652 terminx 82
        return 0;
83
 
6827 terminx 84
    char const c    = g_keyAsciiFIFO[g_keyAsciiPos];
85
    g_keyAsciiPos = ((g_keyAsciiPos + 1) & (KEYFIFOSIZ - 1));
86
 
87
    return c;
1652 terminx 88
}
89
 
6827 terminx 90
void keyFlushChars(void)
1652 terminx 91
{
6827 terminx 92
    Bmemset(&g_keyAsciiFIFO,0,sizeof(g_keyAsciiFIFO));
93
    g_keyAsciiPos = g_keyAsciiEnd = 0;
1652 terminx 94
}
95
 
6827 terminx 96
const char *keyGetName(int32_t num) { return ((unsigned)num >= NUMKEYS) ? NULL : g_keyNameTable[num]; }
97
 
98
vec2_t  g_mousePos;
99
vec2_t  g_mouseAbs;
100
int32_t g_mouseBits;
101
uint8_t g_mouseClickState;
102
 
103
bool g_mouseEnabled;
104
bool g_mouseGrabbed;
105
bool g_mouseInsideWindow   = 1;
106
bool g_mouseLockedToWindow = 1;
107
 
108
void (*g_mouseCallback)(int32_t, int32_t);
109
void mouseSetCallback(void(*callback)(int32_t, int32_t)) { g_mouseCallback = callback; }
110
 
111
int32_t mouseAdvanceClickState(void)
1652 terminx 112
{
6827 terminx 113
    switch (g_mouseClickState)
114
    {
115
        case MOUSE_PRESSED: g_mouseClickState  = MOUSE_HELD; return 1;
116
        case MOUSE_RELEASED: g_mouseClickState = MOUSE_IDLE; return 1;
117
        case MOUSE_HELD: return 1;
118
    }
119
    return 0;
1652 terminx 120
}
121
 
6827 terminx 122
void mouseReadPos(int32_t *x, int32_t *y)
1857 terminx 123
{
6827 terminx 124
    if (!g_mouseEnabled || !g_mouseGrabbed || !appactive)
125
    {
126
        *x = *y = 0;
127
        return;
128
    }
129
 
130
    *x = g_mousePos.x;
131
    *y = g_mousePos.y;
132
    g_mousePos.x = g_mousePos.y = 0;
1857 terminx 133
}
134
 
6827 terminx 135
int32_t mouseReadAbs(vec2_t * const pResult, vec2_t const * const pInput)
2623 helixhorne 136
{
6827 terminx 137
    if (!g_mouseEnabled || !appactive || !g_mouseInsideWindow || (osd && osd->flags & OSD_CAPTURE))
4738 hendricks2 138
        return 0;
139
 
6827 terminx 140
    int32_t const xwidth = max(scale(240<<16, xdim, ydim), 320<<16);
4738 hendricks2 141
 
6939 pogokeen 142
    pResult->x = scale(pInput->x, xwidth, xres) - ((xwidth>>1) - (320<<15));
143
    pResult->y = scale(pInput->y, 200<<16, yres);
4738 hendricks2 144
 
7321 terminx 145
    pResult->y = divscale16(pResult->y - (200<<15), rotatesprite_yxaspect) + (200<<15) - rotatesprite_y_offset;
146
 
4738 hendricks2 147
    return 1;
2623 helixhorne 148
}
149
 
7181 terminx 150
int32_t mouseReadButtons(void)
1857 terminx 151
{
7181 terminx 152
    return (!g_mouseEnabled || !appactive || !g_mouseInsideWindow || (osd && osd->flags & OSD_CAPTURE)) ? 0 : g_mouseBits;
1857 terminx 153
}
154
 
6827 terminx 155
controllerinput_t joystick;
2728 hendricks2 156
 
6827 terminx 157
void joySetCallback(void (*callback)(int32_t, int32_t)) { joystick.pCallback = callback; }
158
void joyReadButtons(int32_t *pResult) { *pResult = appactive ? joystick.bits : 0; }
159
 
6065 hendricks2 160
#if defined __linux || defined EDUKE32_BSD || defined __APPLE__
4719 terminx 161
# include <sys/mman.h>
162
#endif
163
 
164
#if !defined(NOASM) && !defined(GEKKO) && !defined(__ANDROID__)
165
#ifdef __cplusplus
166
extern "C" {
167
#endif
168
    extern intptr_t dep_begin, dep_end;
169
#ifdef __cplusplus
4766 hendricks2 170
}
4719 terminx 171
#endif
172
#endif
173
 
4723 terminx 174
#if !defined(NOASM) && !defined(GEKKO) && !defined(__ANDROID__)
5760 hendricks2 175
static int32_t nx_unprotect(intptr_t beg, intptr_t end, int prot)
4719 terminx 176
{
177
# if defined _WIN32
5760 hendricks2 178
#  define B_PROT_RW PAGE_READWRITE
179
#  define B_PROT_RX PAGE_EXECUTE_READ
180
#  define B_PROT_RWX PAGE_EXECUTE_READWRITE
181
 
4719 terminx 182
    DWORD oldprot;
183
 
5760 hendricks2 184
    if (!VirtualProtect((LPVOID) beg, (SIZE_T)end - (SIZE_T)beg, prot, &oldprot))
4719 terminx 185
    {
186
        initprintf("VirtualProtect() error! Crashing in 3... 2... 1...\n");
187
        return 1;
188
    }
5037 hendricks2 189
# elif defined __linux || defined EDUKE32_BSD || defined __APPLE__
5760 hendricks2 190
#  define B_PROT_RW (PROT_READ|PROT_WRITE)
191
#  define B_PROT_RX (PROT_READ|PROT_EXEC)
192
#  define B_PROT_RWX (PROT_READ|PROT_WRITE|PROT_EXEC)
193
 
4719 terminx 194
    int32_t pagesize;
195
    size_t dep_begin_page;
196
    pagesize = sysconf(_SC_PAGE_SIZE);
197
    if (pagesize == -1)
198
    {
199
        initprintf("Error getting system page size\n");
200
        return 1;
201
    }
202
    dep_begin_page = ((size_t)beg) & ~(pagesize-1);
5760 hendricks2 203
    if (mprotect((void *) dep_begin_page, (size_t)end - dep_begin_page, prot) < 0)
4719 terminx 204
    {
205
        initprintf("Error making code writeable (errno=%d)\n", errno);
206
        return 1;
207
    }
208
# else
209
#  error "Don't know how to unprotect the self-modifying assembly on this platform!"
210
# endif
211
 
212
    return 0;
213
}
4723 terminx 214
#endif
4719 terminx 215
 
216
 
3291 helixhorne 217
// Calculate ylookup[] and call setvlinebpl()
218
void calc_ylookup(int32_t bpl, int32_t lastyidx)
219
{
220
    int32_t i, j=0;
4724 helixhorne 221
    static int32_t ylookupsiz;
3291 helixhorne 222
 
4724 helixhorne 223
    Bassert(lastyidx <= MAXYDIM);
224
 
4719 terminx 225
    lastyidx++;
226
 
4695 terminx 227
    if (lastyidx > ylookupsiz)
3291 helixhorne 228
    {
7705 terminx 229
        Xaligned_free(ylookup);
4695 terminx 230
 
231
        ylookup = (intptr_t *)Xaligned_alloc(16, lastyidx * sizeof(intptr_t));
232
        ylookupsiz = lastyidx;
233
    }
234
 
235
    for (i=0; i<=lastyidx-4; i+=4)
236
    {
3291 helixhorne 237
        ylookup[i] = j;
4695 terminx 238
        ylookup[i + 1] = j + bpl;
239
        ylookup[i + 2] = j + (bpl << 1);
240
        ylookup[i + 3] = j + (bpl * 3);
241
        j += (bpl << 2);
242
    }
243
 
4724 helixhorne 244
    for (; i<lastyidx; i++)
4695 terminx 245
    {
246
        ylookup[i] = j;
3291 helixhorne 247
        j += bpl;
248
    }
249
 
250
    setvlinebpl(bpl);
251
}
252
 
4719 terminx 253
 
254
void makeasmwriteable(void)
255
{
256
#if !defined(NOASM) && !defined(GEKKO) && !defined(__ANDROID__)
5760 hendricks2 257
    nx_unprotect((intptr_t)&dep_begin, (intptr_t)&dep_end, B_PROT_RWX);
4719 terminx 258
#endif
259
}
260
 
5938 terminx 261
int32_t vsync=0;
6827 terminx 262
int32_t g_logFlushWindow = 1;
5938 terminx 263
 
99 terminx 264
#ifdef USE_OPENGL
1625 terminx 265
struct glinfo_t glinfo =
584 terminx 266
{
1506 plagman 267
    "Unknown",  // vendor
268
    "Unknown",  // renderer
269
    "0.0.0",    // version
270
    "",         // extensions
109 terminx 271
 
1506 plagman 272
    1.0,        // max anisotropy
8710 terminx 273
    0,          // structure filled
274
    0,          // supported extensions
584 terminx 275
};
99 terminx 276
 
8710 terminx 277
void fill_glinfo(void)
278
{
279
    glinfo.extensions = (const char *)glGetString(GL_EXTENSIONS);
280
    glinfo.renderer   = (const char *)glGetString(GL_RENDERER);
281
    glinfo.vendor     = (const char *)glGetString(GL_VENDOR);
282
    glinfo.version    = (const char *)glGetString(GL_VERSION);
283
 
284
#ifdef POLYMER
285
    if (!Bstrcmp(glinfo.vendor, "ATI Technologies Inc."))
286
    {
287
        pr_ati_fboworkaround = 1;
288
        initprintf("Enabling ATI FBO color attachment workaround.\n");
289
 
290
        if (Bstrstr(glinfo.renderer, "Radeon X1"))
291
        {
292
            pr_ati_nodepthoffset = 1;
293
            initprintf("Enabling ATI R520 polygon offset workaround.\n");
294
        }
295
# ifdef __APPLE__
296
        // See bug description at http://lists.apple.com/archives/mac-opengl/2005/Oct/msg00169.html
297
        if (!Bstrncmp(glinfo.renderer, "ATI Radeon 9600", 15))
298
        {
299
            pr_ati_textureformat_one = 1;
300
            initprintf("Enabling ATI Radeon 9600 texture format workaround.\n");
301
        }
302
# endif
303
    }
304
#endif  // defined POLYMER
305
 
306
    // process the extensions string and flag stuff we recognize
307
    glinfo.depthtex = !!Bstrstr(glinfo.extensions, "GL_ARB_depth_texture");
308
    glinfo.fbos     = !!Bstrstr(glinfo.extensions, "GL_EXT_framebuffer_object") || !!Bstrstr(glinfo.extensions, "GL_OES_framebuffer_object");
309
    glinfo.shadow   = !!Bstrstr(glinfo.extensions, "GL_ARB_shadow");
310
    glinfo.texnpot  = !!Bstrstr(glinfo.extensions, "GL_ARB_texture_non_power_of_two") || !!Bstrstr(glinfo.extensions, "GL_OES_texture_npot");
311
 
312
#if !defined EDUKE32_GLES
313
    glinfo.bgra             = !!Bstrstr(glinfo.extensions, "GL_EXT_bgra");
314
    glinfo.bufferstorage    = !!Bstrstr(glinfo.extensions, "GL_ARB_buffer_storage");
315
    glinfo.clamptoedge      = !!Bstrstr(glinfo.extensions, "GL_EXT_texture_edge_clamp") || !!Bstrstr(glinfo.extensions, "GL_SGIS_texture_edge_clamp");
316
    glinfo.debugoutput      = !!Bstrstr(glinfo.extensions, "GL_ARB_debug_output");
317
    glinfo.depthclamp       = !!Bstrstr(glinfo.extensions, "GL_ARB_depth_clamp");
318
    glinfo.glsl             = !!Bstrstr(glinfo.extensions, "GL_ARB_shader_objects");
319
    glinfo.multitex         = !!Bstrstr(glinfo.extensions, "GL_ARB_multitexture");
320
    glinfo.occlusionqueries = !!Bstrstr(glinfo.extensions, "GL_ARB_occlusion_query");
321
    glinfo.rect             = !!Bstrstr(glinfo.extensions, "GL_NV_texture_rectangle") || !!Bstrstr(glinfo.extensions, "GL_EXT_texture_rectangle");
322
    glinfo.sync             = !!Bstrstr(glinfo.extensions, "GL_ARB_sync");
323
    glinfo.texcompr         = !!Bstrstr(glinfo.extensions, "GL_ARB_texture_compression") && Bstrcmp(glinfo.vendor, "ATI Technologies Inc.");
324
    glinfo.vbos             = !!Bstrstr(glinfo.extensions, "GL_ARB_vertex_buffer_object");
325
    glinfo.vsync            = !!Bstrstr(glinfo.extensions, "WGL_EXT_swap_control") || !!Bstrstr(glinfo.extensions, "GLX_EXT_swap_control");
326
 
327
# ifdef DYNAMIC_GLEXT
328
    if (glinfo.texcompr && (!glCompressedTexImage2D || !glGetCompressedTexImage))
329
    {
330
        // lacking the necessary extensions to do this
331
        initprintf("Warning: the GL driver lacks necessary functions to use caching\n");
332
        glinfo.texcompr = 0;
333
    }
334
# endif
335
#else
336
    // don't bother checking because ETC2 et al. are not listed in extensions anyway
337
    glinfo.texcompr = 1; // !!Bstrstr(glinfo.extensions, "GL_OES_compressed_ETC1_RGB8_texture");
338
#endif
339
 
340
    glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glinfo.maxanisotropy);
341
 
342
    if (!glinfo.filled)
343
    {
344
        int32_t oldbpp = bpp;
345
        bpp = 32;
346
        osdcmd_glinfo(NULL);
347
        glinfo.filled = 1;
348
        bpp = oldbpp;
349
    }
350
}
351
 
4015 helixhorne 352
// Used to register the game's / editor's osdcmd_vidmode() functions here.
7154 terminx 353
int32_t (*baselayer_osdcmd_vidmode_func)(osdcmdptr_t parm);
4015 helixhorne 354
 
7154 terminx 355
static int osdfunc_setrendermode(osdcmdptr_t parm)
99 terminx 356
{
4015 helixhorne 357
    if (parm->numparms != 1)
358
        return OSDCMD_SHOWHELP;
359
 
8170 terminx 360
    int32_t m = Bstrtol(parm->parms[0], NULL, 10);
99 terminx 361
 
4015 helixhorne 362
    if (m != REND_CLASSIC && m != REND_POLYMOST && m != REND_POLYMER)
363
        return OSDCMD_SHOWHELP;
99 terminx 364
 
4015 helixhorne 365
    if ((m==REND_CLASSIC) != (bpp==8) && baselayer_osdcmd_vidmode_func)
366
    {
367
        // Mismatch between video mode and requested renderer, do auto switch.
368
        osdfuncparm_t parm;
369
        char arg[4];
370
 
371
        const char *ptrptr[1];
372
        ptrptr[0] = arg;
373
 
374
        Bmemset(&parm, 0, sizeof(parm));
375
 
376
        if (m==REND_CLASSIC)
377
            Bmemcpy(&arg, "8", 2);
378
        else
379
            Bmemcpy(&arg, "32", 3);
380
 
381
        // CAUTION: we assume that the osdcmd_vidmode function doesn't use any
382
        // other member!
383
        parm.numparms = 1;
384
        parm.parms = ptrptr;
385
 
386
        baselayer_osdcmd_vidmode_func(&parm);
387
    }
388
 
6831 terminx 389
    videoSetRenderMode(m);
99 terminx 390
 
7020 terminx 391
    char const *renderer = "other";
5547 terminx 392
 
6829 terminx 393
    switch (videoGetRenderMode())
3347 terminx 394
    {
395
    case REND_CLASSIC:
7020 terminx 396
#ifdef NOASM
397
        renderer = "classic software (C)";
398
#else
399
        renderer = "classic software (ASM)";
400
#endif
3347 terminx 401
        break;
402
    case REND_POLYMOST:
5547 terminx 403
        renderer = "polygonal OpenGL";
3347 terminx 404
        break;
5663 terminx 405
#ifdef POLYMER
3347 terminx 406
    case REND_POLYMER:
5547 terminx 407
        renderer = "great justice (Polymer)";
3347 terminx 408
        break;
5663 terminx 409
#endif
3347 terminx 410
    }
411
 
5547 terminx 412
    OSD_Printf("Rendering method changed to %s\n", renderer);
3347 terminx 413
 
109 terminx 414
    return OSDCMD_OK;
99 terminx 415
}
6827 terminx 416
 
99 terminx 417
#ifdef DEBUGGINGAIDS
7154 terminx 418
static int osdcmd_hicsetpalettetint(osdcmdptr_t parm)
99 terminx 419
{
6557 hendricks2 420
    int32_t parms[8];
109 terminx 421
 
6557 hendricks2 422
    if (parm->numparms < 1 || (int32_t)ARRAY_SIZE(parms) < parm->numparms) return OSDCMD_SHOWHELP;
109 terminx 423
 
6557 hendricks2 424
    size_t i;
425
    for (i = 0; (int32_t)i < parm->numparms; ++i)
426
        parms[i] = Batol(parm->parms[i]);
427
    for (; i < ARRAY_SIZE(parms); ++i)
428
        parms[i] = 0;
109 terminx 429
 
6557 hendricks2 430
    // order is intentional
431
    hicsetpalettetint(parms[0],parms[1],parms[2],parms[3],parms[5],parms[6],parms[7],parms[4]);
109 terminx 432
 
433
    return OSDCMD_OK;
99 terminx 434
}
435
#endif
436
 
7154 terminx 437
int osdcmd_glinfo(osdcmdptr_t UNUSED(parm))
99 terminx 438
{
6297 terminx 439
    UNREFERENCED_CONST_PARAMETER(parm);
654 terminx 440
 
584 terminx 441
    if (bpp == 8)
442
    {
5001 terminx 443
        initprintf("glinfo: not in OpenGL mode!\n");
109 terminx 444
        return OSDCMD_OK;
445
    }
446
 
5001 terminx 447
    initprintf("OpenGL information\n %s %s %s\n",
448
               glinfo.vendor, glinfo.renderer, glinfo.version);
848 terminx 449
 
8710 terminx 450
    if (!glinfo.filled)
848 terminx 451
        return OSDCMD_OK;
452
 
6827 terminx 453
    char const *s[] = { "supported", "not supported" };
454
 
455
#define SUPPORTED(x) (x ? s[0] : s[1])
456
 
457
    initprintf(" BGRA textures:           %s\n", SUPPORTED(glinfo.bgra));
458
    initprintf(" Clamp-to-edge:           %s\n", SUPPORTED(glinfo.clamptoedge));
8710 terminx 459
    initprintf(" Framebuffer objects:     %s\n", SUPPORTED(glinfo.fbos));
6827 terminx 460
    initprintf(" Multi-texturing:         %s\n", SUPPORTED(glinfo.multitex));
8710 terminx 461
    initprintf(" Non-power-of-2 textures: %s\n", SUPPORTED(glinfo.texnpot));
5001 terminx 462
#ifndef EDUKE32_GLES
8710 terminx 463
    initprintf(" Buffer storage:          %s\n", SUPPORTED(glinfo.bufferstorage));
464
    initprintf(" Debug output:            %s\n", SUPPORTED(glinfo.debugoutput));
6827 terminx 465
    initprintf(" Depth textures:          %s\n", SUPPORTED(glinfo.depthtex));
8710 terminx 466
    initprintf(" GLSL:                    %s\n", SUPPORTED(glinfo.glsl));
467
    initprintf(" Occlusion queries:       %s\n", SUPPORTED(glinfo.occlusionqueries));
468
    initprintf(" Rectangle textures:      %s\n", SUPPORTED(glinfo.rect));
6827 terminx 469
    initprintf(" Shadow textures:         %s\n", SUPPORTED(glinfo.shadow));
8710 terminx 470
    initprintf(" Sync:                    %s\n", SUPPORTED(glinfo.sync));
471
    initprintf(" Texture compression:     %s\n", SUPPORTED(glinfo.texcompr));
6827 terminx 472
    initprintf(" Vertex buffer objects:   %s\n", SUPPORTED(glinfo.vbos));
5001 terminx 473
#endif
6827 terminx 474
    initprintf(" Maximum anisotropy:      %.1f%s\n", glinfo.maxanisotropy, glinfo.maxanisotropy > 1.0 ? "" : " (no anisotropic filtering)");
109 terminx 475
 
6827 terminx 476
#undef SUPPORTED
109 terminx 477
 
6827 terminx 478
    initprintf(" Extensions:\n%s", glinfo.extensions);
479
 
109 terminx 480
    return OSDCMD_OK;
99 terminx 481
}
482
#endif
483
 
7154 terminx 484
static int osdcmd_cvar_set_baselayer(osdcmdptr_t parm)
99 terminx 485
{
1665 terminx 486
    int32_t r = osdcmd_cvar_set(parm);
109 terminx 487
 
1665 terminx 488
    if (r != OSDCMD_OK) return r;
489
 
490
    if (!Bstrcasecmp(parm->name, "vid_gamma") || !Bstrcasecmp(parm->name, "vid_brightness") || !Bstrcasecmp(parm->name, "vid_contrast"))
491
    {
6829 terminx 492
        videoSetPalette(GAMMA_CALC,0,0);
1665 terminx 493
        return r;
109 terminx 494
    }
8716 terminx 495
    else if (!Bstrcasecmp(parm->name, "r_maxfps") || !Bstrcasecmp(parm->name, "r_maxfpsoffset"))
496
    {
497
        if (r_maxfps > 0) r_maxfps = clamp(r_maxfps, 30, 1000);
498
        g_frameDelay = calcFrameDelay(r_maxfps, r_maxfpsoffset);
499
    }
1665 terminx 500
    return r;
99 terminx 501
}
502
 
1205 terminx 503
int32_t baselayer_init(void)
99 terminx 504
{
2601 helixhorne 505
#ifdef _WIN32
506
// on Windows, don't save the "r_screenaspect" cvar because the physical screen size is
507
// determined at startup
508
# define SCREENASPECT_CVAR_TYPE (CVAR_UINT|CVAR_NOSAVE)
509
#else
510
# define SCREENASPECT_CVAR_TYPE (CVAR_UINT)
511
#endif
6297 terminx 512
    static osdcvardata_t cvars_engine[] =
1352 terminx 513
    {
6807 terminx 514
        { "lz4compressionlevel","adjust LZ4 compression level used for savegames",(void *) &lz4CompressionLevel, CVAR_INT, 1, 32 },
8065 terminx 515
        { "r_borderless", "borderless windowed mode: 0: never  1: always  2: if resolution matches desktop", (void *) &r_borderless, CVAR_INT|CVAR_RESTARTVID, 0, 2 },
516
        { "r_displayindex","index of output display",(void *)&r_displayindex, CVAR_INT|CVAR_RESTARTVID, 0, 10 },
3783 terminx 517
        { "r_usenewaspect","enable/disable new screen aspect ratio determination code",(void *) &r_usenewaspect, CVAR_BOOL, 0, 1 },
518
        { "r_screenaspect","if using r_usenewaspect and in fullscreen, screen aspect ratio in the form XXYY, e.g. 1609 for 16:9",
2959 helixhorne 519
          (void *) &r_screenxy, SCREENASPECT_CVAR_TYPE, 0, 9999 },
7755 terminx 520
        { "r_fpgrouscan","use floating-point numbers for slope rendering",(void *) &r_fpgrouscan, CVAR_BOOL, 0, 1 },
3783 terminx 521
        { "r_novoxmips","turn off/on the use of mipmaps when rendering 8-bit voxels",(void *) &novoxmips, CVAR_BOOL, 0, 1 },
522
        { "r_voxels","enable/disable automatic sprite->voxel rendering",(void *) &usevoxels, CVAR_BOOL, 0, 1 },
8716 terminx 523
        { "r_maxfps", "limit the frame rate", (void *)&r_maxfps, CVAR_INT | CVAR_FUNCPTR, -1, 1000 },
524
        { "r_maxfpsoffset", "menu-controlled offset for r_maxfps", (void *)&r_maxfpsoffset, CVAR_INT | CVAR_FUNCPTR, -10, 10 },
2024 helixhorne 525
#ifdef YAX_ENABLE
3783 terminx 526
        { "r_tror_nomaskpass", "enable/disable additional pass in TROR software rendering", (void *)&r_tror_nomaskpass, CVAR_BOOL, 0, 1 },
2024 helixhorne 527
#endif
4327 terminx 528
        { "r_windowpositioning", "enable/disable window position memory", (void *) &windowpos, CVAR_BOOL, 0, 1 },
6828 terminx 529
        { "vid_gamma","adjusts gamma component of gamma ramp",(void *) &g_videoGamma, CVAR_FLOAT|CVAR_FUNCPTR, 0, 10 },
530
        { "vid_contrast","adjusts contrast component of gamma ramp",(void *) &g_videoContrast, CVAR_FLOAT|CVAR_FUNCPTR, 0, 10 },
531
        { "vid_brightness","adjusts brightness component of gamma ramp",(void *) &g_videoBrightness, CVAR_FLOAT|CVAR_FUNCPTR, 0, 10 },
3349 terminx 532
#ifdef DEBUGGINGAIDS
1762 terminx 533
        { "debug1","debug counter",(void *) &debug1, CVAR_FLOAT, -100000, 100000 },
534
        { "debug2","debug counter",(void *) &debug2, CVAR_FLOAT, -100000, 100000 },
3349 terminx 535
#endif
4261 helixhorne 536
#ifdef DEBUG_MASK_DRAWING
4264 helixhorne 537
        { "debug_maskdrawmode", "Show mask draw orders", (void *)&g_maskDrawMode, CVAR_BOOL, 0, 1 },
4261 helixhorne 538
#endif
1352 terminx 539
    };
540
 
7130 terminx 541
    for (auto & i : cvars_engine)
542
        OSD_RegisterCvar(&i, (i.flags & CVAR_FUNCPTR) ? osdcmd_cvar_set_baselayer : osdcmd_cvar_set);
1625 terminx 543
 
1820 terminx 544
#ifdef USE_OPENGL
109 terminx 545
    OSD_RegisterFunction("setrendermode","setrendermode <number>: sets the engine's rendering mode.\n"
546
                         "Mode numbers are:\n"
547
                         "   0 - Classic Build software\n"
548
                         "   3 - Polygonal OpenGL\n"
5663 terminx 549
#ifdef POLYMER
1652 terminx 550
                         "   4 - Great justice renderer (Polymer)\n"
5663 terminx 551
#endif
109 terminx 552
                         ,
553
                         osdfunc_setrendermode);
5419 hendricks2 554
 
1564 plagman 555
# ifdef DEBUGGINGAIDS
109 terminx 556
    OSD_RegisterFunction("hicsetpalettetint","hicsetpalettetint: sets palette tinting values",osdcmd_hicsetpalettetint);
1564 plagman 557
# endif
5419 hendricks2 558
 
109 terminx 559
    OSD_RegisterFunction("glinfo","glinfo: shows OpenGL information about the current OpenGL mode",osdcmd_glinfo);
5419 hendricks2 560
 
1352 terminx 561
    polymost_initosdfuncs();
99 terminx 562
#endif
1352 terminx 563
 
6827 terminx 564
    for (native_t i = 0; i < NUMKEYS; i++) g_keyRemapTable[i] = i;
565
 
109 terminx 566
    return 0;
99 terminx 567
}
568
 
3377 helixhorne 569
void maybe_redirect_outputs(void)
570
{
571
#if !(defined __APPLE__ && defined __BIG_ENDIAN__)
572
    char *argp;
573
 
574
    // pipe standard outputs to files
8156 terminx 575
    if ((argp = Bgetenv("EDUKE32_LOGSTDOUT")) == NULL || Bstrcasecmp(argp, "TRUE"))
6827 terminx 576
        return;
3377 helixhorne 577
 
6827 terminx 578
    FILE *fp = freopen("stdout.txt", "w", stdout);
3377 helixhorne 579
 
6827 terminx 580
    if (!fp)
581
        fp = fopen("stdout.txt", "w");
582
 
583
    if (fp)
584
    {
585
        setvbuf(fp, 0, _IONBF, 0);
586
        *stdout = *fp;
587
        *stderr = *fp;
588
    }
3377 helixhorne 589
#endif
590
}
8716 terminx 591
 
592
int engineFPSLimit(void)
593
{
594
    if (!r_maxfps)
595
        return true;
596
 
597
    g_frameDelay = calcFrameDelay(r_maxfps, r_maxfpsoffset);
598
 
599
    uint64_t const  frameJitter = timerGetPerformanceFrequency() / 1000ull;
600
    uint64_t        frameTicks;
601
    static uint64_t nextFrameTicks;
602
    static uint64_t frameDelay;
603
 
604
    if (g_frameDelay != frameDelay)
605
    {
606
        nextFrameTicks = timerGetPerformanceCounter() + g_frameDelay;
607
        frameDelay = g_frameDelay;
608
    }
609
 
610
    do { handleevents(); } while (nextFrameTicks - (frameTicks = timerGetPerformanceCounter()) < frameJitter);
611
 
612
    if (nextFrameTicks - frameTicks > g_frameDelay)
613
    {
614
        while (nextFrameTicks - frameTicks > g_frameDelay)
615
            nextFrameTicks += g_frameDelay;
616
 
617
        return true;
618
    }
619
 
620
    return false;
621
}