X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_window.pas;h=63de883338008a7f57c01742c4cf8eae7c5bf960;hb=2490c26ff92664ba96915ef1a7c6bd38c8137bda;hp=258b489b1f8f35f335061f207515c48406bab2b0;hpb=6880f8a491a247a34d6afb5508d0a64196a3d26d;p=d2df-sdl.git diff --git a/src/game/g_window.pas b/src/game/g_window.pas index 258b489..63de883 100644 --- a/src/game/g_window.pas +++ b/src/game/g_window.pas @@ -1,9 +1,8 @@ -(* Copyright (C) DooM 2D:Forever Developers +(* Copyright (C) Doom 2D: Forever Developers * * 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 @@ -18,868 +17,30 @@ unit g_window; interface -uses - utils; - -function SDLMain (): Integer; -function GetTimer (): Int64; -procedure ResetTimer (); -function CreateGLWindow (Title: PChar): Boolean; -procedure KillGLWindow (); -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 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; - + procedure ProcessLoading (forceUpdate: Boolean=false); implementation -uses -{$IFDEF WINDOWS}Windows,{$ENDIF} - SysUtils, Classes, MAPDEF, - 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, - sdlcarcass, fui_ctls; - - -const - ProgressUpdateMSecs = 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; -{$ENDIF} - wNeedTimeReset: Boolean = false; - wMinimized: Boolean = false; - wLoadingProgress: Boolean = false; - wLoadingQuit: Boolean = false; -{$IFNDEF WINDOWS} - ticksOverflow: Int64 = -1; - lastTicks: Uint32 = 0; // to detect overflow -{$ENDIF} - - -procedure KillGLWindow (); -begin - if (h_Wnd <> 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)} - 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; - if gWinMaximized then wFlags := wFlags or SDL_WINDOW_MAXIMIZED; - - KillGLWindow(); - - 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 (h_GL <> nil) 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 - gWinSizeX := gScreenWidth; - gWinSizeY := gScreenHeight; -{$IF not DEFINED(HEADLESS)} - 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; - gScreenWidth := w; - gScreenHeight := h; - end; - - if (gFullscreen <> fullscreen) then - begin - result := 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 - gScreenWidth := ev.data1; - gScreenHeight := ev.data2; - 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 - if wMinimized then - begin - e_ResizeWindow(gScreenWidth, gScreenHeight); - wMinimized := false; - wActivate := true; - end; - if not gWinMaximized 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 - if wMinimized then - begin - e_ResizeWindow(gScreenWidth, gScreenHeight); - wMinimized := false; - wActivate := true; - end; - if gWinMaximized then 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); + uses + {$IFNDEF HEADLESS} + r_render, {$ENDIF} + e_sound, g_system, g_net + ; - 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(); - 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; - if assigned(oglInitCB) then oglInitCB(); -{$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; - - -var - prevLoadingUpdateTime: UInt64 = 0; - -procedure ProcessLoading (forceUpdate: Boolean=false); -var - ev: TSDL_Event; - ID: LongWord; - stt: UInt64; -begin - FillChar(ev, sizeof(ev), 0); - wLoadingProgress := true; - - while (SDL_PollEvent(@ev) > 0) do + procedure ProcessLoading (forceUpdate: Boolean = False); 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 not wMinimized then - begin - if forceUpdate then + if sys_HandleInput() = False then begin - prevLoadingUpdateTime := getTimeMilli(); + {$IFNDEF HEADLESS} + r_Render_DrawLoading(forceUpdate); + {$ENDIF} + e_SoundUpdate(); + if NetMode = NET_SERVER then + g_Net_Host_Update + else if (NetMode = NET_CLIENT) and (NetState <> NET_STATE_AUTH) then + g_Net_Client_UpdateWhileLoading end - else - begin - stt := getTimeMilli(); - if (stt < prevLoadingUpdateTime) or (stt-prevLoadingUpdateTime >= ProgressUpdateMSecs) then - begin - prevLoadingUpdateTime := stt; - forceUpdate := true; - end; - end; - - if forceUpdate then - begin - if g_Texture_Get('INTER', ID) then - begin - e_DrawSize(ID, 0, 0, 0, false, false, gScreenWidth, gScreenHeight) - end - else - begin - e_Clear(GL_COLOR_BUFFER_BIT, 0, 0, 0); - end; - - DrawLoadingStat(); - SwapBuffers(); - end; end; - e_SoundUpdate(); - - if NetMode = NET_SERVER then - begin - g_Net_Host_Update(); - end - else - 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; - - -function ProcessMessage (): Boolean; -var - i, t: Integer; -begin - result := g_ProcessMessages(); - - Time := GetTimer(); - Time_Delta := Time-Time_Old; - - flag := false; - - if wNeedTimeReset then - begin - Time_Delta := 28; - wNeedTimeReset := false; - end; - - g_Map_ProfilersBegin(); - g_Mons_ProfilersBegin(); - - t := Time_Delta div 28; - if (t > 0) then - begin - flag := true; - for i := 1 to t do - begin - if (NetMode = NET_SERVER) then g_Net_Host_Update() - else if (NetMode = NET_CLIENT) then g_Net_Client_Update(); - Update(); - end; - end - else - begin - if (NetMode = NET_SERVER) then g_Net_Host_Update() - else if (NetMode = NET_CLIENT) then g_Net_Client_Update(); - end; - - g_Map_ProfilersEnd(); - g_Mons_ProfilersEnd(); - - if wLoadingQuit then - begin - g_Game_Free(); - g_Game_Quit(); - end; - - if (gExit = EXIT_QUIT) then - begin - result := true; - exit; - end; - - // Âðåìÿ ïðåäûäóùåãî îáíîâëåíèÿ - if flag then - begin - Time_Old := Time-(Time_Delta mod 28); - if (not wMinimized) then - begin - Draw(); - SwapBuffers(); - end; - end - else - begin - Sleep(1); // release time slice, so we won't eat 100% CPU - end; - - e_SoundUpdate(); -end; - - -procedure ReDrawWindow (); -begin - SwapBuffers(); -end; - - -procedure InitOpenGL (vsync: Boolean); -{$IF not DEFINED(HEADLESS)} -var - v: Byte; -{$ENDIF} -begin -{$IF not DEFINED(HEADLESS)} - 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); - 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... - SDL_GL_SetSwapInterval(v); -{$ENDIF} -end; - - -function glHasExtension (const name: AnsiString): Boolean; -var - exts: PChar; - i: Integer; - found: Boolean; - extName: ShortString; -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 - 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); - end; -end; - - -function SDLMain (): Integer; -var - idx: Integer; - {$IF not DEFINED(HEADLESS)} - ltmp: Integer; - {$ENDIF} - arg: AnsiString; - mdfo: TStream; -begin -{$IFDEF HEADLESS} - e_NoGraphics := true; -{$ENDIF} - - idx := 1; - while (idx <= ParamCount) do - begin - arg := ParamStr(idx); - Inc(idx); - if arg = '--opengl-dump-exts' then gwin_dump_extensions := true; - //if arg = '--twinkletwinkle' then gwin_k8_enable_light_experiments := true; - if arg = '--jah' then g_profile_history_size := 100; - if arg = '--no-particles' then gpart_dbg_enabled := false; - if arg = '--no-los' then gmon_dbg_los_enabled := false; - - if arg = '--profile-render' then g_profile_frame_draw := true; - if arg = '--profile-coldet' then g_profile_collision := true; - if arg = '--profile-los' then g_profile_los := true; - - if arg = '--no-part-phys' then gpart_dbg_phys_enabled := false; - if arg = '--no-part-physics' then gpart_dbg_phys_enabled := false; - if arg = '--no-particles-phys' then gpart_dbg_phys_enabled := false; - if arg = '--no-particles-physics' then gpart_dbg_phys_enabled := false; - if arg = '--no-particle-phys' then gpart_dbg_phys_enabled := false; - if arg = '--no-particle-physics' then gpart_dbg_phys_enabled := false; - - {.$IF DEFINED(D2F_DEBUG)} - if arg = '--aimline' then g_dbg_aimline_on := true; - {.$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(fuiRenderScale, ParamStr(idx)) then fuiRenderScale := 1.0; - Inc(idx); - end; - end; - - if (arg = '--game-scale') or (arg = '-game-scale') then - begin - if (idx <= ParamCount) then - begin - if not conParseFloat(g_dbg_scale, ParamStr(idx)) then g_dbg_scale := 1.0; - Inc(idx); - end; - end; - - if (arg = '--write-mapdef') or (arg = '-write-mapdef') then - begin - mdfo := createDiskFile('mapdef.txt'); - mdfo.WriteBuffer(defaultMapDef[1], Length(defaultMapDef)); - mdfo.Free(); - Halt(0); - end; - end; - - e_WriteLog('Initializing OpenGL', TMsgType.Notify); - InitOpenGL(gVSync); - - e_WriteLog('Creating GL window', TMsgType.Notify); - if not CreateGLWindow(PChar(Format('Doom 2D: Forever %s', [GAME_VERSION]))) then - begin - result := 0; - exit; - end; - - {EnumDisplayModes();} - -{$IFDEF HEADLESS} - //gwin_k8_enable_light_experiments := false; - gwin_has_stencil := false; - glLegacyNPOT := false; - gwin_dump_extensions := false; -{$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 - begin - e_WriteLog('NPOT textures: NO', TMsgType.Warning); - glLegacyNPOT := true; - end - else - begin - e_WriteLog('NPOT textures: YES', TMsgType.Notify); - glLegacyNPOT := false; - end; - gwin_dump_extensions := false; -{$ENDIF} - - Init(); - Time_Old := GetTimer(); - - // Êîìàíäíàÿ ñòðîêà - if (ParamCount > 0) then g_Game_Process_Params(); - - // Çàïðîñ ÿçûêà - if (not gGameOn) and gAskLanguage then g_Menu_AskLanguage(); - - e_WriteLog('Entering the main loop', TMsgType.Notify); - - // main loop - while not ProcessMessage() do begin end; - - Release(); - KillGLWindow(); - - result := 0; -end; - - end.