DEADSOFTWARE

59e78702837c555b40e90103f08bccf5633806ac
[d2df-sdl.git] / src / game / g_main.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, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *)
16 {$MODE DELPHI}
17 unit g_main;
19 interface
21 procedure Main();
22 procedure Init();
23 procedure Release();
24 procedure Update();
25 procedure Draw();
26 procedure KeyPress(K: Word);
27 procedure CharPress(C: Char);
29 var
30 GameDir: string;
31 DataDir: string;
32 MapsDir: string;
33 ModelsDir: string;
34 GameWAD: string;
36 implementation
38 uses
39 SDL2, GL, GLExt, wadreader, e_log, g_window,
40 e_graphics, e_input, g_game, g_console, g_gui,
41 e_sound, g_options, g_sound, g_player,
42 g_weapons, SysUtils, g_triggers, MAPDEF, g_map,
43 MAPSTRUCT, g_menu, g_language, g_net, utils, conbuf;
45 var
46 charbuff: Array [0..15] of Char;
48 procedure Main();
49 var
50 sdlflags: LongWord;
51 begin
52 e_InitWritelnDriver();
54 GetDir(0, GameDir);
55 MapsDir := GameDir + '/maps/';
56 DataDir := GameDir + '/data/';
57 ModelsDir := DataDir + 'models/';
58 GameWAD := DataDir + 'Game.wad';
60 e_InitLog(GameDir + '/' + LOG_FILENAME, WM_NEWFILE);
62 e_WriteLog('Read config file', MSG_NOTIFY);
63 g_Options_Read(GameDir + '/' + CONFIG_FILENAME);
65 {$IFDEF HEADLESS}
66 conbufDumpToStdOut := true;
67 {$ENDIF}
68 e_WriteToStdOut := False; //{$IFDEF HEADLESS}True;{$ELSE}False;{$ENDIF}
70 //GetSystemDefaultLCID()
72 //e_WriteLog('Read language file', MSG_NOTIFY);
73 //g_Language_Load(DataDir + gLanguage + '.txt');
74 e_WriteLog(gLanguage, MSG_NOTIFY);
75 g_Language_Set(gLanguage);
77 {$IFDEF HEADLESS}
78 sdlflags := SDL_INIT_TIMER or $00004000;
79 {$ELSE}
80 {$IFDEF USE_SDLMIXER}
81 sdlflags := SDL_INIT_EVERYTHING;
82 {$ELSE}
83 sdlflags := SDL_INIT_JOYSTICK or SDL_INIT_TIMER or SDL_INIT_VIDEO;
84 {$ENDIF}
85 {$ENDIF}
86 if SDL_Init(sdlflags) < 0 then
87 raise Exception.Create('SDL: Init failed: ' + SDL_GetError());
89 {$IFDEF HEADLESS}
90 SDL_StartTextInput();
91 {$ENDIF}
93 e_WriteLog('Entering SDLMain', MSG_NOTIFY);
95 {$WARNINGS OFF}
96 SDLMain();
97 {$WARNINGS ON}
99 {$IFDEF HEADLESS}
100 SDL_StopTextInput();
101 {$ENDIF}
103 e_WriteLog('Releasing SDL', MSG_NOTIFY);
104 SDL_Quit();
105 end;
107 procedure Init();
108 var
109 a: Integer;
110 begin
111 Randomize;
113 e_WriteLog('Init Input', MSG_NOTIFY);
114 e_InitInput();
116 if (e_JoysticksAvailable > 0) then
117 e_WriteLog('Input: Joysticks available.', MSG_NOTIFY)
118 else
119 e_WriteLog('Input: No Joysticks.', MSG_NOTIFY);
121 if (not gNoSound) then
122 begin
123 e_WriteLog('Initializing sound system', MSG_NOTIFY);
124 e_InitSoundSystem({$IFDEF HEADLESS}True{$ELSE}False{$ENDIF});
125 end;
127 e_WriteLog('Init game', MSG_NOTIFY);
128 g_Game_Init();
130 for a := 0 to 15 do charbuff[a] := ' ';
131 end;
133 procedure Release();
134 begin
135 e_WriteLog('Releasing engine', MSG_NOTIFY);
136 e_ReleaseEngine();
138 e_WriteLog('Releasing Input', MSG_NOTIFY);
139 e_ReleaseInput();
141 if not gNoSound then
142 begin
143 e_WriteLog('Releasing FMOD', MSG_NOTIFY);
144 e_ReleaseSoundSystem();
145 end;
146 end;
148 procedure Update();
149 begin
150 g_Game_Update();
151 end;
153 procedure Draw();
154 begin
155 g_Game_Draw();
156 end;
158 function Translit(S: String): String;
159 var
160 i: Integer;
161 begin
162 Result := S;
163 for i := 1 to Length(Result) do
164 case Result[i] of
165 'É': Result[i] := 'Q';
166 'Ö': Result[i] := 'W';
167 'Ó': Result[i] := 'E';
168 'Ê': Result[i] := 'R';
169 'Å': Result[i] := 'T';
170 'Í': Result[i] := 'Y';
171 'Ã': Result[i] := 'U';
172 'Ø': Result[i] := 'I';
173 'Ù': Result[i] := 'O';
174 'Ç': Result[i] := 'P';
175 'Õ': Result[i] := '['; //Chr(219);
176 'Ú': Result[i] := ']'; //Chr(221);
177 'Ô': Result[i] := 'A';
178 'Û': Result[i] := 'S';
179 'Â': Result[i] := 'D';
180 'À': Result[i] := 'F';
181 'Ï': Result[i] := 'G';
182 'Ð': Result[i] := 'H';
183 'Î': Result[i] := 'J';
184 'Ë': Result[i] := 'K';
185 'Ä': Result[i] := 'L';
186 'Æ': Result[i] := ';'; //Chr(186);
187 'Ý': Result[i] := #39; //Chr(222);
188 'ß': Result[i] := 'Z';
189 '×': Result[i] := 'X';
190 'Ñ': Result[i] := 'C';
191 'Ì': Result[i] := 'V';
192 'È': Result[i] := 'B';
193 'Ò': Result[i] := 'N';
194 'Ü': Result[i] := 'M';
195 'Á': Result[i] := ','; //Chr(188);
196 'Þ': Result[i] := '.'; //Chr(190);
197 end;
198 end;
201 function CheckCheat (ct: TStrings_Locale; eofs: Integer=0): Boolean;
202 var
203 ls1, ls2: string;
204 begin
205 ls1 := CheatEng[ct];
206 ls2 := Translit(CheatRus[ct]);
207 if length(ls1) = 0 then ls1 := '~';
208 if length(ls2) = 0 then ls2 := '~';
209 result :=
210 (Copy(charbuff, 17-Length(ls1)-eofs, Length(ls1)) = ls1) or
211 (Translit(Copy(charbuff, 17-Length(ls1)-eofs, Length(ls1))) = ls1) or
212 (Copy(charbuff, 17-Length(ls2)-eofs, Length(ls2)) = ls2) or
213 (Translit(Copy(charbuff, 17-Length(ls2)-eofs, Length(ls2))) = ls2);
215 if ct = I_GAME_CHEAT_JETPACK then
216 begin
217 e_WriteLog('ls1: ['+ls1+']', MSG_NOTIFY);
218 e_WriteLog('ls2: ['+ls2+']', MSG_NOTIFY);
219 e_WriteLog('bf0: ['+Copy(charbuff, 17-Length(ls1)-eofs, Length(ls1))+']', MSG_NOTIFY);
220 e_WriteLog('bf1: ['+Translit(Copy(charbuff, 17-Length(ls1)-eofs, Length(ls1)))+']', MSG_NOTIFY);
221 e_WriteLog('bf2: ['+Copy(charbuff, 17-Length(ls2)-eofs, Length(ls2))+']', MSG_NOTIFY);
222 e_WriteLog('bf3: ['+Translit(Copy(charbuff, 17-Length(ls2)-eofs, Length(ls2)))+']', MSG_NOTIFY);
223 end;
225 end;
228 procedure Cheat();
229 const
230 CHEAT_DAMAGE = 500;
231 label
232 Cheated;
233 var
234 s, s2: string;
235 c: Char16;
236 a: Integer;
237 begin
238 if (not gGameOn) or (not gCheats) or ((gGameSettings.GameType <> GT_SINGLE) and
239 (gGameSettings.GameMode <> GM_COOP) and (not gDebugMode))
240 or g_Game_IsNet then Exit;
242 s := 'SOUND_GAME_RADIO';
244 //
245 if CheckCheat(I_GAME_CHEAT_GODMODE) then
246 begin
247 if gPlayer1 <> nil then gPlayer1.GodMode := not gPlayer1.GodMode;
248 if gPlayer2 <> nil then gPlayer2.GodMode := not gPlayer2.GodMode;
249 goto Cheated;
250 end;
251 // RAMBO
252 if CheckCheat(I_GAME_CHEAT_WEAPONS) then
253 begin
254 if gPlayer1 <> nil then gPlayer1.AllRulez(False);
255 if gPlayer2 <> nil then gPlayer2.AllRulez(False);
256 goto Cheated;
257 end;
258 // TANK
259 if CheckCheat(I_GAME_CHEAT_HEALTH) then
260 begin
261 if gPlayer1 <> nil then gPlayer1.AllRulez(True);
262 if gPlayer2 <> nil then gPlayer2.AllRulez(True);
263 goto Cheated;
264 end;
265 // IDDQD
266 if CheckCheat(I_GAME_CHEAT_DEATH) then
267 begin
268 if gPlayer1 <> nil then gPlayer1.Damage(CHEAT_DAMAGE, 0, 0, 0, HIT_TRAP);
269 if gPlayer2 <> nil then gPlayer2.Damage(CHEAT_DAMAGE, 0, 0, 0, HIT_TRAP);
270 s := 'SOUND_MONSTER_HAHA';
271 goto Cheated;
272 end;
273 //
274 if CheckCheat(I_GAME_CHEAT_DOORS) then
275 begin
276 g_Triggers_OpenAll();
277 goto Cheated;
278 end;
279 // GOODBYE
280 if CheckCheat(I_GAME_CHEAT_NEXTMAP) then
281 begin
282 if gTriggers <> nil then
283 for a := 0 to High(gTriggers) do
284 if gTriggers[a].TriggerType = TRIGGER_EXIT then
285 begin
286 gExitByTrigger := True;
287 g_Game_ExitLevel(gTriggers[a].Data.MapName);
288 Break;
289 end;
290 goto Cheated;
291 end;
292 //
293 s2 := Copy(charbuff, 15, 2);
294 if CheckCheat(I_GAME_CHEAT_CHANGEMAP, 2) and (s2[1] >= '0') and (s2[1] <= '9') and (s2[2] >= '0') and (s2[2] <= '9') then
295 begin
296 if g_Map_Exist(MapsDir+gGameSettings.WAD+':\MAP'+s2) then
297 begin
298 c := 'MAP00';
299 c[3] := s2[1];
300 c[4] := s2[2];
301 g_Game_ExitLevel(c);
302 end;
303 goto Cheated;
304 end;
305 //
306 if CheckCheat(I_GAME_CHEAT_FLY) then
307 begin
308 gFly := not gFly;
309 goto Cheated;
310 end;
311 // BULLFROG
312 if CheckCheat(I_GAME_CHEAT_JUMPS) then
313 begin
314 VEL_JUMP := 30-VEL_JUMP;
315 goto Cheated;
316 end;
317 // FORMULA1
318 if CheckCheat(I_GAME_CHEAT_SPEED) then
319 begin
320 MAX_RUNVEL := 32-MAX_RUNVEL;
321 goto Cheated;
322 end;
323 // CONDOM
324 if CheckCheat(I_GAME_CHEAT_SUIT) then
325 begin
326 if gPlayer1 <> nil then gPlayer1.GiveItem(ITEM_SUIT);
327 if gPlayer2 <> nil then gPlayer2.GiveItem(ITEM_SUIT);
328 goto Cheated;
329 end;
330 //
331 if CheckCheat(I_GAME_CHEAT_AIR) then
332 begin
333 if gPlayer1 <> nil then gPlayer1.GiveItem(ITEM_OXYGEN);
334 if gPlayer2 <> nil then gPlayer2.GiveItem(ITEM_OXYGEN);
335 goto Cheated;
336 end;
337 // PURELOVE
338 if CheckCheat(I_GAME_CHEAT_BERSERK) then
339 begin
340 if gPlayer1 <> nil then gPlayer1.GiveItem(ITEM_MEDKIT_BLACK);
341 if gPlayer2 <> nil then gPlayer2.GiveItem(ITEM_MEDKIT_BLACK);
342 goto Cheated;
343 end;
344 //
345 if CheckCheat(I_GAME_CHEAT_JETPACK) then
346 begin
347 if gPlayer1 <> nil then gPlayer1.GiveItem(ITEM_JETPACK);
348 if gPlayer2 <> nil then gPlayer2.GiveItem(ITEM_JETPACK);
349 goto Cheated;
350 end;
351 // CASPER
352 if CheckCheat(I_GAME_CHEAT_NOCLIP) then
353 begin
354 if gPlayer1 <> nil then gPlayer1.SwitchNoClip;
355 if gPlayer2 <> nil then gPlayer2.SwitchNoClip;
356 goto Cheated;
357 end;
358 //
359 if CheckCheat(I_GAME_CHEAT_NOTARGET) then
360 begin
361 if gPlayer1 <> nil then gPlayer1.NoTarget := not gPlayer1.NoTarget;
362 if gPlayer2 <> nil then gPlayer2.NoTarget := not gPlayer2.NoTarget;
363 goto Cheated;
364 end;
365 // INFERNO
366 if CheckCheat(I_GAME_CHEAT_NORELOAD) then
367 begin
368 if gPlayer1 <> nil then gPlayer1.NoReload := not gPlayer1.NoReload;
369 if gPlayer2 <> nil then gPlayer2.NoReload := not gPlayer2.NoReload;
370 goto Cheated;
371 end;
372 if CheckCheat(I_GAME_CHEAT_AIMLINE) then
373 begin
374 gAimLine := not gAimLine;
375 goto Cheated;
376 end;
377 if CheckCheat(I_GAME_CHEAT_AUTOMAP) then
378 begin
379 gShowMap := not gShowMap;
380 goto Cheated;
381 end;
382 Exit;
384 Cheated:
385 g_Sound_PlayEx(s);
386 end;
388 procedure KeyPress(K: Word);
389 var
390 Msg: g_gui.TMessage;
391 begin
392 case K of
393 IK_PAUSE: // <Pause/Break>:
394 begin
395 if (g_ActiveWindow = nil) then
396 g_Game_Pause(not gPause);
397 end;
399 IK_BACKQUOTE: // <`/~/¨/¸>:
400 begin
401 g_Console_Switch();
402 end;
404 IK_ESCAPE: // <Esc>:
405 begin
406 if gChatShow then
407 begin
408 g_Console_Chat_Switch();
409 Exit;
410 end;
412 if gConsoleShow then
413 g_Console_Switch()
414 else
415 if g_ActiveWindow <> nil then
416 begin
417 Msg.Msg := WM_KEYDOWN;
418 Msg.WParam := IK_ESCAPE;
419 g_ActiveWindow.OnMessage(Msg);
420 end
421 else
422 if gState <> STATE_FOLD then
423 if gGameOn
424 or (gState = STATE_INTERSINGLE)
425 or (gState = STATE_INTERCUSTOM)
426 then
427 g_Game_InGameMenu(True)
428 else
429 if (gExit = 0) and (gState <> STATE_SLIST) then
430 begin
431 if gState <> STATE_MENU then
432 if NetMode <> NET_NONE then
433 begin
434 g_Game_StopAllSounds(True);
435 g_Game_Free;
436 gState := STATE_MENU;
437 Exit;
438 end;
440 g_GUI_ShowWindow('MainMenu');
441 g_Sound_PlayEx('MENU_OPEN');
442 end;
443 end;
445 IK_F2, IK_F3, IK_F4, IK_F5, IK_F6, IK_F7, IK_F10:
446 begin // <F2> .. <F6> � <F12>
447 if gGameOn and (not gConsoleShow) and (not gChatShow) then
448 begin
449 while g_ActiveWindow <> nil do
450 g_GUI_HideWindow(False);
452 if (not g_Game_IsNet) then
453 g_Game_Pause(True);
455 case K of
456 IK_F2:
457 g_Menu_Show_SaveMenu();
458 IK_F3:
459 g_Menu_Show_LoadMenu();
460 IK_F4:
461 g_Menu_Show_GameSetGame();
462 IK_F5:
463 g_Menu_Show_OptionsVideo();
464 IK_F6:
465 g_Menu_Show_OptionsSound();
466 IK_F7:
467 g_Menu_Show_EndGameMenu();
468 IK_F10:
469 g_Menu_Show_QuitGameMenu();
470 end;
471 end;
472 end;
474 else
475 begin
476 gJustChatted := False;
477 if gConsoleShow or gChatShow then
478 g_Console_Control(K)
479 else
480 if g_ActiveWindow <> nil then
481 begin
482 Msg.Msg := WM_KEYDOWN;
483 Msg.WParam := K;
484 g_ActiveWindow.OnMessage(Msg);
485 end
486 else
487 begin
488 if (gState = STATE_MENU) then
489 begin
490 g_GUI_ShowWindow('MainMenu');
491 g_Sound_PlayEx('MENU_OPEN');
492 end;
493 end;
494 end;
495 end;
496 end;
498 procedure CharPress(C: Char);
499 var
500 Msg: g_gui.TMessage;
501 a: Integer;
502 begin
503 if (not gChatShow) and ((C = '`') or (C = '~') or (C = '¸') or (C = '¨')) then
504 Exit;
506 if gConsoleShow or gChatShow then
507 g_Console_Char(C)
508 else
509 if g_ActiveWindow <> nil then
510 begin
511 Msg.Msg := WM_CHAR;
512 Msg.WParam := Ord(C);
513 g_ActiveWindow.OnMessage(Msg);
514 end
515 else
516 begin
517 for a := 0 to 14 do charbuff[a] := charbuff[a+1];
518 charbuff[15] := UpCase1251(C);
519 Cheat();
520 end;
521 end;
523 end.