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}
18 interface
20 uses
21 utils;
38 // returns `true` if quit event was received
42 var
50 implementation
52 uses
54 {$INCLUDE ../nogl/noGLuses.inc}
55 {$IFDEF ENABLE_HOLMES}
57 {$ENDIF}
66 const
69 var
74 {$IF not DEFINED(HEADLESS)}
77 {$ENDIF}
83 {$IFNDEF WINDOWS}
86 {$ENDIF}
92 begin
93 {$IFDEF ENABLE_HOLMES}
94 if (h_GL <> nil) and (not preserveGL) then begin if (assigned(oglDeinitCB)) then oglDeinitCB(); end;
95 {$ENDIF}
98 begin
100 {$IFDEF USE_NANOGL}
101 nanoGL_Destroy;
102 {$ENDIF}
104 {$IFDEF USE_NOGL}
105 nogl_Quit;
106 {$ENDIF}
116 {$IF not DEFINED(HEADLESS)}
117 var
121 {$ENDIF}
122 begin
123 {$IF not DEFINED(HEADLESS)}
129 if gFullscreen then wFlags := wFlags {or SDL_WINDOW_FULLSCREEN} else wFlags := wFlags or SDL_WINDOW_RESIZABLE;
130 if (not gFullscreen) and (not preserveGL) and gWinMaximized then wFlags := wFlags or SDL_WINDOW_MAXIMIZED else gWinMaximized := false;
133 begin
140 begin
144 end
145 else
146 begin
147 e_WriteLog('SDL: found display mode for '+IntToStr(gScreenWidth)+'x'+IntToStr(gScreenHeight)+': '+IntToStr(cmode.w)+'x'+IntToStr(cmode.h), TMsgType.Notify);
154 begin
155 //SDL_SetWindowMaximumSize(h_Wnd, gScreenWidth, gScreenHeight);
156 //SDL_SetWindowDisplayMode(h_Wnd, @cmode);
161 //SDL_SetWindowFullscreen(h_Wnd, SDL_WINDOW_FULLSCREEN);
162 //SDL_SetWindowFullscreen(h_Wnd, 0);
163 end
164 else
165 begin
167 h_Wnd := SDL_CreateWindow(PChar(wTitle), gWinRealPosX, gWinRealPosY, gScreenWidth, gScreenHeight, wFlags);
178 begin
183 begin
184 e_WriteLog('SDL: fullscreen window got size '+IntToStr(nw)+'x'+IntToStr(nh)+': '+IntToStr(gScreenWidth)+'x'+IntToStr(gScreenHeight), TMsgType.Notify);
187 end
188 else
189 begin
190 e_WriteLog('SDL: fullscreen window got invalid size: '+IntToStr(nw)+'x'+IntToStr(nh), TMsgType.Notify);
194 {$IFDEF ENABLE_HOLMES}
197 if (h_GL <> nil) and (not preserveGL) then begin if (assigned(oglInitCB)) then oglInitCB(); end;
198 {$ENDIF}
199 {$ENDIF}
206 var
209 begin
216 begin
234 begin
240 begin
241 e_LogWritefln(' ChangeWindowSize: (ws=%dx%d) (ss=%dx%d)', [gWinSizeX, gWinSizeY, gScreenWidth, gScreenHeight]);
244 {$IF not DEFINED(HEADLESS)}
245 {$IFDEF ENABLE_HOLMES}
248 {$ENDIF}
251 {$IF DEFINED(ANDROID)}
252 (* This will fix menu reset on keyboard showing *)
254 g_Menu_Reset;
255 {$ELSE}
256 g_Menu_Reset;
257 {$ENDIF}
259 {$ENDIF}
264 {$IF not DEFINED(HEADLESS)}
265 var
267 {$ENDIF}
268 begin
270 {$IF not DEFINED(HEADLESS)}
274 begin
282 begin
290 begin
294 {$ENDIF}
299 var
301 begin
307 SDL_WINDOWEVENT_MOVED:
308 begin
310 begin
316 SDL_WINDOWEVENT_MINIMIZED:
317 begin
320 begin
324 begin
332 SDL_WINDOWEVENT_RESIZED:
333 begin
334 e_LogWritefln('Resize: (os=%dx%d) (ns=%dx%d)', [gScreenWidth, gScreenHeight, Integer(ev.data1), Integer(ev.data2)]);
335 {if (gFullscreen) then
336 begin
337 e_LogWriteln(' fullscreen fix applied.');
338 if (gScreenWidth <> ev.data1) or (gScreenHeight <> ev.data2) then
339 begin
340 SDL_SetWindowSize(h_Wnd, gScreenWidth, gScreenHeight);
341 end;
342 end
343 else}
344 begin
351 begin
353 e_WriteLog('[DEBUG] WinMsgs: Resized to ' + IntToStr(ev.data1) + 'x' + IntToStr(ev.data2), TMsgType.Notify);
357 SDL_WINDOWEVENT_EXPOSED:
360 SDL_WINDOWEVENT_MAXIMIZED:
361 begin
364 begin
370 begin
373 begin
380 SDL_WINDOWEVENT_RESTORED:
381 begin
384 begin
391 begin
397 SDL_WINDOWEVENT_FOCUS_GAINED:
398 begin
400 //e_WriteLog('window gained focus!', MSG_NOTIFY);
403 SDL_WINDOWEVENT_FOCUS_LOST:
404 begin
407 //e_WriteLog('window lost focus!', MSG_NOTIFY);
412 begin
414 begin
416 e_UnpressAllKeys;
419 begin
420 //e_WriteLog('deactivating sounds', MSG_NOTIFY);
425 begin
432 {$IFDEF ENABLE_HOLMES}
434 {$ENDIF}
436 end
438 begin
440 begin
441 //e_WriteLog('activating window', MSG_NOTIFY);
444 begin
445 //e_WriteLog('activating sounds', MSG_NOTIFY);
450 begin
457 {$IFDEF ENABLE_HOLMES}
459 {$ENDIF}
466 var
472 begin
476 SDL_WINDOWEVENT:
479 SDL_QUITEV:
480 begin
482 begin
484 begin
487 end
488 else
489 begin
497 begin
502 {$IF not DEFINED(HEADLESS) and DEFINED(ENABLE_HOLMES)}
504 begin
505 // event eaten, but...
507 exit;
509 {$ENDIF}
511 begin
516 end
518 begin
519 // key repeat in menus and shit
526 begin
530 e_LogWritefln('Input Debug: jbutton, joy=%s, button=%s, keycode=%s, press=%s', [ev.jbutton.which, ev.jbutton.button, key, down]);
533 end
534 else
535 begin
537 begin
539 e_LogWritefln('Input Debug: NOT IN RANGE! jbutton, joy=%s, button=%s, press=%s', [ev.jbutton.which, ev.jbutton.button, down])
540 end
543 SDL_JOYAXISMOTION:
545 begin
550 e_LogWritefln('Input Debug: jaxis, joy=%s, axis=%s, value=%s, zeroaxes=%s, deadzone=%s', [ev.jaxis.which, ev.jaxis.axis, ev.jaxis.value, JoystickZeroAxes[ev.jaxis.which, ev.jaxis.axis], e_JoystickDeadzones[ev.jaxis.which]]);
552 if ev.jaxis.value < JoystickZeroAxes[ev.jaxis.which, ev.jaxis.axis] - e_JoystickDeadzones[ev.jaxis.which] then
553 begin
555 begin
561 end
562 else if ev.jaxis.value > JoystickZeroAxes[ev.jaxis.which, ev.jaxis.axis] + e_JoystickDeadzones[ev.jaxis.which] then
563 begin
565 begin
571 end
572 else
573 begin
575 begin
580 begin
585 end
586 else
587 begin
589 e_LogWritefln('Input Debug: NOT IN RANGE! jaxis, joy=%s, axis=%s, value=%s, zeroaxes=%s, deadzone=%s', [ev.jaxis.which, ev.jaxis.axis, ev.jaxis.value, JoystickZeroAxes[ev.jaxis.which, ev.jaxis.axis], e_JoystickDeadzones[ev.jaxis.which]])
592 SDL_JOYHATMOTION:
594 begin
596 e_LogWritefln('Input Debug: jhat, joy=%s, hat=%s, value=%s', [ev.jhat.which, ev.jhat.hat, ev.jhat.value]);
602 begin
604 begin
609 end
612 end
613 else
614 begin
616 e_LogWritefln('Input Debug: NOT IN RANGE! jhat, joy=%s, hat=%s, value=%s', [ev.jhat.which, ev.jhat.hat, ev.jhat.value])
619 SDL_JOYDEVICEADDED:
621 begin
624 begin
628 JoystickZeroAxes[ev.jdevice.which, i] := SDL_JoystickGetAxis(JoystickHandle[ev.jdevice.which], i)
629 end
630 else
632 end
633 else
634 begin
635 e_LogWritefln('Warning! Added Joystick %s, but we support only <= %s', [ev.jdevice.which, e_MaxJoys])
638 SDL_JOYDEVICEREMOVED:
639 begin
642 begin
647 end
650 {$IF not DEFINED(HEADLESS) and DEFINED(ENABLE_HOLMES)}
653 {$ENDIF}
655 SDL_TEXTINPUT:
656 begin
668 // other key presses and joysticks are handled in e_input
674 begin
675 {$IF not DEFINED(HEADLESS)}
677 {$ENDIF}
682 begin
688 {$IF not DEFINED(HEADLESS)}
690 {$ENDIF}
694 begin
697 exit;
700 {$IF not DEFINED(HEADLESS)}
703 {$IFDEF ENABLE_HOLMES}
706 {$ENDIF}
708 {$IFDEF USE_NANOGL}
710 begin
713 exit;
715 {$ENDIF}
716 {$IFDEF USE_NOGL}
717 nogl_Init;
718 {$ENDIF}
719 {$IFDEF ENABLE_HOLMES}
721 {$ENDIF}
723 {$ENDIF}
732 {$IFDEF WINDOWS}
733 // windoze sux; in headless mode `GetTickCount()` (and SDL) returns shit
735 var
737 begin
742 {$ELSE}
744 var
747 begin
750 begin
753 end
754 else
755 begin
757 begin
758 // overflow, increment overflow ;-)
767 {$ENDIF}
771 begin
777 var
779 begin
785 {$IFNDEF HEADLESS}
786 var
788 {$ENDIF}
791 var
793 {$IFNDEF HEADLESS}
795 {$ENDIF}
796 begin
801 begin
805 //e_PollJoysticks();
808 begin
810 exit;
813 {$IFNDEF HEADLESS}
815 begin
817 begin
819 forceUpdate := (stt < prevLoadingUpdateTime) or (stt-prevLoadingUpdateTime >= ProgressUpdateMSecs);
823 begin
833 {$ENDIF}
838 begin
840 end
841 else
842 begin
843 if (NetMode = NET_CLIENT) and (NetState <> NET_STATE_AUTH) then g_Net_Client_UpdateWhileLoading();
851 var
853 begin
857 begin
861 //e_PollJoysticks();
866 var
868 begin
877 begin
887 begin
890 begin
895 end
896 else
897 begin
908 begin
914 begin
916 exit;
919 // Âðåìÿ ïðåäûäóùåãî îáíîâëåíèÿ
921 begin
924 begin
928 end
929 else
930 begin
939 begin
945 {$IF not DEFINED(HEADLESS)}
946 var
948 {$ENDIF}
949 begin
950 {$IF not DEFINED(HEADLESS)}
953 begin
955 end
956 else
957 begin
958 if vsync then e_WriteLog('VSync: ON', TMsgType.Notify) else e_WriteLog('VSync: OFF', TMsgType.Notify);
960 {$ENDIF}
965 begin
966 {$IF not DEFINED(HEADLESS)}
967 {$IFDEF USE_GLES1}
971 {$ELSE}
979 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); // lights; it is enough to have 1-bit stencil buffer for lighting, but...
980 {$ENDIF}
981 {$ENDIF}
986 var
991 begin
998 begin
1000 begin
1004 begin
1006 end
1007 else
1008 begin
1016 begin
1020 if found and ((exts[Length(name)] = #0) or (exts[Length(name)] = ' ')) then begin result := true; exit; end;
1028 var
1030 {$IF not DEFINED(HEADLESS)}
1032 {$ENDIF}
1035 {$IFDEF ENABLE_HOLMES}
1038 {$ENDIF}
1039 begin
1040 {$IFDEF HEADLESS}
1042 {$ELSE}
1043 {$IFDEF ENABLE_HOLMES}
1045 begin
1049 {$ENDIF}
1050 {$ENDIF}
1054 begin
1058 //if arg = '--twinkletwinkle' then gwin_k8_enable_light_experiments := true;
1076 {.$IF DEFINED(D2F_DEBUG)}
1078 {.$ENDIF}
1080 {$IFDEF ENABLE_HOLMES}
1084 begin
1086 begin
1093 begin
1095 begin
1098 {$IFNDEF HEADLESS}
1100 begin
1107 {$ELSE}
1108 // fuck off, fpc!
1111 {$ENDIF}
1115 {$ENDIF}
1118 begin
1120 begin
1127 begin
1140 begin
1143 exit;
1146 {EnumDisplayModes();}
1148 {$IFDEF HEADLESS}
1149 //gwin_k8_enable_light_experiments := false;
1153 {$ELSE}
1160 begin
1163 end
1164 else
1165 begin
1170 {$ENDIF}
1175 // Êîìàíäíàÿ ñòðîêà
1178 {$IFNDEF HEADLESS}
1179 // Çàïðîñ ÿçûêà
1181 {$ENDIF}
1185 // main loop
1195 initialization