diff --git a/src/game/g_window.pas b/src/game/g_window.pas
index 479ffcb16c69fd93924066f95ff3cc1aa442831d..80e63fd640ae7fce250d3e713d7d6944440cfeb6 100644 (file)
--- a/src/game/g_window.pas
+++ b/src/game/g_window.pas
procedure ProcessLoading (forceUpdate: Boolean=false);
+// returns `true` if quit event was received
+function g_ProcessMessages (): Boolean;
+
var
gwin_dump_extensions: Boolean = false;
SDL2, GL, GLExt, e_graphics, e_log, e_texture, g_main,
g_console, e_input, g_options, g_game,
g_basic, g_textures, e_sound, g_sound, g_menu, ENet, g_net,
- g_map, g_gfx, g_monsters, g_holmes, xprofiler;
+ g_map, g_gfx, g_monsters, g_holmes, xprofiler,
+ sdlcarcass, fui_ctls;
const
var
h_Wnd: PSDL_Window = nil;
h_GL: TSDL_GLContext = nil;
- wFlags: LongWord = 0;
Time, Time_Delta, Time_Old: Int64;
flag: Boolean;
+{$IF not DEFINED(HEADLESS)}
wTitle: PChar = nil;
+{$ENDIF}
wNeedTimeReset: Boolean = false;
wMinimized: Boolean = false;
wLoadingProgress: Boolean = false;
ticksOverflow: Int64 = -1;
lastTicks: Uint32 = 0; // to detect overflow
{$ENDIF}
-{$IF not DEFINED(HEADLESS)}
- curMsButState: Word = 0;
- curKbState: Word = 0;
- curMsX: Integer = 0;
- curMsY: Integer = 0;
-{$ENDIF}
+
+
+procedure KillGLWindow ();
+begin
+ if (h_GL <> nil) then begin if (assigned(oglDeinitCB)) then oglDeinitCB(); end;
+ if (h_Wnd <> nil) then SDL_DestroyWindow(h_Wnd);
+ if (h_GL <> nil) then SDL_GL_DeleteContext(h_GL);
+ h_Wnd := nil;
+ h_GL := nil;
+end;
function g_Window_SetDisplay (preserveGL: Boolean = false): Boolean;
{$IF not DEFINED(HEADLESS)}
var
mode, cmode: TSDL_DisplayMode;
+ wFlags: LongWord = 0;
{$ENDIF}
begin
{$IF not DEFINED(HEADLESS)}
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;
+ KillGLWindow();
if gFullscreen then
begin
SDL_GL_MakeCurrent(h_Wnd, h_GL);
SDL_ShowCursor(SDL_DISABLE);
+ if (h_GL <> nil) then begin if (assigned(oglInitCB)) then oglInitCB(); end;
{$ENDIF}
result := true;
end;
-function GetDisplayModes(dbpp: LongWord; var selres: LongWord): SSArray;
+function GetDisplayModes (dbpp: LongWord; var selres: LongWord): SSArray;
var
mode: TSDL_DisplayMode;
res, i, k, n, pw, ph: Integer;
g_Game_SetupScreenSize();
g_Menu_Reset();
g_Game_ClearLoading();
- g_Holmes_VidModeChanged();
{$ENDIF}
end;
function g_Window_SetSize (w, h: Word; fullscreen: Boolean): Boolean;
+{$IF not DEFINED(HEADLESS)}
var
preserve: Boolean;
+{$ENDIF}
begin
result := false;
{$IF not DEFINED(HEADLESS)}
end;
-procedure resetKMState ();
-begin
-{$IF not DEFINED(HEADLESS)}
- curMsButState := 0;
- curKbState := 0;
-{$ENDIF}
-end;
-
-
function WindowEventHandler (constref ev: TSDL_WindowEvent): Boolean;
var
wActivate, wDeactivate: Boolean;
SDL_WINDOWEVENT_MINIMIZED:
begin
- resetKMState();
e_UnpressAllKeys();
if not wMinimized then
begin
SDL_WINDOWEVENT_RESIZED:
begin
- resetKMState();
gScreenWidth := ev.data1;
gScreenHeight := ev.data2;
ChangeWindowSize();
SDL_WINDOWEVENT_MAXIMIZED:
begin
- resetKMState();
if wMinimized then
begin
e_ResizeWindow(gScreenWidth, gScreenHeight);
SDL_WINDOWEVENT_RESTORED:
begin
- resetKMState();
if wMinimized then
begin
e_ResizeWindow(gScreenWidth, gScreenHeight);
wMinimized := false;
wActivate := true;
end;
- if gWinMaximized then
- gWinMaximized := false;
+ if gWinMaximized then gWinMaximized := false;
if g_debug_WinMsgs then
begin
g_Console_Add('Now restored');
SDL_WINDOWEVENT_FOCUS_GAINED:
begin
- resetKMState();
wActivate := true;
//e_WriteLog('window gained focus!', MSG_NOTIFY);
- g_Holmes_WindowFocused();
end;
SDL_WINDOWEVENT_FOCUS_LOST:
begin
- resetKMState();
wDeactivate := true;
e_UnpressAllKeys();
//e_WriteLog('window lost focus!', MSG_NOTIFY);
- g_Holmes_WindowBlured();
end;
end;
end;
gWinActive := false;
+
+ if assigned(winBlurCB) then winBlurCB();
end;
end
else if wActivate then
end;
gWinActive := true;
+ if assigned(winFocusCB) then winFocusCB();
end;
end;
end;
var
key, keychr: Word;
uc: UnicodeChar;
- {$IF not DEFINED(HEADLESS)}
- msev: THMouseEvent;
- kbev: THKeyEvent;
- {$ENDIF}
-
- function buildBut (b: Byte): Word;
- begin
- result := 0;
- case b of
- SDL_BUTTON_LEFT: result := result or THMouseEvent.Left;
- SDL_BUTTON_MIDDLE: result := result or THMouseEvent.Middle;
- SDL_BUTTON_RIGHT: result := result or THMouseEvent.Right;
- end;
- end;
-
- {$IF not DEFINED(HEADLESS)}
- procedure updateKBState ();
- var
- kbstate: PUint8;
- begin
- curKbState := 0;
- kbstate := SDL_GetKeyboardState(nil);
- if (kbstate[SDL_SCANCODE_LCTRL] <> 0) or (kbstate[SDL_SCANCODE_RCTRL] <> 0) then curKbState := curKbState or THKeyEvent.ModCtrl;
- if (kbstate[SDL_SCANCODE_LALT] <> 0) or (kbstate[SDL_SCANCODE_RALT] <> 0) then curKbState := curKbState or THKeyEvent.ModAlt;
- if (kbstate[SDL_SCANCODE_LSHIFT] <> 0) or (kbstate[SDL_SCANCODE_RSHIFT] <> 0) then curKbState := curKbState or THKeyEvent.ModShift;
- end;
- {$ENDIF}
-
+ down: Boolean;
begin
result := false;
- {$IF not DEFINED(HEADLESS)}
- updateKBState();
- {$ENDIF}
case ev.type_ of
SDL_WINDOWEVENT:
SDL_QUITEV:
begin
- if gExit <> EXIT_QUIT then
+ if (gExit <> EXIT_QUIT) then
begin
if not wLoadingProgress then
begin
g_Game_Quit();
end
else
+ begin
wLoadingQuit := true;
+ end;
end;
result := true;
end;
SDL_KEYDOWN, SDL_KEYUP:
begin
key := ev.key.keysym.scancode;
+ down := (ev.type_ = SDL_KEYDOWN);
{$IF not DEFINED(HEADLESS)}
- if (g_holmes_enabled) then
+ if fuiOnSDLEvent(ev) then
begin
- if (ev.type_ = SDL_KEYDOWN) then kbev.kind := THKeyEvent.Press else kbev.kind := THKeyEvent.Release;
- kbev.scan := ev.key.keysym.scancode;
- kbev.sym := ev.key.keysym.sym;
- kbev.bstate := curMsButState;
- kbev.kstate := curKbState;
- if g_Holmes_keyEvent(kbev) then
- begin
- if (ev.type_ <> SDL_KEYDOWN) then e_KeyUpDown(ev.key.keysym.scancode, false);
- exit;
- end;
+ // event eaten, but...
+ if not down then e_KeyUpDown(key, false);
+ exit;
end;
{$ENDIF}
- if (ev.type_ = SDL_KEYDOWN) then KeyPress(key);
- e_KeyUpDown(ev.key.keysym.scancode, (ev.type_ = SDL_KEYDOWN));
+ if down then KeyPress(key);
+ e_KeyUpDown(key, down);
end;
{$IF not DEFINED(HEADLESS)}
- SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONUP:
- begin
- msev.dx := ev.button.x-curMsX;
- msev.dy := ev.button.y-curMsY;
- curMsX := ev.button.x;
- curMsY := ev.button.y;
- if (ev.type_ = SDL_MOUSEBUTTONDOWN) then msev.kind := THMouseEvent.Press else msev.kind := THMouseEvent.Release;
- msev.but := buildBut(ev.button.button);
- msev.x := curMsX;
- msev.y := curMsY;
- if (msev.but <> 0) then
- begin
- // ev.button.clicks: Byte
- if (ev.type_ = SDL_MOUSEBUTTONDOWN) then curMsButState := curMsButState or msev.but else curMsButState := curMsButState and (not msev.but);
- msev.bstate := curMsButState;
- msev.kstate := curKbState;
- if (g_holmes_enabled) then g_Holmes_mouseEvent(msev);
- end;
- end;
- SDL_MOUSEWHEEL:
- begin
- if (ev.wheel.y <> 0) then
- begin
- msev.dx := 0;
- msev.dy := ev.wheel.y;
- msev.kind := THMouseEvent.Press;
- if (ev.wheel.y < 0) then msev.but := THMouseEvent.WheelUp else msev.but := THMouseEvent.WheelDown;
- msev.x := curMsX;
- msev.y := curMsY;
- msev.bstate := curMsButState;
- msev.kstate := curKbState;
- if (g_holmes_enabled) then g_Holmes_mouseEvent(msev);
- end;
- end;
- SDL_MOUSEMOTION:
- begin
- msev.dx := ev.button.x-curMsX;
- msev.dy := ev.button.y-curMsY;
- curMsX := ev.button.x;
- curMsY := ev.button.y;
- msev.kind := THMouseEvent.Motion;
- msev.but := 0;
- msev.x := curMsX;
- msev.y := curMsY;
- msev.bstate := curMsButState;
- msev.kstate := curKbState;
- if (g_holmes_enabled) then g_Holmes_mouseEvent(msev);
- end;
+ SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONUP, SDL_MOUSEWHEEL, SDL_MOUSEMOTION:
+ fuiOnSDLEvent(ev);
{$ENDIF}
SDL_TEXTINPUT:
Utf8ToUnicode(@uc, PChar(ev.text.text), 1);
keychr := Word(uc);
if (keychr > 127) then keychr := Word(wchar2win(WideChar(keychr)));
- CharPress(AnsiChar(keychr));
+ if (keychr > 0) and (keychr <= 255) then CharPress(AnsiChar(keychr));
end;
// other key presses and joysticks are handled in e_input
end;
-procedure KillGLWindow();
-begin
- if (h_Wnd <> nil) then SDL_DestroyWindow(h_Wnd);
- if (h_GL <> nil) then SDL_GL_DeleteContext(h_GL);
- h_Wnd := nil;
- h_GL := nil;
-end;
-
-
function CreateGLWindow (Title: PChar): Boolean;
begin
result := false;
gWinSizeX := gScreenWidth;
gWinSizeY := gScreenHeight;
+{$IF not DEFINED(HEADLESS)}
wTitle := Title;
+{$ENDIF}
e_WriteLog('Creating window', TMsgType.Notify);
if not g_Window_SetDisplay() then
{$IF not DEFINED(HEADLESS)}
h_Gl := SDL_GL_CreateContext(h_Wnd);
if (h_Gl = nil) then exit;
+ if (assigned(oglInitCB)) then oglInitCB();
{$ENDIF}
e_ResizeWindow(gScreenWidth, gScreenHeight);
while (SDL_PollEvent(@ev) > 0) do
begin
+ EventHandler(ev);
if (ev.type_ = SDL_QUITEV) then break;
end;
+ e_PollJoysticks();
if (ev.type_ = SDL_QUITEV) or (gExit = EXIT_QUIT) then
begin
end;
-function ProcessMessage (): Boolean;
+function g_ProcessMessages (): Boolean;
var
- i, t: Integer;
ev: TSDL_Event;
begin
result := false;
FillChar(ev, SizeOf(ev), 0);
-
while (SDL_PollEvent(@ev) > 0) do
begin
result := EventHandler(ev);
if (ev.type_ = SDL_QUITEV) then exit;
end;
+ e_PollJoysticks();
+end;
+
+
+function ProcessMessage (): Boolean;
+var
+ i, t: Integer;
+begin
+ result := g_ProcessMessages();
Time := GetTimer();
Time_Delta := Time-Time_Old;
{$ENDIF}
arg: AnsiString;
mdfo: TStream;
+ itmp: Integer;
+ valres: Word;
begin
{$IFDEF HEADLESS}
e_NoGraphics := true;
+{$ELSE}
+ if (not g_holmes_imfunctional) then
+ begin
+ uiInitialize();
+ uiContext.font := 'win14';
+ end;
{$ENDIF}
idx := 1;
{.$ENDIF}
if arg = '--holmes' then begin g_holmes_enabled := true; g_Game_SetDebugMode(); end;
+
if (arg = '--holmes-ui-scale') or (arg = '-holmes-ui-scale') then
begin
if (idx <= ParamCount) then
begin
- if not conParseFloat(g_holmes_ui_scale, ParamStr(idx)) then g_holmes_ui_scale := 1.0;
+ if not conParseFloat(fuiRenderScale, ParamStr(idx)) then fuiRenderScale := 1.0;
+ Inc(idx);
+ end;
+ end;
+
+ if (arg = '--holmes-font') or (arg = '-holmes-font') then
+ begin
+ if (idx <= ParamCount) then
+ begin
+ itmp := 0;
+ val(ParamStr(idx), itmp, valres);
+ {$IFNDEF HEADLESS}
+ if (valres = 0) and (not g_holmes_imfunctional) then
+ begin
+ case itmp of
+ 8: uiContext.font := 'win8';
+ 14: uiContext.font := 'win14';
+ 16: uiContext.font := 'win16';
+ end;
+ end;
+ {$ELSE}
+ // fuck off, fpc!
+ itmp := itmp;
+ valres := valres;
+ {$ENDIF}
Inc(idx);
end;
end;
if not glHasExtension('GL_ARB_texture_non_power_of_two') then
begin
- e_WriteLog('Driver DID''T advertised NPOT textures support', TMsgType.Warning);
+ e_WriteLog('NPOT textures: NO', TMsgType.Warning);
glLegacyNPOT := true;
end
else
begin
- e_WriteLog('Driver advertised NPOT textures support', TMsgType.Notify);
+ e_WriteLog('NPOT textures: YES', TMsgType.Notify);
glLegacyNPOT := false;
end;
gwin_dump_extensions := false;