X-Git-Url: http://deadsoftware.ru/gitweb?p=d2df-sdl.git;a=blobdiff_plain;f=src%2Fgame%2Fg_window.pas;h=7774c0a34c0c03b2bda5fd5418ece817dc492963;hp=56df2d169d730e2526a2d373328f85436675c0b1;hb=676995a77ad243efc0abee75841f81e86a7262a0;hpb=376b5b869bc531910583ff8bf68d8aabeb048497 diff --git a/src/game/g_window.pas b/src/game/g_window.pas index 56df2d1..7774c0a 100644 --- a/src/game/g_window.pas +++ b/src/game/g_window.pas @@ -2,8 +2,7 @@ * * 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. + * the Free Software Foundation, version 3 of the License ONLY. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -22,627 +21,82 @@ uses utils; function SDLMain (): Integer; -function GetTimer (): Int64; procedure ResetTimer (); -procedure PushExitEvent (); -function ProcessMessage (): Boolean; -procedure ReDrawWindow (); -procedure SwapBuffers (); -procedure Sleep (ms: LongWord); -function GetDisplayModes (dbpp: LongWord; var selres: LongWord): SSArray; -function g_Window_SetDisplay (preserveGL: Boolean=false): Boolean; -function g_Window_SetSize (w, h: Word; fullscreen: Boolean): Boolean; -procedure g_SetVSync (vsync: Boolean); - procedure ProcessLoading (forceUpdate: Boolean=false); -// returns `true` if quit event was received -function g_ProcessMessages (): Boolean; - - var gwin_dump_extensions: Boolean = false; gwin_has_stencil: Boolean = false; gwin_k8_enable_light_experiments: Boolean = false; g_dbg_aimline_on: Boolean = false; - + g_dbg_input: Boolean = False; implementation uses {$IFDEF WINDOWS}Windows,{$ENDIF} - SysUtils, Classes, MAPDEF, - SDL2, GL, GLExt, e_graphics, e_log, e_texture, g_main, +{$IFDEF ENABLE_HOLMES} + g_holmes, sdlcarcass, fui_ctls, +{$ENDIF} +{$INCLUDE ../nogl/noGLuses.inc} + SysUtils, Classes, MAPDEF, Math, + 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, - sdlcarcass, fui_ctls; + g_map, g_gfx, g_monsters, xprofiler, + g_touch, g_gui, g_system, g_netmaster; const - ProgressUpdateMSecs = 1;//100; + ProgressUpdateMSecs = 35; //1;//100; var - h_Wnd: PSDL_Window = nil; - h_GL: TSDL_GLContext = nil; Time, Time_Delta, Time_Old: Int64; flag: Boolean; -{$IF not DEFINED(HEADLESS)} - wTitle: PChar = nil; - wasFullscreen: Boolean = true; // so we need to recreate the window -{$ENDIF} wNeedTimeReset: Boolean = false; wMinimized: Boolean = false; - wMaximized: Boolean = false; - wLoadingProgress: Boolean = false; wLoadingQuit: Boolean = false; -{$IFNDEF WINDOWS} - ticksOverflow: Int64 = -1; - lastTicks: Uint32 = 0; // to detect overflow -{$ENDIF} - - -procedure KillGLWindow (preserveGL: Boolean); -begin - if (h_GL <> nil) and (not preserveGL) then begin if (assigned(oglDeinitCB)) then oglDeinitCB(); end; - if (h_Wnd <> nil) then SDL_DestroyWindow(h_Wnd); - if (h_GL <> nil) and (not preserveGL) then SDL_GL_DeleteContext(h_GL); - h_Wnd := nil; - if (not preserveGL) then h_GL := nil; -end; - - -function g_Window_SetDisplay (preserveGL: Boolean = false): Boolean; -{$IF not DEFINED(HEADLESS)} -var - mode, cmode: TSDL_DisplayMode; - wFlags: LongWord = 0; - nw, nh: Integer; -{$ENDIF} -begin -{$IF not DEFINED(HEADLESS)} - result := false; - - e_WriteLog('Setting display mode...', TMsgType.Notify); - - wFlags := SDL_WINDOW_OPENGL {or SDL_WINDOW_RESIZABLE}; - if gFullscreen then wFlags := wFlags {or SDL_WINDOW_FULLSCREEN} else wFlags := wFlags or SDL_WINDOW_RESIZABLE; - if (not gFullscreen) and (not preserveGL) and gWinMaximized then wFlags := wFlags or SDL_WINDOW_MAXIMIZED else gWinMaximized := false; - - 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 - e_WriteLog('SDL: cannot find display mode for '+IntToStr(gScreenWidth), TMsgType.Notify); - gScreenWidth := 800; - gScreenHeight := 600; - end - else - begin - e_WriteLog('SDL: found display mode for '+IntToStr(gScreenWidth)+'x'+IntToStr(gScreenHeight)+': '+IntToStr(cmode.w)+'x'+IntToStr(cmode.h), TMsgType.Notify); - gScreenWidth := cmode.w; - gScreenHeight := cmode.h; - end; - end; - - if (preserveGL) and (h_Wnd <> nil) and (not gFullscreen) and (not wasFullscreen) then - begin - //SDL_SetWindowMaximumSize(h_Wnd, gScreenWidth, gScreenHeight); - //SDL_SetWindowDisplayMode(h_Wnd, @cmode); - if (wMaximized) then SDL_RestoreWindow(h_Wnd); - wMaximized := false; - gWinMaximized := false; - SDL_SetWindowSize(h_Wnd, gScreenWidth, gScreenHeight); - //SDL_SetWindowFullscreen(h_Wnd, SDL_WINDOW_FULLSCREEN); - //SDL_SetWindowFullscreen(h_Wnd, 0); - end - else - begin - KillGLWindow(preserveGL); - h_Wnd := SDL_CreateWindow(PChar(wTitle), gWinRealPosX, gWinRealPosY, gScreenWidth, gScreenHeight, wFlags); - if gFullscreen then - SDL_SetWindowFullscreen(h_Wnd, SDL_WINDOW_FULLSCREEN); - if (h_Wnd = nil) then exit; - end; - wasFullscreen := gFullscreen; - - SDL_GL_MakeCurrent(h_Wnd, h_GL); - SDL_ShowCursor(SDL_DISABLE); - if (gFullscreen) then - begin - nw := 0; - nh := 0; - SDL_GetWindowSize(h_Wnd, @nw, @nh); - if (nw > 128) and (nh > 128) then - begin - e_WriteLog('SDL: fullscreen window got size '+IntToStr(nw)+'x'+IntToStr(nh)+': '+IntToStr(gScreenWidth)+'x'+IntToStr(gScreenHeight), TMsgType.Notify); - gScreenWidth := nw; - gScreenHeight := nh; - end - else - begin - e_WriteLog('SDL: fullscreen window got invalid size: '+IntToStr(nw)+'x'+IntToStr(nh), TMsgType.Notify); - end; - end; - fuiScrWdt := gScreenWidth; - fuiScrHgt := gScreenHeight; - if (h_GL <> nil) and (not preserveGL) then begin if (assigned(oglInitCB)) then oglInitCB(); end; -{$ENDIF} - - result := true; -end; - - -function GetDisplayModes (dbpp: LongWord; var selres: LongWord): SSArray; -var - mode: TSDL_DisplayMode; - res, i, k, n, pw, ph: Integer; -begin - SetLength(result, 0); - {$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.', TMsgType.Notify); -end; - - -procedure Sleep (ms: LongWord); -begin - SDL_Delay(ms); -end; - - -procedure ChangeWindowSize (); -begin - e_LogWritefln(' ChangeWindowSize: (ws=%dx%d) (ss=%dx%d)', [gWinSizeX, gWinSizeY, gScreenWidth, gScreenHeight]); - gWinSizeX := gScreenWidth; - gWinSizeY := gScreenHeight; -{$IF not DEFINED(HEADLESS)} - fuiScrWdt := gScreenWidth; - fuiScrHgt := gScreenHeight; - e_ResizeWindow(gScreenWidth, gScreenHeight); - g_Game_SetupScreenSize(); - g_Menu_Reset(); - g_Game_ClearLoading(); -{$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)} - preserve := false; - - if (gScreenWidth <> w) or (gScreenHeight <> h) then - begin - result := true; - preserve := true; - gScreenWidth := w; - gScreenHeight := h; - end; - - if (gFullscreen <> fullscreen) then - begin - result := true; - preserve := true; - gFullscreen := fullscreen; - preserve := true; - end; - - if result then - begin - g_Window_SetDisplay(preserve); - ChangeWindowSize(); - end; -{$ENDIF} -end; - - -function WindowEventHandler (constref ev: TSDL_WindowEvent): Boolean; -var - wActivate, wDeactivate: Boolean; -begin - result := false; - wActivate := false; - wDeactivate := false; - - case ev.event of - SDL_WINDOWEVENT_MOVED: - begin - if not (gFullscreen or gWinMaximized) then - begin - gWinRealPosX := ev.data1; - gWinRealPosY := ev.data2; - end; - end; - - SDL_WINDOWEVENT_MINIMIZED: - begin - e_UnpressAllKeys(); - if not wMinimized then - begin - e_ResizeWindow(0, 0); - wMinimized := true; - if g_debug_WinMsgs then - begin - g_Console_Add('Now minimized'); - e_WriteLog('[DEBUG] WinMsgs: Now minimized', TMsgType.Notify); - end; - wDeactivate := true; - end; - end; - - SDL_WINDOWEVENT_RESIZED: - begin - e_LogWritefln('Resize: (os=%dx%d) (ns=%dx%d)', [gScreenWidth, gScreenHeight, Integer(ev.data1), Integer(ev.data2)]); - {if (gFullscreen) then - begin - e_LogWriteln(' fullscreen fix applied.'); - if (gScreenWidth <> ev.data1) or (gScreenHeight <> ev.data2) then - begin - SDL_SetWindowSize(h_Wnd, gScreenWidth, gScreenHeight); - end; - end - else} - begin - gScreenWidth := ev.data1; - gScreenHeight := ev.data2; - end; - ChangeWindowSize(); - SwapBuffers(); - if g_debug_WinMsgs then - begin - g_Console_Add('Resized to ' + IntToStr(ev.data1) + 'x' + IntToStr(ev.data2)); - e_WriteLog('[DEBUG] WinMsgs: Resized to ' + IntToStr(ev.data1) + 'x' + IntToStr(ev.data2), TMsgType.Notify); - end; - end; - - SDL_WINDOWEVENT_EXPOSED: - SwapBuffers(); - - SDL_WINDOWEVENT_MAXIMIZED: - begin - wMaximized := true; - if wMinimized then - begin - e_ResizeWindow(gScreenWidth, gScreenHeight); - wMinimized := false; - wActivate := true; - end; - if (not gWinMaximized) and (not gFullscreen) then - begin - gWinMaximized := true; - if g_debug_WinMsgs then - begin - g_Console_Add('Now maximized'); - e_WriteLog('[DEBUG] WinMsgs: Now maximized', TMsgType.Notify); - end; - end; - end; - - SDL_WINDOWEVENT_RESTORED: - begin - wMaximized := false; - if wMinimized then - begin - e_ResizeWindow(gScreenWidth, gScreenHeight); - wMinimized := false; - wActivate := true; - end; - gWinMaximized := false; - if g_debug_WinMsgs then - begin - g_Console_Add('Now restored'); - e_WriteLog('[DEBUG] WinMsgs: Now restored', TMsgType.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_UnpressAllKeys(); - //e_WriteLog('window lost focus!', MSG_NOTIFY); - end; - end; - - if wDeactivate then - begin - if gWinActive then - begin - e_WriteLog('deactivating window', TMsgType.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 - g_Console_Add('Now inactive'); - e_WriteLog('[DEBUG] WinMsgs: Now inactive', TMsgType.Notify); - end; - - gWinActive := false; - - if assigned(winBlurCB) then winBlurCB(); - end; - end - else if wActivate then - 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 - g_Console_Add('Now active'); - e_WriteLog('[DEBUG] WinMsgs: Now active', TMsgType.Notify); - end; - - gWinActive := true; - if assigned(winFocusCB) then winFocusCB(); - end; - end; -end; - - -function EventHandler (var ev: TSDL_Event): Boolean; -var - key, keychr: Word; - uc: UnicodeChar; - down: Boolean; -begin - result := false; - - case ev.type_ of - SDL_WINDOWEVENT: - result := WindowEventHandler(ev.window); - - SDL_QUITEV: - begin - if (gExit <> EXIT_QUIT) then - begin - if not wLoadingProgress then - begin - g_Game_Free(); - 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 fuiOnSDLEvent(ev) then - begin - // event eaten, but... - if not down then e_KeyUpDown(key, false); - exit; - end; - {$ENDIF} - if down then KeyPress(key); - e_KeyUpDown(key, down); - end; - - {$IF not DEFINED(HEADLESS)} - SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONUP, SDL_MOUSEWHEEL, SDL_MOUSEMOTION: - fuiOnSDLEvent(ev); - {$ENDIF} - - SDL_TEXTINPUT: - begin - Utf8ToUnicode(@uc, PChar(ev.text.text), 1); - keychr := Word(uc); - if (keychr > 127) then keychr := Word(wchar2win(WideChar(keychr))); - if (keychr > 0) and (keychr <= 255) then CharPress(AnsiChar(keychr)); - end; - - // other key presses and joysticks are handled in e_input - end; -end; - - -procedure SwapBuffers (); -begin - {$IF not DEFINED(HEADLESS)} - SDL_GL_SwapWindow(h_Wnd); - {$ENDIF} -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 - begin - KillGLWindow(false); - e_WriteLog('Window creation error (resolution not supported?)', TMsgType.Fatal); - exit; - end; - -{$IF not DEFINED(HEADLESS)} - h_GL := SDL_GL_CreateContext(h_Wnd); - if (h_GL = nil) then exit; - fuiScrWdt := gScreenWidth; - fuiScrHgt := gScreenHeight; - if (assigned(oglInitCB)) then oglInitCB(); - g_SetVSync(gVSync); -{$ENDIF} - - e_ResizeWindow(gScreenWidth, gScreenHeight); - e_InitGL(); - - result := true; -end; - - -{$IFDEF WINDOWS} -// windoze sux; in headless mode `GetTickCount()` (and SDL) returns shit -function GetTimer (): Int64; -var - F, C: Int64; -begin - QueryPerformanceFrequency(F); - QueryPerformanceCounter(C); - result := Round(C/F*1000{000}); -end; -{$ELSE} -function GetTimer (): Int64; -var - t: Uint32; - tt: Int64; -begin - t := SDL_GetTicks(); - 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 wNeedTimeReset := true; end; - -procedure PushExitEvent (); -var - ev: TSDL_Event; -begin - ev.type_ := SDL_QUITEV; - SDL_PushEvent(@ev); -end; - - +{$IFNDEF HEADLESS} var prevLoadingUpdateTime: UInt64 = 0; +{$ENDIF} procedure ProcessLoading (forceUpdate: Boolean=false); +{$IFNDEF HEADLESS} var - ev: TSDL_Event; - ID: LongWord; stt: UInt64; +{$ENDIF} begin - FillChar(ev, sizeof(ev), 0); - wLoadingProgress := true; - - 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 - wLoadingProgress := false; - exit; - end; + if sys_HandleInput() = True then + Exit; +{$IFNDEF HEADLESS} if not wMinimized then begin - if forceUpdate then - begin - prevLoadingUpdateTime := getTimeMilli(); - end - else + if not forceUpdate then begin stt := getTimeMilli(); - if (stt < prevLoadingUpdateTime) or (stt-prevLoadingUpdateTime >= ProgressUpdateMSecs) then - begin - prevLoadingUpdateTime := stt; - forceUpdate := true; - end; + forceUpdate := (stt < prevLoadingUpdateTime) or (stt-prevLoadingUpdateTime >= ProgressUpdateMSecs); end; if forceUpdate then begin - if g_Texture_Get('INTER', ID) then - begin - e_DrawSize(ID, 0, 0, 0, false, false, gScreenWidth, gScreenHeight); - e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150); - end - else - begin - e_Clear(GL_COLOR_BUFFER_BIT, 0, 0, 0); - end; + DrawMenuBackground('INTER'); + e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150); DrawLoadingStat(); - SwapBuffers(); + g_Console_Draw(True); + sys_Repaint; + prevLoadingUpdateTime := getTimeMilli(); end; end; +{$ENDIF} e_SoundUpdate(); @@ -654,23 +108,6 @@ begin begin if (NetMode = NET_CLIENT) and (NetState <> NET_STATE_AUTH) then g_Net_Client_UpdateWhileLoading(); end; - - wLoadingProgress := false; -end; - - -function g_ProcessMessages (): Boolean; -var - 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; @@ -678,9 +115,9 @@ function ProcessMessage (): Boolean; var i, t: Integer; begin - result := g_ProcessMessages(); + result := sys_HandleInput(); - Time := GetTimer(); + Time := sys_GetTicks(); Time_Delta := Time-Time_Old; flag := false; @@ -711,6 +148,8 @@ begin else if (NetMode = NET_CLIENT) then g_Net_Client_Update(); end; + if NetMode = NET_SERVER then g_Net_Flush(); + g_Map_ProfilersEnd(); g_Mons_ProfilersEnd(); @@ -729,124 +168,81 @@ begin // Âðåìÿ ïðåäûäóùåãî îáíîâëåíèÿ if flag then begin - Time_Old := Time-(Time_Delta mod 28); + Time_Old := Time - (Time_Delta mod 28); if (not wMinimized) then begin - Draw(); - SwapBuffers(); - end; + Draw; + sys_Repaint + end end else begin - Sleep(1); // release time slice, so we won't eat 100% CPU + sys_Delay(1) // release time slice, so we won't eat 100% CPU end; e_SoundUpdate(); end; - -procedure ReDrawWindow (); -begin - SwapBuffers(); -end; - - -procedure g_SetVSync (vsync: Boolean); -{$IF not DEFINED(HEADLESS)} +function GLExtensionList (): SSArray; var - v: Byte; -{$ENDIF} + s: PChar; + i, j, num: GLint; begin -{$IF not DEFINED(HEADLESS)} - if vsync then v := 1 else v := 0; - if (SDL_GL_SetSwapInterval(v) <> 0) then - begin - e_WriteLog('oops; can''t change vsync option, restart required', TMsgType.Warning); - end - else - begin - if vsync then e_WriteLog('VSync: ON', TMsgType.Notify) else e_WriteLog('VSync: OFF', TMsgType.Notify); + result := nil; + s := glGetString(GL_EXTENSIONS); + if s <> nil then + begin + num := 0; + i := 0; + j := 0; + while (s[i] <> #0) and (s[i] = ' ') do Inc(i); + while (s[i] <> #0) do + begin + while (s[i] <> #0) and (s[i] <> ' ') do Inc(i); + SetLength(result, num+1); + result[num] := Copy(s, j+1, i-j); + while (s[i] <> #0) and (s[i] = ' ') do Inc(i); + j := i; + Inc(num); + end; end; -{$ENDIF} end; - -procedure InitOpenGL (); -begin -{$IF not DEFINED(HEADLESS)} - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); // lights; it is enough to have 1-bit stencil buffer for lighting, but... -{$ENDIF} -end; - - -function glHasExtension (const name: AnsiString): Boolean; +function GLExtensionSupported (ext: AnsiString): Boolean; var - exts: PChar; - i: Integer; - found: Boolean; - extName: ShortString; + exts: SSArray; + e: AnsiString; begin result := false; - if (Length(name) = 0) then exit; - exts := glGetString(GL_EXTENSIONS); - if (exts = nil) then exit; - while (exts[0] <> #0) and (exts[0] = ' ') do Inc(exts); - while (exts[0] <> #0) do + exts := GLExtensionList(); + for e in exts do begin - if gwin_dump_extensions then - begin - i := 0; - while (exts[i] <> #0) and (exts[i] <> ' ') do Inc(i); - if i > 255 then - begin - e_WriteLog('FUUUUUUUUUUUUU', TMsgType.Warning); - end - else - begin - Move(exts^, extName[1], i); - extName[0] := Char(i); - e_WriteLog(Format('EXT: %s', [extName]), TMsgType.Notify); - end; - end; - found := true; - for i := 0 to length(name)-1 do - begin - if (exts[i] = #0) then begin found := false; break; end; - if (exts[i] <> name[i+1]) then begin found := false; break; end; - end; - if found and ((exts[Length(name)] = #0) or (exts[Length(name)] = ' ')) then begin result := true; exit; end; - while (exts[0] <> #0) and (exts[0] <> ' ') do Inc(exts); - while (exts[0] <> #0) and (exts[0] = ' ') do Inc(exts); + //writeln('<', e, '> : [', ext, '] = ', strEquCI1251(e, ext)); + if (strEquCI1251(e, ext)) then begin result := true; exit; end; end; end; +procedure PrintGLSupportedExtensions; +begin + e_LogWritefln('GL Vendor: %s', [glGetString(GL_VENDOR)]); + e_LogWritefln('GL Renderer: %s', [glGetString(GL_RENDERER)]); + e_LogWritefln('GL Version: %s', [glGetString(GL_VERSION)]); + e_LogWritefln('GL Shaders: %s', [glGetString(GL_SHADING_LANGUAGE_VERSION)]); + e_LogWritefln('GL Extensions: %s', [glGetString(GL_EXTENSIONS)]); +end; function SDLMain (): Integer; var idx: Integer; - {$IF not DEFINED(HEADLESS)} - ltmp: Integer; - {$ENDIF} arg: AnsiString; mdfo: TStream; + {$IFDEF ENABLE_HOLMES} itmp: Integer; valres: Word; + {$ENDIF} begin {$IFDEF HEADLESS} e_NoGraphics := true; -{$ELSE} - if (not g_holmes_imfunctional) then - begin - uiInitialize(); - uiContext.font := 'win14'; - end; {$ENDIF} idx := 1; @@ -871,10 +267,13 @@ begin if arg = '--no-particle-phys' then gpart_dbg_phys_enabled := false; if arg = '--no-particle-physics' then gpart_dbg_phys_enabled := false; + if arg = '--debug-input' then g_dbg_input := True; + {.$IF DEFINED(D2F_DEBUG)} if arg = '--aimline' then g_dbg_aimline_on := true; {.$ENDIF} +{$IFDEF ENABLE_HOLMES} if arg = '--holmes' then begin g_holmes_enabled := true; g_Game_SetDebugMode(); end; if (arg = '--holmes-ui-scale') or (arg = '-holmes-ui-scale') then @@ -909,6 +308,7 @@ begin Inc(idx); end; end; +{$ENDIF} if (arg = '--game-scale') or (arg = '-game-scale') then begin @@ -926,62 +326,63 @@ begin mdfo.Free(); Halt(0); end; - end; - - e_WriteLog('Initializing OpenGL', TMsgType.Notify); - InitOpenGL(); - e_WriteLog('Creating GL window', TMsgType.Notify); - if not CreateGLWindow(PChar(Format('Doom 2D: Forever %s', [GAME_VERSION]))) then - begin - result := 0; - exit; + if (arg = '--pixel-scale') or (arg = '-pixel-scale') then + begin + if (idx <= ParamCount) then + begin + if not conParseFloat(r_pixel_scale, ParamStr(idx)) then r_pixel_scale := 1.0; + Inc(idx); + end; + end; end; - {EnumDisplayModes();} - -{$IFDEF HEADLESS} - //gwin_k8_enable_light_experiments := false; - gwin_has_stencil := false; - glLegacyNPOT := false; - gwin_dump_extensions := false; +{$IFNDEF USE_SYSSTUB} + PrintGLSupportedExtensions; + glLegacyNPOT := not (GLExtensionSupported('GL_ARB_texture_non_power_of_two') or GLExtensionSupported('GL_OES_texture_npot')); {$ELSE} - SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, @ltmp); - e_LogWritefln('stencil buffer size: %s', [ltmp]); - gwin_has_stencil := (ltmp > 0); - - if not glHasExtension('GL_ARB_texture_non_power_of_two') then + glLegacyNPOT := False; + glRenderToFBO := False; +{$ENDIF} + if glNPOTOverride and glLegacyNPOT then begin - e_WriteLog('NPOT textures: NO', TMsgType.Warning); glLegacyNPOT := true; + e_logWriteln('NPOT texture emulation: FORCED'); end else begin - e_WriteLog('NPOT textures: YES', TMsgType.Notify); - glLegacyNPOT := false; + if (glLegacyNPOT) then e_logWriteln('NPOT texture emulation: enabled') + else e_logWriteln('NPOT texture emulation: disabled'); end; gwin_dump_extensions := false; -{$ENDIF} - Init(); - Time_Old := GetTimer(); + Init; + Time_Old := sys_GetTicks(); + + g_Net_InitLowLevel(); // Êîìàíäíàÿ ñòðîêà if (ParamCount > 0) then g_Game_Process_Params(); +{$IFNDEF HEADLESS} // Çàïðîñ ÿçûêà if (not gGameOn) and gAskLanguage then g_Menu_AskLanguage(); +{$ENDIF} e_WriteLog('Entering the main loop', TMsgType.Notify); // main loop while not ProcessMessage() do begin end; + g_Net_Slist_ShutdownAll(); + Release(); - KillGLWindow(false); + g_Net_DeinitLowLevel(); result := 0; end; +initialization + conRegVar('d_input', @g_dbg_input, '', '') end.