Subversion Repositories eduke32

Rev

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

Rev Author Line No. Line
5 Plagman 1
// SDL interface layer
2
// for the Build Engine
2456 hendricks2 3
// by Jonathon Fowler (jf@jonof.id.au)
5 Plagman 4
//
4074 hendricks2 5
// Use SDL 1.2 or 2.0 from http://www.libsdl.org
5 Plagman 6
 
3116 hendricks2 7
#define __STDC_FORMAT_MACROS
8
#define __STDC_LIMIT_MACROS
5 Plagman 9
#include <stdlib.h>
2985 helixhorne 10
#include <math.h>  // pow
1485 helixhorne 11
#include <signal.h>
710 terminx 12
#include "sdl_inc.h"
5 Plagman 13
#include "compat.h"
14
#include "sdlayer.h"
15
#include "cache1d.h"
2222 helixhorne 16
//#include "pragmas.h"
5 Plagman 17
#include "a.h"
18
#include "build.h"
19
#include "osd.h"
20
 
4432 terminx 21
#if SDL_MAJOR_VERSION==1 // SDL 1.2
1644 helixhorne 22
// for SDL_WaitEventTimeout defined below
23
#include <SDL/SDL_events.h>
24
#endif
25
 
5 Plagman 26
#ifdef USE_OPENGL
27
# include "glbuild.h"
28
#endif
29
 
3221 hendricks2 30
#if defined _WIN32
31
# define WIN32_LEAN_AND_MEAN
32
# include <windows.h>
33
# include "winbits.h"
34
#elif defined __APPLE__
5 Plagman 35
# include "osxbits.h"
2861 helixhorne 36
# include <mach/mach.h>
37
# include <mach/mach_time.h>
5 Plagman 38
#elif defined HAVE_GTK2
39
# include "gtkbits.h"
3497 hendricks2 40
#elif defined GEKKO
41
# define HW_RVL
42
# include <ogc/lwp.h>
43
# include <ogc/lwp_watchdog.h>
1935 helixhorne 44
#endif
45
 
3368 hendricks2 46
#if !defined _WIN32 && !defined HAVE_GTK2 && !defined __APPLE__
1205 terminx 47
int32_t startwin_open(void) { return 0; }
48
int32_t startwin_close(void) { return 0; }
2158 helixhorne 49
int32_t startwin_puts(const char *s) { UNREFERENCED_PARAMETER(s); return 0; }
50
int32_t startwin_idle(void *s) { UNREFERENCED_PARAMETER(s); return 0; }
51
int32_t startwin_settitle(const char *s) { UNREFERENCED_PARAMETER(s); return 0; }
5 Plagman 52
#endif
53
 
1644 helixhorne 54
/// These can be useful for debugging sometimes...
55
//#define SDL_WM_GrabInput(x) SDL_WM_GrabInput(SDL_GRAB_OFF)
56
//#define SDL_ShowCursor(x) SDL_ShowCursor(SDL_ENABLE)
57
 
5 Plagman 58
#define SURFACE_FLAGS   (SDL_SWSURFACE|SDL_HWPALETTE|SDL_HWACCEL)
59
 
60
// undefine to restrict windowed resolutions to conventional sizes
61
#define ANY_WINDOWED_SIZE
62
 
258 terminx 63
// fix for mousewheel
4200 hendricks2 64
int32_t inputchecked = 0;
258 terminx 65
 
3583 helixhorne 66
extern int32_t app_main(int32_t argc, const char **argv);
5 Plagman 67
 
1762 terminx 68
char quitevent=0, appactive=1, novideo=0;
5 Plagman 69
 
70
// video
4089 hendricks2 71
static SDL_Surface *sdl_surface/*=NULL*/;
4080 hendricks2 72
static SDL_Surface *sdl_buffersurface=NULL;
4432 terminx 73
 
2777 helixhorne 74
#if SDL_MAJOR_VERSION==2
4089 hendricks2 75
static SDL_Palette *sdl_palptr=NULL;
76
static SDL_Window *sdl_window=NULL;
77
static SDL_GLContext sdl_context=NULL;
4253 hendricks2 78
static SDL_Texture *sdl_texture=NULL;
79
static SDL_Renderer *sdl_renderer=NULL;
2777 helixhorne 80
#endif
4432 terminx 81
 
2023 helixhorne 82
int32_t xres=-1, yres=-1, bpp=0, fullscreen=0, bytesperline;
618 terminx 83
intptr_t frameplace=0;
1205 terminx 84
int32_t lockcount=0;
5 Plagman 85
char modechange=1;
86
char offscreenrendering=0;
87
char videomodereset = 0;
88
char nofog=0;
1205 terminx 89
static uint16_t sysgamma[3][256];
90
extern int32_t curbrightness, gammabrightness;
5 Plagman 91
#ifdef USE_OPENGL
92
// OpenGL stuff
1036 terminx 93
char nogl=0;
4102 hendricks2 94
static int32_t vsync_render=0;
5 Plagman 95
#endif
96
 
2222 helixhorne 97
// last gamma, contrast, brightness
98
static float lastvidgcb[3];
99
 
2119 helixhorne 100
//#define KEY_PRINT_DEBUG
101
 
4075 hendricks2 102
#include "sdlkeytrans.c"
5 Plagman 103
 
104
//static SDL_Surface * loadtarga(const char *fn);               // for loading the icon
1762 terminx 105
static SDL_Surface *appicon = NULL;
106
static SDL_Surface *loadappicon(void);
5 Plagman 107
 
1658 terminx 108
static mutex_t m_initprintf;
109
 
1716 plagman 110
// Joystick dead and saturation zones
111
uint16_t *joydead, *joysatur;
112
 
3219 hendricks2 113
#ifdef _WIN32
114
//
4084 hendricks2 115
// win_gethwnd() -- gets the window handle
116
//
117
HWND win_gethwnd(void)
118
{
119
    struct SDL_SysWMinfo wmInfo;
120
    SDL_VERSION(&wmInfo.version);
121
 
122
#if SDL_MAJOR_VERSION==1
123
    if (SDL_GetWMInfo(&wmInfo) != 1)
4432 terminx 124
        return 0;
125
 
126
    return wmInfo.window;
4084 hendricks2 127
#else
128
    if (SDL_GetWindowWMInfo(sdl_window, &wmInfo) != SDL_TRUE)
129
        return 0;
130
 
131
    if (wmInfo.subsystem == SDL_SYSWM_WINDOWS)
132
        return wmInfo.info.win.window;
133
#endif
134
 
135
    initprintf("win_gethwnd: Unknown WM subsystem?!\n");
136
 
137
    return 0;
138
}
139
//
3219 hendricks2 140
// win_gethinstance() -- gets the application instance
141
//
3278 hendricks2 142
HINSTANCE win_gethinstance(void)
3219 hendricks2 143
{
3278 hendricks2 144
    return (HINSTANCE)GetModuleHandle(NULL);
3219 hendricks2 145
}
146
#endif
147
 
1205 terminx 148
int32_t wm_msgbox(char *name, char *fmt, ...)
5 Plagman 149
{
298 terminx 150
    char buf[2048];
109 terminx 151
    va_list va;
5 Plagman 152
 
659 plagman 153
    UNREFERENCED_PARAMETER(name);
154
 
109 terminx 155
    va_start(va,fmt);
4120 helixhorne 156
    vsnprintf(buf,sizeof(buf),fmt,va);
109 terminx 157
    va_end(va);
5 Plagman 158
 
159
#if defined(__APPLE__)
109 terminx 160
    return osx_msgbox(name, buf);
5 Plagman 161
#elif defined HAVE_GTK2
109 terminx 162
    if (gtkbuild_msgbox(name, buf) >= 0) return 1;
4254 hendricks2 163
#elif defined _WIN32
164
    MessageBox(win_gethwnd(),buf,name,MB_OK|MB_TASKMODAL);
165
    return 0;
4440 terminx 166
#elif defined __ANDROID__
167
    initprintf("wm_msgbox called. Message: %s: %s",name,buf);
168
    return 0;
4085 hendricks2 169
#elif SDL_MAJOR_VERSION==2
4120 helixhorne 170
# if !defined _WIN32
171
    // Replace all tab chars with spaces because the hand-rolled SDL message
172
    // box diplays the former as N/L instead of whitespace.
173
    {
174
        int32_t i;
175
        for (i=0; i<(int32_t)sizeof(buf); i++)
176
            if (buf[i] == '\t')
177
                buf[i] = ' ';
178
    }
179
# endif
4085 hendricks2 180
    return SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, name, buf, NULL);
5 Plagman 181
#endif
109 terminx 182
    puts(buf);
183
    puts("   (press Return or Enter to continue)");
184
    getchar();
5 Plagman 185
 
109 terminx 186
    return 0;
5 Plagman 187
}
188
 
1205 terminx 189
int32_t wm_ynbox(char *name, char *fmt, ...)
5 Plagman 190
{
298 terminx 191
    char buf[2048];
109 terminx 192
    char c;
193
    va_list va;
4254 hendricks2 194
#if (!defined(__APPLE__) && defined(HAVE_GTK2)) || defined _WIN32
1205 terminx 195
    int32_t r;
660 plagman 196
#endif
5 Plagman 197
 
659 plagman 198
    UNREFERENCED_PARAMETER(name);
199
 
109 terminx 200
    va_start(va,fmt);
201
    vsprintf(buf,fmt,va);
202
    va_end(va);
5 Plagman 203
 
204
#if defined __APPLE__
109 terminx 205
    return osx_ynbox(name, buf);
5 Plagman 206
#elif defined HAVE_GTK2
109 terminx 207
    if ((r = gtkbuild_ynbox(name, buf)) >= 0) return r;
4254 hendricks2 208
#elif defined _WIN32
209
    r = MessageBox(win_gethwnd(),buf,name,MB_YESNO|MB_ICONQUESTION|MB_TASKMODAL);
210
    if (r==IDYES) return 1;
211
    return 0;
4440 terminx 212
#elif defined __ANDROID__
213
    initprintf("wm_ynbox called, this is bad! Message: %s: %s",name,buf);
214
    initprintf("Returning false..");
215
    return 0;
5 Plagman 216
#endif
109 terminx 217
    puts(buf);
218
    puts("   (type 'Y' or 'N', and press Return or Enter to continue)");
219
    do c = getchar(); while (c != 'Y' && c != 'y' && c != 'N' && c != 'n');
220
    if (c == 'Y' || c == 'y') return 1;
5 Plagman 221
 
109 terminx 222
    return 0;
5 Plagman 223
}
224
 
225
void wm_setapptitle(char *name)
226
{
4440 terminx 227
#ifdef __ANDROID__
228
         initprintf("wm_setapptitle called");
229
         return;
230
#endif
231
 
342 terminx 232
    if (name)
2559 helixhorne 233
        Bstrncpyz(apptitle, name, sizeof(apptitle));
5 Plagman 234
 
2777 helixhorne 235
#if SDL_MAJOR_VERSION == 1
109 terminx 236
    SDL_WM_SetCaption(apptitle, NULL);
2777 helixhorne 237
#else
238
    SDL_SetWindowTitle(sdl_window, apptitle);
239
#endif
5 Plagman 240
 
194 terminx 241
    startwin_settitle(apptitle);
5 Plagman 242
}
243
 
244
 
245
//
246
//
247
// ---------------------------------------
248
//
249
// System
250
//
251
// ---------------------------------------
252
//
253
//
254
 
1205 terminx 255
int32_t main(int32_t argc, char *argv[])
5 Plagman 256
{
1205 terminx 257
    int32_t r;
3382 hendricks2 258
#ifdef USE_OPENGL
622 terminx 259
    char *argp;
3382 hendricks2 260
#endif
109 terminx 261
 
262
    buildkeytranslationtable();
263
 
3221 hendricks2 264
#ifdef _WIN32
265
    if (!CheckWinVersion())
266
    {
267
        MessageBox(0, "This application requires Windows XP or better to run.",
268
                   apptitle, MB_OK|MB_ICONSTOP);
269
        return -1;
270
    }
271
 
272
    win_open();
273
#endif
274
 
5 Plagman 275
#ifdef HAVE_GTK2
109 terminx 276
    gtkbuild_init(&argc, &argv);
5 Plagman 277
#endif
194 terminx 278
    startwin_open();
5 Plagman 279
 
3377 helixhorne 280
    maybe_redirect_outputs();
1736 helixhorne 281
 
1820 terminx 282
#ifdef USE_OPENGL
622 terminx 283
    if ((argp = Bgetenv("BUILD_NOFOG")) != NULL)
284
        nofog = Batol(argp);
285
#endif
286
 
109 terminx 287
    baselayer_init();
3583 helixhorne 288
    r = app_main(argc, (const char **)argv);
5 Plagman 289
 
194 terminx 290
    startwin_close();
5 Plagman 291
#ifdef HAVE_GTK2
109 terminx 292
    gtkbuild_exit(r);
5 Plagman 293
#endif
3221 hendricks2 294
#ifdef _WIN32
295
    win_close();
296
#endif
297
 
109 terminx 298
    return r;
5 Plagman 299
}
300
 
1820 terminx 301
#ifdef USE_OPENGL
1205 terminx 302
void setvsync(int32_t sync)
889 terminx 303
{
4090 hendricks2 304
    if (vsync_render == sync) return;
305
    vsync_render = sync;
4102 hendricks2 306
 
4432 terminx 307
# if SDL_MAJOR_VERSION == 1
889 terminx 308
    resetvideomode();
309
    if (setgamemode(fullscreen,xdim,ydim,bpp))
310
        OSD_Printf("restartvid: Reset failed...\n");
4090 hendricks2 311
# else
312
    if (sdl_context)
313
        SDL_GL_SetSwapInterval(vsync_render);
314
# endif
889 terminx 315
}
316
#endif
5 Plagman 317
 
1762 terminx 318
static void attach_debugger_here(void) {}
1485 helixhorne 319
 
3972 hendricks2 320
 
1879 plagman 321
/* XXX: libexecinfo could be used on systems without gnu libc. */
3972 hendricks2 322
#if !defined _WIN32 && defined __GNUC__ && !defined __OpenBSD__ && !(defined __APPLE__ && defined __BIG_ENDIAN__) && !defined(GEKKO) && !defined(__ANDROID__) && !defined __OPENDINGUX__
1712 helixhorne 323
# define PRINTSTACKONSEGV 1
324
# include <execinfo.h>
325
#endif
326
 
