X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_window.pas;h=f711ab2149a49a1ca504bb506c1c84c32ae44eef;hb=cd0837a23eed9896737537add1a93d878a227840;hp=d4cd928673a591bd2b16dbf0d7156cf708cf2be9;hpb=30bcb89f4decd5b5885ebde1fbb943b6563b1e3e;p=d2df-sdl.git diff --git a/src/game/g_window.pas b/src/game/g_window.pas index d4cd928..f711ab2 100644 --- a/src/game/g_window.pas +++ b/src/game/g_window.pas @@ -1,9 +1,10 @@ +{$MODE DELPHI} unit g_window; interface uses - WADEDITOR; + wadreader; function SDLMain(): Integer; function GetTimer(): Int64; @@ -23,6 +24,7 @@ function g_Window_SetSize(W, H: Word; FScreen: Boolean): Boolean; implementation uses +{$IFDEF WINDOWS}Windows,{$ENDIF} SDL2, GL, GLExt, e_graphics, e_log, g_main, g_console, SysUtils, e_input, g_options, g_game, g_basic, g_textures, e_sound, g_sound, g_menu, ENet, g_net; @@ -35,13 +37,17 @@ var flag: Boolean; wTitle: PChar = nil; wNeedTimeReset: Boolean = False; - wWindowCreated: Boolean = False; + //wWindowCreated: Boolean = False; //wCursorShown: Boolean = False; wMinimized: Boolean = False; //wNeedFree: Boolean = True; wLoadingProgress: Boolean = False; wLoadingQuit: Boolean = False; {wWinPause: Byte = 0;} +{$IFNDEF WINDOWS} + ticksOverflow: Int64 = -1; + lastTicks: Uint32 = 0; // to detect overflow +{$ENDIF} const // TODO: move this to a separate file @@ -68,33 +74,53 @@ begin end; function g_Window_SetDisplay(PreserveGL: Boolean = False): Boolean; +var + mode, cmode: TSDL_DisplayMode; begin +{$IFDEF HEADLESS} + Result := True; + Exit; +{$ENDIF} + Result := False; e_WriteLog('Setting display mode...', MSG_NOTIFY); - // if wWindowCreated and PreserveGL then - // e_SaveGLContext(); // we need this and restore because of a bug in SDL1.2, apparently - wFlags := SDL_WINDOW_OPENGL or SDL_WINDOW_RESIZABLE; if gFullscreen then wFlags := wFlags or SDL_WINDOW_FULLSCREEN; if gWinMaximized then wFlags := wFlags or SDL_WINDOW_MAXIMIZED; - + if h_Wnd <> nil then begin SDL_DestroyWindow(h_Wnd); h_Wnd := nil; end; + if gFullscreen then + begin + mode.w := gScreenWidth; + mode.h := gScreenHeight; + mode.format := 0; + mode.refresh_rate := 0; + mode.driverdata := nil; + if SDL_GetClosestDisplayMode(0, @mode, @cmode) = nil then + begin + gScreenWidth := 800; + gScreenHeight := 600; + end + else + begin + gScreenWidth := cmode.w; + gScreenHeight := cmode.h; + end; + end; + h_Wnd := SDL_CreateWindow(PChar(wTitle), gWinRealPosX, gWinRealPosY, gScreenWidth, gScreenHeight, wFlags); if h_Wnd = nil then Exit; - + SDL_GL_MakeCurrent(h_Wnd, h_GL); SDL_ShowCursor(SDL_DISABLE); - // if wWindowCreated and PreserveGL then - // e_RestoreGLContext(); - Result := True; end; @@ -106,20 +132,25 @@ end; function GetDisplayModes(dBPP: DWORD; var SelRes: DWORD): SArray; var mode: TSDL_DisplayMode; - res, i, k: Integer; + res, i, k, n, pw, ph: Integer; begin SetLength(Result, 0); - - k := 0; - for i := 0 to SDL_GetNumDisplayModes(0) do + {$IFDEF HEADLESS}Exit;{$ENDIF} + k := 0; SelRes := 0; + n := SDL_GetNumDisplayModes(0); + pw := 0; ph := 0; + for i := 0 to n do begin res := SDL_GetDisplayMode(0, i, @mode); if res < 0 then continue; + if SDL_BITSPERPIXEL(mode.format) = gBPP then continue; + if (mode.w = pw) and (mode.h = ph) then continue; if (mode.w = gScreenWidth) and (mode.h = gScreenHeight) then SelRes := k; Inc(k); SetLength(Result, k); Result[k-1] := IntToStr(mode.w) + 'x' + IntToStr(mode.h); + pw := mode.w; ph := mode.h end; e_WriteLog('SDL: Got ' + IntToStr(k) + ' resolutions.', MSG_NOTIFY); @@ -134,6 +165,7 @@ procedure ChangeWindowSize(); begin gWinSizeX := gScreenWidth; gWinSizeY := gScreenHeight; + {$IFDEF HEADLESS}Exit;{$ENDIF} e_ResizeWindow(gScreenWidth, gScreenHeight); g_Game_SetupScreenSize(); g_Menu_Reset(); @@ -145,6 +177,7 @@ var Preserve: Boolean; begin Result := False; + {$IFDEF HEADLESS}Exit;{$ENDIF} Preserve := False; if (gScreenWidth <> W) or (gScreenHeight <> H) then @@ -175,7 +208,7 @@ begin Result := False; wActivate := False; wDeactivate := False; - + case ev.event of SDL_WINDOWEVENT_MOVED: begin @@ -185,7 +218,7 @@ begin gWinRealPosY := ev.data2; end; end; - + SDL_WINDOWEVENT_MINIMIZED: begin if not wMinimized then @@ -201,7 +234,7 @@ begin wDeactivate := True; end; end; - + SDL_WINDOWEVENT_RESIZED: begin gScreenWidth := ev.data1; @@ -214,10 +247,10 @@ begin e_WriteLog('[DEBUG] WinMsgs: Resized to ' + IntToStr(ev.data1) + 'x' + IntToStr(ev.data2), MSG_NOTIFY); end; end; - + SDL_WINDOWEVENT_EXPOSED: SwapBuffers(); - + SDL_WINDOWEVENT_MAXIMIZED: begin if wMinimized then @@ -236,7 +269,7 @@ begin end; end; end; - + SDL_WINDOWEVENT_RESTORED: begin if wMinimized then @@ -253,23 +286,33 @@ begin e_WriteLog('[DEBUG] WinMsgs: Now restored', MSG_NOTIFY); end; end; - + SDL_WINDOWEVENT_FOCUS_GAINED: + begin wActivate := True; - + //e_WriteLog('window gained focus!', MSG_NOTIFY); + end; + SDL_WINDOWEVENT_FOCUS_LOST: + begin wDeactivate := True; + //e_WriteLog('window lost focus!', MSG_NOTIFY); + end; end; - + if wDeactivate then begin if gWinActive then begin + e_WriteLog('deactivating window', MSG_NOTIFY); e_EnableInput := False; e_ClearInputBuffer(); if gMuteWhenInactive then + begin + //e_WriteLog('deactivating sounds', MSG_NOTIFY); e_MuteChannels(True); + end; if g_debug_WinMsgs then begin @@ -284,10 +327,14 @@ begin begin if not gWinActive then begin + //e_WriteLog('activating window', MSG_NOTIFY); e_EnableInput := True; if gMuteWhenInactive then + begin + //e_WriteLog('activating sounds', MSG_NOTIFY); e_MuteChannels(False); + end; if g_debug_WinMsgs then begin @@ -331,7 +378,7 @@ begin key := ev.key.keysym.scancode; KeyPress(key); end; - + SDL_TEXTINPUT: begin Utf8ToUnicode(@uc, PChar(ev.text.text), 1); @@ -347,6 +394,7 @@ end; procedure SwapBuffers(); begin + {$IFDEF HEADLESS}Exit;{$ENDIF} SDL_GL_SwapWindow(h_Wnd); end; @@ -356,7 +404,7 @@ begin if h_GL <> nil then SDL_GL_DeleteContext(h_GL); h_Wnd := nil; h_GL := nil; - wWindowCreated := False; + //wWindowCreated := False; end; function CreateGLWindow(Title: PChar): Boolean; @@ -378,10 +426,11 @@ begin exit; end; +{$IFNDEF HEADLESS} h_Gl := SDL_GL_CreateContext(h_Wnd); if h_Gl = nil then Exit; - - wWindowCreated := True; +{$ENDIF} + //wWindowCreated := True; e_ResizeWindow(gScreenWidth, gScreenHeight); e_InitGL(); @@ -389,10 +438,42 @@ begin Result := True; end; +{$IFDEF WINDOWS} +// windoze sux; in headless mode `GetTickCount()` (and SDL) returns shit function GetTimer(): Int64; +var + F, C: Int64; begin - Result := SDL_GetTicks() * 1000; // TODO: do we really need microseconds here? + QueryPerformanceFrequency(F); + QueryPerformanceCounter(C); + Result := Round(C/F*1000{000}); end; +{$ELSE} +function GetTimer(): Int64; +var + t: Uint32; + tt: Int64; +begin + t := SDL_GetTicks() {* 1000}; // TODO: do we really need microseconds here? k8: NOPE! + if ticksOverflow = -1 then + begin + ticksOverflow := 0; + lastTicks := t; + end + else + begin + if lastTicks > t then + begin + // overflow, increment overflow ;-) + ticksOverflow := ticksOverflow+(Int64($ffffffff)+Int64(1)); + tt := (Int64($ffffffff)+Int64(1))+Int64(t); + t := Uint32(tt-lastTicks); + end; + end; + lastTicks := t; + result := ticksOverflow+Int64(t); +end; +{$ENDIF} procedure ResetTimer(); begin @@ -472,11 +553,11 @@ begin if wNeedTimeReset then begin - Time_Delta := 27777; + Time_Delta := (27777 div 1000); wNeedTimeReset := False; end; - t := Time_Delta div 27777; + t := Time_Delta div (27777 div 1000); if t > 0 then begin flag := True; @@ -508,7 +589,7 @@ begin // Âðåìÿ ïðåäûäóùåãî îáíîâëåíèÿ: if flag then begin - Time_Old := Time - (Time_Delta mod 27777); + Time_Old := Time - (Time_Delta mod (27777 div 1000)); if (not wMinimized) then begin Draw(); @@ -532,6 +613,7 @@ procedure InitOpenGL(VSync: Boolean); var v: Byte; begin + {$IFDEF HEADLESS}Exit;{$ENDIF} if VSync then v := 1 else v := 0; SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); @@ -545,6 +627,10 @@ end; function SDLMain(): Integer; begin +{$IFDEF HEADLESS} + e_NoGraphics := True; +{$ENDIF} + e_WriteLog('Creating GL window', MSG_NOTIFY); if not CreateGLWindow(PChar(Format('Doom 2D: Forever %s', [GAME_VERSION]))) then begin