DEADSOFTWARE

Android: Fixed first video configuration and unpredicted key resetting
[d2df-sdl.git] / src / game / g_options.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 {$INCLUDE ../shared/a_modes.inc}
17 unit g_options;
19 interface
21 uses
22 g_language, g_weapons;
24 type
25 TPlayerControl = record
26 KeyRight: Word;
27 KeyLeft: Word;
28 KeyUp: Word;
29 KeyDown: Word;
30 KeyFire: Word;
31 KeyJump: Word;
32 KeyNextWeapon: Word;
33 KeyPrevWeapon: Word;
34 KeyOpen: Word;
35 KeyStrafe: Word;
36 KeyWeapon: array [WP_FIRST..WP_LAST] of Word;
38 KeyRight2: Word;
39 KeyLeft2: Word;
40 KeyUp2: Word;
41 KeyDown2: Word;
42 KeyFire2: Word;
43 KeyJump2: Word;
44 KeyNextWeapon2: Word;
45 KeyPrevWeapon2: Word;
46 KeyOpen2: Word;
47 KeyStrafe2: Word;
48 KeyWeapon2: array [WP_FIRST..WP_LAST] of Word;
49 end;
51 TGameControls = record
52 TakeScreenshot: Word;
53 Stat: Word;
54 Chat: Word;
55 TeamChat: Word;
56 end;
58 TControls = record
59 GameControls: TGameControls;
60 P1Control: TPlayerControl;
61 P2Control: TPlayerControl;
62 end;
64 procedure g_Options_SetDefault();
65 procedure g_Options_Read(FileName: String);
66 procedure g_Options_Write(FileName: String);
67 procedure g_Options_Write_Language(FileName: String);
68 procedure g_Options_Write_Video(FileName: String);
69 procedure g_Options_Write_Gameplay_Custom(FileName: String);
70 procedure g_Options_Write_Gameplay_Net(FileName: String);
71 procedure g_Options_Write_Net_Server(FileName: String);
72 procedure g_Options_Write_Net_Client(FileName: String);
74 const DF_Default_Megawad_Start = 'megawads/DOOM2D.WAD:\MAP01';
76 var
77 gGameControls: TControls;
78 gScreenWidth: Word;
79 gScreenHeight: Word;
80 gWinRealPosX: Integer;
81 gWinRealPosY: Integer;
82 gBPP: Byte;
83 gFreq: Byte;
84 gFullscreen: Boolean;
85 gWinMaximized: Boolean;
86 gVSync: Boolean;
87 glLegacyNPOT: Boolean;
88 gTextureFilter: Boolean;
89 gNoSound: Boolean;
90 gSoundLevel: Byte;
91 gMusicLevel: Byte;
92 gMaxSimSounds: Byte;
93 gMuteWhenInactive: Boolean;
94 gAdvCorpses: Boolean;
95 gAdvBlood: Boolean;
96 gAdvGibs: Boolean;
97 gGibsCount: Integer;
98 gBloodCount: Byte;
99 gFlash: Byte;
100 gDrawBackGround: Boolean;
101 gShowMessages: Boolean;
102 gRevertPlayers: Boolean;
103 gLanguage: String;
104 gAskLanguage: Boolean;
105 gcMap: String;
106 gcGameMode: String;
107 gcTimeLimit: Word;
108 gcGoalLimit: Word;
109 gcMaxLives: Byte;
110 gcPlayers: Byte;
111 gcTeamDamage: Boolean;
112 gcAllowExit: Boolean;
113 gcWeaponStay: Boolean;
114 gcMonsters: Boolean;
115 gcBotsVS: String;
116 gnMap: String;
117 gnGameMode: String;
118 gnTimeLimit: Word;
119 gnGoalLimit: Word;
120 gnMaxLives: Byte;
121 gnPlayers: Byte;
122 gnTeamDamage: Boolean;
123 gnAllowExit: Boolean;
124 gnWeaponStay: Boolean;
125 gnMonsters: Boolean;
126 gnBotsVS: String;
127 gsSDLSampleRate: Integer;
128 gsSDLBufferSize: Integer;
129 gSFSDebug: Boolean;
130 gSFSFastMode: Boolean;
131 gDefaultMegawadStart: AnsiString;
132 gBerserkAutoswitch: Boolean;
134 implementation
136 uses
137 {$IFDEF USE_NANOGL}
138 nanoGL,
139 {$ELSE}
140 GL, GLExt,
141 {$ENDIF}
142 e_log, e_input, g_window, g_sound, g_gfx, g_player, Math,
143 g_map, g_net, g_netmaster, SysUtils, CONFIG, g_game, g_main, e_texture,
144 g_items, wadreader, e_graphics, g_touch, SDL2;
146 procedure g_Options_SetDefaultVideo;
147 {$IF DEFINED(ANDROID)}
148 var
149 display: PSDL_DisplayMode;
150 {$ENDIF}
151 begin
152 {$IF DEFINED(ANDROID)}
153 (* On android set max screen size *)
154 SDL_GetCurrentDisplayMode(0, display);
155 gScreenWidth := display.w;
156 gScreenHeight := display.h;
157 gWinRealPosX := 0;
158 gWinRealPosY := 0;
159 gWinMaximized := False;
160 gFullScreen := False; (* if True then rotation not allowed *)
161 gBPP := 32;
162 gVSync := True;
163 gTextureFilter := True;
164 glLegacyNPOT := False;
165 {$ELSE}
166 (* On other systems use default 800x600 *)
167 gScreenWidth := 800;
168 gScreenHeight := 600;
169 gWinRealPosX := 0;
170 gWinRealPosY := 0;
171 gWinMaximized := False;
172 gFullScreen := False;
173 gBPP := 32;
174 gVSync := True;
175 gTextureFilter := True;
176 glLegacyNPOT := False;
177 {$ENDIF}
178 end;
180 procedure g_Options_SetDefault();
181 var
182 i: Integer;
183 begin
184 (* section Sound *)
185 gNoSound := False;
186 gSoundLevel := 75;
187 gMusicLevel := 65;
188 gMaxSimSounds := 8;
189 gMuteWhenInactive := False;
190 gAnnouncer := ANNOUNCE_MEPLUS;
191 gSoundEffectsDF := True;
192 gUseChatSounds := True;
193 gsSDLSampleRate := 44100;
194 gsSDLBufferSize := 2048;
196 g_Sound_SetupAllVolumes(gSoundLevel, gMusicLevel);
198 (* section GameControls *)
199 with gGameControls.GameControls do
200 begin
201 TakeScreenshot := SDL_SCANCODE_F12;
202 Stat := SDL_SCANCODE_L;
203 Chat := SDL_SCANCODE_T;
204 TeamChat := SDL_SCANCODE_Y;
205 end;
207 (* section Player1 *)
208 with gGameControls.P1Control do
209 begin
210 KeyRight := SDL_SCANCODE_KP_6;
211 KeyLeft := SDL_SCANCODE_KP_4;
212 KeyUp := SDL_SCANCODE_KP_8;
213 KeyDown := SDL_SCANCODE_KP_5;
214 KeyFire := SDL_SCANCODE_SLASH;
215 KeyJump := SDL_SCANCODE_RCTRL;
216 KeyNextWeapon := SDL_SCANCODE_KP_7;
217 KeyPrevWeapon := SDL_SCANCODE_KP_9;
218 KeyOpen := SDL_SCANCODE_RSHIFT;
219 KeyStrafe := SDL_SCANCODE_PERIOD;
221 for i := 0 to 9 do
222 begin
223 KeyWeapon[i] := SDL_SCANCODE_1 + i (* 1, ..., 9, 0 *)
224 end;
225 KeyWeapon[10] := SDL_SCANCODE_MINUS;
226 for i := 11 to High(KeyWeapon) do
227 begin
228 KeyWeapon[i] := 0
229 end;
231 KeyRight2 := VK_RIGHT;
232 KeyLeft2 := VK_LEFT;
233 KeyUp2 := VK_UP;
234 KeyDown2 := VK_DOWN;
235 KeyFire2 := VK_FIRE;
236 KeyJump2 := VK_JUMP;
237 KeyNextWeapon2 := VK_NEXT;
238 KeyPrevWeapon2 := VK_PREV;
239 KeyOpen2 := VK_OPEN;
240 KeyStrafe2 := VK_STRAFE;
242 for i := 0 to High(KeyWeapon2) do
243 begin
244 KeyWeapon2[i] := VK_0 + i
245 end;
246 end;
248 with gPlayer1Settings do
249 begin
250 Name := 'Player1';
251 Model := STD_PLAYER_MODEL;
252 Color.R := PLAYER1_DEF_COLOR.R;
253 Color.G := PLAYER1_DEF_COLOR.G;
254 Color.B := PLAYER1_DEF_COLOR.B;
255 Team := TEAM_RED;
256 end;
258 (* section Player2 *)
259 with gGameControls.P2Control do
260 begin
261 KeyRight := SDL_SCANCODE_D;
262 KeyLeft := SDL_SCANCODE_A;
263 KeyUp := SDL_SCANCODE_W;
264 KeyDown := SDL_SCANCODE_S;
265 KeyFire := SDL_SCANCODE_G;
266 KeyJump := SDL_SCANCODE_SPACE;
267 KeyNextWeapon := SDL_SCANCODE_E;
268 KeyPrevWeapon := SDL_SCANCODE_Q;
269 KeyOpen := SDL_SCANCODE_F;
270 KeyStrafe := SDL_SCANCODE_LSHIFT;
271 for i := 0 to High(KeyWeapon) do
272 begin
273 KeyWeapon[i] := 0
274 end;
276 KeyRight2 := 0;
277 KeyLeft2 := 0;
278 KeyUp2 := 0;
279 KeyDown2 := 0;
280 KeyFire2 := 0;
281 KeyJump2 := 0;
282 KeyNextWeapon2 := 0;
283 KeyPrevWeapon2 := 0;
284 KeyOpen2 := 0;
285 KeyStrafe2 := 0;
287 for i := 0 to High(KeyWeapon2) do
288 begin
289 KeyWeapon2[i] := 0;
290 end
291 end;
293 with gPlayer2Settings do
294 begin
295 Name := 'Player2';
296 Model := STD_PLAYER_MODEL;
297 Color.R := PLAYER2_DEF_COLOR.R;
298 Color.G := PLAYER2_DEF_COLOR.G;
299 Color.B := PLAYER2_DEF_COLOR.B;
300 Team := TEAM_BLUE;
301 end;
303 (* section Joysticks *)
304 for i := 0 to e_MaxJoys - 1 do
305 begin
306 e_JoystickDeadzones[i] := 8192
307 end;
309 (* section Touch *)
310 g_touch_size := 1.0;
311 g_touch_fire := True;
312 g_touch_offset := 50;
313 g_touch_alt := False;
315 (* section Game *)
316 g_GFX_SetMax(2000);
317 g_Shells_SetMax(300);
318 g_Gibs_SetMax(150);
319 g_Corpses_SetMax(20);
320 gGibsCount := 32;
321 ITEM_RESPAWNTIME := 60 * 36;
322 gBloodCount := 4;
323 gAdvBlood := True;
324 gAdvCorpses := True;
325 gAdvGibs := True;
326 gFlash := 1;
327 gDrawBackGround := True;
328 gShowMessages := True;
329 gRevertPlayers := False;
330 gChatBubble := 4;
331 gSFSDebug := False;
332 gSFSFastMode := False;
333 e_FastScreenshots := True;
334 gDefaultMegawadStart := DF_Default_Megawad_Start;
335 gBerserkAutoswitch := True;
336 g_dbg_scale := 1.0;
338 gAskLanguage := True;
339 gLanguage := LANGUAGE_ENGLISH;
341 (* section GameplayCustom *)
342 gcMap := '';
343 gcGameMode := _lc[I_MENU_GAME_TYPE_DM];
344 gcTimeLimit := 0;
345 gcGoalLimit := 0;
346 gcMaxLives := 0;
347 gcPlayers := 1;
348 gcTeamDamage := False;
349 gcAllowExit := True;
350 gcWeaponStay := False;
351 gcMonsters := False;
352 gcBotsVS := 'Everybody';
354 (* section GameplayNetwork *)
355 gnMap := '';
356 gnGameMode := _lc[I_MENU_GAME_TYPE_DM];
357 gnTimeLimit := 0;
358 gnGoalLimit := 0;
359 gnMaxLives := 0;
360 gnPlayers := 1;
361 gnTeamDamage := False;
362 gnAllowExit := True;
363 gnWeaponStay := False;
364 gnMonsters := False;
365 gnBotsVS := 'Everybody';
367 (* section MasterServer *)
368 NetSlistIP := 'mpms.doom2d.org';
369 NetSlistPort := 25665;
370 g_Net_Slist_Set(NetSlistIP, NetSlistPort);
372 (* section Server *)
373 NetServerName := 'Unnamed Server';
374 NetPassword := '';
375 NetPort := 25666;
376 NetMaxClients := 16;
377 NetAllowRCON := False;
378 NetRCONPassword := 'default';
379 NetUseMaster := True;
380 NetUpdateRate := 0;
381 NetRelupdRate := 18;
382 NetMasterRate := 60000;
383 NetForwardPorts := False;
385 (* section Client *)
386 NetInterpLevel := 2;
387 NetForcePlayerUpdate := False;
388 NetPredictSelf := True;
389 NetClientIP := '127.0.0.1';
390 NetClientPort := NetPort;
391 end;
393 procedure g_Options_Read(FileName: String);
394 var
395 i: Integer;
396 config: TConfig;
397 section: String;
399 procedure ReadInteger (VAR v: Integer; param: String; minv: Integer = Low(Integer); maxv: Integer = High(Integer));
400 begin
401 v := Max(Min(config.ReadInt(section, param, v), maxv), minv)
402 end;
404 procedure ReadInteger (VAR v: Single; param: String; minv: Integer = Low(Integer); maxv: Integer = High(Integer)); overload;
405 begin
406 v := Max(Min(config.ReadInt(section, param, Integer(v)), maxv), minv)
407 end;
409 procedure ReadInteger (VAR v: LongWord; param: String; minv: LongWord = Low(LongWord); maxv: LongWord = High(LongWord)); overload;
410 begin
411 v := Max(Min(config.ReadInt(section, param, v), maxv), minv)
412 end;
414 procedure ReadInteger (VAR v: Word; param: String; minv: Word = Low(Word); maxv: Word = High(Word)); overload;
415 begin
416 v := Max(Min(config.ReadInt(section, param, v), maxv), minv)
417 end;
419 procedure ReadInteger (VAR v: Byte; param: String; minv: Byte = Low(Byte); maxv: Byte = High(Byte)); overload;
420 begin
421 v := Max(Min(config.ReadInt(section, param, v), maxv), minv)
422 end;
424 procedure ReadBoolean (VAR v: Boolean; param: String);
425 begin
426 v := config.ReadBool(section, param, v)
427 end;
429 procedure ReadString (VAR v: String; param: String);
430 begin
431 v := config.ReadStr(section, param, v)
432 end;
434 begin
435 gAskLanguage := True;
436 e_WriteLog('Reading config', TMsgType.Notify);
437 g_Options_SetDefault;
439 if FileExists(FileName) = False then
440 begin
441 e_WriteLog('Config file '+FileName+' not found', TMsgType.Warning);
442 g_Options_SetDefaultVideo;
443 Exit
444 end;
446 config := TConfig.CreateFile(FileName);
448 section := 'Video';
449 ReadInteger(gScreenWidth, 'ScreenWidth', 0);
450 ReadInteger(gScreenHeight, 'ScreenHeight', 0);
451 ReadInteger(gWinRealPosX, 'WinPosX', 60);
452 ReadInteger(gWinRealPosY, 'WinPosY', 60);
453 ReadBoolean(gFullScreen, 'Fullscreen');
454 ReadBoolean(gWinMaximized, 'Maximized');
455 ReadInteger(gBPP, 'BPP', 0);
456 ReadInteger(gFreq, 'Freq', 0);
457 ReadBoolean(gVSync, 'VSync');
458 ReadBoolean(gTextureFilter, 'TextureFilter');
459 ReadBoolean(glLegacyNPOT, 'LegacyCompatible');
461 section := 'Sound';
462 ReadBoolean(gNoSound, 'NoSound');
463 ReadInteger(gSoundLevel, 'SoundLevel', 0, 255);
464 ReadInteger(gMusicLevel, 'MusicLevel', 0, 255);
465 ReadInteger(gMaxSimSounds, 'MaxSimSounds', 2, 66);
466 ReadBoolean(gMuteWhenInactive, 'MuteInactive');
467 ReadInteger(gAnnouncer, 'Announcer', ANNOUNCE_NONE, ANNOUNCE_ALL);
468 ReadBoolean(gSoundEffectsDF, 'SoundEffectsDF');
469 ReadBoolean(gUseChatSounds, 'ChatSounds');
470 ReadInteger(gsSDLSampleRate, 'SDLSampleRate', 11025, 96000);
471 ReadInteger(gsSDLBufferSize, 'SDLBufferSize', 64, 16384);
473 section := 'GameControls';
474 with gGameControls.GameControls do
475 begin
476 ReadInteger(TakeScreenshot, 'TakeScreenshot');
477 ReadInteger(Stat, 'Stat');
478 ReadInteger(Chat, 'Chat');
479 ReadInteger(TeamChat, 'TeamChat');
480 end;
482 section := 'Player1';
483 with gGameControls.P1Control do
484 begin
485 ReadInteger(KeyRight, 'KeyRight');
486 ReadInteger(KeyLeft, 'KeyLeft');
487 ReadInteger(KeyUp, 'KeyUp');
488 ReadInteger(KeyDown, 'KeyDown');
489 ReadInteger(KeyFire, 'KeyFire');
490 ReadInteger(KeyJump, 'KeyJump');
491 ReadInteger(KeyNextWeapon, 'KeyNextWeapon');
492 ReadInteger(KeyPrevWeapon, 'KeyPrevWeapon');
493 ReadInteger(KeyOpen, 'KeyOpen');
494 ReadInteger(KeyStrafe, 'KeyStrafe');
496 for i := 0 to High(KeyWeapon) do
497 begin
498 ReadInteger(KeyWeapon[i], 'KeyWeapon' + IntToStr(i))
499 end;
501 ReadInteger(KeyRight2, 'KeyRight2');
502 ReadInteger(KeyLeft2, 'KeyLeft2');
503 ReadInteger(KeyUp2, 'KeyUp2');
504 ReadInteger(KeyDown2, 'KeyDown2');
505 ReadInteger(KeyFire2, 'KeyFire2');
506 ReadInteger(KeyJump2, 'KeyJump2');
507 ReadInteger(KeyNextWeapon2, 'KeyNextWeapon2');
508 ReadInteger(KeyPrevWeapon2, 'KeyPrevWeapon2');
509 ReadInteger(KeyOpen2, 'KeyOpen2');
510 ReadInteger(KeyStrafe2, 'KeyStrafe2');
512 for i := 0 to High(KeyWeapon2) do
513 begin
514 ReadInteger(KeyWeapon2[i], 'KeyWeapon2' + IntToStr(i))
515 end;
516 end;
518 section := 'Player1';
519 with gPlayer1Settings do
520 begin
521 ReadString(Name, 'name');
522 ReadString(Model, 'model');
523 ReadInteger(Color.R, 'red', 0, 255);
524 ReadInteger(Color.G, 'green', 0, 255);
525 ReadInteger(Color.B, 'blue', 0, 255);
526 ReadInteger(Team, 'team');
527 if (Team < TEAM_RED) or (Team > TEAM_BLUE) then
528 Team := TEAM_RED;
529 end;
531 section := 'Player2';
532 with gGameControls.P2Control do
533 begin
534 ReadInteger(KeyRight, 'KeyRight');
535 ReadInteger(KeyLeft, 'KeyLeft');
536 ReadInteger(KeyUp, 'KeyUp');
537 ReadInteger(KeyDown, 'KeyDown');
538 ReadInteger(KeyFire, 'KeyFire');
539 ReadInteger(KeyJump, 'KeyJump');
540 ReadInteger(KeyNextWeapon, 'KeyNextWeapon');
541 ReadInteger(KeyPrevWeapon, 'KeyPrevWeapon');
542 ReadInteger(KeyOpen, 'KeyOpen');
543 ReadInteger(KeyStrafe, 'KeyStrafe');
545 for i := 0 to High(KeyWeapon) do
546 begin
547 ReadInteger(KeyWeapon[i], 'KeyWeapon' + IntToStr(i))
548 end;
550 ReadInteger(KeyRight2, 'KeyRight2');
551 ReadInteger(KeyLeft2, 'KeyLeft2');
552 ReadInteger(KeyUp2, 'KeyUp2');
553 ReadInteger(KeyDown2, 'KeyDown2');
554 ReadInteger(KeyFire2, 'KeyFire2');
555 ReadInteger(KeyJump2, 'KeyJump2');
556 ReadInteger(KeyNextWeapon2, 'KeyNextWeapon2');
557 ReadInteger(KeyPrevWeapon2, 'KeyPrevWeapon2');
558 ReadInteger(KeyOpen2, 'KeyOpen2');
559 ReadInteger(KeyStrafe2, 'KeyStrafe2');
561 for i := 0 to High(KeyWeapon2) do
562 begin
563 ReadInteger(KeyWeapon2[i], 'KeyWeapon2' + IntToStr(i))
564 end;
565 end;
567 section := 'Player2';
568 with gPlayer2Settings do
569 begin
570 ReadString(Name, 'name');
571 ReadString(Model, 'model');
572 ReadInteger(Color.R, 'red', 0, 255);
573 ReadInteger(Color.G, 'green', 0, 255);
574 ReadInteger(Color.B, 'blue', 0, 255);
575 ReadInteger(Team, 'team');
576 if (Team < TEAM_RED) or (Team > TEAM_BLUE) then
577 Team := TEAM_RED;
578 end;
580 section := 'Joysticks';
581 for i := 0 to e_MaxJoys - 1 do
582 begin
583 ReadInteger(e_JoystickDeadzones[i], 'Deadzone' + IntToStr(i))
584 end;
586 section := 'Touch';
587 ReadInteger(g_touch_size, 'Size', 0); g_touch_size := g_touch_size / 10;
588 ReadBoolean(g_touch_fire, 'Fire');
589 ReadInteger(g_touch_offset, 'Offset', 0, 100);
590 ReadBoolean(g_touch_alt, 'Alt');
592 section := 'Game';
593 ReadInteger(i, 'MaxParticles', 1000, 50000); g_GFX_SetMax(i);
594 ReadInteger(i, 'MaxShells', 300, 600); g_Shells_SetMax(i);
595 ReadInteger(i, 'MaxGibs', 150, 500); g_Gibs_SetMax(i);
596 ReadInteger(i, 'MaxCorpses', 20, 100); g_Corpses_SetMax(i);
597 ReadInteger(i, 'GibsCount');
598 case i of
599 0: gGibsCount := 0;
600 1: gGibsCount := 8;
601 2: gGibsCount := 16;
602 3: gGibsCount := 32;
603 else gGibsCount := 48;
604 end;
605 ReadInteger(ITEM_RESPAWNTIME, 'ItemRespawnTime', 0); ITEM_RESPAWNTIME := ITEM_RESPAWNTIME * 36;
606 ReadInteger(gBloodCount, 'BloodCount', 0, 4);
607 ReadBoolean(gAdvBlood, 'AdvancesBlood');
608 ReadBoolean(gAdvCorpses, 'AdvancesCorpses');
609 ReadBoolean(gAdvGibs, 'AdvancesGibs');
610 ReadInteger(gFlash, 'Flash', 0, 2);
611 ReadBoolean(gDrawBackGround, 'BackGround');
612 ReadBoolean(gShowMessages, 'Messages');
613 ReadBoolean(gRevertPlayers, 'RevertPlayers');
614 ReadInteger(gChatBubble, 'ChatBubble', 0, 4);
615 ReadBoolean(gSFSDebug, 'SFSDebug'); wadoptDebug := gSFSDebug;
616 ReadBoolean(gSFSFastMode, 'SFSFastMode'); wadoptFast := gSFSFastMode;
617 ReadBoolean(e_FastScreenshots, 'FastScreenshots');
618 ReadString(gDefaultMegawadStart, 'DefaultMegawadStart');
619 ReadBoolean(gBerserkAutoswitch, 'BerserkAutoswitching');
620 ReadInteger(g_dbg_scale, 'Scale', 1); g_dbg_scale := g_dbg_scale / 100;
621 ReadString(gLanguage, 'Language');
622 if (gLanguage = LANGUAGE_RUSSIAN) or (gLanguage = LANGUAGE_ENGLISH) then
623 gAskLanguage := False
624 else
625 gLanguage := LANGUAGE_ENGLISH;
627 section := 'GameplayCustom';
628 ReadString(gcMap, 'Map');
629 ReadString(gcGameMode, 'GameMode');
630 ReadInteger(gcTimeLimit, 'TimeLimit', 0, 65535);
631 ReadInteger(gcGoalLimit, 'GoalLimit', 0, 65535);
632 ReadInteger(gcMaxLives, 'MaxLives', 0, 255);
633 ReadInteger(gcPlayers, 'Players', 0, 2);
634 ReadBoolean(gcTeamDamage, 'TeamDamage');
635 ReadBoolean(gcAllowExit, 'AllowExit');
636 ReadBoolean(gcWeaponStay, 'WeaponStay');
637 ReadBoolean(gcMonsters, 'Monsters');
638 ReadString(gcBotsVS, 'BotsVS');
640 with gGameSettings do
641 begin
642 GameMode := g_Game_TextToMode(gcGameMode);
643 if GameMode = GM_NONE then
644 GameMode := GM_DM;
645 if GameMode = GM_SINGLE then
646 GameMode := GM_COOP;
647 TimeLimit := gcTimeLimit;
648 GoalLimit := gcGoalLimit;
649 MaxLives := gcMaxLives;
651 Options := 0;
652 if gcTeamDamage then
653 Options := Options or GAME_OPTION_TEAMDAMAGE;
654 if gcAllowExit then
655 Options := Options or GAME_OPTION_ALLOWEXIT;
656 if gcWeaponStay then
657 Options := Options or GAME_OPTION_WEAPONSTAY;
658 if gcMonsters then
659 Options := Options or GAME_OPTION_MONSTERS;
660 if gcBotsVS = 'Everybody' then
661 Options := Options or GAME_OPTION_BOTVSPLAYER or GAME_OPTION_BOTVSMONSTER;
662 if gcBotsVS = 'Players' then
663 Options := Options or GAME_OPTION_BOTVSPLAYER;
664 if gcBotsVS = 'Monsters' then
665 Options := Options or GAME_OPTION_BOTVSMONSTER;
666 end;
668 section := 'GameplayNetwork';
669 ReadString(gnMap, 'Map');
670 ReadString(gnGameMode, 'GameMode');
671 ReadInteger(gnTimeLimit, 'TimeLimit', 0, 65535);
672 ReadInteger(gnGoalLimit, 'GoalLimit', 0, 65535);
673 ReadInteger(gnMaxLives, 'MaxLives', 0, 255);
674 ReadInteger(gnPlayers, 'Players', 0, 2);
675 ReadBoolean(gnTeamDamage, 'TeamDamage');
676 ReadBoolean(gnAllowExit, 'AllowExit');
677 ReadBoolean(gnWeaponStay, 'WeaponStay');
678 ReadBoolean(gnMonsters, 'Monsters');
679 ReadString(gnBotsVS, 'BotsVS');
681 section := 'MasterServer';
682 ReadString(NetSlistIP, 'IP');
683 ReadInteger(NetSlistPort, 'Port', 0, 65535);
684 g_Net_Slist_Set(NetSlistIP, NetSlistPort);
686 section := 'Server';
687 ReadString(NetServerName, 'Name');
688 ReadString(NetPassword, 'Password');
689 ReadInteger(NetPort, 'Port', 0, 65535);
690 ReadInteger(NetMaxClients, 'MaxClients', 0, NET_MAXCLIENTS);
691 ReadBoolean(NetAllowRCON, 'RCON');
692 ReadString(NetRCONPassword, 'RCONPassword');
693 ReadBoolean(NetUseMaster, 'SyncWithMaster');
694 ReadInteger(NetUpdateRate, 'UpdateInterval', 0);
695 ReadInteger(NetRelupdRate, 'ReliableUpdateInterval', 0);
696 ReadInteger(NetMasterRate, 'MasterSyncInterval', 1);
697 ReadBoolean(NetForwardPorts, 'ForwardPorts');
699 section := 'Client';
700 ReadInteger(NetInterpLevel, 'InterpolationSteps', 0);
701 ReadBoolean(NetForcePlayerUpdate, 'ForcePlayerUpdate');
702 ReadBoolean(NetPredictSelf, 'PredictSelf');
703 ReadString(NetClientIP, 'LastIP');
704 ReadInteger(NetClientPort, 'LastPort', 0, 65535);
706 config.Free();
708 //if gTextureFilter then TEXTUREFILTER := GL_LINEAR else TEXTUREFILTER := GL_NEAREST;
709 end;
711 procedure g_Options_Write(FileName: String);
712 var
713 config: TConfig;
714 i: Integer;
715 begin
716 e_WriteLog('Writing config', TMsgType.Notify);
718 config := TConfig.CreateFile(FileName);
720 config.WriteInt('Video', 'ScreenWidth', gScreenWidth);
721 config.WriteInt('Video', 'ScreenHeight', gScreenHeight);
722 config.WriteInt('Video', 'WinPosX', gWinRealPosX);
723 config.WriteInt('Video', 'WinPosY', gWinRealPosY);
724 config.WriteBool('Video', 'Fullscreen', gFullScreen);
725 config.WriteBool('Video', 'Maximized', gWinMaximized);
726 config.WriteInt('Video', 'BPP', gBPP);
727 config.WriteBool('Video', 'VSync', gVSync);
728 config.WriteBool('Video', 'TextureFilter', gTextureFilter);
729 config.WriteBool('Video', 'LegacyCompatible', glLegacyNPOT);
731 config.WriteBool('Sound', 'NoSound', gNoSound);
732 config.WriteInt('Sound', 'SoundLevel', gSoundLevel);
733 config.WriteInt('Sound', 'MusicLevel', gMusicLevel);
734 config.WriteInt('Sound', 'MaxSimSounds', gMaxSimSounds);
735 config.WriteBool('Sound', 'MuteInactive', gMuteWhenInactive);
736 config.WriteInt('Sound', 'Announcer', gAnnouncer);
737 config.WriteBool('Sound', 'SoundEffectsDF', gSoundEffectsDF);
738 config.WriteBool('Sound', 'ChatSounds', gUseChatSounds);
739 config.WriteInt('Sound', 'SDLSampleRate', gsSDLSampleRate);
740 config.WriteInt('Sound', 'SDLBufferSize', gsSDLBufferSize);
742 with config, gGameControls.GameControls do
743 begin
744 WriteInt('GameControls', 'TakeScreenshot', TakeScreenshot);
745 WriteInt('GameControls', 'Stat', Stat);
746 WriteInt('GameControls', 'Chat', Chat);
747 WriteInt('GameControls', 'TeamChat', TeamChat);
748 end;
750 with config, gGameControls.P1Control, gPlayer1Settings do
751 begin
752 WriteInt('Player1', 'KeyRight', KeyRight);
753 WriteInt('Player1', 'KeyLeft', KeyLeft);
754 WriteInt('Player1', 'KeyUp', KeyUp);
755 WriteInt('Player1', 'KeyDown', KeyDown);
756 WriteInt('Player1', 'KeyFire', KeyFire);
757 WriteInt('Player1', 'KeyJump', KeyJump);
758 WriteInt('Player1', 'KeyNextWeapon', KeyNextWeapon);
759 WriteInt('Player1', 'KeyPrevWeapon', KeyPrevWeapon);
760 WriteInt('Player1', 'KeyOpen', KeyOpen);
761 WriteInt('Player1', 'KeyStrafe', KeyStrafe);
762 for i := 0 to High(KeyWeapon) do
763 WriteInt('Player1', 'KeyWeapon' + IntToStr(i), KeyWeapon[i]);
765 WriteInt('Player1', 'KeyRight2', KeyRight2);
766 WriteInt('Player1', 'KeyLeft2', KeyLeft2);
767 WriteInt('Player1', 'KeyUp2', KeyUp2);
768 WriteInt('Player1', 'KeyDown2', KeyDown2);
769 WriteInt('Player1', 'KeyFire2', KeyFire2);
770 WriteInt('Player1', 'KeyJump2', KeyJump2);
771 WriteInt('Player1', 'KeyNextWeapon2', KeyNextWeapon2);
772 WriteInt('Player1', 'KeyPrevWeapon2', KeyPrevWeapon2);
773 WriteInt('Player1', 'KeyOpen2', KeyOpen2);
774 WriteInt('Player1', 'KeyStrafe2', KeyStrafe2);
775 for i := 0 to High(KeyWeapon2) do
776 WriteInt('Player1', 'KeyWeapon2' + IntToStr(i), KeyWeapon2[i]);
778 WriteStr('Player1', 'Name', Name);
779 WriteStr('Player1', 'model', Model);
780 WriteInt('Player1', 'red', Color.R);
781 WriteInt('Player1', 'green', Color.G);
782 WriteInt('Player1', 'blue', Color.B);
783 WriteInt('Player1', 'team', Team);
784 end;
786 with config, gGameControls.P2Control, gPlayer2Settings do
787 begin
788 WriteInt('Player2', 'KeyRight', KeyRight);
789 WriteInt('Player2', 'KeyLeft', KeyLeft);
790 WriteInt('Player2', 'KeyUp', KeyUp);
791 WriteInt('Player2', 'KeyDown', KeyDown);
792 WriteInt('Player2', 'KeyFire', KeyFire);
793 WriteInt('Player2', 'KeyJump', KeyJump);
794 WriteInt('Player2', 'KeyNextWeapon', KeyNextWeapon);
795 WriteInt('Player2', 'KeyPrevWeapon', KeyPrevWeapon);
796 WriteInt('Player2', 'KeyOpen', KeyOpen);
797 WriteInt('Player2', 'KeyStrafe', KeyStrafe);
798 for i := 0 to High(KeyWeapon) do
799 WriteInt('Player2', 'KeyWeapon' + IntToStr(i), KeyWeapon[i]);
801 WriteInt('Player2', 'KeyRight2', KeyRight2);
802 WriteInt('Player2', 'KeyLeft2', KeyLeft2);
803 WriteInt('Player2', 'KeyUp2', KeyUp2);
804 WriteInt('Player2', 'KeyDown2', KeyDown2);
805 WriteInt('Player2', 'KeyFire2', KeyFire2);
806 WriteInt('Player2', 'KeyJump2', KeyJump2);
807 WriteInt('Player2', 'KeyNextWeapon2', KeyNextWeapon2);
808 WriteInt('Player2', 'KeyPrevWeapon2', KeyPrevWeapon2);
809 WriteInt('Player2', 'KeyOpen2', KeyOpen2);
810 WriteInt('Player2', 'KeyStrafe2', KeyStrafe2);
811 for i := 0 to High(KeyWeapon2) do
812 WriteInt('Player2', 'KeyWeapon2' + IntToStr(i), KeyWeapon2[i]);
814 WriteStr('Player2', 'Name', Name);
815 WriteStr('Player2', 'model', Model);
816 WriteInt('Player2', 'red', Color.R);
817 WriteInt('Player2', 'green', Color.G);
818 WriteInt('Player2', 'blue', Color.B);
819 WriteInt('Player2', 'team', Team);
820 end;
822 for i := 0 to e_MaxJoys-1 do
823 config.WriteInt('Joysticks', 'Deadzone' + IntToStr(i), e_JoystickDeadzones[i]);
825 config.WriteInt('Touch', 'Size', Round(g_touch_size * 10));
826 config.WriteBool('Touch', 'Fire', g_touch_fire);
827 config.WriteInt('Touch', 'Offset', Round(g_touch_offset));
828 config.WriteBool('Touch', 'Alt', g_touch_alt);
830 with config do
831 case gGibsCount of
832 0: config.WriteInt('Game', 'GibsCount', 0);
833 8: config.WriteInt('Game', 'GibsCount', 1);
834 16: config.WriteInt('Game', 'GibsCount', 2);
835 32: config.WriteInt('Game', 'GibsCount', 3);
836 else config.WriteInt('Game', 'GibsCount', 4);
837 end;
839 config.WriteInt('Game', 'ItemRespawnTime', ITEM_RESPAWNTIME div 36);
840 config.WriteInt('Game', 'MaxParticles', g_GFX_GetMax());
841 config.WriteInt('Game', 'MaxShells', g_Shells_GetMax());
842 config.WriteInt('Game', 'MaxGibs', g_Gibs_GetMax());
843 config.WriteInt('Game', 'MaxCorpses', g_Corpses_GetMax());
844 config.WriteInt('Game', 'BloodCount', gBloodCount);
845 config.WriteBool('Game', 'AdvancesBlood', gAdvBlood);
846 config.WriteBool('Game', 'AdvancesCorpses', gAdvCorpses);
847 config.WriteBool('Game', 'AdvancesGibs', gAdvGibs);
848 config.WriteInt('Game', 'Flash', gFlash);
849 config.WriteBool('Game', 'BackGround', gDrawBackGround);
850 config.WriteBool('Game', 'Messages', gShowMessages);
851 config.WriteBool('Game', 'RevertPlayers', gRevertPlayers);
852 config.WriteInt('Game', 'ChatBubble', gChatBubble);
853 config.WriteBool('Game', 'SFSDebug', gSFSDebug);
854 config.WriteBool('Game', 'SFSFastMode', gSFSFastMode);
855 config.WriteBool('Game', 'FastScreenshots', e_FastScreenshots);
856 config.WriteStr('Game', 'DefaultMegawadStart', gDefaultMegawadStart);
857 config.WriteBool('Game', 'BerserkAutoswitching', gBerserkAutoswitch);
858 config.WriteInt('Game', 'Scale', Round(g_dbg_scale * 100));
860 config.WriteStr ('GameplayCustom', 'Map', gcMap);
861 config.WriteStr ('GameplayCustom', 'GameMode', gcGameMode);
862 config.WriteInt ('GameplayCustom', 'TimeLimit', gcTimeLimit);
863 config.WriteInt ('GameplayCustom', 'GoalLimit', gcGoalLimit);
864 config.WriteInt ('GameplayCustom', 'MaxLives', gcMaxLives);
865 config.WriteInt ('GameplayCustom', 'Players', gcPlayers);
866 config.WriteBool('GameplayCustom', 'TeamDamage', gcTeamDamage);
867 config.WriteBool('GameplayCustom', 'AllowExit', gcAllowExit);
868 config.WriteBool('GameplayCustom', 'WeaponStay', gcWeaponStay);
869 config.WriteBool('GameplayCustom', 'Monsters', gcMonsters);
870 config.WriteStr ('GameplayCustom', 'BotsVS', gcBotsVS);
872 config.WriteStr ('GameplayNetwork', 'Map', gnMap);
873 config.WriteStr ('GameplayNetwork', 'GameMode', gnGameMode);
874 config.WriteInt ('GameplayNetwork', 'TimeLimit', gnTimeLimit);
875 config.WriteInt ('GameplayNetwork', 'GoalLimit', gnGoalLimit);
876 config.WriteInt ('GameplayNetwork', 'MaxLives', gnMaxLives);
877 config.WriteInt ('GameplayNetwork', 'Players', gnPlayers);
878 config.WriteBool('GameplayNetwork', 'TeamDamage', gnTeamDamage);
879 config.WriteBool('GameplayNetwork', 'AllowExit', gnAllowExit);
880 config.WriteBool('GameplayNetwork', 'WeaponStay', gnWeaponStay);
881 config.WriteBool('GameplayNetwork', 'Monsters', gnMonsters);
882 config.WriteStr ('GameplayNetwork', 'BotsVS', gnBotsVS);
884 config.WriteStr('MasterServer', 'IP', NetSlistIP);
885 config.WriteInt('MasterServer', 'Port', NetSlistPort);
887 config.WriteStr ('Server', 'Name', NetServerName);
888 config.WriteStr ('Server', 'Password', NetPassword);
889 config.WriteInt ('Server', 'Port', NetPort);
890 config.WriteInt ('Server', 'MaxClients', NetMaxClients);
891 config.WriteBool('Server', 'RCON', NetAllowRCON);
892 config.WriteStr ('Server', 'RCONPassword', NetRCONPassword);
893 config.WriteBool('Server', 'SyncWithMaster', NetUseMaster);
894 config.WriteBool('Server', 'ForwardPorts', NetForwardPorts);
895 config.WriteInt ('Server', 'UpdateInterval', NetUpdateRate);
896 config.WriteInt ('Server', 'ReliableUpdateInterval', NetRelupdRate);
897 config.WriteInt ('Server', 'MasterSyncInterval', NetMasterRate);
899 config.WriteInt ('Client', 'InterpolationSteps', NetInterpLevel);
900 config.WriteBool ('Client', 'ForcePlayerUpdate', NetForcePlayerUpdate);
901 config.WriteBool ('Client', 'PredictSelf', NetPredictSelf);
902 config.WriteStr ('Client', 'LastIP', NetClientIP);
903 config.WriteInt ('Client', 'LastPort', NetClientPort);
905 config.SaveFile(FileName);
906 config.Free();
907 end;
909 procedure g_Options_Write_Language(FileName: String);
910 var
911 config: TConfig;
912 begin
913 e_WriteLog('Writing language config', TMsgType.Notify);
915 config := TConfig.CreateFile(FileName);
916 config.WriteStr('Game', 'Language', gLanguage);
917 config.SaveFile(FileName);
918 config.Free();
919 end;
921 procedure g_Options_Write_Video(FileName: String);
922 var
923 config: TConfig;
924 sW, sH: Integer;
925 begin
926 e_WriteLog('Writing resolution to config', TMsgType.Notify);
928 config := TConfig.CreateFile(FileName);
930 if gWinMaximized and (not gFullscreen) then
931 begin
932 sW := gWinSizeX;
933 sH := gWinSizeY;
934 end
935 else
936 begin
937 sW := gScreenWidth;
938 sH := gScreenHeight;
939 end;
940 e_LogWritefln(' (ws=%dx%d) (ss=%dx%d)', [gWinSizeX, gWinSizeY, gScreenWidth, gScreenHeight]);
942 config.WriteInt('Video', 'ScreenWidth', sW);
943 config.WriteInt('Video', 'ScreenHeight', sH);
944 config.WriteInt('Video', 'WinPosX', gWinRealPosX);
945 config.WriteInt('Video', 'WinPosY', gWinRealPosY);
946 config.WriteBool('Video', 'Fullscreen', gFullscreen);
947 config.WriteBool('Video', 'Maximized', gWinMaximized);
949 config.SaveFile(FileName);
950 config.Free();
951 end;
953 procedure g_Options_Write_Gameplay_Custom(FileName: String);
954 var
955 config: TConfig;
956 begin
957 e_WriteLog('Writing custom gameplay config', TMsgType.Notify);
959 config := TConfig.CreateFile(FileName);
961 config.WriteStr ('GameplayCustom', 'Map', gcMap);
962 config.WriteStr ('GameplayCustom', 'GameMode', gcGameMode);
963 config.WriteInt ('GameplayCustom', 'TimeLimit', gcTimeLimit);
964 config.WriteInt ('GameplayCustom', 'GoalLimit', gcGoalLimit);
965 config.WriteInt ('GameplayCustom', 'MaxLives', gcMaxLives);
966 config.WriteInt ('GameplayCustom', 'Players', gcPlayers);
967 config.WriteBool('GameplayCustom', 'TeamDamage', gcTeamDamage);
968 config.WriteBool('GameplayCustom', 'AllowExit', gcAllowExit);
969 config.WriteBool('GameplayCustom', 'WeaponStay', gcWeaponStay);
970 config.WriteBool('GameplayCustom', 'Monsters', gcMonsters);
971 config.WriteStr ('GameplayCustom', 'BotsVS', gcBotsVS);
973 config.SaveFile(FileName);
974 config.Free();
975 end;
977 procedure g_Options_Write_Gameplay_Net(FileName: String);
978 var
979 config: TConfig;
980 begin
981 e_WriteLog('Writing network gameplay config', TMsgType.Notify);
983 config := TConfig.CreateFile(FileName);
985 config.WriteStr ('GameplayNetwork', 'Map', gnMap);
986 config.WriteStr ('GameplayNetwork', 'GameMode', gnGameMode);
987 config.WriteInt ('GameplayNetwork', 'TimeLimit', gnTimeLimit);
988 config.WriteInt ('GameplayNetwork', 'GoalLimit', gnGoalLimit);
989 config.WriteInt ('GameplayNetwork', 'MaxLives', gnMaxLives);
990 config.WriteInt ('GameplayNetwork', 'Players', gnPlayers);
991 config.WriteBool('GameplayNetwork', 'TeamDamage', gnTeamDamage);
992 config.WriteBool('GameplayNetwork', 'AllowExit', gnAllowExit);
993 config.WriteBool('GameplayNetwork', 'WeaponStay', gnWeaponStay);
994 config.WriteBool('GameplayNetwork', 'Monsters', gnMonsters);
995 config.WriteStr ('GameplayNetwork', 'BotsVS', gnBotsVS);
997 config.SaveFile(FileName);
998 config.Free();
999 end;
1001 procedure g_Options_Write_Net_Server(FileName: String);
1002 var
1003 config: TConfig;
1004 begin
1005 e_WriteLog('Writing server config', TMsgType.Notify);
1007 config := TConfig.CreateFile(FileName);
1009 config.WriteStr ('Server', 'Name', NetServerName);
1010 config.WriteStr ('Server', 'Password', NetPassword);
1011 config.WriteInt ('Server', 'Port', NetPort);
1012 config.WriteInt ('Server', 'MaxClients', NetMaxClients);
1013 config.WriteBool('Server', 'SyncWithMaster', NetUseMaster);
1014 config.WriteBool('Server', 'ForwardPorts', NetForwardPorts);
1016 config.SaveFile(FileName);
1017 config.Free();
1018 end;
1020 procedure g_Options_Write_Net_Client(FileName: String);
1021 var
1022 config: TConfig;
1023 begin
1024 e_WriteLog('Writing client config', TMsgType.Notify);
1026 config := TConfig.CreateFile(FileName);
1028 config.WriteStr('Client', 'LastIP', NetClientIP);
1029 config.WriteInt('Client', 'LastPort', NetClientPort);
1031 config.SaveFile(FileName);
1032 config.Free();
1033 end;
1035 end.