4089 hendricks2 327
static inline char grabmouse_low(char a);
328
 
1485 helixhorne 329
static void sighandler(int signum)
330
{
1644 helixhorne 331
    UNREFERENCED_PARAMETER(signum);
1519 helixhorne 332
//    if (signum==SIGSEGV)
1485 helixhorne 333
    {
4089 hendricks2 334
        grabmouse_low(0);
1712 helixhorne 335
#if PRINTSTACKONSEGV
336
        {
337
            void *addr[32];
338
            int32_t errfd = fileno(stderr);
4385 terminx 339
            int32_t n=backtrace(addr, ARRAY_SIZE(addr));
1712 helixhorne 340
            backtrace_symbols_fd(addr, n, errfd);
341
        }
342
        // This is useful for attaching the debugger post-mortem. For those pesky
343
        // cases where the program runs through happily when inspected from the start.
344
//        usleep(15000000);
345
#endif
1485 helixhorne 346
        attach_debugger_here();
3221 hendricks2 347
        app_crashhandler();
1485 helixhorne 348
        uninitsystem();
1712 helixhorne 349
        exit(8);
1485 helixhorne 350
    }
351
}
352
 
5 Plagman 353
//
354
// initsystem() -- init SDL systems
355
//
1205 terminx 356
int32_t initsystem(void)
5 Plagman 357
{
849 terminx 358
    /*
872 terminx 359
    #ifdef DEBUGGINGAIDS
109 terminx 360
    const SDL_VideoInfo *vid;
872 terminx 361
    #endif
849 terminx 362
    */
109 terminx 363
    SDL_version compiled;
5 Plagman 364
 
2777 helixhorne 365
#if SDL_MAJOR_VERSION < 2
366
    const SDL_version *linked = SDL_Linked_Version();
367
#else
368
    SDL_version linked_;
369
    const SDL_version *linked = &linked_;
370
    SDL_GetVersion(&linked_);
371
#endif
372
 
109 terminx 373
    SDL_VERSION(&compiled);
5 Plagman 374
 
1658 terminx 375
    mutex_init(&m_initprintf);
376
 
3221 hendricks2 377
#ifdef _WIN32
378
    win_init();
379
#endif
380
 
627 terminx 381
    initprintf("Initializing SDL system interface "
710 terminx 382
               "(compiled against SDL version %d.%d.%d, found version %d.%d.%d)\n",
383
               compiled.major, compiled.minor, compiled.patch,
384
               linked->major, linked->minor, linked->patch);
5 Plagman 385
 
710 terminx 386
    if (SDL_VERSIONNUM(linked->major,linked->minor,linked->patch) < SDL_REQUIREDVERSION)
723 terminx 387
    {
388
        /*reject running under SDL versions older than what is stated in sdl_inc.h */
710 terminx 389
        initprintf("You need at least v%d.%d.%d of SDL to run this game\n",SDL_MIN_X,SDL_MIN_Y,SDL_MIN_Z);
390
        return -1;
391
    }
392
 
109 terminx 393
    if (SDL_Init(SDL_INIT_VIDEO //| SDL_INIT_TIMER
5 Plagman 394
#ifdef NOSDLPARACHUTE
109 terminx 395
                 | SDL_INIT_NOPARACHUTE
5 Plagman 396
#endif
342 terminx 397
                ))
398
    {
1762 terminx 399
        initprintf("Initialization failed! (%s)\nNon-interactive mode enabled\n", SDL_GetError());
400
        /*        if (SDL_Init(0))
401
                {
402
                    initprintf("Initialization failed! (%s)\n", SDL_GetError());
403
                    return -1;
404
                }
405
                else
406
                */
1810 plagman 407
        novideo = 1;
408
#ifdef USE_OPENGL
409
        nogl = 1;
410
#endif
109 terminx 411
    }
5 Plagman 412
 
1485 helixhorne 413
    signal(SIGSEGV, sighandler);
2169 helixhorne 414
    signal(SIGILL, sighandler);  /* clang -fcatch-undefined-behavior uses an ill. insn */
1519 helixhorne 415
    signal(SIGABRT, sighandler);
416
    signal(SIGFPE, sighandler);
1485 helixhorne 417
 
109 terminx 418
    atexit(uninitsystem);
5 Plagman 419
 
109 terminx 420
    frameplace = 0;
421
    lockcount = 0;
5 Plagman 422
 
423
#ifdef USE_OPENGL
1762 terminx 424
    if (!novideo && loadgldriver(getenv("BUILD_GLDRV")))
342 terminx 425
    {
109 terminx 426
        initprintf("Failed loading OpenGL driver. GL modes will be unavailable.\n");
427
        nogl = 1;
428
    }
5 Plagman 429
#endif
430
 
3086 terminx 431
#if !defined(__APPLE__) && !defined(__ANDROID__)
1762 terminx 432
 
1544 terminx 433
    //icon = loadtarga("icon.tga");
1762 terminx 434
 
435
    if (!novideo)
436
    {
437
        appicon = loadappicon();
438
        if (appicon)
2777 helixhorne 439
        {
440
#if SDL_MAJOR_VERSION==1
1762 terminx 441
            SDL_WM_SetIcon(appicon, 0);
2777 helixhorne 442
#else
443
            SDL_SetWindowIcon(sdl_window, appicon);
444
#endif
445
        }
1762 terminx 446
    }
5 Plagman 447
#endif
448
 
1762 terminx 449
    if (!novideo)
2777 helixhorne 450
    {
451
#if SDL_MAJOR_VERSION==1
452
        char drvname[32];
1762 terminx 453
        if (SDL_VideoDriverName(drvname, 32))
454
            initprintf("Using \"%s\" video driver\n", drvname);
2777 helixhorne 455
#else
456
        const char *drvname = SDL_GetVideoDriver(0);
457
        if (drvname)
458
            initprintf("Using \"%s\" video driver\n", drvname);
459
#endif
460
    }
5 Plagman 461
 
849 terminx 462
    /*
109 terminx 463
    // dump a quick summary of the graphics hardware
872 terminx 464
    #ifdef DEBUGGINGAIDS
109 terminx 465
    vid = SDL_GetVideoInfo();
466
    initprintf("Video device information:\n");
467
    initprintf("  Can create hardware surfaces?          %s\n", (vid->hw_available)?"Yes":"No");
468
    initprintf("  Window manager available?              %s\n", (vid->wm_available)?"Yes":"No");
469
    initprintf("  Accelerated hardware blits?            %s\n", (vid->blit_hw)?"Yes":"No");
470
    initprintf("  Accelerated hardware colourkey blits?  %s\n", (vid->blit_hw_CC)?"Yes":"No");
471
    initprintf("  Accelerated hardware alpha blits?      %s\n", (vid->blit_hw_A)?"Yes":"No");
472
    initprintf("  Accelerated software blits?            %s\n", (vid->blit_sw)?"Yes":"No");
473
    initprintf("  Accelerated software colourkey blits?  %s\n", (vid->blit_sw_CC)?"Yes":"No");
474
    initprintf("  Accelerated software alpha blits?      %s\n", (vid->blit_sw_A)?"Yes":"No");
475
    initprintf("  Accelerated colour fills?              %s\n", (vid->blit_fill)?"Yes":"No");
476
    initprintf("  Total video memory:                    %dKB\n", vid->video_mem);
872 terminx 477
    #endif
478
    */
109 terminx 479
    return 0;
5 Plagman 480
}
481
 
482
 
483
//
484
// uninitsystem() -- uninit SDL systems
485
//
486
void uninitsystem(void)
487
{
109 terminx 488
    uninitinput();
489
    uninittimer();
5 Plagman 490
 
1544 terminx 491
    if (appicon)
1552 terminx 492
    {
1544 terminx 493
        SDL_FreeSurface(appicon);
1552 terminx 494
        appicon = NULL;
495
    }
1544 terminx 496
 
109 terminx 497
    SDL_Quit();
5 Plagman 498
 
3221 hendricks2 499
#ifdef _WIN32
500
    win_uninit();
501
#endif
502
 
5 Plagman 503
#ifdef USE_OPENGL
109 terminx 504
    unloadgldriver();
5 Plagman 505
#endif
506
}
507
 
508
 
509
//
4090 hendricks2 510
// system_getcvars() -- propagate any cvars that are read post-initialization
511
//
512
void system_getcvars(void)
513
{
4102 hendricks2 514
#ifdef USE_OPENGL
4090 hendricks2 515
    setvsync(vsync);
4102 hendricks2 516
#endif
4090 hendricks2 517
}
518
 
4440 terminx 519
#ifdef __ANDROID__
520
#include <android/log.h>
521
#endif
4090 hendricks2 522
 
523
//
5 Plagman 524
// initprintf() -- prints a string to the intitialization window
525
//
526
void initprintf(const char *f, ...)
527
{
109 terminx 528
    va_list va;
1663 helixhorne 529
    char buf[2048];
530
    static char dabuf[2048];
5 Plagman 531
 
109 terminx 532
    va_start(va, f);
1663 helixhorne 533
    Bvsnprintf(buf, sizeof(buf), f, va);
109 terminx 534
    va_end(va);
5 Plagman 535
 
4440 terminx 536
#ifdef __ANDROID__
537
    __android_log_print(ANDROID_LOG_INFO,"DUKE", "%s",buf);
538
#endif
1762 terminx 539
    OSD_Printf("%s", buf);
540
//    Bprintf("%s", buf);
109 terminx 541
 
1658 terminx 542
    mutex_lock(&m_initprintf);
1203 terminx 543
    if (Bstrlen(dabuf) + Bstrlen(buf) > 1022)
544
    {
545
        startwin_puts(dabuf);
546
        Bmemset(dabuf, 0, sizeof(dabuf));
547
    }
548
 
549
    Bstrcat(dabuf,buf);
550
 
1430 terminx 551
    if (flushlogwindow || Bstrlen(dabuf) > 768)
1203 terminx 552
    {
553
        startwin_puts(dabuf);
3219 hendricks2 554
#ifndef _WIN32
1203 terminx 555
        startwin_idle(NULL);
4086 hendricks2 556
#else
557
        handleevents();
3219 hendricks2 558
#endif
1203 terminx 559
        Bmemset(dabuf, 0, sizeof(dabuf));
560
    }
1658 terminx 561
    mutex_unlock(&m_initprintf);
5 Plagman 562
}
563
 
564
//
565
// debugprintf() -- prints a debug string to stderr
566
//
567
void debugprintf(const char *f, ...)
568
{
1935 helixhorne 569
#if defined DEBUGGINGAIDS && !(defined __APPLE__ && defined __BIG_ENDIAN__)
109 terminx 570
    va_list va;
5 Plagman 571
 
109 terminx 572
    va_start(va,f);
573
    Bvfprintf(stderr, f, va);
574
    va_end(va);
661 plagman 575
#else
576
    UNREFERENCED_PARAMETER(f);
5 Plagman 577
#endif
578
}
579
 
580
 
581
//
582
//
583
// ---------------------------------------
584
//
585
// All things Input
586
//
587
// ---------------------------------------
588
//
589
//
590
 
1205 terminx 591
// static int32_t joyblast=0;
5 Plagman 592
static SDL_Joystick *joydev = NULL;
593
 
594
//
595
// initinput() -- init input system
596
//
1205 terminx 597
int32_t initinput(void)
5 Plagman 598
{
1205 terminx 599
    int32_t i,j;
109 terminx 600
 
5 Plagman 601
#ifdef __APPLE__
109 terminx 602
    // force OS X to operate in >1 button mouse mode so that LMB isn't adulterated
603
    if (!getenv("SDL_HAS3BUTTONMOUSE")) putenv("SDL_HAS3BUTTONMOUSE=1");
5 Plagman 604
#endif
1114 terminx 605
    if (!remapinit)
1229 terminx 606
        for (i=0; i<256; i++)
1114 terminx 607
            remap[i]=i;
608
    remapinit=1;
5 Plagman 609
 
2777 helixhorne 610
#if SDL_MAJOR_VERSION==1
1114 terminx 611
    if (SDL_EnableKeyRepeat(250, 30)) // doesn't do anything in 1.3
612
        initprintf("Error enabling keyboard repeat.\n");
2777 helixhorne 613
    SDL_EnableUNICODE(1);       // let's hope this doesn't hit us too hard
614
#endif
109 terminx 615
    inputdevices = 1|2; // keyboard (1) and mouse (2)
1857 terminx 616
    mousegrab = 0;
5 Plagman 617
 
1206 terminx 618
    memset(key_names,0,sizeof(key_names));
4432 terminx 619
 
620
 
621
#if SDL_MAJOR_VERSION == 1
622
    i = SDLK_LAST-1;
623
#else
624
    i = SDL_NUM_SCANCODES-1;
625
#endif
626
 
627
    for (; i>=0; i--)
342 terminx 628
    {
109 terminx 629
        if (!keytranslation[i]) continue;
4432 terminx 630
        Bstrncpyz(key_names[ keytranslation[i] ],
631
            #if SDL_MAJOR_VERSION == 1
632
            SDL_GetKeyName((SDLKey)i),
1109 terminx 633
#else
4432 terminx 634
            SDL_GetKeyName(SDL_SCANCODE_TO_KEYCODE(i)),
635
#endif
636
            sizeof(key_names[i]));
1109 terminx 637
    }
5 Plagman 638
 
342 terminx 639
    if (!SDL_InitSubSystem(SDL_INIT_JOYSTICK))
640
    {
109 terminx 641
        i = SDL_NumJoysticks();
642
        initprintf("%d joystick(s) found\n",i);
4074 hendricks2 643
        for (j=0; j<i; j++)
644
            initprintf("  %d. %s\n", j+1,
645
#if SDL_MAJOR_VERSION==1
646
                SDL_JoystickName(j)
647
#else
648
                SDL_JoystickNameForIndex(j)
649
#endif
650
                );
109 terminx 651
        joydev = SDL_JoystickOpen(0);
342 terminx 652
        if (joydev)
653
        {
109 terminx 654
            SDL_JoystickEventState(SDL_ENABLE);
289 terminx 655
            inputdevices |= 4;
5 Plagman 656
 
109 terminx 657
            joynumaxes    = SDL_JoystickNumAxes(joydev);
658
            joynumbuttons = min(32,SDL_JoystickNumButtons(joydev));
659
            joynumhats    = SDL_JoystickNumHats(joydev);
660
            initprintf("Joystick 1 has %d axes, %d buttons, and %d hat(s).\n",
661
                       joynumaxes,joynumbuttons,joynumhats);
5 Plagman 662
 
1205 terminx 663
            joyaxis = (int32_t *)Bcalloc(joynumaxes, sizeof(int32_t));
2331 helixhorne 664
            if (joynumhats)
665
                joyhat = (int32_t *)Bcalloc(joynumhats, sizeof(int32_t));
1716 plagman 666
 
667
            for (i = 0; i < joynumhats; i++)
1762 terminx 668
                joyhat[i] = -1; // centre
1716 plagman 669
 
670
            joydead = (uint16_t *)Bcalloc(joynumaxes, sizeof(uint16_t));
671
            joysatur = (uint16_t *)Bcalloc(joynumaxes, sizeof(uint16_t));
109 terminx 672
        }
673
    }
674
 
675
    return 0;
5 Plagman 676
}
677
 
