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}
23 * - Window resizing using SDL_VIDEORESIZE
29 function sys_GetTicks (): Int64;
30 procedure sys_Delay (ms
: Integer);
32 (* --- Graphics --- *)
33 function sys_GetDispalyModes (bpp
: Integer): SSArray
;
34 function sys_SetDisplayMode (w
, h
, bpp
: Integer; fullscreen
: Boolean): Boolean;
35 procedure sys_EnableVSync (yes
: Boolean);
36 procedure sys_Repaint
;
39 function sys_HandleInput (): Boolean;
40 procedure sys_RequestQuit
;
50 e_log
, e_graphics
, e_input
,
51 g_options
, g_window
, g_console
, g_game
, g_menu
;
56 (* --------- Utils --------- *)
58 function sys_GetTicks (): Int64;
60 Result
:= SDL_GetTicks()
63 procedure sys_Delay (ms
: Integer);
68 (* --------- Graphics --------- *)
70 procedure UpdateSize (w
, h
: Integer);
78 {$IFDEF ENABLE_HOLMES}
84 g_Game_SetupScreenSize
;
89 function InitWindow (w
, h
, bpp
: Integer; fullScreen
: Boolean): Boolean;
92 e_LogWritefln('InitWindow %s %s %s %s', [w
, h
, bpp
, fullscreen
]);
94 SDL_GL_SetAttribute(SDL_GL_RED_SIZE
, 8);
95 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE
, 8);
96 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE
, 8);
97 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE
, 16);
98 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER
, 1);
99 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE
, 8); // lights; it is enough to have 1-bit stencil buffer for lighting, but...
100 flags
:= SDL_OPENGL
or SDL_VIDEORESIZE
;
102 flags
:= flags
or SDL_FULLSCREEN
;
103 if (screen
= nil) or (SDL_VideoModeOk(w
, h
, bpp
, flags
) <> 0) then
105 SDL_FreeSurface(screen
);
106 screen
:= SDL_SetVideoMode(w
, h
, bpp
, flags
);
107 if screen
<> nil then
109 SDL_WM_SetCaption('Doom 2D: Forever (SDL 1.2)', nil);
116 e_LogWritefln('SDL: video mode not supported', [])
120 procedure sys_Repaint
;
125 procedure sys_EnableVSync (yes
: Boolean);
130 function sys_GetDispalyModes (bpp
: Integer): SSArray
;
131 var m
: PPSDL_Rect
; f
: TSDL_PixelFormat
; i
, count
: Integer;
133 SetLength(result
, 0);
134 FillChar(f
, sizeof(f
), 0);
136 f
.BitsPerPixel
:= bpp
;
137 f
.BytesPerPixel
:= (bpp
+ 7) div 8;
138 m
:= SDL_ListModes(@f
, SDL_OPENGL
or SDL_FULLSCREEN
);
139 if (m
<> NIL) and (IntPtr(m
) <> -1) then
142 while m
[count
] <> nil do inc(count
);
143 SetLength(result
, count
);
144 for i
:= 0 to count
- 1 do
145 result
[i
] := IntToStr(m
[i
].w
) + 'x' + IntToStr(m
[i
].h
);
149 function sys_SetDisplayMode (w
, h
, bpp
: Integer; fullscreen
: Boolean): Boolean;
151 result
:= InitWindow(w
, h
, bpp
, fullscreen
)
154 (* --------- Input --------- *)
156 function Key2Stub (key
: Integer): Integer;
160 SDLK_ESCAPE
: x
:= IK_ESCAPE
;
161 SDLK_RETURN
: x
:= IK_RETURN
;
162 SDLK_KP_ENTER
: x
:= IK_KPRETURN
;
163 SDLK_KP0
: x
:= IK_KPINSERT
;
165 SDLK_KP8
: x
:= IK_KPUP
;
166 SDLK_DOWN
: x
:= IK_DOWN
;
167 SDLK_KP2
: x
:= IK_KPDOWN
;
168 SDLK_LEFT
: x
:= IK_LEFT
;
169 SDLK_KP4
: x
:= IK_KPLEFT
;
170 SDLK_RIGHT
: x
:= IK_RIGHT
;
171 SDLK_KP6
: x
:= IK_KPRIGHT
;
172 SDLK_DELETE
: x
:= IK_DELETE
;
173 SDLK_HOME
: x
:= IK_HOME
;
174 SDLK_KP7
: x
:= IK_KPHOME
;
175 SDLK_INSERT
: x
:= IK_INSERT
;
176 SDLK_SPACE
: x
:= IK_SPACE
;
177 SDLK_LSHIFT
: x
:= IK_SHIFT
;
178 SDLK_LALT
: x
:= IK_ALT
;
179 SDLK_TAB
: x
:= IK_TAB
;
180 SDLK_PAGEUP
: x
:= IK_PAGEUP
;
181 SDLK_KP9
: x
:= IK_KPPAGEUP
;
182 SDLK_PAGEDOWN
: x
:= IK_PAGEDN
;
183 SDLK_KP3
: x
:= IK_KPPAGEDN
;
184 SDLK_KP5
: x
:= IK_KP5
;
185 SDLK_NUMLOCK
: x
:= IK_NUMLOCK
;
186 SDLK_KP_DIVIDE
: x
:= IK_KPDIVIDE
;
187 SDLK_KP_MULTIPLY
: x
:= IK_KPMULTIPLE
;
188 SDLK_KP_MINUS
: x
:= IK_KPMINUS
;
189 SDLK_KP_PLUS
: x
:= IK_KPPLUS
;
190 SDLK_KP_PERIOD
: x
:= IK_KPDOT
;
191 SDLK_CAPSLOCK
: x
:= IK_CAPSLOCK
;
192 SDLK_RSHIFT
: x
:= IK_RSHIFT
;
193 SDLK_LCTRL
: x
:= IK_CTRL
;
194 SDLK_RCTRL
: x
:= IK_RCTRL
;
195 SDLK_RALT
: x
:= IK_RALT
;
196 SDLK_LSUPER
: x
:= IK_WIN
;
197 SDLK_RSUPER
: x
:= IK_RWIN
;
198 SDLK_MENU
: x
:= IK_MENU
;
199 SDLK_PRINT
: x
:= IK_PRINTSCR
;
200 SDLK_SCROLLOCK
: x
:= IK_SCROLLLOCK
;
201 SDLK_LEFTBRACKET
: x
:= IK_LBRACKET
;
202 SDLK_RIGHTBRACKET
: x
:= IK_RBRACKET
;
203 SDLK_SEMICOLON
: x
:= IK_SEMICOLON
;
204 SDLK_QUOTE
: x
:= IK_QUOTE
;
205 SDLK_BACKSLASH
: x
:= IK_BACKSLASH
;
206 SDLK_SLASH
: x
:= IK_SLASH
;
207 SDLK_COMMA
: x
:= IK_COMMA
;
208 SDLK_PERIOD
: x
:= IK_DOT
;
209 SDLK_EQUALS
: x
:= IK_EQUALS
;
229 SDLK_F10
: x
:= IK_F10
;
230 SDLK_F11
: x
:= IK_F11
;
231 SDLK_F12
: x
:= IK_F12
;
232 SDLK_END
: x
:= IK_END
;
233 SDLK_KP1
: x
:= IK_KPEND
;
234 SDLK_BACKSPACE
: x
:= IK_BACKSPACE
;
235 SDLK_BACKQUOTE
: x
:= IK_BACKQUOTE
;
236 SDLK_PAUSE
: x
:= IK_PAUSE
;
237 SDLK_A
..SDLK_Z
: x
:= IK_A
+ (key
- SDLK_A
);
238 SDLK_MINUS
: x
:= IK_MINUS
;
245 procedure HandleKeyboard (var ev
: TSDL_KeyboardEvent
);
246 var down
: Boolean; key
, stb
: Integer;
248 down
:= (ev
.type_
= SDL_KEYDOWN
);
249 key
:= ev
.keysym
.sym
;
250 stb
:= Key2Stub(key
);
252 e_LogWritefln('Input Debug: keysym, press=%s, scancode=%s SDL.ev.key.state=%s', [down
, key
, ev
.state
]);
253 e_KeyUpDown(stb
, down
);
254 g_Console_ProcessBind(stb
, down
);
255 (* !!! need text input -- console, cheaats, fields *)
258 function sys_HandleInput (): Boolean;
262 while SDL_PollEvent(@ev
) <> 0 do
265 SDL_QUITEV
: result
:= true;
266 SDL_VIDEORESIZE
: InitWindow(ev
.resize
.w
, ev
.resize
.h
, gBPP
, gFullscreen
);
267 SDL_KEYUP
, SDL_KEYDOWN
: HandleKeyboard(ev
.key
);
272 procedure sys_RequestQuit
;
275 ev
.quit
.type_
:= SDL_QUITEV
;
279 (* --------- Init --------- *)
282 var flags
: Uint32
; ok
: Boolean;
284 flags
:= SDL_INIT_VIDEO
or SDL_INIT_AUDIO
or
285 SDL_INIT_TIMER
or SDL_INIT_JOYSTICK
286 (*or SDL_INIT_NOPARACHUTE*);
287 if SDL_Init(flags
) <> 0 then
288 raise Exception
.Create('SDL: Init failed: ' + SDL_GetError());
289 ok
:= InitWindow(gScreenWidth
, gScreenHeight
, gBPP
, gFullScreen
);
291 raise Exception
.Create('SDL: failed to set videomode: ' + SDL_GetError
)
296 e_WriteLog('Releasing SDL', TMsgType
.Notify
);
297 SDL_FreeSurface(screen
);