/* * Copyright (C) 2017 The Contributors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * A copy of the GNU General Public License can be found in the file * "gpl.txt" in the top directory of this repository. */ #include int32_t sdl_verbose = 0; #define ver(...) _ver(sdl_verbose, 0, __VA_ARGS__) #define ver2(...) _ver(sdl_verbose, 1, __VA_ARGS__) #define ver3(...) _ver(sdl_verbose, 2, __VA_ARGS__) typedef void (*sdl_func_t)(void); static sdl_func_t sdl_funcs[] = { ser_sdl, vid_sdl }; void sdl_init(void) { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_TIMER) < 0) { fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError()); exit(1); } SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_VERBOSE); if (SDLNet_Init() < 0) { fail("SDLNet_Init() failed: %s", SDLNet_GetError()); } if (TTF_Init() < 0) { fail("TTF_Init() failed: %s", TTF_GetError()); } SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); SDL_StartTextInput(); } void sdl_quit(void) { TTF_Quit(); SDLNet_Quit(); SDL_Quit(); } void sdl_loop(void) { inf("entering SDL loop"); #if defined EMU_LINUX SDL_Scancode down = SDL_SCANCODE_UNKNOWN; #endif bool rel_mod = false; while (SDL_AtomicGet(&run) != 0) { for (int32_t i = 0; i < ARRAY_COUNT(sdl_funcs); ++i) { sdl_funcs[i](); } SDL_Event ev; while (SDL_PollEvent(&ev) > 0) { ver2("sdl ev %d", ev.type); #if defined EMU_LINUX // Work around duplicate key-down events on Linux. if (ev.type == SDL_KEYDOWN) { if (down == ev.key.keysym.scancode) { ver2("sdl dedup: skip %d", (int32_t)down); continue; } down = ev.key.keysym.scancode; ver2("sdl dedup: %d", (int32_t)down); } else if (ev.type == SDL_KEYUP) { down = SDL_SCANCODE_UNKNOWN; ver2("sdl dedup: reset"); } #endif if (ev.type == SDL_QUIT || (ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_ESCAPE)) { inf("quit event"); SDL_AtomicSet(&run, 0); continue; } if (ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_DOWN) { ver("sdl ev down-arrow"); rel_mod = true; ser_mou_res(); continue; } if (ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_UP) { ver("sdl ev up-arrow"); rel_mod = false; continue; } if (rel_mod) { if (ev.type == SDL_MOUSEMOTION) { ver("sdl ev mousemotion (%d, %d)", ev.motion.xrel, ev.motion.yrel); ser_mou_mov(&ev.motion); continue; } if (ev.type == SDL_MOUSEBUTTONDOWN) { ver("sdl ev mousebuttondown %d", ev.button.button); ser_mou_dn(&ev.button); continue; } if (ev.type == SDL_MOUSEBUTTONUP) { ver("sdl ev mousebuttonup %d", ev.button.button); ser_mou_up(&ev.button); continue; } } if (ev.type == SDL_TEXTINPUT) { ver("sdl ev text input %d", ev.text.text[0]); ser_text(&ev.text); continue; } if (ev.type == SDL_KEYDOWN) { ver("sdl ev key down %d", (int32_t)ev.key.keysym.sym); ser_key(&ev.key); continue; } } SDL_Delay(50); if (SDL_GetRelativeMouseMode() != rel_mod) { SDL_SetRelativeMouseMode(rel_mod); if (rel_mod) { inf("MOUSE CAPTURED - press UP-ARROW KEY to release"); } else { inf("mouse released"); } } } inf("leaving SDL loop"); }