678
//
679
// uninitinput() -- uninit input system
680
//
681
void uninitinput(void)
682
{
109 terminx 683
    uninitmouse();
5 Plagman 684
 
342 terminx 685
    if (joydev)
686
    {
109 terminx 687
        SDL_JoystickClose(joydev);
688
        joydev = NULL;
689
    }
5 Plagman 690
}
691
 
2624 helixhorne 692
#ifndef GEKKO
1205 terminx 693
const char *getjoyname(int32_t what, int32_t num)
5 Plagman 694
{
109 terminx 695
    static char tmp[64];
5 Plagman 696
 
342 terminx 697
    switch (what)
698
    {
109 terminx 699
    case 0:     // axis
700
        if ((unsigned)num > (unsigned)joynumaxes) return NULL;
1221 terminx 701
        Bsprintf(tmp,"Axis %d",num);
1205 terminx 702
        return (char *)tmp;
5 Plagman 703
 
109 terminx 704
    case 1: // button
705
        if ((unsigned)num > (unsigned)joynumbuttons) return NULL;
1221 terminx 706
        Bsprintf(tmp,"Button %d",num);
1205 terminx 707
        return (char *)tmp;
5 Plagman 708
 
109 terminx 709
    case 2: // hat
710
        if ((unsigned)num > (unsigned)joynumhats) return NULL;
1221 terminx 711
        Bsprintf(tmp,"Hat %d",num);
1205 terminx 712
        return (char *)tmp;
5 Plagman 713
 
109 terminx 714
    default:
715
        return NULL;
716
    }
5 Plagman 717
}
2624 helixhorne 718
#else
719
static const char *joynames[3][15] =
720
{
721
        {
722
                "Left Stick X",
723
                "Left Stick Y",
724
                "Right Stick X",
725
                "Right Stick Y",
2728 hendricks2 726
                "Axis 5",
727
                "Axis 6",
728
                "Axis 7",
729
                "Axis 8",
730
                "Axis 9",
731
                "Axis 10",
732
                "Axis 11",
733
                "Axis 12",
734
                "Axis 13",
735
                "Axis 14",
736
                "Axis 15",
2624 helixhorne 737
        },
738
        {
739
                "Button A",
740
                "Button B",
741
                "Button 1",
742
                "Button 2",
743
                "Button -",
744
                "Button +",
2728 hendricks2 745
                "Button HOME",
2624 helixhorne 746
                "Button Z",
747
                "Button C",
748
                "Button X",
749
                "Button Y",
750
                "Trigger L",
751
                "Trigger R",
2728 hendricks2 752
                "Trigger ZL",
753
                "Trigger ZR",
2624 helixhorne 754
        },
755
        {
2728 hendricks2 756
                "D-Pad Up",
757
                "D-Pad Right",
758
                "D-Pad Down",
759
                "D-Pad Left",
760
                "Hat 5",
761
                "Hat 6",
762
                "Hat 7",
763
                "Hat 8",
764
                "Hat 9",
765
                "Hat 10",
766
                "Hat 11",
767
                "Hat 12",
768
                "Hat 13",
769
                "Hat 14",
770
                "Hat 15",
2624 helixhorne 771
        }
772
};
773
const char *getjoyname(int32_t what, int32_t num)
774
{
775
    switch (what)
776
    {
777
    case 0:     // axis
778
        if ((unsigned)num > (unsigned)joynumaxes) return NULL;
779
        return joynames[0][num];
5 Plagman 780
 
2624 helixhorne 781
    case 1: // button
782
        if ((unsigned)num > (unsigned)joynumbuttons) return NULL;
783
        return joynames[1][num];
1586 terminx 784
 
2624 helixhorne 785
    case 2: // hat
786
        if ((unsigned)num > (unsigned)joynumhats) return NULL;
787
        return joynames[2][num];
788
 
789
    default:
790
        return NULL;
791
    }
792
}
793
#endif
794
 
795
 
5 Plagman 796
//
797
// initmouse() -- init mouse input
798
//
1205 terminx 799
int32_t initmouse(void)
5 Plagman 800
{
109 terminx 801
    moustat=1;
618 terminx 802
    grabmouse(1); // FIXME - SA
109 terminx 803
    return 0;
5 Plagman 804
}
805
 
806
//
807
// uninitmouse() -- uninit mouse input
808
//
809
void uninitmouse(void)
810
{
109 terminx 811
    grabmouse(0);
812
    moustat=0;
5 Plagman 813
}
814
 
815
 
816
//
4089 hendricks2 817
// grabmouse_low() -- show/hide mouse cursor, lower level (doesn't check state).
818
//                    furthermore return 0 if successful.
819
//
820
 
821
static inline char grabmouse_low(char a)
822
{
4432 terminx 823
#if !defined __ANDROID__ && (!defined DEBUGGINGAIDS || defined _WIN32 || defined __APPLE__)
4089 hendricks2 824
#if SDL_MAJOR_VERSION==1
825
    SDL_ShowCursor(a ? SDL_DISABLE : SDL_ENABLE);
826
    return (SDL_WM_GrabInput(a ? SDL_GRAB_ON : SDL_GRAB_OFF) != (a ? SDL_GRAB_ON : SDL_GRAB_OFF));
827
#else
828
    /* FIXME: Maybe it's better to make sure that grabmouse_low
829
       is called only when a window is ready?                */
830
    if (sdl_window)
831
        SDL_SetWindowGrab(sdl_window, a ? SDL_TRUE : SDL_FALSE);
832
    return SDL_SetRelativeMouseMode(a ? SDL_TRUE : SDL_FALSE);
833
#endif
4432 terminx 834
#endif
4089 hendricks2 835
}
836
 
837
//
5 Plagman 838
// grabmouse() -- show/hide mouse cursor
839
//
840
void grabmouse(char a)
841
{
342 terminx 842
    if (appactive && moustat)
843
    {
3221 hendricks2 844
#if !defined __ANDROID__ && (!defined DEBUGGINGAIDS || defined _WIN32 || defined __APPLE__)
4089 hendricks2 845
        if ((a != mousegrab) && !grabmouse_low(a))
4095 helixhorne 846
#endif
1857 terminx 847
            mousegrab = a;
342 terminx 848
    }
849
    else
850
    {
1857 terminx 851
        mousegrab = a;
109 terminx 852
    }
853
    mousex = mousey = 0;
2623 helixhorne 854
    mouseabsx = mouseabsy = 0;
5 Plagman 855
}
856
 
857
//
858
// setjoydeadzone() -- sets the dead and saturation zones for the joystick
859
//
1205 terminx 860
void setjoydeadzone(int32_t axis, uint16_t dead, uint16_t satur)
655 terminx 861
{
1716 plagman 862
    joydead[axis] = dead;
863
    joysatur[axis] = satur;
655 terminx 864
}
5 Plagman 865
 
866
 
867
//
868
// getjoydeadzone() -- gets the dead and saturation zones for the joystick
869
//
1205 terminx 870
void getjoydeadzone(int32_t axis, uint16_t *dead, uint16_t *satur)
5 Plagman 871
{
1716 plagman 872
    *dead = joydead[axis];
873
    *satur = joysatur[axis];
5 Plagman 874
}
875
 
876
 
877
//
878
// releaseallbuttons()
879
//
880
void releaseallbuttons(void)
342 terminx 881
{}
5 Plagman 882
 
883
 
884
//
885
//
886
// ---------------------------------------
887
//
888
// All things Timer
889
// Ken did this
890
//
891
// ---------------------------------------
892
//
893
//
894
 
895
static Uint32 timerfreq=0;
896
static Uint32 timerlastsample=0;
2285 helixhorne 897
int32_t timerticspersec=0;
3934 helixhorne 898
static double msperu64tick = 0;
342 terminx 899
static void(*usertimercallback)(void) = NULL;
5 Plagman 900
 
2778 helixhorne 901
 
5 Plagman 902
//
627 terminx 903
// inittimer() -- initialize timer
5 Plagman 904
//
1205 terminx 905
int32_t inittimer(int32_t tickspersecond)
5 Plagman 906
{
109 terminx 907
    if (timerfreq) return 0;    // already installed
5 Plagman 908
 
627 terminx 909
//    initprintf("Initializing timer\n");
5 Plagman 910
 
3221 hendricks2 911
#ifdef _WIN32
912
    {
913
        int32_t t = win_inittimer();
914
        if (t < 0)
915
            return t;
916
    }
917
#endif
918
 
109 terminx 919
    timerfreq = 1000;
920
    timerticspersec = tickspersecond;
921
    timerlastsample = SDL_GetTicks() * timerticspersec / timerfreq;
5 Plagman 922
 
109 terminx 923
    usertimercallback = NULL;
5 Plagman 924
 
3934 helixhorne 925
    msperu64tick = 1000.0 / (double)getu64tickspersec();
2778 helixhorne 926
 
109 terminx 927
    return 0;
5 Plagman 928
}
929
 
930
//
931
// uninittimer() -- shut down timer
932
//
933
void uninittimer(void)
934
{
109 terminx 935
    if (!timerfreq) return;
5 Plagman 936
 
109 terminx 937
    timerfreq=0;
2778 helixhorne 938
 
3221 hendricks2 939
#ifdef _WIN32
940
    win_timerfreq=0;
941
#endif
942
 
3934 helixhorne 943
    msperu64tick = 0;
5 Plagman 944
}
945
 
946
//
947
// sampletimer() -- update totalclock
948
//
949
void sampletimer(void)
950
{
109 terminx 951
    Uint32 i;
1205 terminx 952
    int32_t n;
5 Plagman 953
 
109 terminx 954
    if (!timerfreq) return;
955
    i = SDL_GetTicks();
1205 terminx 956
    n = (int32_t)(i * timerticspersec / timerfreq) - timerlastsample;
342 terminx 957
    if (n>0)
958
    {
109 terminx 959
        totalclock += n;
960
        timerlastsample += n;
961
    }
962
 
963
    if (usertimercallback) for (; n>0; n--) usertimercallback();
5 Plagman 964
}
965
 
966
//
967
// getticks() -- returns the sdl ticks count
968
//
1205 terminx 969
uint32_t getticks(void)
5 Plagman 970
{
1205 terminx 971
    return (uint32_t)SDL_GetTicks();
5 Plagman 972
}
973
 
2026 helixhorne 974
// high-resolution timers for profiling
3934 helixhorne 975
uint64_t getu64ticks(void)
2026 helixhorne 976
{
4432 terminx 977
#if (SDL_MAJOR_VERSION == 1) // SDL 1.2
3278 hendricks2 978
# if defined _WIN32
3934 helixhorne 979
    return win_getu64ticks();
3278 hendricks2 980
# elif defined __APPLE__
981
    return mach_absolute_time();
982
# elif _POSIX_TIMERS>0 && defined _POSIX_MONOTONIC_CLOCK
2778 helixhorne 983
    // This is SDL HG's SDL_GetPerformanceCounter() when clock_gettime() is
984
    // available.
985
    uint64_t ticks;
986
    struct timespec now;
987
 
988
    clock_gettime(CLOCK_MONOTONIC, &now);
989
    ticks = now.tv_sec;
990
    ticks *= 1000000000;
991
    ticks += now.tv_nsec;
3497 hendricks2 992
    return ticks;
993
# elif defined GEKKO
994
    return ticks_to_nanosecs(gettime());
2778 helixhorne 995
# else
2861 helixhorne 996
// Blar. This pragma is unsupported on earlier GCC versions.
997
// At least we'll get a warning and a reference to this line...
3934 helixhorne 998
#  pragma message "Using low-resolution (1ms) timer for getu64ticks. Profiling will work badly."
2026 helixhorne 999
    return SDL_GetTicks();
2778 helixhorne 1000
# endif
4432 terminx 1001
#else  // SDL 2.0
2778 helixhorne 1002
    return SDL_GetPerformanceCounter();
1003
#endif
2026 helixhorne 1004
}
5 Plagman 1005
 
3934 helixhorne 1006
uint64_t getu64tickspersec(void)
2026 helixhorne 1007
{
4432 terminx 1008
#if (SDL_MAJOR_VERSION == 1) // SDL 1.2
3278 hendricks2 1009
# if defined _WIN32
3221 hendricks2 1010
    return win_timerfreq;
2861 helixhorne 1011
# elif defined __APPLE__
1012
    static mach_timebase_info_data_t ti;
1013
    if (ti.denom == 0)
1014
        (void)mach_timebase_info(&ti);  // ti.numer/ti.denom: nsec/(m_a_t() tick)
1015
    return (1000000000LL*ti.denom)/ti.numer;
3278 hendricks2 1016
# elif _POSIX_TIMERS>0 && defined _POSIX_MONOTONIC_CLOCK
1017
    return 1000000000;
3497 hendricks2 1018
# elif defined GEKKO
1019
    return TB_NSPERSEC;
2861 helixhorne 1020
# else
1021
    return 1000;
2778 helixhorne 1022
# endif
4432 terminx 1023
#else  // SDL 2.0
2778 helixhorne 1024
    return SDL_GetPerformanceFrequency();
1025
#endif
2026 helixhorne 1026
}
1027
 
2778 helixhorne 1028
// Returns the time since an unspecified starting time in milliseconds.
1029
// (May be not monotonic for certain configurations.)
1030
ATTRIBUTE((flatten))
3935 helixhorne 1031
double gethiticks(void)
2026 helixhorne 1032
{
3934 helixhorne 1033
    return (double)getu64ticks() * msperu64tick;
2026 helixhorne 1034
}
1035
 
5 Plagman 1036
//
1037
// gettimerfreq() -- returns the number of ticks per second the timer is configured to generate
1038
//
1205 terminx 1039
int32_t gettimerfreq(void)
5 Plagman 1040
{
109 terminx 1041
    return timerticspersec;
5 Plagman 1042
}
1043
 
