X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_window.pas;h=80e63fd640ae7fce250d3e713d7d6944440cfeb6;hb=dcddacd6f339e310c23663bd7e0b6ec7733ccf0f;hp=479ffcb16c69fd93924066f95ff3cc1aa442831d;hpb=fa19c8b6935b105a8414ff342fafea86635e7cec;p=d2df-sdl.git diff --git a/src/game/g_window.pas b/src/game/g_window.pas index 479ffcb..80e63fd 100644 --- a/src/game/g_window.pas +++ b/src/game/g_window.pas @@ -37,6 +37,9 @@ function g_Window_SetSize (w, h: Word; fullscreen: Boolean): Boolean; procedure ProcessLoading (forceUpdate: Boolean=false); +// returns `true` if quit event was received +function g_ProcessMessages (): Boolean; + var gwin_dump_extensions: Boolean = false; @@ -53,7 +56,8 @@ uses 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 @@ -62,10 +66,11 @@ 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; @@ -74,18 +79,23 @@ var 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)} @@ -97,11 +107,7 @@ begin 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 @@ -127,13 +133,14 @@ 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; @@ -176,14 +183,15 @@ begin 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)} @@ -212,15 +220,6 @@ begin 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; @@ -241,7 +240,6 @@ begin SDL_WINDOWEVENT_MINIMIZED: begin - resetKMState(); e_UnpressAllKeys(); if not wMinimized then begin @@ -258,7 +256,6 @@ begin SDL_WINDOWEVENT_RESIZED: begin - resetKMState(); gScreenWidth := ev.data1; gScreenHeight := ev.data2; ChangeWindowSize(); @@ -275,7 +272,6 @@ begin SDL_WINDOWEVENT_MAXIMIZED: begin - resetKMState(); if wMinimized then begin e_ResizeWindow(gScreenWidth, gScreenHeight); @@ -295,15 +291,13 @@ begin 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'); @@ -313,19 +307,15 @@ begin 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; @@ -350,6 +340,8 @@ begin end; gWinActive := false; + + if assigned(winBlurCB) then winBlurCB(); end; end else if wActivate then @@ -372,6 +364,7 @@ begin end; gWinActive := true; + if assigned(winFocusCB) then winFocusCB(); end; end; end; @@ -381,39 +374,9 @@ function EventHandler (var ev: TSDL_Event): Boolean; 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: @@ -421,7 +384,7 @@ begin SDL_QUITEV: begin - if gExit <> EXIT_QUIT then + if (gExit <> EXIT_QUIT) then begin if not wLoadingProgress then begin @@ -429,7 +392,9 @@ begin g_Game_Quit(); end else + begin wLoadingQuit := true; + end; end; result := true; end; @@ -437,74 +402,22 @@ begin 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: @@ -512,7 +425,7 @@ begin 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 @@ -528,15 +441,6 @@ begin 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; @@ -544,7 +448,9 @@ begin gWinSizeX := gScreenWidth; gWinSizeY := gScreenHeight; +{$IF not DEFINED(HEADLESS)} wTitle := Title; +{$ENDIF} e_WriteLog('Creating window', TMsgType.Notify); if not g_Window_SetDisplay() then @@ -557,6 +463,7 @@ begin {$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); @@ -633,8 +540,10 @@ begin 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 @@ -689,19 +598,26 @@ 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; @@ -845,9 +761,17 @@ var {$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; @@ -877,11 +801,36 @@ begin {.$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; @@ -928,12 +877,12 @@ begin 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;