DEADSOFTWARE

fix slope interpolation; add r_maxfps
[d2df-sdl.git] / src / game / g_window.pas
1 (* Copyright (C) Doom 2D: Forever Developers
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, version 3 of the License ONLY.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *)
15 {$INCLUDE ../shared/a_modes.inc}
16 unit g_window;
18 interface
20 uses
21 utils;
23 function SDLMain (): Integer;
24 procedure ResetTimer ();
25 procedure ProcessLoading (forceUpdate: Boolean=false);
27 var
28 gwin_dump_extensions: Boolean = false;
29 gwin_has_stencil: Boolean = false;
30 gwin_k8_enable_light_experiments: Boolean = false;
31 g_dbg_aimline_on: Boolean = false;
32 g_dbg_input: Boolean = False;
34 implementation
36 uses
37 {$IFDEF WINDOWS}Windows,{$ENDIF}
38 {$IFDEF ENABLE_HOLMES}
39 g_holmes, sdlcarcass, fui_ctls,
40 {$ENDIF}
41 {$INCLUDE ../nogl/noGLuses.inc}
42 SysUtils, Classes, MAPDEF, Math,
43 e_graphics, e_log, e_texture, g_main,
44 g_console, e_input, g_options, g_game,
45 g_basic, g_textures, e_sound, g_sound, g_menu, ENet, g_net,
46 g_map, g_gfx, g_monsters, xprofiler,
47 g_touch, g_gui, g_system, g_netmaster;
50 const
51 ProgressUpdateMSecs = 35; //1;//100;
53 var
54 Time, Time_Delta, Time_Old: Int64;
55 Frame: Int64;
56 flag: Boolean;
57 wNeedTimeReset: Boolean = false;
58 wMinimized: Boolean = false;
59 wLoadingQuit: Boolean = false;
61 procedure ResetTimer ();
62 begin
63 wNeedTimeReset := true;
64 end;
66 {$IFNDEF HEADLESS}
67 var
68 prevLoadingUpdateTime: UInt64 = 0;
69 {$ENDIF}
71 procedure ProcessLoading (forceUpdate: Boolean=false);
72 {$IFNDEF HEADLESS}
73 var
74 stt: UInt64;
75 {$ENDIF}
76 begin
77 if sys_HandleInput() = True then
78 Exit;
80 {$IFNDEF HEADLESS}
81 if not wMinimized then
82 begin
83 if not forceUpdate then
84 begin
85 stt := getTimeMilli();
86 forceUpdate := (stt < prevLoadingUpdateTime) or (stt-prevLoadingUpdateTime >= ProgressUpdateMSecs);
87 end;
89 if forceUpdate then
90 begin
91 DrawMenuBackground('INTER');
92 e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150);
94 DrawLoadingStat();
95 g_Console_Draw(True);
96 sys_Repaint;
97 prevLoadingUpdateTime := getTimeMilli();
98 end;
99 end;
100 {$ENDIF}
102 e_SoundUpdate();
104 if NetMode = NET_SERVER then
105 begin
106 g_Net_Host_Update();
107 end
108 else
109 begin
110 if (NetMode = NET_CLIENT) and (NetState <> NET_STATE_AUTH) then g_Net_Client_UpdateWhileLoading();
111 end;
112 end;
115 function ProcessMessage (): Boolean;
116 var
117 i, t: Integer;
118 begin
119 result := sys_HandleInput();
121 Time := sys_GetTicks();
122 Time_Delta := Time-Time_Old;
124 flag := false;
126 if wNeedTimeReset then
127 begin
128 Frame := 0;
129 Time_Delta := 28;
130 wNeedTimeReset := false;
131 end;
133 g_Map_ProfilersBegin();
134 g_Mons_ProfilersBegin();
136 t := Time_Delta div 28;
137 if (t > 0) then
138 begin
139 flag := true;
140 for i := 1 to t do
141 begin
142 if (NetMode = NET_SERVER) then g_Net_Host_Update()
143 else if (NetMode = NET_CLIENT) then g_Net_Client_Update();
144 Update();
145 end;
146 end
147 else
148 begin
149 if (NetMode = NET_SERVER) then g_Net_Host_Update()
150 else if (NetMode = NET_CLIENT) then g_Net_Client_Update();
151 end;
153 if NetMode = NET_SERVER then g_Net_Flush();
155 g_Map_ProfilersEnd();
156 g_Mons_ProfilersEnd();
158 if wLoadingQuit then
159 begin
160 g_Game_Free();
161 g_Game_Quit();
162 end;
164 if (gExit = EXIT_QUIT) then
165 begin
166 result := true;
167 exit;
168 end;
170 // Âðåìÿ ïðåäûäóùåãî îáíîâëåíèÿ
171 if flag then
172 Time_Old := Time - (Time_Delta mod 28);
174 // don't wait if VSync is on, GL already probably waits enough
175 if gLerpActors then
176 flag := (Time - Frame >= gFrameTime) or gVSync;
178 if flag then
179 begin
180 if (not wMinimized) then
181 begin
182 if gPause or not gLerpActors then
183 gLerpFactor := 1.0
184 else
185 gLerpFactor := nmin(1.0, (Time - Time_Old) / 28.0);
186 Draw;
187 sys_Repaint
188 end;
189 Frame := Time
190 end
191 else
192 sys_Delay(1);
194 e_SoundUpdate();
195 end;
197 function GLExtensionList (): SSArray;
198 var
199 s: PChar;
200 i, j, num: GLint;
201 begin
202 result := nil;
203 s := glGetString(GL_EXTENSIONS);
204 if s <> nil then
205 begin
206 num := 0;
207 i := 0;
208 j := 0;
209 while (s[i] <> #0) and (s[i] = ' ') do Inc(i);
210 while (s[i] <> #0) do
211 begin
212 while (s[i] <> #0) and (s[i] <> ' ') do Inc(i);
213 SetLength(result, num+1);
214 result[num] := Copy(s, j+1, i-j);
215 while (s[i] <> #0) and (s[i] = ' ') do Inc(i);
216 j := i;
217 Inc(num);
218 end;
219 end;
220 end;
222 function GLExtensionSupported (ext: AnsiString): Boolean;
223 var
224 exts: SSArray;
225 e: AnsiString;
226 begin
227 result := false;
228 exts := GLExtensionList();
229 for e in exts do
230 begin
231 //writeln('<', e, '> : [', ext, '] = ', strEquCI1251(e, ext));
232 if (strEquCI1251(e, ext)) then begin result := true; exit; end;
233 end;
234 end;
236 procedure PrintGLSupportedExtensions;
237 begin
238 e_LogWritefln('GL Vendor: %s', [glGetString(GL_VENDOR)]);
239 e_LogWritefln('GL Renderer: %s', [glGetString(GL_RENDERER)]);
240 e_LogWritefln('GL Version: %s', [glGetString(GL_VERSION)]);
241 e_LogWritefln('GL Shaders: %s', [glGetString(GL_SHADING_LANGUAGE_VERSION)]);
242 e_LogWritefln('GL Extensions: %s', [glGetString(GL_EXTENSIONS)]);
243 end;
245 function SDLMain (): Integer;
246 var
247 idx: Integer;
248 arg: AnsiString;
249 mdfo: TStream;
250 {$IFDEF ENABLE_HOLMES}
251 itmp: Integer;
252 valres: Word;
253 {$ENDIF}
254 begin
255 {$IFDEF HEADLESS}
256 e_NoGraphics := true;
257 {$ENDIF}
259 idx := 1;
260 while (idx <= ParamCount) do
261 begin
262 arg := ParamStr(idx);
263 Inc(idx);
264 if arg = '--opengl-dump-exts' then gwin_dump_extensions := true;
265 //if arg = '--twinkletwinkle' then gwin_k8_enable_light_experiments := true;
266 if arg = '--jah' then g_profile_history_size := 100;
267 if arg = '--no-particles' then gpart_dbg_enabled := false;
268 if arg = '--no-los' then gmon_dbg_los_enabled := false;
270 if arg = '--profile-render' then g_profile_frame_draw := true;
271 if arg = '--profile-coldet' then g_profile_collision := true;
272 if arg = '--profile-los' then g_profile_los := true;
274 if arg = '--no-part-phys' then gpart_dbg_phys_enabled := false;
275 if arg = '--no-part-physics' then gpart_dbg_phys_enabled := false;
276 if arg = '--no-particles-phys' then gpart_dbg_phys_enabled := false;
277 if arg = '--no-particles-physics' then gpart_dbg_phys_enabled := false;
278 if arg = '--no-particle-phys' then gpart_dbg_phys_enabled := false;
279 if arg = '--no-particle-physics' then gpart_dbg_phys_enabled := false;
281 if arg = '--debug-input' then g_dbg_input := True;
283 {.$IF DEFINED(D2F_DEBUG)}
284 if arg = '--aimline' then g_dbg_aimline_on := true;
285 {.$ENDIF}
287 {$IFDEF ENABLE_HOLMES}
288 if arg = '--holmes' then begin g_holmes_enabled := true; g_Game_SetDebugMode(); end;
290 if (arg = '--holmes-ui-scale') or (arg = '-holmes-ui-scale') then
291 begin
292 if (idx <= ParamCount) then
293 begin
294 if not conParseFloat(fuiRenderScale, ParamStr(idx)) then fuiRenderScale := 1.0;
295 Inc(idx);
296 end;
297 end;
299 if (arg = '--holmes-font') or (arg = '-holmes-font') then
300 begin
301 if (idx <= ParamCount) then
302 begin
303 itmp := 0;
304 val(ParamStr(idx), itmp, valres);
305 {$IFNDEF HEADLESS}
306 if (valres = 0) and (not g_holmes_imfunctional) then
307 begin
308 case itmp of
309 8: uiContext.font := 'win8';
310 14: uiContext.font := 'win14';
311 16: uiContext.font := 'win16';
312 end;
313 end;
314 {$ELSE}
315 // fuck off, fpc!
316 itmp := itmp;
317 valres := valres;
318 {$ENDIF}
319 Inc(idx);
320 end;
321 end;
322 {$ENDIF}
324 if (arg = '--game-scale') or (arg = '-game-scale') then
325 begin
326 if (idx <= ParamCount) then
327 begin
328 if not conParseFloat(g_dbg_scale, ParamStr(idx)) then g_dbg_scale := 1.0;
329 Inc(idx);
330 end;
331 end;
333 if (arg = '--write-mapdef') or (arg = '-write-mapdef') then
334 begin
335 mdfo := createDiskFile('mapdef.txt');
336 mdfo.WriteBuffer(defaultMapDef[1], Length(defaultMapDef));
337 mdfo.Free();
338 Halt(0);
339 end;
341 if (arg = '--pixel-scale') or (arg = '-pixel-scale') then
342 begin
343 if (idx <= ParamCount) then
344 begin
345 if not conParseFloat(r_pixel_scale, ParamStr(idx)) then r_pixel_scale := 1.0;
346 Inc(idx);
347 end;
348 end;
349 end;
351 {$IFNDEF USE_SYSSTUB}
352 PrintGLSupportedExtensions;
353 glLegacyNPOT := not (GLExtensionSupported('GL_ARB_texture_non_power_of_two') or GLExtensionSupported('GL_OES_texture_npot'));
354 {$ELSE}
355 glLegacyNPOT := False;
356 glRenderToFBO := False;
357 {$ENDIF}
358 if glNPOTOverride and glLegacyNPOT then
359 begin
360 glLegacyNPOT := true;
361 e_logWriteln('NPOT texture emulation: FORCED');
362 end
363 else
364 begin
365 if (glLegacyNPOT) then e_logWriteln('NPOT texture emulation: enabled')
366 else e_logWriteln('NPOT texture emulation: disabled');
367 end;
368 gwin_dump_extensions := false;
370 Init;
371 Time_Old := sys_GetTicks();
373 g_Net_InitLowLevel();
375 // Êîìàíäíàÿ ñòðîêà
376 if (ParamCount > 0) then g_Game_Process_Params();
378 {$IFNDEF HEADLESS}
379 // Çàïðîñ ÿçûêà
380 if (not gGameOn) and gAskLanguage then g_Menu_AskLanguage();
381 {$ENDIF}
383 e_WriteLog('Entering the main loop', TMsgType.Notify);
385 // main loop
386 while not ProcessMessage() do begin end;
388 g_Net_Slist_ShutdownAll();
390 Release();
392 g_Net_DeinitLowLevel();
393 result := 0;
394 end;
397 initialization
398 conRegVar('d_input', @g_dbg_input, '', '')
399 end.