1044
 
1045
//
1046
// installusertimercallback() -- set up a callback function to be called when the timer is fired
1047
//
342 terminx 1048
void(*installusertimercallback(void(*callback)(void)))(void)
5 Plagman 1049
{
342 terminx 1050
    void(*oldtimercallback)(void);
5 Plagman 1051
 
109 terminx 1052
    oldtimercallback = usertimercallback;
1053
    usertimercallback = callback;
5 Plagman 1054
 
109 terminx 1055
    return oldtimercallback;
5 Plagman 1056
}
1057
 
1058
 
1059
 
1060
//
1061
//
1062
// ---------------------------------------
1063
//
1064
// All things Video
1065
//
1066
// ---------------------------------------
1067
//
109 terminx 1068
//
5 Plagman 1069
 
1070
 
1071
//
1072
// getvalidmodes() -- figure out what video modes are available
1073
//
4068 helixhorne 1074
static int sortmodes(const void *a_, const void *b_)
5 Plagman 1075
{
1205 terminx 1076
    int32_t x;
5 Plagman 1077
 
4068 helixhorne 1078
    const struct validmode_t *a = (const struct validmode_t *)a_;
1079
    const struct validmode_t *b = (const struct validmode_t *)b_;
1080
 
109 terminx 1081
    if ((x = a->fs   - b->fs)   != 0) return x;
1082
    if ((x = a->bpp  - b->bpp)  != 0) return x;
1083
    if ((x = a->xdim - b->xdim) != 0) return x;
1084
    if ((x = a->ydim - b->ydim) != 0) return x;
5 Plagman 1085
 
109 terminx 1086
    return 0;
5 Plagman 1087
}
4432 terminx 1088
 
1089
#define ADDMODE(x,y,c,f) do { \
1090
    if (validmodecnt<MAXVALIDMODES) { \
1091
    int32_t mn; \
1092
    for(mn=0;mn<validmodecnt;mn++) \
1093
    if (validmode[mn].xdim==x && validmode[mn].ydim==y && \
1094
    validmode[mn].bpp==c  && validmode[mn].fs==f) break; \
1095
    if (mn==validmodecnt) { \
1096
    validmode[validmodecnt].xdim=x; \
1097
    validmode[validmodecnt].ydim=y; \
1098
    validmode[validmodecnt].bpp=c; \
1099
    validmode[validmodecnt].fs=f; \
1100
    validmodecnt++; \
1101
    /*initprintf("  - %dx%d %d-bit %s\n", x, y, c, (f&1)?"fullscreen":"windowed");*/ \
1102
    } \
1103
    } \
1104
} while (0)
1105
 
1106
#define CHECK(w,h) if ((w < maxx) && (h < maxy))
1107
 
1108
 
5 Plagman 1109
static char modeschecked=0;
4432 terminx 1110
 
1111
#if SDL_MAJOR_VERSION==1
5 Plagman 1112
void getvalidmodes(void)
1113
{
4089 hendricks2 1114
    int32_t i, maxx=0, maxy=0;
1115
    int32_t j;
4432 terminx 1116
    static int32_t cdepths [] =
584 terminx 1117
    {
1118
        8,
5 Plagman 1119
#ifdef USE_OPENGL
4432 terminx 1120
        16, 24, 32,
5 Plagman 1121
#endif
584 terminx 1122
 
1123
    };
109 terminx 1124
    SDL_Rect **modes;
1829 terminx 1125
    SDL_PixelFormat pf;
1126
 
1127
    pf.palette = NULL;
1128
    pf.BitsPerPixel = 8;
1129
    pf.BytesPerPixel = 1;
5 Plagman 1130
 
1762 terminx 1131
    if (modeschecked || novideo) return;
5 Plagman 1132
 
109 terminx 1133
    validmodecnt=0;
4432 terminx 1134
    //    initprintf("Detecting video modes:\n");
5 Plagman 1135
 
4089 hendricks2 1136
    // do fullscreen modes first
342 terminx 1137
    for (j=0; cdepths[j]; j++)
1138
    {
2777 helixhorne 1139
# ifdef USE_OPENGL
194 terminx 1140
        if (nogl && cdepths[j] > 8) continue;
2777 helixhorne 1141
# endif
109 terminx 1142
        pf.BitsPerPixel = cdepths[j];
1143
        pf.BytesPerPixel = cdepths[j] >> 3;
5 Plagman 1144
 
4080 hendricks2 1145
        // We convert paletted contents to non-paletted
1146
        modes = SDL_ListModes((cdepths[j] == 8) ? NULL : &pf, SURFACE_FLAGS | SDL_FULLSCREEN);
1114 terminx 1147
 
4432 terminx 1148
        if (modes == (SDL_Rect **) 0)
342 terminx 1149
        {
109 terminx 1150
            if (cdepths[j] > 8) cdepths[j] = -1;
1151
            continue;
1152
        }
5 Plagman 1153
 
4432 terminx 1154
        if (modes == (SDL_Rect **) -1)
342 terminx 1155
        {
109 terminx 1156
            for (i=0; defaultres[i][0]; i++)
4432 terminx 1157
                ADDMODE(defaultres[i][0], defaultres[i][1], cdepths[j], 1);
1836 helixhorne 1158
        }
342 terminx 1159
        else
1160
        {
1161
            for (i=0; modes[i]; i++)
1162
            {
109 terminx 1163
                if ((modes[i]->w > MAXXDIM) || (modes[i]->h > MAXYDIM)) continue;
5 Plagman 1164
 
1836 helixhorne 1165
                ADDMODE(modes[i]->w, modes[i]->h, cdepths[j], 1);
5 Plagman 1166
 
342 terminx 1167
                if ((modes[i]->w > maxx) && (modes[i]->h > maxy))
1168
                {
109 terminx 1169
                    maxx = modes[i]->w;
1170
                    maxy = modes[i]->h;
1171
                }
1172
            }
1173
        }
1174
    }
4432 terminx 1175
 
1176
    if (maxx == 0 && maxy == 0)
1177
    {
1178
        initprintf("No fullscreen modes available!\n");
1179
        maxx = MAXXDIM; maxy = MAXYDIM;
1180
    }
1181
 
1182
    // add windowed modes next
1183
    for (j=0; cdepths[j]; j++)
1184
    {
1185
#ifdef USE_OPENGL
1186
        if (nogl && cdepths[j] > 8) continue;
1187
#endif
1188
        if (cdepths[j] < 0) continue;
1189
        for (i=0; defaultres[i][0]; i++)
1190
            CHECK(defaultres[i][0], defaultres[i][1])
1191
            ADDMODE(defaultres[i][0], defaultres[i][1], cdepths[j], 0);
1192
    }
1193
 
1194
    qsort((void *) validmode, validmodecnt, sizeof(struct validmode_t), &sortmodes);
1195
 
1196
    modeschecked=1;
1197
}
1198
 
1199
#else
1200
 
1201
void getvalidmodes(void)
1202
{
1203
    int32_t i, maxx=0, maxy=0;
1204
    SDL_DisplayMode dispmode;
1205
 
1206
    if (modeschecked || novideo) return;
1207
 
1208
    validmodecnt=0;
1209
    //    initprintf("Detecting video modes:\n");
1210
 
1211
    // do fullscreen modes first
4089 hendricks2 1212
    for (i=0; i<SDL_GetNumDisplayModes(0); i++)
1213
    {
1214
        SDL_GetDisplayMode(0, i, &dispmode);
1215
        if ((dispmode.w > MAXXDIM) || (dispmode.h > MAXYDIM)) continue;
1216
 
1217
        // HACK: 8-bit == Software, 32-bit == OpenGL
1218
        ADDMODE(dispmode.w, dispmode.h, 8, 1);
1219
#ifdef USE_OPENGL
1220
        if (!nogl)
1221
            ADDMODE(dispmode.w, dispmode.h, 32, 1);
1222
#endif
1223
        if ((dispmode.w > maxx) && (dispmode.h > maxy))
1224
        {
1225
            maxx = dispmode.w;
1226
            maxy = dispmode.h;
1227
        }
1228
    }
342 terminx 1229
    if (maxx == 0 && maxy == 0)
1230
    {
109 terminx 1231
        initprintf("No fullscreen modes available!\n");
1232
        maxx = MAXXDIM; maxy = MAXYDIM;
1233
    }
5 Plagman 1234
 
109 terminx 1235
    // add windowed modes next
4432 terminx 1236
    for (i=0; defaultres[i][0]; i++)
1237
        CHECK(defaultres[i][0], defaultres[i][1])
342 terminx 1238
    {
4089 hendricks2 1239
            // HACK: 8-bit == Software, 32-bit == OpenGL
4432 terminx 1240
            ADDMODE(defaultres[i][0], defaultres[i][1], 8, 0);
4089 hendricks2 1241
#ifdef USE_OPENGL
1242
            if (!nogl)
4432 terminx 1243
                ADDMODE(defaultres[i][0], defaultres[i][1], 32, 0);
4089 hendricks2 1244
#endif
4432 terminx 1245
    }
5 Plagman 1246
 
4432 terminx 1247
    qsort((void *) validmode, validmodecnt, sizeof(struct validmode_t), &sortmodes);
5 Plagman 1248
 
109 terminx 1249
    modeschecked=1;
5 Plagman 1250
}
4432 terminx 1251
#endif
5 Plagman 1252
 
4432 terminx 1253
#undef CHECK
1254
#undef ADDMODE
5 Plagman 1255
 
1256
//
1257
// checkvideomode() -- makes sure the video mode passed is legal
1258
//
1205 terminx 1259
int32_t checkvideomode(int32_t *x, int32_t *y, int32_t c, int32_t fs, int32_t forced)
5 Plagman 1260
{
1205 terminx 1261
    int32_t i, nearest=-1, dx, dy, odx=9999, ody=9999;
5 Plagman 1262
 
109 terminx 1263
    getvalidmodes();
5 Plagman 1264
 
109 terminx 1265
    if (c>8
5 Plagman 1266
#ifdef USE_OPENGL
109 terminx 1267
            && nogl
5 Plagman 1268
#endif
109 terminx 1269
       ) return -1;
5 Plagman 1270
 
109 terminx 1271
    // fix up the passed resolution values to be multiples of 8
1272
    // and at least 320x200 or at most MAXXDIMxMAXYDIM
1273
    if (*x < 320) *x = 320;
1274
    if (*y < 200) *y = 200;
1275
    if (*x > MAXXDIM) *x = MAXXDIM;
1276
    if (*y > MAXYDIM) *y = MAXYDIM;
1114 terminx 1277
//    *x &= 0xfffffff8l;
5 Plagman 1278
 
342 terminx 1279
    for (i=0; i<validmodecnt; i++)
1280
    {
109 terminx 1281
        if (validmode[i].bpp != c) continue;
1282
        if (validmode[i].fs != fs) continue;
1283
        dx = klabs(validmode[i].xdim - *x);
1284
        dy = klabs(validmode[i].ydim - *y);
342 terminx 1285
        if (!(dx | dy))
584 terminx 1286
        {
1287
            // perfect match
109 terminx 1288
            nearest = i;
1289
            break;
1290
        }
342 terminx 1291
        if ((dx <= odx) && (dy <= ody))
1292
        {
109 terminx 1293
            nearest = i;
1294
            odx = dx; ody = dy;
1295
        }
1296
    }
1297
 
331 terminx 1298
#ifdef ANY_WINDOWED_SIZE
194 terminx 1299
    if (!forced && (fs&1) == 0 && (nearest < 0 || (validmode[nearest].xdim!=*x || validmode[nearest].ydim!=*y)))
109 terminx 1300
        return 0x7fffffffl;
331 terminx 1301
#endif
5 Plagman 1302
 
342 terminx 1303
    if (nearest < 0)
1304
    {
109 terminx 1305
        // no mode that will match (eg. if no fullscreen modes)
1306
        return -1;
1307
    }
5 Plagman 1308
 
109 terminx 1309
    *x = validmode[nearest].xdim;
1310
    *y = validmode[nearest].ydim;
5 Plagman 1311
 
109 terminx 1312
    return nearest;             // JBF 20031206: Returns the mode number
5 Plagman 1313
}
1314
 
2777 helixhorne 1315
static int32_t needpalupdate;
1316
static SDL_Color sdlayer_pal[256];
5 Plagman 1317
 
4089 hendricks2 1318
static void destroy_window_resources()
2777 helixhorne 1319
{
4082 hendricks2 1320
        if (sdl_buffersurface)
1321
            SDL_FreeSurface(sdl_buffersurface);
1322
        sdl_buffersurface = NULL;
4089 hendricks2 1323
        /* We should NOT destroy the window surface. This is done automatically
1324
           when SDL_DestroyWindow or SDL_SetVideoMode is called.             */
4270 hendricks2 1325
 
1326
#if SDL_MAJOR_VERSION==2
1327
        if (sdl_renderer && sdl_texture && sdl_surface)
4082 hendricks2 1328
            SDL_FreeSurface(sdl_surface);
2777 helixhorne 1329
        sdl_surface = NULL;
4082 hendricks2 1330
        if (sdl_context)
1331
            SDL_GL_DeleteContext(sdl_context);
1332
        sdl_context = NULL;
4253 hendricks2 1333
        if (sdl_texture)
1334
            SDL_DestroyTexture(sdl_texture);
1335
        sdl_texture = NULL;
1336
        if (sdl_renderer)
1337
            SDL_DestroyRenderer(sdl_renderer);
1338
        sdl_renderer = NULL;
2777 helixhorne 1339
        if (sdl_window)
1340
            SDL_DestroyWindow(sdl_window);
1341
        sdl_window = NULL;
4088 hendricks2 1342
#endif
2777 helixhorne 1343
}
1344
 
