25e95eca8841d5a987f5e87bb218bc0cb4f26fb9
1 (* Copyright (C) Doom 2D: Forever Developers
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.
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.
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/>.
15 {$INCLUDE ../shared/a_modes.inc}
22 * - Window resizing using SDL_VIDEORESIZE
23 * -- Linux: GL drawing area have wrong size
24 * -- OSX: GL context are recreated
30 function sys_GetTicks (): Int64;
31 procedure sys_Delay (ms
: Integer);
33 (* --- Graphics --- *)
34 function sys_GetDispalyModes (bpp
: Integer): SSArray
;
35 function sys_SetDisplayMode (w
, h
, bpp
: Integer; fullscreen
: Boolean): Boolean;
36 procedure sys_EnableVSync (yes
: Boolean);
37 procedure sys_Repaint
;
40 function sys_HandleInput (): Boolean;
41 procedure sys_RequestQuit
;
51 e_log
, e_graphics
, e_input
,
52 g_options
, g_window
, g_console
, g_game
, g_menu
, g_gui
, g_main
;
57 (* --------- Utils --------- *)
59 function sys_GetTicks (): Int64;
61 Result
:= SDL_GetTicks()
64 procedure sys_Delay (ms
: Integer);
69 (* --------- Graphics --------- *)
71 procedure UpdateSize (w
, h
: Integer);
79 {$IFDEF ENABLE_HOLMES}
85 g_Game_SetupScreenSize
;
90 function InitWindow (w
, h
, bpp
: Integer; fullScreen
: Boolean): Boolean;
93 e_LogWritefln('InitWindow %s %s %s %s', [w
, h
, bpp
, fullscreen
]);
95 SDL_GL_SetAttribute(SDL_GL_RED_SIZE
, 8);
96 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE
, 8);
97 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE
, 8);
98 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE
, 16);
99 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER
, 1);
100 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE
, 8); // lights; it is enough to have 1-bit stencil buffer for lighting, but...
101 flags
:= SDL_OPENGL
or SDL_VIDEORESIZE
;
103 flags
:= flags
or SDL_FULLSCREEN
;
104 if (screen
= nil) or (SDL_VideoModeOk(w
, h
, bpp
, flags
) <> 0) then
106 SDL_FreeSurface(screen
);
107 screen
:= SDL_SetVideoMode(w
, h
, bpp
, flags
);
108 if screen
<> nil then
110 SDL_WM_SetCaption('Doom 2D: Forever (SDL 1.2)', nil);
117 e_LogWritefln('SDL: video mode not supported', [])
121 procedure sys_Repaint
;
126 procedure sys_EnableVSync (yes
: Boolean);
131 function sys_GetDispalyModes (bpp
: Integer): SSArray
;
132 var m
: PPSDL_Rect
; f
: TSDL_PixelFormat
; i
, count
: Integer;
134 SetLength(result
, 0);
135 FillChar(f
, sizeof(f
), 0);
137 f
.BitsPerPixel
:= bpp
;
138 f
.BytesPerPixel
:= (bpp
+ 7) div 8;
139 m
:= SDL_ListModes(@f
, SDL_OPENGL
or SDL_FULLSCREEN
);
140 if (m
<> NIL) and (IntPtr(m
) <> -1) then
143 while m
[count
] <> nil do inc(count
);
144 SetLength(result
, count
);
145 for i
:= 0 to count
- 1 do
146 result
[i
] := IntToStr(m
[i
].w
) + 'x' + IntToStr(m
[i
].h
);
150 function sys_SetDisplayMode (w
, h
, bpp
: Integer; fullscreen
: Boolean): Boolean;
152 result
:= InitWindow(w
, h
, bpp
, fullscreen
)
155 (* --------- Input --------- *)
157 function Key2Stub (key
: Integer): Integer;
161 SDLK_ESCAPE
: x
:= IK_ESCAPE
;
162 SDLK_RETURN
: x
:= IK_RETURN
;
163 SDLK_KP_ENTER
: x
:= IK_KPRETURN
;
164 SDLK_KP0
: x
:= IK_KPINSERT
;
166 SDLK_KP8
: x
:= IK_KPUP
;
167 SDLK_DOWN
: x
:= IK_DOWN
;
168 SDLK_KP2
: x
:= IK_KPDOWN
;
169 SDLK_LEFT
: x
:= IK_LEFT
;
170 SDLK_KP4
: x
:= IK_KPLEFT
;
171 SDLK_RIGHT
: x
:= IK_RIGHT
;
172 SDLK_KP6
: x
:= IK_KPRIGHT
;
173 SDLK_DELETE
: x
:= IK_DELETE
;
174 SDLK_HOME
: x
:= IK_HOME
;
175 SDLK_KP7
: x
:= IK_KPHOME
;
176 SDLK_INSERT
: x
:= IK_INSERT
;
177 SDLK_SPACE
: x
:= IK_SPACE
;
178 SDLK_LSHIFT
: x
:= IK_SHIFT
;
179 SDLK_LALT
: x
:= IK_ALT
;
180 SDLK_TAB
: x
:= IK_TAB
;
181 SDLK_PAGEUP
: x
:= IK_PAGEUP
;
182 SDLK_KP9
: x
:= IK_KPPAGEUP
;
183 SDLK_PAGEDOWN
: x
:= IK_PAGEDN
;
184 SDLK_KP3
: x
:= IK_KPPAGEDN
;
185 SDLK_KP5
: x
:= IK_KP5
;
186 SDLK_NUMLOCK
: x
:= IK_NUMLOCK
;
187 SDLK_KP_DIVIDE
: x
:= IK_KPDIVIDE
;
188 SDLK_KP_MULTIPLY
: x
:= IK_KPMULTIPLE
;
189 SDLK_KP_MINUS
: x
:= IK_KPMINUS
;
190 SDLK_KP_PLUS
: x
:= IK_KPPLUS
;
191 SDLK_KP_PERIOD
: x
:= IK_KPDOT
;
192 SDLK_CAPSLOCK
: x
:= IK_CAPSLOCK
;
193 SDLK_RSHIFT
: x
:= IK_RSHIFT
;
194 SDLK_LCTRL
: x
:= IK_CTRL
;
195 SDLK_RCTRL
: x
:= IK_RCTRL
;
196 SDLK_RALT
: x
:= IK_RALT
;
197 SDLK_LSUPER
: x
:= IK_WIN
;
198 SDLK_RSUPER
: x
:= IK_RWIN
;
199 SDLK_MENU
: x
:= IK_MENU
;
200 SDLK_PRINT
: x
:= IK_PRINTSCR
;
201 SDLK_SCROLLOCK
: x
:= IK_SCROLLLOCK
;
202 SDLK_LEFTBRACKET
: x
:= IK_LBRACKET
;
203 SDLK_RIGHTBRACKET
: x
:= IK_RBRACKET
;
204 SDLK_SEMICOLON
: x
:= IK_SEMICOLON
;
205 SDLK_QUOTE
: x
:= IK_QUOTE
;
206 SDLK_BACKSLASH
: x
:= IK_BACKSLASH
;
207 SDLK_SLASH
: x
:= IK_SLASH
;
208 SDLK_COMMA
: x
:= IK_COMMA
;
209 SDLK_PERIOD
: x
:= IK_DOT
;
210 SDLK_EQUALS
: x
:= IK_EQUALS
;
230 SDLK_F10
: x
:= IK_F10
;
231 SDLK_F11
: x
:= IK_F11
;
232 SDLK_F12
: x
:= IK_F12
;
233 SDLK_END
: x
:= IK_END
;
234 SDLK_KP1
: x
:= IK_KPEND
;
235 SDLK_BACKSPACE
: x
:= IK_BACKSPACE
;
236 SDLK_BACKQUOTE
: x
:= IK_BACKQUOTE
;
237 SDLK_PAUSE
: x
:= IK_PAUSE
;
238 SDLK_A
..SDLK_Z
: x
:= IK_A
+ (key
- SDLK_A
);
239 SDLK_MINUS
: x
:= IK_MINUS
;
240 SDLK_RMETA
: x
:= IK_RMETA
;
241 SDLK_LMETA
: x
:= IK_LMETA
;
248 procedure HandleKeyboard (var ev
: TSDL_KeyboardEvent
);
249 var down
, repeated
: Boolean; key
: Integer; ch
: Char;
251 key
:= Key2Stub(ev
.keysym
.sym
);
252 down
:= (ev
.type_
= SDL_KEYDOWN
);
253 repeated
:= down
and e_KeyPressed(key
);
254 ch
:= wchar2win(WideChar(ev
.keysym
.unicode
));
256 e_LogWritefln('Input Debug: keysym, down=%s, sym=%s, state=%s, unicode=%s, stubsym=%s, cp1251=%s', [down
, ev
.keysym
.sym
, ev
.state
, ev
.keysym
.unicode
, key
, Ord(ch
)]);
259 e_KeyUpDown(key
, down
);
260 g_Console_ProcessBind(key
, down
);
262 else if gConsoleShow
or gChatShow
or (g_ActiveWindow
<> nil) then
266 if down
and IsValid1251(ev
.keysym
.unicode
) and IsPrintable1251(ch
) then
270 function sys_HandleInput (): Boolean;
274 while SDL_PollEvent(@ev
) <> 0 do
277 SDL_QUITEV
: result
:= true;
278 SDL_VIDEORESIZE
: InitWindow(ev
.resize
.w
, ev
.resize
.h
, gBPP
, gFullscreen
);
279 SDL_KEYUP
, SDL_KEYDOWN
: HandleKeyboard(ev
.key
);
284 procedure sys_RequestQuit
;
287 ev
.quit
.type_
:= SDL_QUITEV
;
291 (* --------- Init --------- *)
294 var flags
: Uint32
; ok
: Boolean;
296 flags
:= SDL_INIT_VIDEO
or SDL_INIT_AUDIO
or
297 SDL_INIT_TIMER
or SDL_INIT_JOYSTICK
298 (*or SDL_INIT_NOPARACHUTE*);
299 if SDL_Init(flags
) <> 0 then
300 raise Exception
.Create('SDL: Init failed: ' + SDL_GetError());
301 ok
:= InitWindow(gScreenWidth
, gScreenHeight
, gBPP
, gFullScreen
);
303 raise Exception
.Create('SDL: failed to set videomode: ' + SDL_GetError
);
304 SDL_EnableUNICODE(1);
305 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY
, SDL_DEFAULT_REPEAT_INTERVAL
);
310 e_WriteLog('Releasing SDL', TMsgType
.Notify
);
311 SDL_FreeSurface(screen
);