truelight@0: #include "stdafx.h" truelight@0: truelight@0: #if defined(WITH_SDL) truelight@0: #include "ttd.h" truelight@0: #include "gfx.h" truelight@0: #include "sound.h" truelight@0: #include "window.h" truelight@0: #include truelight@0: #include "player.h" truelight@0: #include "hal.h" truelight@0: truelight@0: #ifdef UNIX truelight@0: #include truelight@0: #endif truelight@0: truelight@0: #define DYNAMICALLY_LOADED_SDL truelight@0: truelight@0: static SDL_Surface *_sdl_screen; truelight@0: static int _sdl_usage; truelight@0: static bool _all_modes; truelight@0: truelight@0: #define MAX_DIRTY_RECTS 100 truelight@0: static SDL_Rect _dirty_rects[MAX_DIRTY_RECTS]; truelight@0: static int _num_dirty_rects; truelight@0: truelight@193: #define SDL_CALL truelight@0: truelight@0: #if defined(DYNAMICALLY_LOADED_SDL) && defined(WIN32) truelight@0: truelight@0: bool LoadLibraryList(void **proc, const char *dll); truelight@0: truelight@0: typedef struct { truelight@0: int (SDLCALL *SDL_Init)(Uint32); truelight@0: int (SDLCALL *SDL_InitSubSystem)(Uint32); truelight@0: char *(SDLCALL *SDL_GetError)(); truelight@0: void (SDLCALL *SDL_QuitSubSystem)(Uint32); truelight@0: void (SDLCALL *SDL_UpdateRect)(SDL_Surface *, Sint32, Sint32, Uint32, Uint32); truelight@0: void (SDLCALL *SDL_UpdateRects)(SDL_Surface *, int, SDL_Rect *); truelight@0: int (SDLCALL *SDL_SetColors)(SDL_Surface *, SDL_Color *, int, int); truelight@0: void (SDLCALL *SDL_WM_SetCaption)(const char *, const char *); truelight@0: int (SDLCALL *SDL_ShowCursor)(int); truelight@0: void (SDLCALL *SDL_FreeSurface)(SDL_Surface *); truelight@0: int (SDLCALL *SDL_PollEvent)(SDL_Event *); truelight@0: void (SDLCALL *SDL_WarpMouse)(Uint16, Uint16); truelight@0: uint32 (SDLCALL *SDL_GetTicks)(); truelight@0: int (SDLCALL *SDL_OpenAudio)(SDL_AudioSpec *, SDL_AudioSpec*); truelight@0: void (SDLCALL *SDL_PauseAudio)(int); truelight@0: void (SDLCALL *SDL_CloseAudio)(); truelight@0: int (SDLCALL *SDL_LockSurface)(SDL_Surface*); truelight@0: void (SDLCALL *SDL_UnlockSurface)(SDL_Surface*); truelight@0: SDLMod (SDLCALL *SDL_GetModState)(); truelight@0: void (SDLCALL *SDL_Delay)(Uint32); truelight@0: void (SDLCALL *SDL_Quit)(); truelight@0: SDL_Surface *(SDLCALL *SDL_SetVideoMode)(int,int,int,Uint32); truelight@0: int (SDLCALL *SDL_EnableKeyRepeat)(int,int); truelight@0: void (SDLCALL *SDL_EnableUNICODE)(int); truelight@0: void (SDLCALL *SDL_VideoDriverName)(char *, int); truelight@0: SDL_Rect **(SDLCALL *SDL_ListModes)(void *, int); truelight@0: Uint8 *(SDLCALL *SDL_GetKeyState)(int *); truelight@0: } SDLProcs; truelight@0: truelight@0: #define M(x) x "\0" truelight@193: static const char sdl_files[] = truelight@0: M("sdl.dll") truelight@0: M("SDL_Init") truelight@0: M("SDL_InitSubSystem") truelight@0: M("SDL_GetError") truelight@0: M("SDL_QuitSubSystem") truelight@0: M("SDL_UpdateRect") truelight@0: M("SDL_UpdateRects") truelight@0: M("SDL_SetColors") truelight@0: M("SDL_WM_SetCaption") truelight@0: M("SDL_ShowCursor") truelight@0: M("SDL_FreeSurface") truelight@0: M("SDL_PollEvent") truelight@0: M("SDL_WarpMouse") truelight@0: M("SDL_GetTicks") truelight@0: M("SDL_OpenAudio") truelight@0: M("SDL_PauseAudio") truelight@0: M("SDL_CloseAudio") truelight@0: M("SDL_LockSurface") truelight@0: M("SDL_UnlockSurface") truelight@0: M("SDL_GetModState") truelight@0: M("SDL_Delay") truelight@0: M("SDL_Quit") truelight@0: M("SDL_SetVideoMode") truelight@0: M("SDL_EnableKeyRepeat") truelight@0: M("SDL_EnableUNICODE") truelight@0: M("SDL_VideoDriverName") truelight@0: M("SDL_ListModes") truelight@0: M("SDL_GetKeyState") truelight@0: M("") truelight@0: ; truelight@0: #undef M truelight@0: truelight@0: static SDLProcs _proc; truelight@0: truelight@0: static char *LoadSdlDLL() truelight@0: { truelight@193: if (_proc.SDL_Init != NULL) truelight@0: return NULL; truelight@0: if (!LoadLibraryList((void**)&_proc, sdl_files)) truelight@0: return "Unable to load sdl.dll"; truelight@0: return NULL; truelight@0: } truelight@0: truelight@0: #undef SDL_CALL truelight@0: #define SDL_CALL _proc. truelight@0: truelight@0: #endif truelight@0: truelight@0: truelight@0: #ifdef UNIX truelight@0: static void SdlAbort(int sig) truelight@0: { truelight@0: /* Own hand-made parachute for the cases of failed assertions. */ truelight@0: SDL_CALL SDL_Quit(); truelight@0: } truelight@0: #endif truelight@0: truelight@0: truelight@0: static char *SdlOpen(uint32 x) truelight@0: { truelight@0: #if defined(DYNAMICALLY_LOADED_SDL) && defined(WIN32) truelight@0: { char *s = LoadSdlDLL(); if (s) return s; } truelight@0: #endif truelight@0: if (_sdl_usage++ == 0) { truelight@0: if (SDL_CALL SDL_Init(x) == -1) truelight@0: return SDL_CALL SDL_GetError(); truelight@0: } else if (x) { truelight@0: if (SDL_CALL SDL_InitSubSystem(x) == -1) truelight@0: return SDL_CALL SDL_GetError(); truelight@0: } truelight@0: truelight@0: #ifdef UNIX truelight@0: signal(SIGABRT, SdlAbort); truelight@0: #endif truelight@0: truelight@0: return NULL; truelight@0: } truelight@0: truelight@0: static void SdlClose(uint32 x) truelight@0: { truelight@0: if (x) truelight@0: SDL_CALL SDL_QuitSubSystem(x); truelight@0: if (--_sdl_usage == 0) { truelight@0: SDL_CALL SDL_Quit(); truelight@0: #ifdef UNIX truelight@0: #ifndef __MORPHOS__ truelight@0: signal(SIGABRT, SIG_DFL); truelight@0: #else truelight@0: signal(SIGABRT, (void (*)(int))0 ); truelight@0: #endif truelight@0: #endif truelight@0: } truelight@0: } truelight@0: truelight@0: static void SdlVideoMakeDirty(int left, int top, int width, int height) truelight@0: { truelight@0: // printf("(%d,%d)-(%d,%d)\n", left, top, width, height); truelight@0: // _pixels_redrawn += width*height; truelight@0: if (_num_dirty_rects < MAX_DIRTY_RECTS) { truelight@0: _dirty_rects[_num_dirty_rects].x = left; truelight@0: _dirty_rects[_num_dirty_rects].y = top; truelight@0: _dirty_rects[_num_dirty_rects].w = width; truelight@0: _dirty_rects[_num_dirty_rects].h = height; truelight@0: } truelight@0: _num_dirty_rects++; truelight@0: } truelight@0: truelight@0: static SDL_Color pal[256]; truelight@0: truelight@0: static void UpdatePalette(uint start, uint end) { truelight@0: uint i; truelight@0: byte *b; truelight@0: truelight@0: for(i = start, b = _cur_palette + start * 3; i != end; i++, b += 3) { truelight@0: pal[i].r = b[0]; truelight@0: pal[i].g = b[1]; truelight@0: pal[i].b = b[2]; truelight@0: pal[i].unused = b[3]; truelight@0: } truelight@0: truelight@0: SDL_CALL SDL_SetColors(_sdl_screen, pal, start, end); truelight@0: } truelight@0: truelight@0: static void InitPalette(void) { truelight@0: UpdatePalette(0, 256); truelight@0: } truelight@0: dominik@18: static void CheckPaletteAnim() truelight@0: { truelight@0: if(_pal_last_dirty != -1) { truelight@0: UpdatePalette(_pal_first_dirty, _pal_last_dirty + 1); truelight@0: _pal_last_dirty = -1; truelight@0: } dominik@18: } dominik@18: dominik@18: static void DrawSurfaceToScreen() dominik@18: { dominik@18: int n; truelight@0: truelight@0: if ((n=_num_dirty_rects) != 0) { truelight@0: _num_dirty_rects = 0; truelight@0: if (n > MAX_DIRTY_RECTS) truelight@0: SDL_CALL SDL_UpdateRect(_sdl_screen, 0, 0, 0, 0); truelight@0: else { truelight@0: SDL_CALL SDL_UpdateRects(_sdl_screen, n, _dirty_rects); truelight@0: } truelight@0: } truelight@0: } truelight@0: truelight@0: static int CDECL compare_res(const void *pa, const void *pb) truelight@0: { darkvater@222: int x = ((const uint16*)pa)[0] - ((const uint16*)pb)[0]; truelight@0: if (x) return x; darkvater@222: return ((const uint16*)pa)[1] - ((const uint16*)pb)[1]; truelight@0: } truelight@0: truelight@0: static const uint16 default_resolutions[][2] = { truelight@0: {640,480}, truelight@0: {800,600}, truelight@0: {1024,768}, truelight@0: {1152,864}, truelight@0: {1280,960}, truelight@0: {1280,1024}, truelight@0: {1400,1050}, truelight@0: {1600,1200}, truelight@0: }; truelight@0: truelight@0: static void GetVideoModes(void) { truelight@0: int i; truelight@0: SDL_Rect **modes; truelight@0: truelight@0: modes = SDL_CALL SDL_ListModes(NULL, SDL_SWSURFACE + (_fullscreen ? SDL_FULLSCREEN : 0)); truelight@0: darkvater@245: if(modes == NULL) darkvater@245: error("sdl: no modes available"); dominik@119: darkvater@245: _all_modes = (modes == (void*)-1); darkvater@245: darkvater@245: if (_all_modes) { truelight@0: // all modes available, put some default ones here truelight@0: memcpy(_resolutions, default_resolutions, sizeof(default_resolutions)); darkvater@245: _num_resolutions = lengthof(default_resolutions); truelight@0: } else { dominik@128: int n = 0; dominik@119: for(i = 0; modes[i]; i++) { dominik@128: int w = modes[i]->w; dominik@128: int h = modes[i]->h; truelight@193: if (IS_INT_INSIDE(w, 640, MAX_SCREEN_WIDTH+1) && truelight@0: IS_INT_INSIDE(h, 480, MAX_SCREEN_HEIGHT+1) && truelight@0: w%8 == 0 && h%8 == 0) { // disable screen resolutions which are not multiples of 8 dominik@128: int j; dominik@128: for (j = 0; j < n; ++j) dominik@128: if (_resolutions[j][0] == w && _resolutions[j][1] == h) dominik@128: break; dominik@128: if (j == n) { dominik@128: _resolutions[n][0] = w; dominik@128: _resolutions[n][1] = h; darkvater@245: if (++n == lengthof(_resolutions)) break; dominik@128: } truelight@0: } truelight@0: } truelight@0: _num_resolutions = n; darkvater@245: qsort(_resolutions, n, sizeof(_resolutions[0]), compare_res); truelight@0: } truelight@0: } truelight@0: truelight@0: static int GetAvailableVideoMode(int *w, int *h) truelight@0: { truelight@0: int i; truelight@0: truelight@0: truelight@0: // all modes available? truelight@0: if (_all_modes) truelight@0: return 1; truelight@0: truelight@0: // is the wanted mode among the available modes? truelight@0: for(i = 0; i != _num_resolutions; i++) { truelight@0: if(*w == _resolutions[i][0] && *h == _resolutions[i][1]) truelight@0: return 1; truelight@0: } truelight@0: truelight@0: // use the default mode truelight@0: *w = _resolutions[0][0]; truelight@0: *h = _resolutions[0][1]; truelight@0: return 2; truelight@0: } truelight@0: truelight@0: static bool CreateMainSurface(int w, int h) truelight@0: { truelight@0: SDL_Surface *newscreen; truelight@0: bool sizechange; truelight@0: truelight@0: GetAvailableVideoMode(&w, &h); truelight@0: truelight@0: sizechange = (_screen.width != w || _screen.height != h); truelight@0: _screen.pitch = _screen.width = w; truelight@0: _screen.height = h; truelight@0: truelight@0: DEBUG(misc, 0) ("sdl: using mode %dx%d", w, h); truelight@0: darkvater@36: // DO NOT CHANGE TO HWSURFACE, IT DOES NOT WORK darkvater@34: newscreen = SDL_CALL SDL_SetVideoMode(w, h, 8, SDL_SWSURFACE + SDL_HWPALETTE + (_fullscreen?SDL_FULLSCREEN:SDL_RESIZABLE)); truelight@0: if(newscreen == NULL) truelight@0: return false; truelight@0: truelight@0: _sdl_screen = newscreen; truelight@0: InitPalette(); truelight@0: truelight@0: SDL_CALL SDL_WM_SetCaption("OpenTTD", "OpenTTD"); truelight@0: SDL_CALL SDL_ShowCursor(0); truelight@0: truelight@0: // if(sizechange) truelight@0: GameSizeChanged(); truelight@0: truelight@0: return true; truelight@0: } truelight@0: truelight@0: typedef struct { truelight@0: uint16 vk_from; truelight@0: byte vk_count; truelight@0: byte map_to; truelight@0: } VkMapping; truelight@0: truelight@0: #define AS(x,z) {x,0,z} truelight@0: #define AM(x,y,z,w) {x,y-x,z} truelight@0: truelight@0: static const VkMapping _vk_mapping[] = { truelight@0: // Pageup stuff + up/down truelight@0: AM(SDLK_PAGEUP,SDLK_PAGEDOWN, WKC_PAGEUP, WKC_PAGEDOWN), truelight@0: AS(SDLK_UP, WKC_UP), truelight@0: AS(SDLK_DOWN, WKC_DOWN), truelight@0: AS(SDLK_LEFT, WKC_LEFT), truelight@0: AS(SDLK_RIGHT, WKC_RIGHT), truelight@0: truelight@0: AS(SDLK_HOME, WKC_HOME), truelight@0: AS(SDLK_END, WKC_END), truelight@0: truelight@0: AS(SDLK_INSERT, WKC_INSERT), truelight@0: AS(SDLK_DELETE, WKC_DELETE), truelight@0: truelight@0: // Map letters & digits truelight@0: AM(SDLK_a,SDLK_z,'A','Z'), truelight@0: AM(SDLK_0,SDLK_9,'0','9'), truelight@0: truelight@0: AS(SDLK_ESCAPE, WKC_ESC), truelight@0: AS(SDLK_BACKSPACE, WKC_BACKSPACE), truelight@0: truelight@0: AS(SDLK_SPACE, WKC_SPACE), truelight@0: AS(SDLK_RETURN, WKC_RETURN), truelight@0: AS(SDLK_TAB, WKC_TAB), truelight@0: truelight@0: // Function keys truelight@0: AM(SDLK_F1, SDLK_F12, WKC_F1, WKC_F12), truelight@0: truelight@0: // Numeric part. truelight@0: // What is the virtual keycode for numeric enter?? truelight@0: AM(SDLK_KP0,SDLK_KP9, WKC_NUM_0, WKC_NUM_9), truelight@0: AS(SDLK_KP_DIVIDE, WKC_NUM_DIV), truelight@0: AS(SDLK_KP_MULTIPLY, WKC_NUM_MUL), truelight@0: AS(SDLK_KP_MINUS, WKC_NUM_MINUS), truelight@0: AS(SDLK_KP_PLUS, WKC_NUM_PLUS), truelight@0: AS(SDLK_KP_ENTER, WKC_NUM_ENTER), truelight@0: AS(SDLK_KP_PERIOD, WKC_NUM_DECIMAL), truelight@193: {0, 0, 0} truelight@0: }; truelight@0: truelight@0: static uint32 ConvertSdlKeyIntoMy(SDL_keysym *sym) truelight@0: { truelight@0: const VkMapping *map = _vk_mapping - 1; truelight@0: uint from; truelight@0: uint key = sym->sym; truelight@0: for(;;) { truelight@0: map++; truelight@0: from = map->vk_from; truelight@0: if (from == 0) { truelight@0: key = 0; truelight@193: break; truelight@0: } truelight@0: if ((uint)(key - from) <= map->vk_count) { truelight@0: key = key - from + map->map_to; truelight@0: break; truelight@0: } truelight@0: } dominik@129: dominik@129: // check scancode for BACKQUOTE key, because we want the key left of "1", not anything else (on non-US keyboards) darkvater@135: #if defined(WIN32) darkvater@135: if (sym->scancode == 41) key |= WKC_BACKQUOTE; darkvater@135: #else bjarni@167: #if defined(__APPLE__) bjarni@167: if (sym->scancode == 10) key |= WKC_BACKQUOTE; bjarni@167: #else bjarni@170: #if defined(__MORPHOS__) bjarni@170: if (sym->scancode == 0) key |= WKC_BACKQUOTE; // yes, that key is code '0' under MorphOS :) bjarni@170: #else bjarni@170: if (sym->scancode == 49) key |= WKC_BACKQUOTE; bjarni@170: #endif bjarni@167: #endif darkvater@135: #endif truelight@0: // META are the command keys on mac truelight@0: if (sym->mod & KMOD_META) key |= WKC_META; truelight@0: if (sym->mod & KMOD_SHIFT) key |= WKC_SHIFT; truelight@0: if (sym->mod & KMOD_CTRL) key |= WKC_CTRL; truelight@0: if (sym->mod & KMOD_ALT) key |= WKC_ALT; bjarni@167: // these two lines really helps porting hotkey combos. Uncomment to use -- Bjarni bjarni@167: //printf("scancode character pressed %d\n", sym->scancode); bjarni@167: //printf("unicode character pressed %d\n", sym->unicode); truelight@0: return (key << 16) + sym->unicode; truelight@0: } truelight@0: truelight@0: static int PollEvent() { truelight@0: SDL_Event ev; truelight@0: truelight@0: if (!SDL_CALL SDL_PollEvent(&ev)) truelight@0: return -2; truelight@0: truelight@0: switch(ev.type) { truelight@0: case SDL_MOUSEMOTION: truelight@0: if (_cursor.fix_at) { truelight@0: int dx = ev.motion.x - _cursor.pos.x; truelight@0: int dy = ev.motion.y - _cursor.pos.y; truelight@0: if (dx != 0 || dy != 0) { truelight@0: _cursor.delta.x += dx; truelight@0: _cursor.delta.y += dy; truelight@0: SDL_CALL SDL_WarpMouse(_cursor.pos.x, _cursor.pos.y); truelight@0: } truelight@0: } else { truelight@0: _cursor.delta.x = ev.motion.x - _cursor.pos.x; truelight@0: _cursor.delta.y = ev.motion.y - _cursor.pos.y; truelight@0: _cursor.pos.x = ev.motion.x; truelight@0: _cursor.pos.y = ev.motion.y; truelight@0: _cursor.dirty = true; truelight@0: } truelight@0: break; truelight@0: truelight@0: case SDL_MOUSEBUTTONDOWN: truelight@0: if (_rightclick_emulate && (SDL_CALL SDL_GetModState() & (KMOD_LCTRL | KMOD_RCTRL))) truelight@0: ev.button.button = SDL_BUTTON_RIGHT; truelight@0: truelight@0: if (ev.button.button == SDL_BUTTON_LEFT) { truelight@0: _left_button_down = true; truelight@0: } else if (ev.button.button == SDL_BUTTON_RIGHT) { truelight@0: _right_button_down = true; truelight@0: _right_button_clicked = true; truelight@0: } truelight@193: #if !defined(WIN32) truelight@0: else if (ev.button.button == SDL_BUTTON_WHEELUP) { truelight@0: _cursor.wheel--; truelight@0: } else if (ev.button.button == SDL_BUTTON_WHEELDOWN) { truelight@0: _cursor.wheel++; truelight@0: } truelight@0: #endif truelight@0: break; truelight@0: truelight@0: case SDL_MOUSEBUTTONUP: truelight@0: if (_rightclick_emulate) { truelight@0: _right_button_down = false; truelight@0: _left_button_down = false; truelight@0: _left_button_clicked = false; truelight@0: } else if (ev.button.button == SDL_BUTTON_LEFT) { truelight@0: _left_button_down = false; truelight@0: _left_button_clicked = false; truelight@0: } else if (ev.button.button == SDL_BUTTON_RIGHT) { truelight@0: _right_button_down = false; truelight@0: } truelight@0: break; truelight@0: truelight@0: case SDL_QUIT: truelight@0: return ML_QUIT; truelight@0: truelight@0: case SDL_KEYDOWN: truelight@0: if ((((ev.key.keysym.sym == SDLK_RETURN) || (ev.key.keysym.sym == SDLK_f)) && (ev.key.keysym.mod & KMOD_ALT)) || (((ev.key.keysym.sym == SDLK_RETURN) || (ev.key.keysym.sym == SDLK_f)) && (ev.key.keysym.mod & KMOD_META))) { truelight@0: _fullscreen ^= true; truelight@0: GetVideoModes(); truelight@0: CreateMainSurface(_screen.width, _screen.height); truelight@0: MarkWholeScreenDirty(); truelight@0: } else { truelight@0: _pressed_key = ConvertSdlKeyIntoMy(&ev.key.keysym); truelight@0: } truelight@0: break; truelight@193: truelight@0: case SDL_VIDEORESIZE: { truelight@0: int w, h; truelight@0: w = ev.resize.w; truelight@0: h = ev.resize.h; truelight@193: truelight@0: w = clamp(w & ~0x7, 64, MAX_SCREEN_WIDTH); truelight@0: h = clamp(h & ~0x7, 64, MAX_SCREEN_HEIGHT); truelight@193: truelight@0: ChangeResInGame(w, h); truelight@193: truelight@0: break; truelight@0: } truelight@0: } truelight@0: return -1; truelight@0: } truelight@0: truelight@0: static const char *SdlVideoStart(char **parm) truelight@0: { truelight@0: char buf[30]; truelight@0: truelight@0: {char *s;if ((s = SdlOpen(SDL_INIT_VIDEO)) != NULL) return s;} truelight@0: truelight@0: SDL_CALL SDL_VideoDriverName(buf, 30); truelight@0: DEBUG(misc, 0) ("sdl: using driver '%s'", buf); truelight@0: truelight@0: GetVideoModes(); truelight@0: CreateMainSurface(_cur_resolution[0], _cur_resolution[1]); truelight@0: MarkWholeScreenDirty(); truelight@0: truelight@0: SDL_CALL SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); truelight@0: SDL_CALL SDL_EnableUNICODE(1); truelight@0: return NULL; truelight@0: } truelight@0: truelight@0: static void SdlVideoStop() truelight@0: { truelight@0: SdlClose(SDL_INIT_VIDEO); truelight@0: } truelight@0: truelight@0: static int SdlVideoMainLoop() truelight@0: { orudge@60: uint32 next_tick = SDL_CALL SDL_GetTicks() + 30, cur_ticks, pal_tick = 0; truelight@0: int i; truelight@0: uint32 mod; truelight@0: int numkeys; truelight@0: Uint8 *keys; truelight@0: truelight@0: while (true) { truelight@0: InteractiveRandom(); // randomness truelight@193: truelight@0: while ((i=PollEvent()) == -1) {} truelight@0: if (i>=0) return i; truelight@0: dominik@18: if (_exit_game) return ML_QUIT; truelight@0: dominik@18: mod = SDL_CALL SDL_GetModState(); truelight@193: keys = SDL_CALL SDL_GetKeyState(&numkeys); truelight@0: #if defined(_DEBUG) truelight@0: if (_shift_pressed) { truelight@0: #else truelight@0: if (keys[SDLK_TAB]) { truelight@0: #endif darkvater@196: if (!_networking) _fast_forward |= 2; truelight@0: } else if (_fast_forward&2) { truelight@0: _fast_forward = 0; truelight@0: } truelight@0: dominik@18: cur_ticks=SDL_CALL SDL_GetTicks(); dominik@18: if ((_fast_forward && !_pause) || cur_ticks > next_tick) dominik@18: next_tick = cur_ticks; dominik@18: dominik@18: if (cur_ticks == next_tick) { dominik@18: next_tick += 30; dominik@18: dominik@18: _ctrl_pressed = !!(mod & (KMOD_LCTRL | KMOD_RCTRL)); dominik@18: _shift_pressed = !!(mod & (KMOD_LSHIFT | KMOD_RSHIFT)); truelight@193: dominik@18: // determine which directional keys are down truelight@193: _dirkeys = truelight@193: (keys[SDLK_LEFT] ? 1 : 0) + truelight@193: (keys[SDLK_UP] ? 2 : 0) + truelight@193: (keys[SDLK_RIGHT] ? 4 : 0) + dominik@18: (keys[SDLK_DOWN] ? 8 : 0); dominik@18: GameLoop(); dominik@18: dominik@18: _screen.dst_ptr = _sdl_screen->pixels; dominik@18: UpdateWindows(); dominik@18: if (++ pal_tick > 4){ dominik@18: CheckPaletteAnim(); dominik@18: pal_tick = 1; truelight@0: } dominik@18: DrawSurfaceToScreen(); truelight@0: } else { dominik@18: SDL_CALL SDL_Delay(1); dominik@18: _screen.dst_ptr = _sdl_screen->pixels; dominik@18: DrawMouseCursor(); dominik@18: DrawSurfaceToScreen(); truelight@0: } truelight@0: } truelight@0: } truelight@0: truelight@0: static bool SdlVideoChangeRes(int w, int h) truelight@0: { truelight@0: // see if the mode is available truelight@0: if (GetAvailableVideoMode(&w, &h) != 1) truelight@0: return false; dominik@18: truelight@0: CreateMainSurface(w, h); truelight@0: return true; truelight@0: } truelight@0: truelight@0: const HalVideoDriver _sdl_video_driver = { truelight@0: SdlVideoStart, truelight@0: SdlVideoStop, truelight@0: SdlVideoMakeDirty, truelight@0: SdlVideoMainLoop, truelight@0: SdlVideoChangeRes, truelight@0: }; truelight@0: truelight@0: static void CDECL fill_sound_buffer(void *userdata, Uint8 *stream, int len) truelight@0: { truelight@0: MxMixSamples(_mixer, stream, len >> 2); truelight@0: } truelight@0: truelight@0: static char *SdlSoundStart(char **parm) truelight@0: { truelight@0: SDL_AudioSpec spec; truelight@193: truelight@0: {char *s;if ((s = SdlOpen(SDL_INIT_AUDIO)) != NULL) return s;} truelight@0: spec.freq = GetDriverParamInt(parm, "hz", 11025); truelight@0: spec.format = AUDIO_S16SYS; truelight@0: spec.channels = 2; truelight@0: spec.samples = 512; truelight@0: *(void**)&spec.callback = fill_sound_buffer; truelight@0: SDL_CALL SDL_OpenAudio(&spec, &spec); truelight@0: SDL_CALL SDL_PauseAudio(0); truelight@0: return NULL; truelight@0: } truelight@0: truelight@0: static void SdlSoundStop() truelight@0: { truelight@0: SDL_CALL SDL_CloseAudio(); truelight@0: SdlClose(SDL_INIT_AUDIO); truelight@0: } truelight@0: truelight@0: const HalSoundDriver _sdl_sound_driver = { truelight@0: SdlSoundStart, truelight@0: SdlSoundStop, truelight@0: }; truelight@0: truelight@0: truelight@0: #include "viewport.h" truelight@0: void redsq_debug(int tile) truelight@0: { truelight@0: _thd.redsq = tile; truelight@0: MarkWholeScreenDirty(); truelight@0: _screen.dst_ptr = _sdl_screen->pixels; truelight@0: UpdateWindows(); truelight@0: truelight@0: SdlVideoMakeDirty(0,0,_screen.width,_screen.height); truelight@0: DrawSurfaceToScreen(); truelight@0: } truelight@0: truelight@0: void DbgRedraw() truelight@0: { truelight@0: SdlVideoMakeDirty(0,0,_screen.width,_screen.height); truelight@0: DrawSurfaceToScreen(); truelight@0: } truelight@0: #endif // WITH_SDL