5 Plagman 1345
//
1346
// setvideomode() -- set SDL video mode
1347
//
1205 terminx 1348
int32_t setvideomode(int32_t x, int32_t y, int32_t c, int32_t fs)
5 Plagman 1349
{
1205 terminx 1350
    int32_t regrab = 0;
1890 helixhorne 1351
#ifdef USE_OPENGL
1205 terminx 1352
    static int32_t warnonce = 0;
4432 terminx 1353
# if (SDL_MAJOR_VERSION == 1)
1205 terminx 1354
    static int32_t ovsync = 1;
2253 helixhorne 1355
# endif
1171 terminx 1356
#endif
109 terminx 1357
    if ((fs == fullscreen) && (x == xres) && (y == yres) && (c == bpp) &&
342 terminx 1358
            !videomodereset)
1359
    {
109 terminx 1360
        OSD_ResizeDisplay(xres,yres);
1361
        return 0;
1362
    }
5 Plagman 1363
 
194 terminx 1364
    if (checkvideomode(&x,&y,c,fs,0) < 0) return -1;
109 terminx 1365
 
194 terminx 1366
    startwin_close();
5 Plagman 1367
 
1857 terminx 1368
    if (mousegrab)
342 terminx 1369
    {
109 terminx 1370
        regrab = 1;
1371
        grabmouse(0);
1372
    }
5 Plagman 1373
 
109 terminx 1374
    if (lockcount) while (lockcount) enddrawing();
5 Plagman 1375
 
1820 terminx 1376
#ifdef USE_OPENGL
109 terminx 1377
    if (bpp > 8 && sdl_surface) polymost_glreset();
5 Plagman 1378
#endif
1379
 
2222 helixhorne 1380
    // clear last gamma/contrast/brightness so that it will be set anew
1381
    lastvidgcb[0] = lastvidgcb[1] = lastvidgcb[2] = 0.0f;
1382
 
2777 helixhorne 1383
#if SDL_MAJOR_VERSION==1
109 terminx 1384
    // restore gamma before we change video modes if it was changed
342 terminx 1385
    if (sdl_surface && gammabrightness)
1386
    {
109 terminx 1387
        SDL_SetGammaRamp(sysgamma[0], sysgamma[1], sysgamma[2]);
1388
        gammabrightness = 0;    // redetect on next mode switch
1389
    }
4080 hendricks2 1390
 
2777 helixhorne 1391
#endif
109 terminx 1392
 
4089 hendricks2 1393
    // deinit
1394
    destroy_window_resources();
1395
 
1820 terminx 1396
#ifdef USE_OPENGL
342 terminx 1397
    if (c > 8)
1398
    {
1205 terminx 1399
        int32_t i, j, multisamplecheck = (glmultisample > 0);
342 terminx 1400
        struct
1401
        {
109 terminx 1402
            SDL_GLattr attr;
1205 terminx 1403
            int32_t value;
342 terminx 1404
        }
584 terminx 1405
        attributes[] =
1406
        {
2014 helixhorne 1407
# if 0
584 terminx 1408
            { SDL_GL_RED_SIZE, 8 },
1409
            { SDL_GL_GREEN_SIZE, 8 },
1410
            { SDL_GL_BLUE_SIZE, 8 },
1411
            { SDL_GL_ALPHA_SIZE, 8 },
1412
            { SDL_GL_BUFFER_SIZE, c },
1413
            { SDL_GL_STENCIL_SIZE, 0 },
1414
            { SDL_GL_ACCUM_RED_SIZE, 0 },
1415
            { SDL_GL_ACCUM_GREEN_SIZE, 0 },
1416
            { SDL_GL_ACCUM_BLUE_SIZE, 0 },
1417
            { SDL_GL_ACCUM_ALPHA_SIZE, 0 },
1418
            { SDL_GL_DEPTH_SIZE, 24 },
2014 helixhorne 1419
# endif
584 terminx 1420
            { SDL_GL_DOUBLEBUFFER, 1 },
1421
            { SDL_GL_MULTISAMPLEBUFFERS, glmultisample > 0 },
1422
            { SDL_GL_MULTISAMPLESAMPLES, glmultisample },
697 plagman 1423
            { SDL_GL_STENCIL_SIZE, 1 },
4432 terminx 1424
# if SDL_MAJOR_VERSION == 1
4090 hendricks2 1425
            { SDL_GL_SWAP_CONTROL, vsync_render },
2014 helixhorne 1426
# endif
584 terminx 1427
        };
5 Plagman 1428
 
109 terminx 1429
        if (nogl) return -1;
5 Plagman 1430
 
3221 hendricks2 1431
# ifdef _WIN32
1432
        win_setvideomode(c);
1433
# endif
1434
 
109 terminx 1435
        initprintf("Setting video mode %dx%d (%d-bpp %s)\n",
1436
                   x,y,c, ((fs&1) ? "fullscreen" : "windowed"));
342 terminx 1437
        do
1438
        {
4385 terminx 1439
            for (i=0; i < (int32_t)ARRAY_SIZE(attributes); i++)
342 terminx 1440
            {
109 terminx 1441
                j = attributes[i].value;
1442
                if (!multisamplecheck &&
1443
                        (attributes[i].attr == SDL_GL_MULTISAMPLEBUFFERS ||
1444
                         attributes[i].attr == SDL_GL_MULTISAMPLESAMPLES)
342 terminx 1445
                   )
1446
                {
109 terminx 1447
                    j = 0;
1448
                }
1449
                SDL_GL_SetAttribute(attributes[i].attr, j);
1450
            }
1451
 
890 terminx 1452
            /* HACK: changing SDL GL attribs only works before surface creation,
1453
               so we have to create a new surface in a different format first
1454
               to force the surface we WANT to be recreated instead of reused. */
4432 terminx 1455
# if SDL_MAJOR_VERSION == 1
4090 hendricks2 1456
            if (vsync_render != ovsync)
890 terminx 1457
            {
1458
                if (sdl_surface)
1459
                {
1460
                    SDL_FreeSurface(sdl_surface);
891 terminx 1461
                    sdl_surface = SDL_SetVideoMode(1, 1, 8, SDL_NOFRAME | SURFACE_FLAGS | ((fs&1)?SDL_FULLSCREEN:0));
890 terminx 1462
                    SDL_FreeSurface(sdl_surface);
1463
                }
4090 hendricks2 1464
                ovsync = vsync_render;
890 terminx 1465
            }
2014 helixhorne 1466
# endif
2777 helixhorne 1467
 
1468
# if SDL_MAJOR_VERSION==1
109 terminx 1469
            sdl_surface = SDL_SetVideoMode(x, y, c, SDL_OPENGL | ((fs&1)?SDL_FULLSCREEN:0));
342 terminx 1470
            if (!sdl_surface)
1471
            {
1472
                if (multisamplecheck)
1473
                {
109 terminx 1474
                    initprintf("Multisample mode not possible. Retrying without multisampling.\n");
1475
                    glmultisample = 0;
1476
                    continue;
1477
                }
1478
                initprintf("Unable to set video mode!\n");
1479
                return -1;
1480
            }
2777 helixhorne 1481
# else
4327 terminx 1482
            sdl_window = SDL_CreateWindow("", windowpos ? windowx : SDL_WINDOWPOS_CENTERED ,windowpos ? windowy : SDL_WINDOWPOS_CENTERED,
4089 hendricks2 1483
                                          x,y, ((fs&1)?SDL_WINDOW_FULLSCREEN:0) | SDL_WINDOW_OPENGL);
1484
            if (!sdl_window)
1485
            {
1486
                initprintf("Unable to set video mode: SDL_CreateWindow failed: %s\n",
1487
                           SDL_GetError());
1488
                return -1;
1489
            }
2777 helixhorne 1490
 
4089 hendricks2 1491
            sdl_context = SDL_GL_CreateContext(sdl_window);
1492
            if (!sdl_context)
1493
            {
1494
                initprintf("Unable to set video mode: SDL_GL_CreateContext failed: %s\n",
1495
                           SDL_GetError());
1496
                destroy_window_resources();
2777 helixhorne 1497
                return -1;
4089 hendricks2 1498
            }
4090 hendricks2 1499
            SDL_GL_SetSwapInterval(vsync_render);
2777 helixhorne 1500
#endif
4089 hendricks2 1501
 
1502
#ifdef _WIN32
1503
            loadglextensions();
1504
#endif
342 terminx 1505
        }
1506
        while (multisamplecheck--);
1507
    }
1508
    else
2014 helixhorne 1509
#endif  // defined USE_OPENGL
109 terminx 1510
    {
1511
        initprintf("Setting video mode %dx%d (%d-bpp %s)\n",
4432 terminx 1512
            x, y, c, ((fs&1) ? "fullscreen" : "windowed"));
2777 helixhorne 1513
#if SDL_MAJOR_VERSION==1
4080 hendricks2 1514
        // We convert paletted contents to non-paletted
1515
        sdl_surface = SDL_SetVideoMode(x, y, 0, SURFACE_FLAGS | ((fs&1)?SDL_FULLSCREEN:0));
342 terminx 1516
        if (!sdl_surface)
1517
        {
109 terminx 1518
            initprintf("Unable to set video mode!\n");
1519
            return -1;
1520
        }
4080 hendricks2 1521
        sdl_buffersurface = SDL_CreateRGBSurface(SURFACE_FLAGS, x, y, c, 0, 0, 0, 0);
1522
        if (!sdl_buffersurface)
1523
        {
1524
            initprintf("Unable to set video mode: SDL_CreateRGBSurface failed: %s\n",
4432 terminx 1525
                SDL_GetError());
4080 hendricks2 1526
            return -1;
1527
        }
2777 helixhorne 1528
#else
1529
 
4432 terminx 1530
#define SDL2_VIDEO_ERR(XX) { initprintf("Unable to set video mode: " XX " failed: %s\n", SDL_GetError()); destroy_window_resources(); return -1; }
1531
#define SDL2_VIDEO_FALLBACK(XX) { initprintf("Falling back to SDL_GetWindowSurface: " XX " failed: %s\n", SDL_GetError()); }
1532
#define SDL2_RENDERER_DESTROY(XX) SDL_DestroyRenderer(XX), XX = NULL
1533
 
2777 helixhorne 1534
        // init
4432 terminx 1535
        sdl_window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
1536
            x, y, ((fs&1) ? SDL_WINDOW_FULLSCREEN : 0));
4089 hendricks2 1537
        if (!sdl_window)
4432 terminx 1538
            SDL2_VIDEO_ERR("SDL_CreateWindow");
2777 helixhorne 1539
 
4253 hendricks2 1540
        sdl_renderer = SDL_CreateRenderer(sdl_window, -1, 0);
1541
        if (!sdl_renderer)
4432 terminx 1542
            SDL2_VIDEO_FALLBACK("SDL_CreateRenderer")
4253 hendricks2 1543
        else
1544
        {
4271 hendricks2 1545
            SDL_RendererInfo sdl_rendererinfo;
1546
            SDL_GetRendererInfo(sdl_renderer, &sdl_rendererinfo);
1547
            if (sdl_rendererinfo.flags & SDL_RENDERER_SOFTWARE) // this would be useless
4432 terminx 1548
                SDL2_RENDERER_DESTROY(sdl_renderer);
4271 hendricks2 1549
            else
1550
            {
1551
                sdl_texture = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_ARGB8888,
4432 terminx 1552
                    SDL_TEXTUREACCESS_STATIC, x, y);
4271 hendricks2 1553
                if (!sdl_texture)
1554
                {
4432 terminx 1555
                    SDL2_VIDEO_FALLBACK("SDL_CreateTexture");
1556
                    SDL2_RENDERER_DESTROY(sdl_renderer);
4271 hendricks2 1557
                }
1558
            }
2777 helixhorne 1559
 
4432 terminx 1560
            if (sdl_texture)
4253 hendricks2 1561
            {
4432 terminx 1562
                sdl_surface = SDL_CreateRGBSurface(0, x, y, 32, 0, 0, 0, 0);
1563
 
1564
                if (!sdl_surface)
1565
                {
1566
                    SDL2_VIDEO_FALLBACK("SDL_CreateRGBSurface");
1567
                    SDL_DestroyTexture(sdl_texture);
1568
                    sdl_texture = NULL;
1569
                    SDL2_RENDERER_DESTROY(sdl_renderer);
1570
                }
4253 hendricks2 1571
            }
1572
        }
1573
 
1574
        if (!sdl_surface)
1575
        {
1576
            sdl_surface = SDL_GetWindowSurface(sdl_window);
1577
            if (!sdl_surface)
4432 terminx 1578
                SDL2_VIDEO_ERR("SDL_GetWindowSurface");
4253 hendricks2 1579
        }
1580
 
4082 hendricks2 1581
        sdl_buffersurface = SDL_CreateRGBSurface(0, x, y, c, 0, 0, 0, 0);
4432 terminx 1582
 
4082 hendricks2 1583
        if (!sdl_buffersurface)
4432 terminx 1584
            SDL2_VIDEO_ERR("SDL_CreateRGBSurface");
4082 hendricks2 1585
 
2777 helixhorne 1586
        if (!sdl_palptr)
1587
            sdl_palptr = SDL_AllocPalette(256);
1588
 
4080 hendricks2 1589
        if (SDL_SetSurfacePalette(sdl_buffersurface, sdl_palptr) < 0)
2777 helixhorne 1590
            initprintf("SDL_SetSurfacePalette failed: %s\n", SDL_GetError());
4432 terminx 1591
 
1592
#undef SDL2_VIDEO_ERR
1593
#undef SDL2_VIDEO_FALLBACK
1594
#undef SDL2_RENDERER_DESTROY
1595
 
2777 helixhorne 1596
#endif
109 terminx 1597
    }
5 Plagman 1598
 
1599
#if 0
109 terminx 1600
    {
1601
        char flags[512] = "";
2253 helixhorne 1602
# define FLAG(x,y) if ((sdl_surface->flags & x) == x) { strcat(flags, y); strcat(flags, " "); }
109 terminx 1603
        FLAG(SDL_HWSURFACE, "HWSURFACE") else
1604
            FLAG(SDL_SWSURFACE, "SWSURFACE")
1605
            FLAG(SDL_ASYNCBLIT, "ASYNCBLIT")
1606
            FLAG(SDL_ANYFORMAT, "ANYFORMAT")
1607
            FLAG(SDL_HWPALETTE, "HWPALETTE")
1608
            FLAG(SDL_DOUBLEBUF, "DOUBLEBUF")
1609
            FLAG(SDL_FULLSCREEN, "FULLSCREEN")
1610
            FLAG(SDL_OPENGL, "OPENGL")
1611
            FLAG(SDL_OPENGLBLIT, "OPENGLBLIT")
1612
            FLAG(SDL_RESIZABLE, "RESIZABLE")
1613
            FLAG(SDL_HWACCEL, "HWACCEL")
1614
            FLAG(SDL_SRCCOLORKEY, "SRCCOLORKEY")
1615
            FLAG(SDL_RLEACCEL, "RLEACCEL")
1616
            FLAG(SDL_SRCALPHA, "SRCALPHA")
1617
            FLAG(SDL_PREALLOC, "PREALLOC")
2253 helixhorne 1618
# undef FLAG
109 terminx 1619
            initprintf("SDL Surface flags: %s\n", flags);
1620
    }
5 Plagman 1621
#endif
1622
 
109 terminx 1623
    {
1624
        //static char t[384];
1625
        //sprintf(t, "%s (%dx%d %s)", apptitle, x, y, ((fs) ? "fullscreen" : "windowed"));
2777 helixhorne 1626
#if SDL_MAJOR_VERSION == 1
109 terminx 1627
        SDL_WM_SetCaption(apptitle, 0);
4432 terminx 1628
 
1629
        if (appicon)
1630
            SDL_WM_SetIcon(appicon, 0);
2777 helixhorne 1631
#else
1632
        SDL_SetWindowTitle(sdl_window, apptitle);
5 Plagman 1633
 
4432 terminx 1634
        if (appicon)
1635
            SDL_SetWindowIcon(sdl_window, appicon);
4110 terminx 1636
#endif
1637
    }
1638
 
5 Plagman 1639
#ifdef USE_OPENGL
342 terminx 1640
    if (c > 8)
1641
    {
248 terminx 1642
        char *p,*p2,*p3;
5 Plagman 1643
 
109 terminx 1644
        polymost_glreset();
5 Plagman 1645
 
109 terminx 1646
        bglEnable(GL_TEXTURE_2D);
1647
        bglShadeModel(GL_SMOOTH); //GL_FLAT
1648
        bglClearColor(0,0,0,0.5); //Black Background
1649
        bglHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); //Use FASTEST for ortho!
1650
        bglHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
1651
        bglDisable(GL_DITHER);
1652
 
248 terminx 1653
        glinfo.vendor     = (const char *)bglGetString(GL_VENDOR);
1654
        glinfo.renderer   = (const char *)bglGetString(GL_RENDERER);
1655
        glinfo.version    = (const char *)bglGetString(GL_VERSION);
1656
        glinfo.extensions = (const char *)bglGetString(GL_EXTENSIONS);
109 terminx 1657
 
2253 helixhorne 1658
# ifdef POLYMER
1762 terminx 1659
        if (!Bstrcmp(glinfo.vendor,"ATI Technologies Inc."))
1660
        {
1445 plagman 1661
            pr_ati_fboworkaround = 1;
1662
            initprintf("Enabling ATI FBO color attachment workaround.\n");
1446 plagman 1663
 
1762 terminx 1664
            if (Bstrstr(glinfo.renderer,"Radeon X1"))
1665
            {
1446 plagman 1666
                pr_ati_nodepthoffset = 1;
1667
                initprintf("Enabling ATI R520 polygon offset workaround.\n");
1762 terminx 1668
            }
1669
            else
1446 plagman 1670
                pr_ati_nodepthoffset = 0;
2253 helixhorne 1671
#  ifdef __APPLE__
1625 terminx 1672
            //See bug description at http://lists.apple.com/archives/mac-opengl/2005/Oct/msg00169.html
1762 terminx 1673
            if (!Bstrncmp(glinfo.renderer,"ATI Radeon 9600", 15))
1674
            {
1593 terminx 1675
                pr_ati_textureformat_one = 1;
1676
                initprintf("Enabling ATI Radeon 9600 texture format workaround.\n");
1762 terminx 1677
            }
1678
            else
1593 terminx 1679
                pr_ati_textureformat_one = 0;
2253 helixhorne 1680
#  endif
1762 terminx 1681
        }
1682
        else
1446 plagman 1683
            pr_ati_fboworkaround = 0;
2253 helixhorne 1684
# endif  // defined POLYMER
1445 plagman 1685
 
109 terminx 1686
        glinfo.maxanisotropy = 1.0;
1687
        glinfo.bgra = 0;
1688
        glinfo.texcompr = 0;
1689
 
1690
        // process the extensions string and flag stuff we recognize
1691
        p = Bstrdup(glinfo.extensions);
1692
        p3 = p;
1762 terminx 1693
        while ((p2 = Bstrtoken(p3==p?p:NULL, " ", (char **)&p3, 1)) != NULL)
342 terminx 1694
        {
1695
            if (!Bstrcmp(p2, "GL_EXT_texture_filter_anisotropic"))
1696
            {
109 terminx 1697
                // supports anisotropy. get the maximum anisotropy level
1698
                bglGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glinfo.maxanisotropy);
342 terminx 1699
            }
1700
            else if (!Bstrcmp(p2, "GL_EXT_texture_edge_clamp") ||
1701
                     !Bstrcmp(p2, "GL_SGIS_texture_edge_clamp"))
1702
            {
109 terminx 1703
                // supports GL_CLAMP_TO_EDGE or GL_CLAMP_TO_EDGE_SGIS
1704
                glinfo.clamptoedge = 1;
342 terminx 1705
            }
1706
            else if (!Bstrcmp(p2, "GL_EXT_bgra"))
1707
            {
109 terminx 1708
                // support bgra textures
1709
                glinfo.bgra = 1;
342 terminx 1710
            }
1857 terminx 1711
            else if (!Bstrcmp(p2, "GL_ARB_texture_compression") && Bstrcmp(glinfo.vendor,"ATI Technologies Inc."))
342 terminx 1712
            {
109 terminx 1713
                // support texture compression
1714
                glinfo.texcompr = 1;
342 terminx 1715
            }
1716
            else if (!Bstrcmp(p2, "GL_ARB_texture_non_power_of_two"))
1717
            {
109 terminx 1718
                // support non-power-of-two texture sizes
1719
                glinfo.texnpot = 1;
342 terminx 1720
            }
1721
            else if (!Bstrcmp(p2, "WGL_3DFX_gamma_control"))
1722
            {
109 terminx 1723
                // 3dfx cards have issues with fog
1724
                nofog = 1;
1725
                if (!(warnonce&1)) initprintf("3dfx card detected: OpenGL fog disabled\n");
1726
                warnonce |= 1;
342 terminx 1727
            }
1728
            else if (!Bstrcmp(p2, "GL_ARB_multisample"))
1729
            {
109 terminx 1730
                // supports multisampling
1731
                glinfo.multisample = 1;
342 terminx 1732
            }
1733
            else if (!Bstrcmp(p2, "GL_NV_multisample_filter_hint"))
1734
            {
109 terminx 1735
                // supports nvidia's multisample hint extension
1736
                glinfo.nvmultisamplehint = 1;
1737
            }
446 Plagman 1738
            else if (!Bstrcmp((char *)p2, "GL_ARB_fragment_program"))
1739
            {
1740
                glinfo.arbfp = 1;
1741
            }
1742
            else if (!Bstrcmp((char *)p2, "GL_ARB_depth_texture"))
1743
            {
1744
                glinfo.depthtex = 1;
1745
            }
1746
            else if (!Bstrcmp((char *)p2, "GL_ARB_shadow"))
1747
            {
1748
                glinfo.shadow = 1;
1749
            }
1750
            else if (!Bstrcmp((char *)p2, "GL_EXT_framebuffer_object"))
1751
            {
1752
                glinfo.fbos = 1;
1753
            }
1754
            else if (!Bstrcmp((char *)p2, "GL_NV_texture_rectangle") ||
1755
                     !Bstrcmp((char *)p2, "GL_EXT_texture_rectangle"))
1756
            {
1757
                glinfo.rect = 1;
1758
            }
459 Plagman 1759
            else if (!Bstrcmp((char *)p2, "GL_ARB_multitexture"))
1760
            {
1761
                glinfo.multitex = 1;
1762
            }
1763
            else if (!Bstrcmp((char *)p2, "GL_ARB_texture_env_combine"))
1764
            {
1765
                glinfo.envcombine = 1;
1766
            }
519 Plagman 1767
            else if (!Bstrcmp((char *)p2, "GL_ARB_vertex_buffer_object"))
1768
            {
1769
                glinfo.vbos = 1;
1770
            }
1222 plagman 1771
            else if (!Bstrcmp((char *)p2, "GL_EXT_gpu_shader4"))
1772
            {
1773
                glinfo.sm4 = 1;
1774
            }
1506 plagman 1775
            else if (!Bstrcmp((char *)p2, "GL_ARB_occlusion_query"))
1776
            {
1777
                glinfo.occlusionqueries = 1;
1778
            }
1779
            else if (!Bstrcmp((char *)p2, "GL_ARB_shader_objects"))
1780
            {
1781
                glinfo.glsl = 1;
1782
            }
2056 plagman 1783
            else if (!Bstrcmp((char *)p2, "GL_ARB_debug_output"))
1784
            {
1785
                glinfo.debugoutput = 1;
1786
            }
109 terminx 1787
        }
1788
        Bfree(p);
627 terminx 1789
 
1790
        if (!glinfo.dumped)
1791
        {
1205 terminx 1792
            int32_t oldbpp = bpp;
748 terminx 1793
            bpp = 32;
627 terminx 1794
            osdcmd_glinfo(NULL);
750 plagman 1795
            glinfo.dumped = 1;
748 terminx 1796
            bpp = oldbpp;
627 terminx 1797
        }
109 terminx 1798
    }
2253 helixhorne 1799
#endif  // defined USE_OPENGL
5 Plagman 1800
 
109 terminx 1801
    xres = x;
1802
    yres = y;
1803
    bpp = c;
1804
    fullscreen = fs;
1805
    //bytesperline = sdl_surface->pitch;
1806
    numpages = c>8?2:1;
1807
    frameplace = 0;
1808
    lockcount = 0;
1809
    modechange=1;
1810
    videomodereset = 0;
1811
    OSD_ResizeDisplay(xres,yres);
5 Plagman 1812
 
109 terminx 1813
    // save the current system gamma to determine if gamma is available
342 terminx 1814
    if (!gammabrightness)
1815
    {
870 terminx 1816
//        float f = 1.0 + ((float)curbrightness / 10.0);
2777 helixhorne 1817
#if SDL_MAJOR_VERSION==1
109 terminx 1818
        if (SDL_GetGammaRamp(sysgamma[0], sysgamma[1], sysgamma[2]) >= 0)
1819
            gammabrightness = 1;
2777 helixhorne 1820
#else
1821
        if (SDL_GetWindowGammaRamp(sdl_window, sysgamma[0], sysgamma[1], sysgamma[2]) == 0)
1822
            gammabrightness = 1;
1823
#endif
109 terminx 1824
        // see if gamma really is working by trying to set the brightness
870 terminx 1825
        if (gammabrightness && setgamma() < 0)
109 terminx 1826
            gammabrightness = 0;        // nope
1827
    }
1828
 
1829
    // setpalettefade will set the palette according to whether gamma worked
1830
    setpalettefade(palfadergb.r, palfadergb.g, palfadergb.b, palfadedelta);
1831
 
1832
    //if (c==8) setpalette(0,256,0);
1833
 
1834
    if (regrab) grabmouse(1);
1835
 
1836
    return 0;
5 Plagman 1837
}
1838
 
1839
 
1840
//
1841
// resetvideomode() -- resets the video system
1842
//
1843
void resetvideomode(void)
1844
{
109 terminx 1845
    videomodereset = 1;
1846
    modeschecked = 0;
5 Plagman 1847
}
1848
 
1849
 
1850
//
1851
// begindrawing() -- locks the framebuffer for drawing
1852
//
1853
void begindrawing(void)
1854
{
342 terminx 1855
    if (bpp > 8)
1856
    {
109 terminx 1857
        if (offscreenrendering) return;
1858
        frameplace = 0;
1859
        bytesperline = 0;
1860
        modechange = 0;
1861
        return;
1862
    }
5 Plagman 1863
 
109 terminx 1864
    // lock the frame
1865
    if (lockcount++ > 0)
1866
        return;
5 Plagman 1867
 
109 terminx 1868
    if (offscreenrendering) return;
5 Plagman 1869
 
4080 hendricks2 1870
    if (SDL_MUSTLOCK(sdl_buffersurface)) SDL_LockSurface(sdl_buffersurface);
1871
    frameplace = (intptr_t)sdl_buffersurface->pixels;
109 terminx 1872
 
4080 hendricks2 1873
    if (sdl_buffersurface->pitch != bytesperline || modechange)
342 terminx 1874
    {
4080 hendricks2 1875
        bytesperline = sdl_buffersurface->pitch;
109 terminx 1876
 
3291 helixhorne 1877
        calc_ylookup(bytesperline, ydim);
1878
 
109 terminx 1879
        modechange=0;
1880
    }
5 Plagman 1881
}
1882
 
1883
 
1884
//
1885
// enddrawing() -- unlocks the framebuffer
1886
//
1887
void enddrawing(void)
1888
{
342 terminx 1889
    if (bpp > 8)
1890
    {
109 terminx 1891
        if (!offscreenrendering) frameplace = 0;
1892
        return;
1893
    }
5 Plagman 1894
 
109 terminx 1895
    if (!frameplace) return;
584 terminx 1896
    if (lockcount > 1) { lockcount--; return; }
109 terminx 1897
    if (!offscreenrendering) frameplace = 0;
1898
    if (lockcount == 0) return;
1899
    lockcount = 0;
5 Plagman 1900
 
109 terminx 1901
    if (offscreenrendering) return;
5 Plagman 1902
 
4080 hendricks2 1903
    if (SDL_MUSTLOCK(sdl_buffersurface)) SDL_UnlockSurface(sdl_buffersurface);
5 Plagman 1904
}
1905
 
1906
//
1907
// showframe() -- update the display
1908
//
1205 terminx 1909
void showframe(int32_t w)
5 Plagman 1910
{
1205 terminx 1911
//    int32_t i,j;
655 terminx 1912
    UNREFERENCED_PARAMETER(w);
5 Plagman 1913
 
1914
#ifdef USE_OPENGL
342 terminx 1915
    if (bpp > 8)
1916
    {
1917
        if (palfadedelta)
3263 helixhorne 1918
            fullscreen_tint_gl(palfadergb.r, palfadergb.g, palfadergb.b, palfadedelta);
5 Plagman 1919
 
4432 terminx 1920
#if SDL_MAJOR_VERSION==1
109 terminx 1921
        SDL_GL_SwapBuffers();
4432 terminx 1922
#else
4082 hendricks2 1923
        SDL_GL_SwapWindow(sdl_window);
4432 terminx 1924
#endif
109 terminx 1925
        return;
1926
    }
5 Plagman 1927
#endif
1928
 
109 terminx 1929
    if (offscreenrendering) return;
5 Plagman 1930
 
342 terminx 1931
    if (lockcount)
1932
    {
584 terminx 1933
        printf("Frame still locked %d times when showframe() called.\n", lockcount);
109 terminx 1934
        while (lockcount) enddrawing();
1935
    }
1936
 
4432 terminx 1937
#if SDL_MAJOR_VERSION==1
2221 helixhorne 1938
    // deferred palette updating
1939
    if (needpalupdate)
1940
    {
4080 hendricks2 1941
        SDL_SetColors(sdl_buffersurface, sdlayer_pal, 0, 256);
2221 helixhorne 1942
        // same as:
4080 hendricks2 1943
        //SDL_SetPalette(sdl_buffersurface, SDL_LOGPAL|SDL_PHYSPAL, pal, 0, 256);
4432 terminx 1944
        needpalupdate = 0;
1945
    }
1946
 
1947
    SDL_BlitSurface(sdl_buffersurface, NULL, sdl_surface, NULL);
1948
 
1949
    SDL_Flip(sdl_surface);
2777 helixhorne 1950
#else
4432 terminx 1951
    // deferred palette updating
1952
    if (needpalupdate)
1953
    {
2777 helixhorne 1954
        if (SDL_SetPaletteColors(sdl_palptr, sdlayer_pal, 0, 256) < 0)
1955
            initprintf("SDL_SetPaletteColors failed: %s\n", SDL_GetError());
2221 helixhorne 1956
        needpalupdate = 0;
1957
    }
1958
 
4082 hendricks2 1959
    SDL_BlitSurface(sdl_buffersurface, NULL, sdl_surface, NULL);
1960
 
4253 hendricks2 1961
    if (sdl_renderer && sdl_texture)
4089 hendricks2 1962
    {
4253 hendricks2 1963
        SDL_UpdateTexture(sdl_texture, NULL, sdl_surface->pixels, sdl_surface->pitch);
1964
 
1965
        SDL_RenderClear(sdl_renderer);
1966
        SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL);
1967
        SDL_RenderPresent(sdl_renderer);
1968
    }
1969
    else if (SDL_UpdateWindowSurface(sdl_window))
1970
    {
4089 hendricks2 1971
        // If a fullscreen X11 window is minimized then this may be required.
1972
        // FIXME: What to do if this fails...
1973
        sdl_surface = SDL_GetWindowSurface(sdl_window);
1974
        SDL_UpdateWindowSurface(sdl_window);
1975
    }
2777 helixhorne 1976
#endif
5 Plagman 1977
}
1978
 
1979
//
1980
// setpalette() -- set palette values
1981
//
1205 terminx 1982
int32_t setpalette(int32_t start, int32_t num)
5 Plagman 1983
{
1205 terminx 1984
    int32_t i,n;
5 Plagman 1985
 
109 terminx 1986
    if (bpp > 8) return 0;      // no palette in opengl
5 Plagman 1987
 
2221 helixhorne 1988
    Bmemcpy(sdlayer_pal, curpalettefaded, 256*4);
5 Plagman 1989
 
342 terminx 1990
    for (i=start, n=num; n>0; i++, n--)
4074 hendricks2 1991
        curpalettefaded[i].f =
1992
#if SDL_MAJOR_VERSION==1
1993
        sdlayer_pal[i].unused
1994
#else
1995
        sdlayer_pal[i].a
1996
#endif
1997
         = 0;
109 terminx 1998
 
2221 helixhorne 1999
    needpalupdate = 1;
1762 terminx 2000
 
2221 helixhorne 2001
    return 0;
5 Plagman 2002
}
2003
 
2004
//
2005
// getpalette() -- get palette values
2006
//
2221 helixhorne 2007
#if 0
1205 terminx 2008
int32_t getpalette(int32_t start, int32_t num, char *dapal)
5 Plagman 2009
{
1625 terminx 2010
    int32_t i;
2011
    SDL_Palette *pal;
5 Plagman 2012
 
1625 terminx 2013
    // we shouldn't need to lock the surface to get the palette
2014
    pal = sdl_surface->format->palette;
5 Plagman 2015
 
1625 terminx 2016
    for (i=num; i>0; i--, start++) {
2017
        dapal[0] = pal->colors[start].b >> 2;
2018
        dapal[1] = pal->colors[start].g >> 2;
2019
        dapal[2] = pal->colors[start].r >> 2;
2020
        dapal += 4;
2021
    }
5 Plagman 2022
 
1625 terminx 2023
    return 1;
5 Plagman 2024
}
2221 helixhorne 2025
#endif
5 Plagman 2026
 
2027
//
2028
// setgamma
2029
//
1205 terminx 2030
int32_t setgamma(void)
5 Plagman 2031
{
4440 terminx 2032
        //return 0;
2033
 
1205 terminx 2034
    int32_t i;
2035
    uint16_t gammaTable[768];
872 terminx 2036
    float gamma = max(0.1f,min(4.f,vid_gamma));
2037
    float contrast = max(0.1f,min(3.f,vid_contrast));
2038
    float bright = max(-0.8f,min(0.8f,vid_brightness));
870 terminx 2039
 
872 terminx 2040
    double invgamma = 1 / gamma;
2041
    double norm = pow(255., invgamma - 1);
2042
 
1762 terminx 2043
    if (novideo) return 0;
2044
 
2222 helixhorne 2045
    if (lastvidgcb[0]==gamma && lastvidgcb[1]==contrast && lastvidgcb[2]==bright)
2046
        return 0;
2047
 
872 terminx 2048
    // This formula is taken from Doomsday
2049
 
2050
    for (i = 0; i < 256; i++)
2051
    {
2052
        double val = i * contrast - (contrast - 1) * 127;
2053
        if (gamma != 1) val = pow(val, invgamma) / norm;
2054
        val += bright * 128;
2055
 
1205 terminx 2056
        gammaTable[i] = gammaTable[i + 256] = gammaTable[i + 512] = (uint16_t)max(0.f,(double)min(0xffff,val*256));
872 terminx 2057
    }
4432 terminx 2058
 
2777 helixhorne 2059
#if SDL_MAJOR_VERSION==1
2222 helixhorne 2060
    i = SDL_SetGammaRamp(&gammaTable[0],&gammaTable[256],&gammaTable[512]);
4432 terminx 2061
    if (i != -1)
2777 helixhorne 2062
#else
2063
    i = INT32_MIN;
2064
    if (sdl_window)
2065
        i = SDL_SetWindowGammaRamp(
2066
            sdl_window,&gammaTable[0],&gammaTable[256],&gammaTable[512]);
2222 helixhorne 2067
 
2777 helixhorne 2068
    if (i < 0)
2222 helixhorne 2069
    {
4440 terminx 2070
#ifndef __ANDROID__ //Don't do this check, it is really supported, TODO
2777 helixhorne 2071
        if (i != INT32_MIN)
2072
            initprintf("Unable to set gamma: SDL_SetWindowGammaRamp failed: %s\n", SDL_GetError());
4440 terminx 2073
#endif
2777 helixhorne 2074
    }
2075
    else
2076
#endif
2077
    {
2222 helixhorne 2078
        lastvidgcb[0] = gamma;
2079
        lastvidgcb[1] = contrast;
2080
        lastvidgcb[2] = bright;
2081
    }
2082
 
2083
    return i;
5 Plagman 2084
}
2085
 
3086 terminx 2086
#if !defined(__APPLE__) && !defined(__ANDROID__)
5 Plagman 2087
extern struct sdlappicon sdlappicon;
1762 terminx 2088
static SDL_Surface *loadappicon(void)
5 Plagman 2089
{
109 terminx 2090
    SDL_Surface *surf;
5 Plagman 2091
 
1762 terminx 2092
    surf = SDL_CreateRGBSurfaceFrom((void *)sdlappicon.pixels,
109 terminx 2093
                                    sdlappicon.width, sdlappicon.height, 32, sdlappicon.width*4,
2094
                                    0xffl,0xff00l,0xff0000l,0xff000000l);
5 Plagman 2095
 
109 terminx 2096
    return surf;
5 Plagman 2097
}
2098
#endif
2099
 
2100
//
2101
//
2102
// ---------------------------------------
2103
//
2104
// Miscellany
2105
//
2106
// ---------------------------------------
2107
//
109 terminx 2108
//
5 Plagman 2109
 
3022 helixhorne 2110
int32_t handleevents_peekkeys(void)
2111
{
2112
    SDL_PumpEvents();
4074 hendricks2 2113
#if SDL_MAJOR_VERSION==1
3022 helixhorne 2114
    return SDL_PeepEvents(NULL, 1, SDL_PEEKEVENT, SDL_EVENTMASK(SDL_KEYDOWN));
2115
#else
4074 hendricks2 2116
    return SDL_PeepEvents(NULL, 1, SDL_PEEKEVENT, SDL_KEYDOWN, SDL_KEYDOWN);
3022 helixhorne 2117
#endif
2118
}
5 Plagman 2119
 
3022 helixhorne 2120
 
5 Plagman 2121
//
2122
// handleevents() -- process the SDL message queue
2123
//   returns !0 if there was an important event worth checking (like quitting)
2124
//
1593 terminx 2125
 
1205 terminx 2126
int32_t handleevents(void)
5 Plagman 2127
{
1205 terminx 2128
    int32_t code, rv=0, j;
109 terminx 2129
    SDL_Event ev;
5 Plagman 2130
 
4200 hendricks2 2131
    if (inputchecked)
2132
    {
2133
        if (moustat)
2134
        {
2135
            if (mousepresscallback)
2136
            {
2137
                if (mouseb & 16)
2138
                    mousepresscallback(5, 0);
2139
                if (mouseb & 32)
2140
                    mousepresscallback(6, 0);
2141
            }
2142
            mouseb &= ~(16|32);
2143
        }
2144
    }
2145
 
342 terminx 2146
    while (SDL_PollEvent(&ev))
2147
    {
2148
        switch (ev.type)
2149
        {
4432 terminx 2150
#if SDL_MAJOR_VERSION==2
1109 terminx 2151
        case SDL_TEXTINPUT:
2152
            j = 0;
2153
            do
2154
            {
2155
                code = ev.text.text[j];
2156
 
4116 helixhorne 2157
                if (code != scantoasc[OSD_OSDKey()] && !keyascfifo_isfull())
1109 terminx 2158
                {
2159
                    if (OSD_HandleChar(code))
4116 helixhorne 2160
                        keyascfifo_insert(code);
1109 terminx 2161
                }
2162
            }
2163
            while (j < SDL_TEXTINPUTEVENT_TEXT_SIZE && ev.text.text[++j]);
2164
            break;
2165
 
109 terminx 2166
        case SDL_KEYDOWN:
2167
        case SDL_KEYUP:
1109 terminx 2168
            code = keytranslation[ev.key.keysym.scancode];
1844 terminx 2169
 
4397 helixhorne 2170
            // XXX: see osd.c, OSD_HandleChar(), there are more...
4163 helixhorne 2171
            if (ev.key.type == SDL_KEYDOWN && !keyascfifo_isfull() &&
1857 terminx 2172
                (ev.key.keysym.scancode == SDL_SCANCODE_RETURN ||
4163 helixhorne 2173
                 ev.key.keysym.scancode == SDL_SCANCODE_KP_ENTER ||
2174
                 ev.key.keysym.scancode == SDL_SCANCODE_ESCAPE ||
2175
                 ev.key.keysym.scancode == SDL_SCANCODE_BACKSPACE ||
2176
                 ev.key.keysym.scancode == SDL_SCANCODE_TAB ||
2177
                 (ev.key.keysym.mod==KMOD_LCTRL &&
2178
                  (ev.key.keysym.scancode == SDL_SCANCODE_F ||
4397 helixhorne 2179
                   ev.key.keysym.scancode == SDL_SCANCODE_G ||
2180
                   ev.key.keysym.scancode == SDL_SCANCODE_K ||
2181
                   ev.key.keysym.scancode == SDL_SCANCODE_U))))
1844 terminx 2182
            {
4074 hendricks2 2183
                char keyvalue;
2184
                switch (ev.key.keysym.scancode)
1844 terminx 2185
                {
4083 hendricks2 2186
                    case SDL_SCANCODE_RETURN: case SDL_SCANCODE_KP_ENTER: keyvalue = '\r'; break;
4117 helixhorne 2187
                    case SDL_SCANCODE_ESCAPE: keyvalue = 27; break;
4074 hendricks2 2188
                    case SDL_SCANCODE_BACKSPACE: keyvalue = '\b'; break;
2189
                    case SDL_SCANCODE_TAB: keyvalue = '\t'; break;
4163 helixhorne 2190
                    case SDL_SCANCODE_F: keyvalue = 6; break;
2191
                    case SDL_SCANCODE_G: keyvalue = 7; break;
4397 helixhorne 2192
                    case SDL_SCANCODE_K: keyvalue = 11; break;
2193
                    case SDL_SCANCODE_U: keyvalue = 21; break;
4074 hendricks2 2194
                    default: keyvalue = 0; break;
2195
                }
2196
                if (OSD_HandleChar(keyvalue))
4116 helixhorne 2197
                    keyascfifo_insert(keyvalue);
1844 terminx 2198
            }
2199
 
4314 hendricks2 2200
           // initprintf("SDL2: got key %d, %d, %u\n", ev.key.keysym.scancode, code, ev.key.type);
1109 terminx 2201
 
2202
            // hook in the osd
4269 hendricks2 2203
            if ((j = OSD_HandleScanCode(code, (ev.key.type == SDL_KEYDOWN))) <= 0)
2204
            {
2205
                if (j == -1) // osdkey
2206
                    for (j = 0; j < KEYSTATUSSIZ; ++j)
2207
                        if (GetKey(j))
2208
                        {
2209
                            SetKey(j, 0);
2210
                            if (keypresscallback)
2211
                                keypresscallback(j, 0);
2212
                        }
1109 terminx 2213
                break;
4269 hendricks2 2214
            }
1109 terminx 2215
 
2216
            if (ev.key.type == SDL_KEYDOWN)
2217
            {
4269 hendricks2 2218
                if (!GetKey(code))
1109 terminx 2219
                {
2220
                    SetKey(code, 1);
2221
                    if (keypresscallback)
1114 terminx 2222
                        keypresscallback(code, 1);
1109 terminx 2223
                }
2224
            }
2225
            else
2226
            {
4193 helixhorne 2227
# if 1
1877 helixhorne 2228
                // The pause key generates a release event right after
4193 helixhorne 2229
                // the pressing one. As a result, it gets unseen
1877 helixhorne 2230
                // by the game most of the time.
2231
                if (code == 0x59)  // pause
2232
                    break;
2253 helixhorne 2233
# endif
1109 terminx 2234
                SetKey(code, 0);
2235
                if (keypresscallback)
1114 terminx 2236
                    keypresscallback(code, 0);
1109 terminx 2237
            }
2238
            break;
4074 hendricks2 2239
        case SDL_MOUSEWHEEL:
2240
           // initprintf("wheel y %d\n",ev.wheel.y);
2241
            if (ev.wheel.y > 0)
2242
            {
2243
                mouseb |= 16;
2244
                if (mousepresscallback)
2245
                    mousepresscallback(5, 1);
2246
            }
2247
            if (ev.wheel.y < 0)
2248
            {
2249
                mouseb |= 32;
2250
                if (mousepresscallback)
2251
                    mousepresscallback(6, 1);
2252
            }
2253
            break;
1109 terminx 2254
        case SDL_WINDOWEVENT:
2255
            switch (ev.window.event)
2256
            {
2257
            case SDL_WINDOWEVENT_FOCUS_GAINED:
2258
                appactive = 1;
1857 terminx 2259
                if (mousegrab && moustat)
4089 hendricks2 2260
                    grabmouse_low(1);
4432 terminx 2261
#ifdef _WIN32
3221 hendricks2 2262
                if (backgroundidle)
2263
                    SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
4432 terminx 2264
#endif
1109 terminx 2265
                break;
2266
            case SDL_WINDOWEVENT_FOCUS_LOST:
2267
                appactive = 0;
1857 terminx 2268
                if (mousegrab && moustat)
4089 hendricks2 2269
                    grabmouse_low(0);
4432 terminx 2270
#ifdef _WIN32
3221 hendricks2 2271
                if (backgroundidle)
2272
                    SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);
4432 terminx 2273
#endif
1109 terminx 2274
                break;
4327 terminx 2275
            case SDL_WINDOWEVENT_MOVED:
2276
                if (windowpos)
2277
                {
2278
                    windowx = ev.window.data1;
2279
                    windowy = ev.window.data2;
2280
                }
2281
                break;
1109 terminx 2282
            }
2283
            break;
2777 helixhorne 2284
// #warning Using SDL 1.3 or 2.X
4432 terminx 2285
#else  // SDL 2.0 ^^^ | vvv SDL 1.2
2777 helixhorne 2286
// #warning Using SDL 1.2
1109 terminx 2287
        case SDL_KEYDOWN:
2288
        case SDL_KEYUP:
109 terminx 2289
            code = keytranslation[ev.key.keysym.sym];
2253 helixhorne 2290
# ifdef KEY_PRINT_DEBUG
2119 helixhorne 2291
            printf("keytranslation[%d] = %s (%d)  %s\n", ev.key.keysym.sym,
2292
                   key_names[code], code, ev.key.type==SDL_KEYDOWN?"DOWN":"UP");
2253 helixhorne 2293
# endif
843 terminx 2294
            if (code != OSD_OSDKey() && ev.key.keysym.unicode != 0 && ev.key.type == SDL_KEYDOWN &&
109 terminx 2295
                    (ev.key.keysym.unicode & 0xff80) == 0 &&
4116 helixhorne 2296
                    !keyascfifo_isfull())
342 terminx 2297
            {
839 qbix79 2298
                if (OSD_HandleChar(ev.key.keysym.unicode & 0x7f))
4116 helixhorne 2299
                    keyascfifo_insert(ev.key.keysym.unicode & 0x7f);
109 terminx 2300
            }
5 Plagman 2301
 
109 terminx 2302
            // hook in the osd
1905 helixhorne 2303
//            if (ev.type==SDL_KEYDOWN)
2304
//                printf("got key SDLK %d (%s), trans 0x%x\n", ev.key.keysym.sym, SDL_GetKeyName(ev.key.keysym.sym), code);
4269 hendricks2 2305
            if ((j = OSD_HandleScanCode(code, (ev.key.type == SDL_KEYDOWN))) <= 0)
2306
            {
2307
                if (j == -1) // osdkey
2308
                    for (j = 0; j < KEYSTATUSSIZ; ++j)
2309
                        if (GetKey(j))
2310
                        {
2311
                            SetKey(j, 0);
2312
                            if (keypresscallback)
2313
                                keypresscallback(j, 0);
2314
                        }
109 terminx 2315
                break;
4269 hendricks2 2316
            }
5 Plagman 2317
 
342 terminx 2318
            if (ev.key.type == SDL_KEYDOWN)
2319
            {
4269 hendricks2 2320
                if (!GetKey(code))
342 terminx 2321
                {
109 terminx 2322
                    SetKey(code, 1);
2323
                    if (keypresscallback)
1114 terminx 2324
                        keypresscallback(code, 1);
109 terminx 2325
                }
342 terminx 2326
            }
2327
            else
2328
            {
2253 helixhorne 2329
# ifdef __linux
1877 helixhorne 2330
                if (code == 0x59)  // pause
2331
                    break;
2253 helixhorne 2332
# endif
109 terminx 2333
                SetKey(code, 0);
2334
                if (keypresscallback)
1114 terminx 2335
                    keypresscallback(code, 0);
109 terminx 2336
            }
2337
            break;
5 Plagman 2338
 
109 terminx 2339
        case SDL_ACTIVEEVENT:
342 terminx 2340
            if (ev.active.state & SDL_APPINPUTFOCUS)
2341
            {
109 terminx 2342
                appactive = ev.active.gain;
3221 hendricks2 2343
# if !defined DEBUGGINGAIDS || defined _WIN32
1857 terminx 2344
                if (mousegrab && moustat)
342 terminx 2345
                {
2346
                    if (appactive)
4089 hendricks2 2347
                        grabmouse_low(1);
342 terminx 2348
                    else
4089 hendricks2 2349
                        grabmouse_low(0);
109 terminx 2350
                }
2253 helixhorne 2351
# endif
3221 hendricks2 2352
# ifdef _WIN32
2353
                if (backgroundidle)
2354
                    SetPriorityClass(GetCurrentProcess(),
2355
                                     appactive ? NORMAL_PRIORITY_CLASS : IDLE_PRIORITY_CLASS);
2356
# endif
109 terminx 2357
                rv=-1;
2358
            }
2359
            break;
2011 helixhorne 2360
#endif  // SDL version
5 Plagman 2361
 
109 terminx 2362
        case SDL_MOUSEBUTTONDOWN:
2363
        case SDL_MOUSEBUTTONUP:
2252 helixhorne 2364
//if (ev.button.button>=0)
2365
//    initprintf("BTN %d\n", ev.button.button);
342 terminx 2366
            switch (ev.button.button)
2367
            {
1107 terminx 2368
                // some of these get reordered to match winlayer
1105 terminx 2369
            default:
1109 terminx 2370
                j = -1; break;
331 terminx 2371
            case SDL_BUTTON_LEFT:
2372
                j = 0; break;
2373
            case SDL_BUTTON_RIGHT:
2374
                j = 1; break;
2375
            case SDL_BUTTON_MIDDLE:
2376
                j = 2; break;
4190 helixhorne 2377
 
2378
#if SDL_MAJOR_VERSION==1 || !defined _WIN32
2379
            // NOTE: SDL1 does have SDL_BUTTON_X1, but that's not what is
2380
            // generated. Neither with SDL2 on Linux. (Other OSs: not tested.)
2381
            case 8:  // 8 --> 3
2382
#else
2383
            // On SDL2/Windows, everything is as it should be.
2384
            case SDL_BUTTON_X1:
2385
#endif
2252 helixhorne 2386
                j = 3; break;
4190 helixhorne 2387
 
2777 helixhorne 2388
#if SDL_MAJOR_VERSION==1
2252 helixhorne 2389
            case SDL_BUTTON_WHEELUP:  // 4
2390
            case SDL_BUTTON_WHEELDOWN:  // 5
331 terminx 2391
                j = ev.button.button; break;
2777 helixhorne 2392
#endif
4190 helixhorne 2393
 
2394
#if SDL_MAJOR_VERSION==1 || !defined _WIN32
2395
            case 9:  // 9 --> 6
2396
#else
2397
            case SDL_BUTTON_X2:
2398
#endif
2252 helixhorne 2399
                j = 6; break;
4190 helixhorne 2400
 
109 terminx 2401
            }
2402
            if (j<0) break;
5 Plagman 2403
 
342 terminx 2404
            if (ev.button.state == SDL_PRESSED)
2405
            {
109 terminx 2406
                mouseb |= (1<<j);
258 terminx 2407
            }
342 terminx 2408
            else
2409
            {
2777 helixhorne 2410
#if SDL_MAJOR_VERSION==1
1101 terminx 2411
                if (j != SDL_BUTTON_WHEELUP && j != SDL_BUTTON_WHEELDOWN)
2777 helixhorne 2412
#endif
1101 terminx 2413
                    mouseb &= ~(1<<j);
258 terminx 2414
            }
5 Plagman 2415
 
109 terminx 2416
            if (mousepresscallback)
2417
                mousepresscallback(j+1, ev.button.state == SDL_PRESSED);
2418
            break;
5 Plagman 2419
 
109 terminx 2420
        case SDL_MOUSEMOTION:
2623 helixhorne 2421
            // SDL <VER> doesn't handle relative mouse movement correctly yet as the cursor still clips to the screen edges
1844 terminx 2422
            // so, we call SDL_WarpMouse() to center the cursor and ignore the resulting motion event that occurs
2623 helixhorne 2423
            //  <VER> is 1.3 for PK, 1.2 for tueidj
2424
            if (appactive && mousegrab)
342 terminx 2425
            {
2623 helixhorne 2426
#ifdef GEKKO
2427
                // check if it's a wiimote pointer pretending to be a mouse
2428
                if (ev.motion.state & SDL_BUTTON_X2MASK)
2429
                {
2430
                    // the absolute values are used to draw the crosshair
2431
                    mouseabsx = ev.motion.x;
2432
                    mouseabsy = ev.motion.y;
2433
                    // hack: reduce the scale of the "relative" motions
2434
                    // to make it act more like a real mouse
2435
                    ev.motion.xrel /= 16;
2436
                    ev.motion.yrel /= 12;
2437
                }
2438
#endif
2439
                if (ev.motion.x != xdim>>1 || ev.motion.y != ydim>>1)
2440
                {
2441
                    mousex += ev.motion.xrel;
2442
                    mousey += ev.motion.yrel;
2718 helixhorne 2443
#if !defined DEBUGGINGAIDS || MY_DEVELOPER_ID==805120924
2777 helixhorne 2444
# if SDL_MAJOR_VERSION==1
2623 helixhorne 2445
                    SDL_WarpMouse(xdim>>1, ydim>>1);
2777 helixhorne 2446
# else
2447
                    SDL_WarpMouseInWindow(sdl_window, xdim>>1, ydim>>1);
2448
# endif
2578 plagman 2449
#endif
2623 helixhorne 2450
                }
109 terminx 2451
            }
2452
            break;
5 Plagman 2453
 
109 terminx 2454
        case SDL_JOYAXISMOTION:
2455
            if (appactive && ev.jaxis.axis < joynumaxes)
1716 plagman 2456
            {
2457
                joyaxis[ev.jaxis.axis] = ev.jaxis.value * 10000 / 32767;
2458
                if ((joyaxis[ev.jaxis.axis] < joydead[ev.jaxis.axis])
1762 terminx 2459
                        && (joyaxis[ev.jaxis.axis] > -joydead[ev.jaxis.axis]))
1716 plagman 2460
                    joyaxis[ev.jaxis.axis] = 0;
2461
                else if (joyaxis[ev.jaxis.axis] >= joysatur[ev.jaxis.axis])
2462
                    joyaxis[ev.jaxis.axis] = 10000;
2463
                else if (joyaxis[ev.jaxis.axis] <= -joysatur[ev.jaxis.axis])
2464
                    joyaxis[ev.jaxis.axis] = -10000;
2465
                else
1762 terminx 2466
                    joyaxis[ev.jaxis.axis] = joyaxis[ev.jaxis.axis] *
2467
                                             10000 / joysatur[ev.jaxis.axis];
1716 plagman 2468
            }
109 terminx 2469
            break;
5 Plagman 2470
 
342 terminx 2471
        case SDL_JOYHATMOTION:
2472
        {
1205 terminx 2473
            int32_t hatvals[16] =
584 terminx 2474
            {
2475
                -1,     // centre
2476
                0,      // up 1
2477
                9000,   // right 2
2478
                4500,   // up+right 3
2479
                18000,  // down 4
2480
                -1,     // down+up!! 5
2481
                13500,  // down+right 6
2482
                -1,     // down+right+up!! 7
2483
                27000,  // left 8
2484
                27500,  // left+up 9
2485
                -1,     // left+right!! 10
2486
                -1,     // left+right+up!! 11
2487
                22500,  // left+down 12
2488
                -1,     // left+down+up!! 13
2489
                -1,     // left+down+right!! 14
2490
                -1,     // left+down+right+up!! 15
2491
            };
331 terminx 2492
            if (appactive && ev.jhat.hat < joynumhats)
2493
                joyhat[ ev.jhat.hat ] = hatvals[ ev.jhat.value & 15 ];
2494
            break;
2495
        }
5 Plagman 2496
 
109 terminx 2497
        case SDL_JOYBUTTONDOWN:
2498
        case SDL_JOYBUTTONUP:
342 terminx 2499
            if (appactive && ev.jbutton.button < joynumbuttons)
2500
            {
109 terminx 2501
                if (ev.jbutton.state == SDL_PRESSED)
2502
                    joyb |= 1 << ev.jbutton.button;
2503
                else
2504
                    joyb &= ~(1 << ev.jbutton.button);
2505
            }
2506
            break;
5 Plagman 2507
 
109 terminx 2508
        case SDL_QUIT:
2509
            quitevent = 1;
2510
            rv=-1;
2511
            break;
5 Plagman 2512
 
109 terminx 2513
        default:
1647 terminx 2514
            //OSD_Printf("Got event (%d)\n", ev.type);
109 terminx 2515
            break;
2516
        }
2517
    }
2518
 
1644 helixhorne 2519
//        if (mousex|mousey) printf("%d,%d\n",mousex,mousey); ///
2520
 
4200 hendricks2 2521
    inputchecked = 0;