DEADSOFTWARE

cc9a71400bc4a4a7cf159a0392e171f0c8c4cae8
[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 function GenPlayerName (n: Integer): String;
66 procedure g_Options_SetDefault();
67 procedure g_Options_Read(FileName: String);
68 procedure g_Options_Write(FileName: String);
69 procedure g_Options_Write_Language(FileName: String);
70 procedure g_Options_Write_Video(FileName: String);
71 procedure g_Options_Write_Gameplay_Custom(FileName: String);
72 procedure g_Options_Write_Gameplay_Net(FileName: String);
73 procedure g_Options_Write_Net_Server(FileName: String);
74 procedure g_Options_Write_Net_Client(FileName: String);
76 const DF_Default_Megawad_Start = 'megawads/DOOM2D.WAD:\MAP01';
78 var
79 gGameControls: TControls;
80 gScreenWidth: Word;
81 gScreenHeight: Word;
82 gWinRealPosX: Integer;
83 gWinRealPosY: Integer;
84 gBPP: Byte;
85 gFreq: Byte;
86 gFullscreen: Boolean;
87 gWinMaximized: Boolean;
88 gVSync: Boolean;
89 glLegacyNPOT: Boolean;
90 gTextureFilter: Boolean;
91 gNoSound: Boolean;
92 gSoundLevel: Byte;
93 gMusicLevel: Byte;
94 gMaxSimSounds: Byte;
95 gMuteWhenInactive: Boolean;
96 gAdvCorpses: Boolean;
97 gAdvBlood: Boolean;
98 gAdvGibs: Boolean;
99 gGibsCount: Integer;
100 gBloodCount: Byte;
101 gFlash: Byte;
102 gDrawBackGround: Boolean;
103 gShowMessages: Boolean;
104 gRevertPlayers: Boolean;
105 gLanguage: String;
106 gAskLanguage: Boolean;
107 gcMap: String;
108 gcGameMode: String;
109 gcTimeLimit: Word;
110 gcGoalLimit: Word;
111 gcMaxLives: Byte;
112 gcPlayers: Byte;
113 gcTeamDamage: Boolean;
114 gcAllowExit: Boolean;
115 gcWeaponStay: Boolean;
116 gcMonsters: Boolean;
117 gcBotsVS: String;
118 gnMap: String;
119 gnGameMode: String;
120 gnTimeLimit: Word;
121 gnGoalLimit: Word;
122 gnMaxLives: Byte;
123 gnPlayers: Byte;
124 gnTeamDamage: Boolean;
125 gnAllowExit: Boolean;
126 gnWeaponStay: Boolean;
127 gnMonsters: Boolean;
128 gnBotsVS: String;
129 gsSDLSampleRate: Integer;
130 gsSDLBufferSize: Integer;
131 gSFSDebug: Boolean;
132 gSFSFastMode: Boolean;
133 gDefaultMegawadStart: AnsiString;
134 gBerserkAutoswitch: Boolean;
136 implementation
138 uses
139 {$INCLUDE ../nogl/noGLuses.inc}
140 e_log, e_input, g_window, g_sound, g_gfx, g_player, Math,
141 g_map, g_net, g_netmaster, SysUtils, CONFIG, g_game, g_main, e_texture,
142 g_items, wadreader, e_graphics, g_touch, SDL2, envvars;
144 var
145 machine: Integer;
147 function GenPlayerName (n: Integer): String;
148 begin
149 ASSERT(n >= 1);
150 Result := GetUserName;
151 if Result = '' then
152 Result := 'Player' + IntToStr(machine MOD 10000);
153 if n = 1 then
154 Result := Copy(Result, 1, 12) + ' '
155 else
156 Result := Copy(Result, 1, 10) + ' ' + IntToStr(n)
157 end;
159 procedure g_Options_SetDefaultVideo;
160 var
161 target, closest, display: TSDL_DisplayMode;
162 percentage: Integer;
163 begin
164 (* Display 0 = Primary display *)
165 SDL_GetDesktopDisplayMode(0, @display);
166 {$IF DEFINED(ANDROID)}
167 gScreenWidth := display.w;
168 gScreenHeight := display.h;
169 //gBPP := SDL_BITSPERPIXEL(dispaly.format);
170 gBPP := 32;
171 gFullScreen := True; (* rotation not allowed? *)
172 {$ELSE}
173 (* Window must be smaller than display *)
174 closest.w := display.w;
175 closest.h := display.h;
176 percentage := 75;
177 while (display.w - closest.w < 48) or (display.h - closest.h < 48) do
178 begin
179 if percentage < 25 then
180 begin
181 closest.w := display.w * 75 div 100;
182 closest.h := display.h * 75 div 100;
183 break;
184 end;
185 target.w := display.w * percentage div 100;
186 target.h := display.h * percentage div 100;
187 target.format := 0; (* didn't care *)
188 target.refresh_rate := 0; (* didn't care *)
189 target.driverdata := nil; (* init *)
190 SDL_GetClosestDisplayMode(0, @target, @closest);
191 Dec(percentage);
192 end;
193 gScreenWidth := closest.w;
194 gScreenHeight := closest.h;
195 //gBPP := SDL_BITSPERPIXEL(closest.format); (* Resolution list didn't work for some reason *)
196 gBPP := 32;
197 gFullScreen := False;
198 {$ENDIF}
199 (* Must be positioned on primary display *)
200 gWinRealPosX := SDL_WINDOWPOS_CENTERED;
201 gWinRealPosY := SDL_WINDOWPOS_CENTERED;
202 gWinMaximized := False;
203 gVSync := True;
204 gTextureFilter := True;
205 glLegacyNPOT := False;
206 e_LogWriteLn('g_Options_SetDefaultVideo: w = ' + IntToStr(gScreenWidth) + ' h = ' + IntToStr(gScreenHeight));
207 end;
209 procedure g_Options_SetDefault();
210 var
211 i: Integer;
212 begin
213 (* section Sound *)
214 gNoSound := False;
215 gSoundLevel := 75;
216 gMusicLevel := 65;
217 gMaxSimSounds := 8;
218 gMuteWhenInactive := False;
219 gAnnouncer := ANNOUNCE_MEPLUS;
220 gSoundEffectsDF := True;
221 gUseChatSounds := True;
222 gsSDLSampleRate := 44100;
223 gsSDLBufferSize := 2048;
225 g_Sound_SetupAllVolumes(gSoundLevel, gMusicLevel);
227 (* section GameControls *)
228 with gGameControls.GameControls do
229 begin
230 TakeScreenshot := SDL_SCANCODE_F12;
231 Stat := SDL_SCANCODE_TAB;
232 Chat := SDL_SCANCODE_T;
233 TeamChat := SDL_SCANCODE_Y;
234 end;
236 (* section Player1 *)
237 with gGameControls.P1Control do
238 begin
239 KeyRight := SDL_SCANCODE_KP_6;
240 KeyLeft := SDL_SCANCODE_KP_4;
241 KeyUp := SDL_SCANCODE_KP_8;
242 KeyDown := SDL_SCANCODE_KP_5;
243 KeyFire := SDL_SCANCODE_SLASH;
244 KeyJump := SDL_SCANCODE_RCTRL;
245 KeyNextWeapon := SDL_SCANCODE_KP_9;
246 KeyPrevWeapon := SDL_SCANCODE_KP_7;
247 KeyOpen := SDL_SCANCODE_RSHIFT;
248 KeyStrafe := SDL_SCANCODE_PERIOD;
250 for i := 0 to 9 do
251 begin
252 KeyWeapon[i] := SDL_SCANCODE_1 + i (* 1, ..., 9, 0 *)
253 end;
254 KeyWeapon[10] := SDL_SCANCODE_MINUS;
255 for i := 11 to High(KeyWeapon) do
256 begin
257 KeyWeapon[i] := 0
258 end;
260 KeyRight2 := VK_RIGHT;
261 KeyLeft2 := VK_LEFT;
262 KeyUp2 := VK_UP;
263 KeyDown2 := VK_DOWN;
264 KeyFire2 := VK_FIRE;
265 KeyJump2 := VK_JUMP;
266 KeyNextWeapon2 := VK_NEXT;
267 KeyPrevWeapon2 := VK_PREV;
268 KeyOpen2 := VK_OPEN;
269 KeyStrafe2 := VK_STRAFE;
271 for i := 0 to High(KeyWeapon2) do
272 begin
273 KeyWeapon2[i] := VK_0 + i
274 end;
275 end;
277 with gPlayer1Settings do
278 begin
279 Name := GenPlayerName(1);
280 Model := STD_PLAYER_MODEL;
281 Color.R := PLAYER1_DEF_COLOR.R;
282 Color.G := PLAYER1_DEF_COLOR.G;
283 Color.B := PLAYER1_DEF_COLOR.B;
284 Team := TEAM_RED;
285 end;
287 (* section Player2 *)
288 with gGameControls.P2Control do
289 begin
290 KeyRight := SDL_SCANCODE_D;
291 KeyLeft := SDL_SCANCODE_A;
292 KeyUp := SDL_SCANCODE_W;
293 KeyDown := SDL_SCANCODE_S;
294 KeyFire := SDL_SCANCODE_G;
295 KeyJump := SDL_SCANCODE_SPACE;
296 KeyNextWeapon := SDL_SCANCODE_E;
297 KeyPrevWeapon := SDL_SCANCODE_Q;
298 KeyOpen := SDL_SCANCODE_F;
299 KeyStrafe := SDL_SCANCODE_LSHIFT;
300 for i := 0 to High(KeyWeapon) do
301 begin
302 KeyWeapon[i] := 0
303 end;
305 KeyRight2 := 0;
306 KeyLeft2 := 0;
307 KeyUp2 := 0;
308 KeyDown2 := 0;
309 KeyFire2 := 0;
310 KeyJump2 := 0;
311 KeyNextWeapon2 := 0;
312 KeyPrevWeapon2 := 0;
313 KeyOpen2 := 0;
314 KeyStrafe2 := 0;
316 for i := 0 to High(KeyWeapon2) do
317 begin
318 KeyWeapon2[i] := 0;
319 end
320 end;
322 with gPlayer2Settings do
323 begin
324 Name := GenPlayerName(2);
325 Model := STD_PLAYER_MODEL;
326 Color.R := PLAYER2_DEF_COLOR.R;
327 Color.G := PLAYER2_DEF_COLOR.G;
328 Color.B := PLAYER2_DEF_COLOR.B;
329 Team := TEAM_BLUE;
330 end;
332 (* section Joysticks *)
333 for i := 0 to e_MaxJoys - 1 do
334 begin
335 e_JoystickDeadzones[i] := 8192
336 end;
338 (* section Touch *)
339 g_touch_size := 1.0;
340 g_touch_fire := True;
341 g_touch_offset := 50;
342 g_touch_alt := False;
344 (* section Game *)
345 g_GFX_SetMax(2000);
346 g_Shells_SetMax(300);
347 g_Gibs_SetMax(150);
348 g_Corpses_SetMax(20);
349 gGibsCount := 32;
350 ITEM_RESPAWNTIME := 60 * 36;
351 gBloodCount := 4;
352 gAdvBlood := True;
353 gAdvCorpses := True;
354 gAdvGibs := True;
355 gFlash := 1;
356 gDrawBackGround := True;
357 gShowMessages := True;
358 gRevertPlayers := False;
359 gChatBubble := 4;
360 gSFSDebug := False;
361 gSFSFastMode := False;
362 e_FastScreenshots := True;
363 gDefaultMegawadStart := DF_Default_Megawad_Start;
364 gBerserkAutoswitch := True;
365 g_dbg_scale := 1.0;
367 gAskLanguage := True;
368 gLanguage := LANGUAGE_ENGLISH;
370 (* section GameplayCustom *)
371 gcMap := '';
372 gcGameMode := _lc[I_MENU_GAME_TYPE_DM];
373 gcTimeLimit := 0;
374 gcGoalLimit := 0;
375 gcMaxLives := 0;
376 gcPlayers := 1;
377 gcTeamDamage := False;
378 gcAllowExit := True;
379 gcWeaponStay := False;
380 gcMonsters := False;
381 gcBotsVS := 'Everybody';
383 (* section GameplayNetwork *)
384 gnMap := '';
385 gnGameMode := _lc[I_MENU_GAME_TYPE_DM];
386 gnTimeLimit := 0;
387 gnGoalLimit := 0;
388 gnMaxLives := 0;
389 gnPlayers := 1;
390 gnTeamDamage := False;
391 gnAllowExit := True;
392 gnWeaponStay := False;
393 gnMonsters := False;
394 gnBotsVS := 'Everybody';
396 (* section MasterServer *)
397 NetSlistIP := 'mpms.doom2d.org';
398 NetSlistPort := 25665;
399 g_Net_Slist_Set(NetSlistIP, NetSlistPort);
401 (* section Server *)
402 NetServerName := 'Unnamed Server';
403 NetPassword := '';
404 NetPort := 25666;
405 NetMaxClients := 16;
406 NetAllowRCON := False;
407 NetRCONPassword := 'default';
408 NetUseMaster := True;
409 NetUpdateRate := 0;
410 NetRelupdRate := 18;
411 NetMasterRate := 60000;
412 NetForwardPorts := False;
414 (* section Client *)
415 NetInterpLevel := 2;
416 NetForcePlayerUpdate := False;
417 NetPredictSelf := True;
418 NetClientIP := '127.0.0.1';
419 NetClientPort := NetPort;
420 end;
422 procedure g_Options_Read(FileName: String);
423 var
424 i: Integer;
425 config: TConfig;
426 section: String;
428 procedure ReadInteger (VAR v: Integer; param: String; minv: Integer = Low(Integer); maxv: Integer = High(Integer));
429 begin
430 v := Max(Min(config.ReadInt(section, param, v), maxv), minv)
431 end;
433 procedure ReadInteger (VAR v: LongWord; param: String; minv: LongWord = Low(LongWord); maxv: LongWord = High(LongWord)); overload;
434 begin
435 v := Max(Min(config.ReadInt(section, param, v), maxv), minv)
436 end;
438 procedure ReadInteger (VAR v: Word; param: String; minv: Word = Low(Word); maxv: Word = High(Word)); overload;
439 begin
440 v := Max(Min(config.ReadInt(section, param, v), maxv), minv)
441 end;
443 procedure ReadInteger (VAR v: Byte; param: String; minv: Byte = Low(Byte); maxv: Byte = High(Byte)); overload;
444 begin
445 v := Max(Min(config.ReadInt(section, param, v), maxv), minv)
446 end;
448 procedure ReadBoolean (VAR v: Boolean; param: String);
449 begin
450 v := config.ReadBool(section, param, v)
451 end;
453 procedure ReadString (VAR v: String; param: String);
454 begin
455 v := config.ReadStr(section, param, v)
456 end;
458 begin
459 gAskLanguage := True;
460 e_WriteLog('Reading config', TMsgType.Notify);
461 g_Options_SetDefault;
463 if FileExists(FileName) = False then
464 begin
465 e_WriteLog('Config file '+FileName+' not found', TMsgType.Warning);
466 g_Options_SetDefaultVideo;
467 Exit
468 end;
470 config := TConfig.CreateFile(FileName);
472 section := 'Video';
473 ReadInteger(gScreenWidth, 'ScreenWidth', 0);
474 ReadInteger(gScreenHeight, 'ScreenHeight', 0);
475 ReadInteger(gWinRealPosX, 'WinPosX', 60);
476 ReadInteger(gWinRealPosY, 'WinPosY', 60);
477 ReadBoolean(gFullScreen, 'Fullscreen');
478 ReadBoolean(gWinMaximized, 'Maximized');
479 ReadInteger(gBPP, 'BPP', 0);
480 ReadInteger(gFreq, 'Freq', 0);
481 ReadBoolean(gVSync, 'VSync');
482 ReadBoolean(gTextureFilter, 'TextureFilter');
483 ReadBoolean(glLegacyNPOT, 'LegacyCompatible');
485 section := 'Sound';
486 ReadBoolean(gNoSound, 'NoSound');
487 ReadInteger(gSoundLevel, 'SoundLevel', 0, 255);
488 ReadInteger(gMusicLevel, 'MusicLevel', 0, 255);
489 ReadInteger(gMaxSimSounds, 'MaxSimSounds', 2, 66);
490 ReadBoolean(gMuteWhenInactive, 'MuteInactive');
491 ReadInteger(gAnnouncer, 'Announcer', ANNOUNCE_NONE, ANNOUNCE_ALL);
492 ReadBoolean(gSoundEffectsDF, 'SoundEffectsDF');
493 ReadBoolean(gUseChatSounds, 'ChatSounds');
494 ReadInteger(gsSDLSampleRate, 'SDLSampleRate', 11025, 96000);
495 ReadInteger(gsSDLBufferSize, 'SDLBufferSize', 64, 16384);
497 section := 'GameControls';
498 with gGameControls.GameControls do
499 begin
500 ReadInteger(TakeScreenshot, 'TakeScreenshot');
501 ReadInteger(Stat, 'Stat');
502 ReadInteger(Chat, 'Chat');
503 ReadInteger(TeamChat, 'TeamChat');
504 end;
506 section := 'Player1';
507 with gGameControls.P1Control do
508 begin
509 ReadInteger(KeyRight, 'KeyRight');
510 ReadInteger(KeyLeft, 'KeyLeft');
511 ReadInteger(KeyUp, 'KeyUp');
512 ReadInteger(KeyDown, 'KeyDown');
513 ReadInteger(KeyFire, 'KeyFire');
514 ReadInteger(KeyJump, 'KeyJump');
515 ReadInteger(KeyNextWeapon, 'KeyNextWeapon');
516 ReadInteger(KeyPrevWeapon, 'KeyPrevWeapon');
517 ReadInteger(KeyOpen, 'KeyOpen');
518 ReadInteger(KeyStrafe, 'KeyStrafe');
520 for i := 0 to High(KeyWeapon) do
521 begin
522 ReadInteger(KeyWeapon[i], 'KeyWeapon' + IntToStr(i))
523 end;
525 ReadInteger(KeyRight2, 'KeyRight2');
526 ReadInteger(KeyLeft2, 'KeyLeft2');
527 ReadInteger(KeyUp2, 'KeyUp2');
528 ReadInteger(KeyDown2, 'KeyDown2');
529 ReadInteger(KeyFire2, 'KeyFire2');
530 ReadInteger(KeyJump2, 'KeyJump2');
531 ReadInteger(KeyNextWeapon2, 'KeyNextWeapon2');
532 ReadInteger(KeyPrevWeapon2, 'KeyPrevWeapon2');
533 ReadInteger(KeyOpen2, 'KeyOpen2');
534 ReadInteger(KeyStrafe2, 'KeyStrafe2');
536 for i := 0 to High(KeyWeapon2) do
537 begin
538 ReadInteger(KeyWeapon2[i], 'KeyWeapon2' + IntToStr(i))
539 end;
540 end;
542 section := 'Player1';
543 with gPlayer1Settings do
544 begin
545 ReadString(Name, 'name');
546 ReadString(Model, 'model');
547 ReadInteger(Color.R, 'red', 0, 255);
548 ReadInteger(Color.G, 'green', 0, 255);
549 ReadInteger(Color.B, 'blue', 0, 255);
550 ReadInteger(Team, 'team');
551 if (Team < TEAM_RED) or (Team > TEAM_BLUE) then
552 Team := TEAM_RED;
553 end;
555 section := 'Player2';
556 with gGameControls.P2Control do
557 begin
558 ReadInteger(KeyRight, 'KeyRight');
559 ReadInteger(KeyLeft, 'KeyLeft');
560 ReadInteger(KeyUp, 'KeyUp');
561 ReadInteger(KeyDown, 'KeyDown');
562 ReadInteger(KeyFire, 'KeyFire');
563 ReadInteger(KeyJump, 'KeyJump');
564 ReadInteger(KeyNextWeapon, 'KeyNextWeapon');
565 ReadInteger(KeyPrevWeapon, 'KeyPrevWeapon');
566 ReadInteger(KeyOpen, 'KeyOpen');
567 ReadInteger(KeyStrafe, 'KeyStrafe');
569 for i := 0 to High(KeyWeapon) do
570 begin
571 ReadInteger(KeyWeapon[i], 'KeyWeapon' + IntToStr(i))
572 end;
574 ReadInteger(KeyRight2, 'KeyRight2');
575 ReadInteger(KeyLeft2, 'KeyLeft2');
576 ReadInteger(KeyUp2, 'KeyUp2');
577 ReadInteger(KeyDown2, 'KeyDown2');
578 ReadInteger(KeyFire2, 'KeyFire2');
579 ReadInteger(KeyJump2, 'KeyJump2');
580 ReadInteger(KeyNextWeapon2, 'KeyNextWeapon2');
581 ReadInteger(KeyPrevWeapon2, 'KeyPrevWeapon2');
582 ReadInteger(KeyOpen2, 'KeyOpen2');
583 ReadInteger(KeyStrafe2, 'KeyStrafe2');
585 for i := 0 to High(KeyWeapon2) do
586 begin
587 ReadInteger(KeyWeapon2[i], 'KeyWeapon2' + IntToStr(i))
588 end;
589 end;
591 section := 'Player2';
592 with gPlayer2Settings do
593 begin
594 ReadString(Name, 'name');
595 ReadString(Model, 'model');
596 ReadInteger(Color.R, 'red', 0, 255);
597 ReadInteger(Color.G, 'green', 0, 255);
598 ReadInteger(Color.B, 'blue', 0, 255);
599 ReadInteger(Team, 'team');
600 if (Team < TEAM_RED) or (Team > TEAM_BLUE) then
601 Team := TEAM_RED;
602 end;
604 section := 'Joysticks';
605 for i := 0 to e_MaxJoys - 1 do
606 begin
607 ReadInteger(e_JoystickDeadzones[i], 'Deadzone' + IntToStr(i))
608 end;
610 section := 'Touch';
611 i := Trunc(g_touch_size * 10); ReadInteger(i, 'Size', 0); g_touch_size := i / 10;
612 ReadBoolean(g_touch_fire, 'Fire');
613 i := Round(g_touch_offset); ReadInteger(i, 'Offset', 0, 100); g_touch_offset := i;
614 ReadBoolean(g_touch_alt, 'Alt');
616 section := 'Game';
617 ReadInteger(i, 'MaxParticles', 1000, 50000); g_GFX_SetMax(i);
618 ReadInteger(i, 'MaxShells', 300, 600); g_Shells_SetMax(i);
619 ReadInteger(i, 'MaxGibs', 150, 500); g_Gibs_SetMax(i);
620 ReadInteger(i, 'MaxCorpses', 20, 100); g_Corpses_SetMax(i);
621 ReadInteger(i, 'GibsCount');
622 case i of
623 0: gGibsCount := 0;
624 1: gGibsCount := 8;
625 2: gGibsCount := 16;
626 3: gGibsCount := 32;
627 else gGibsCount := 48;
628 end;
629 i := ITEM_RESPAWNTIME div 36; ReadInteger(i, 'ItemRespawnTime', 0); ITEM_RESPAWNTIME := i * 36;
630 ReadInteger(gBloodCount, 'BloodCount', 0, 4);
631 ReadBoolean(gAdvBlood, 'AdvancesBlood');
632 ReadBoolean(gAdvCorpses, 'AdvancesCorpses');
633 ReadBoolean(gAdvGibs, 'AdvancesGibs');
634 ReadInteger(gFlash, 'Flash', 0, 2);
635 ReadBoolean(gDrawBackGround, 'BackGround');
636 ReadBoolean(gShowMessages, 'Messages');
637 ReadBoolean(gRevertPlayers, 'RevertPlayers');
638 ReadInteger(gChatBubble, 'ChatBubble', 0, 4);
639 ReadBoolean(gSFSDebug, 'SFSDebug'); wadoptDebug := gSFSDebug;
640 ReadBoolean(gSFSFastMode, 'SFSFastMode'); wadoptFast := gSFSFastMode;
641 ReadBoolean(e_FastScreenshots, 'FastScreenshots');
642 ReadString(gDefaultMegawadStart, 'DefaultMegawadStart');
643 ReadBoolean(gBerserkAutoswitch, 'BerserkAutoswitching');
644 i := Trunc(g_dbg_scale * 100); ReadInteger(i, 'Scale', 100); g_dbg_scale := i / 100;
645 ReadString(gLanguage, 'Language');
646 if (gLanguage = LANGUAGE_RUSSIAN) or (gLanguage = LANGUAGE_ENGLISH) then
647 gAskLanguage := False
648 else
649 gLanguage := LANGUAGE_ENGLISH;
651 section := 'GameplayCustom';
652 ReadString(gcMap, 'Map');
653 ReadString(gcGameMode, 'GameMode');
654 ReadInteger(gcTimeLimit, 'TimeLimit', 0, 65535);
655 ReadInteger(gcGoalLimit, 'GoalLimit', 0, 65535);
656 ReadInteger(gcMaxLives, 'MaxLives', 0, 255);
657 ReadInteger(gcPlayers, 'Players', 0, 2);
658 ReadBoolean(gcTeamDamage, 'TeamDamage');
659 ReadBoolean(gcAllowExit, 'AllowExit');
660 ReadBoolean(gcWeaponStay, 'WeaponStay');
661 ReadBoolean(gcMonsters, 'Monsters');
662 ReadString(gcBotsVS, 'BotsVS');
664 with gGameSettings do
665 begin
666 GameMode := g_Game_TextToMode(gcGameMode);
667 if GameMode = GM_NONE then
668 GameMode := GM_DM;
669 if GameMode = GM_SINGLE then
670 GameMode := GM_COOP;
671 TimeLimit := gcTimeLimit;
672 GoalLimit := gcGoalLimit;
673 MaxLives := gcMaxLives;
675 Options := 0;
676 if gcTeamDamage then
677 Options := Options or GAME_OPTION_TEAMDAMAGE;
678 if gcAllowExit then
679 Options := Options or GAME_OPTION_ALLOWEXIT;
680 if gcWeaponStay then
681 Options := Options or GAME_OPTION_WEAPONSTAY;
682 if gcMonsters then
683 Options := Options or GAME_OPTION_MONSTERS;
684 if gcBotsVS = 'Everybody' then
685 Options := Options or GAME_OPTION_BOTVSPLAYER or GAME_OPTION_BOTVSMONSTER;
686 if gcBotsVS = 'Players' then
687 Options := Options or GAME_OPTION_BOTVSPLAYER;
688 if gcBotsVS = 'Monsters' then
689 Options := Options or GAME_OPTION_BOTVSMONSTER;
690 end;
692 section := 'GameplayNetwork';
693 ReadString(gnMap, 'Map');
694 ReadString(gnGameMode, 'GameMode');
695 ReadInteger(gnTimeLimit, 'TimeLimit', 0, 65535);
696 ReadInteger(gnGoalLimit, 'GoalLimit', 0, 65535);
697 ReadInteger(gnMaxLives, 'MaxLives', 0, 255);
698 ReadInteger(gnPlayers, 'Players', 0, 2);
699 ReadBoolean(gnTeamDamage, 'TeamDamage');
700 ReadBoolean(gnAllowExit, 'AllowExit');
701 ReadBoolean(gnWeaponStay, 'WeaponStay');
702 ReadBoolean(gnMonsters, 'Monsters');
703 ReadString(gnBotsVS, 'BotsVS');
705 section := 'MasterServer';
706 ReadString(NetSlistIP, 'IP');
707 ReadInteger(NetSlistPort, 'Port', 0, 65535);
708 g_Net_Slist_Set(NetSlistIP, NetSlistPort);
710 section := 'Server';
711 ReadString(NetServerName, 'Name');
712 ReadString(NetPassword, 'Password');
713 ReadInteger(NetPort, 'Port', 0, 65535);
714 ReadInteger(NetMaxClients, 'MaxClients', 0, NET_MAXCLIENTS);
715 ReadBoolean(NetAllowRCON, 'RCON');
716 ReadString(NetRCONPassword, 'RCONPassword');
717 ReadBoolean(NetUseMaster, 'SyncWithMaster');
718 ReadInteger(NetUpdateRate, 'UpdateInterval', 0);
719 ReadInteger(NetRelupdRate, 'ReliableUpdateInterval', 0);
720 ReadInteger(NetMasterRate, 'MasterSyncInterval', 1);
721 ReadBoolean(NetForwardPorts, 'ForwardPorts');
723 section := 'Client';
724 ReadInteger(NetInterpLevel, 'InterpolationSteps', 0);
725 ReadBoolean(NetForcePlayerUpdate, 'ForcePlayerUpdate');
726 ReadBoolean(NetPredictSelf, 'PredictSelf');
727 ReadString(NetClientIP, 'LastIP');
728 ReadInteger(NetClientPort, 'LastPort', 0, 65535);
730 config.Free();
732 //if gTextureFilter then TEXTUREFILTER := GL_LINEAR else TEXTUREFILTER := GL_NEAREST;
733 end;
735 procedure g_Options_Write(FileName: String);
736 var
737 config: TConfig;
738 i: Integer;
739 begin
740 e_WriteLog('Writing config', TMsgType.Notify);
742 config := TConfig.CreateFile(FileName);
744 config.WriteInt('Video', 'ScreenWidth', gScreenWidth);
745 config.WriteInt('Video', 'ScreenHeight', gScreenHeight);
746 config.WriteInt('Video', 'WinPosX', gWinRealPosX);
747 config.WriteInt('Video', 'WinPosY', gWinRealPosY);
748 config.WriteBool('Video', 'Fullscreen', gFullScreen);
749 config.WriteBool('Video', 'Maximized', gWinMaximized);
750 config.WriteInt('Video', 'BPP', gBPP);
751 config.WriteBool('Video', 'VSync', gVSync);
752 config.WriteBool('Video', 'TextureFilter', gTextureFilter);
753 config.WriteBool('Video', 'LegacyCompatible', glLegacyNPOT);
755 config.WriteBool('Sound', 'NoSound', gNoSound);
756 config.WriteInt('Sound', 'SoundLevel', gSoundLevel);
757 config.WriteInt('Sound', 'MusicLevel', gMusicLevel);
758 config.WriteInt('Sound', 'MaxSimSounds', gMaxSimSounds);
759 config.WriteBool('Sound', 'MuteInactive', gMuteWhenInactive);
760 config.WriteInt('Sound', 'Announcer', gAnnouncer);
761 config.WriteBool('Sound', 'SoundEffectsDF', gSoundEffectsDF);
762 config.WriteBool('Sound', 'ChatSounds', gUseChatSounds);
763 config.WriteInt('Sound', 'SDLSampleRate', gsSDLSampleRate);
764 config.WriteInt('Sound', 'SDLBufferSize', gsSDLBufferSize);
766 with config, gGameControls.GameControls do
767 begin
768 WriteInt('GameControls', 'TakeScreenshot', TakeScreenshot);
769 WriteInt('GameControls', 'Stat', Stat);
770 WriteInt('GameControls', 'Chat', Chat);
771 WriteInt('GameControls', 'TeamChat', TeamChat);
772 end;
774 with config, gGameControls.P1Control, gPlayer1Settings do
775 begin
776 WriteInt('Player1', 'KeyRight', KeyRight);
777 WriteInt('Player1', 'KeyLeft', KeyLeft);
778 WriteInt('Player1', 'KeyUp', KeyUp);
779 WriteInt('Player1', 'KeyDown', KeyDown);
780 WriteInt('Player1', 'KeyFire', KeyFire);
781 WriteInt('Player1', 'KeyJump', KeyJump);
782 WriteInt('Player1', 'KeyNextWeapon', KeyNextWeapon);
783 WriteInt('Player1', 'KeyPrevWeapon', KeyPrevWeapon);
784 WriteInt('Player1', 'KeyOpen', KeyOpen);
785 WriteInt('Player1', 'KeyStrafe', KeyStrafe);
786 for i := 0 to High(KeyWeapon) do
787 WriteInt('Player1', 'KeyWeapon' + IntToStr(i), KeyWeapon[i]);
789 WriteInt('Player1', 'KeyRight2', KeyRight2);
790 WriteInt('Player1', 'KeyLeft2', KeyLeft2);
791 WriteInt('Player1', 'KeyUp2', KeyUp2);
792 WriteInt('Player1', 'KeyDown2', KeyDown2);
793 WriteInt('Player1', 'KeyFire2', KeyFire2);
794 WriteInt('Player1', 'KeyJump2', KeyJump2);
795 WriteInt('Player1', 'KeyNextWeapon2', KeyNextWeapon2);
796 WriteInt('Player1', 'KeyPrevWeapon2', KeyPrevWeapon2);
797 WriteInt('Player1', 'KeyOpen2', KeyOpen2);
798 WriteInt('Player1', 'KeyStrafe2', KeyStrafe2);
799 for i := 0 to High(KeyWeapon2) do
800 WriteInt('Player1', 'KeyWeapon2' + IntToStr(i), KeyWeapon2[i]);
802 WriteStr('Player1', 'Name', Name);
803 WriteStr('Player1', 'model', Model);
804 WriteInt('Player1', 'red', Color.R);
805 WriteInt('Player1', 'green', Color.G);
806 WriteInt('Player1', 'blue', Color.B);
807 WriteInt('Player1', 'team', Team);
808 end;
810 with config, gGameControls.P2Control, gPlayer2Settings do
811 begin
812 WriteInt('Player2', 'KeyRight', KeyRight);
813 WriteInt('Player2', 'KeyLeft', KeyLeft);
814 WriteInt('Player2', 'KeyUp', KeyUp);
815 WriteInt('Player2', 'KeyDown', KeyDown);
816 WriteInt('Player2', 'KeyFire', KeyFire);
817 WriteInt('Player2', 'KeyJump', KeyJump);
818 WriteInt('Player2', 'KeyNextWeapon', KeyNextWeapon);
819 WriteInt('Player2', 'KeyPrevWeapon', KeyPrevWeapon);
820 WriteInt('Player2', 'KeyOpen', KeyOpen);
821 WriteInt('Player2', 'KeyStrafe', KeyStrafe);
822 for i := 0 to High(KeyWeapon) do
823 WriteInt('Player2', 'KeyWeapon' + IntToStr(i), KeyWeapon[i]);
825 WriteInt('Player2', 'KeyRight2', KeyRight2);
826 WriteInt('Player2', 'KeyLeft2', KeyLeft2);
827 WriteInt('Player2', 'KeyUp2', KeyUp2);
828 WriteInt('Player2', 'KeyDown2', KeyDown2);
829 WriteInt('Player2', 'KeyFire2', KeyFire2);
830 WriteInt('Player2', 'KeyJump2', KeyJump2);
831 WriteInt('Player2', 'KeyNextWeapon2', KeyNextWeapon2);
832 WriteInt('Player2', 'KeyPrevWeapon2', KeyPrevWeapon2);
833 WriteInt('Player2', 'KeyOpen2', KeyOpen2);
834 WriteInt('Player2', 'KeyStrafe2', KeyStrafe2);
835 for i := 0 to High(KeyWeapon2) do
836 WriteInt('Player2', 'KeyWeapon2' + IntToStr(i), KeyWeapon2[i]);
838 WriteStr('Player2', 'Name', Name);
839 WriteStr('Player2', 'model', Model);
840 WriteInt('Player2', 'red', Color.R);
841 WriteInt('Player2', 'green', Color.G);
842 WriteInt('Player2', 'blue', Color.B);
843 WriteInt('Player2', 'team', Team);
844 end;
846 for i := 0 to e_MaxJoys-1 do
847 config.WriteInt('Joysticks', 'Deadzone' + IntToStr(i), e_JoystickDeadzones[i]);
849 config.WriteInt('Touch', 'Size', Round(g_touch_size * 10));
850 config.WriteBool('Touch', 'Fire', g_touch_fire);
851 config.WriteInt('Touch', 'Offset', Round(g_touch_offset));
852 config.WriteBool('Touch', 'Alt', g_touch_alt);
854 with config do
855 case gGibsCount of
856 0: config.WriteInt('Game', 'GibsCount', 0);
857 8: config.WriteInt('Game', 'GibsCount', 1);
858 16: config.WriteInt('Game', 'GibsCount', 2);
859 32: config.WriteInt('Game', 'GibsCount', 3);
860 else config.WriteInt('Game', 'GibsCount', 4);
861 end;
863 config.WriteInt('Game', 'ItemRespawnTime', ITEM_RESPAWNTIME div 36);
864 config.WriteInt('Game', 'MaxParticles', g_GFX_GetMax());
865 config.WriteInt('Game', 'MaxShells', g_Shells_GetMax());
866 config.WriteInt('Game', 'MaxGibs', g_Gibs_GetMax());
867 config.WriteInt('Game', 'MaxCorpses', g_Corpses_GetMax());
868 config.WriteInt('Game', 'BloodCount', gBloodCount);
869 config.WriteBool('Game', 'AdvancesBlood', gAdvBlood);
870 config.WriteBool('Game', 'AdvancesCorpses', gAdvCorpses);
871 config.WriteBool('Game', 'AdvancesGibs', gAdvGibs);
872 config.WriteInt('Game', 'Flash', gFlash);
873 config.WriteBool('Game', 'BackGround', gDrawBackGround);
874 config.WriteBool('Game', 'Messages', gShowMessages);
875 config.WriteBool('Game', 'RevertPlayers', gRevertPlayers);
876 config.WriteInt('Game', 'ChatBubble', gChatBubble);
877 config.WriteBool('Game', 'SFSDebug', gSFSDebug);
878 config.WriteBool('Game', 'SFSFastMode', gSFSFastMode);
879 config.WriteBool('Game', 'FastScreenshots', e_FastScreenshots);
880 config.WriteStr('Game', 'DefaultMegawadStart', gDefaultMegawadStart);
881 config.WriteBool('Game', 'BerserkAutoswitching', gBerserkAutoswitch);
882 config.WriteInt('Game', 'Scale', Round(g_dbg_scale * 100));
884 config.WriteStr ('GameplayCustom', 'Map', gcMap);
885 config.WriteStr ('GameplayCustom', 'GameMode', gcGameMode);
886 config.WriteInt ('GameplayCustom', 'TimeLimit', gcTimeLimit);
887 config.WriteInt ('GameplayCustom', 'GoalLimit', gcGoalLimit);
888 config.WriteInt ('GameplayCustom', 'MaxLives', gcMaxLives);
889 config.WriteInt ('GameplayCustom', 'Players', gcPlayers);
890 config.WriteBool('GameplayCustom', 'TeamDamage', gcTeamDamage);
891 config.WriteBool('GameplayCustom', 'AllowExit', gcAllowExit);
892 config.WriteBool('GameplayCustom', 'WeaponStay', gcWeaponStay);
893 config.WriteBool('GameplayCustom', 'Monsters', gcMonsters);
894 config.WriteStr ('GameplayCustom', 'BotsVS', gcBotsVS);
896 config.WriteStr ('GameplayNetwork', 'Map', gnMap);
897 config.WriteStr ('GameplayNetwork', 'GameMode', gnGameMode);
898 config.WriteInt ('GameplayNetwork', 'TimeLimit', gnTimeLimit);
899 config.WriteInt ('GameplayNetwork', 'GoalLimit', gnGoalLimit);
900 config.WriteInt ('GameplayNetwork', 'MaxLives', gnMaxLives);
901 config.WriteInt ('GameplayNetwork', 'Players', gnPlayers);
902 config.WriteBool('GameplayNetwork', 'TeamDamage', gnTeamDamage);
903 config.WriteBool('GameplayNetwork', 'AllowExit', gnAllowExit);
904 config.WriteBool('GameplayNetwork', 'WeaponStay', gnWeaponStay);
905 config.WriteBool('GameplayNetwork', 'Monsters', gnMonsters);
906 config.WriteStr ('GameplayNetwork', 'BotsVS', gnBotsVS);
908 config.WriteStr('MasterServer', 'IP', NetSlistIP);
909 config.WriteInt('MasterServer', 'Port', NetSlistPort);
911 config.WriteStr ('Server', 'Name', NetServerName);
912 config.WriteStr ('Server', 'Password', NetPassword);
913 config.WriteInt ('Server', 'Port', NetPort);
914 config.WriteInt ('Server', 'MaxClients', NetMaxClients);
915 config.WriteBool('Server', 'RCON', NetAllowRCON);
916 config.WriteStr ('Server', 'RCONPassword', NetRCONPassword);
917 config.WriteBool('Server', 'SyncWithMaster', NetUseMaster);
918 config.WriteBool('Server', 'ForwardPorts', NetForwardPorts);
919 config.WriteInt ('Server', 'UpdateInterval', NetUpdateRate);
920 config.WriteInt ('Server', 'ReliableUpdateInterval', NetRelupdRate);
921 config.WriteInt ('Server', 'MasterSyncInterval', NetMasterRate);
923 config.WriteInt ('Client', 'InterpolationSteps', NetInterpLevel);
924 config.WriteBool ('Client', 'ForcePlayerUpdate', NetForcePlayerUpdate);
925 config.WriteBool ('Client', 'PredictSelf', NetPredictSelf);
926 config.WriteStr ('Client', 'LastIP', NetClientIP);
927 config.WriteInt ('Client', 'LastPort', NetClientPort);
929 config.SaveFile(FileName);
930 config.Free();
931 end;
933 procedure g_Options_Write_Language(FileName: String);
934 var
935 config: TConfig;
936 begin
937 e_WriteLog('Writing language config', TMsgType.Notify);
939 config := TConfig.CreateFile(FileName);
940 config.WriteStr('Game', 'Language', gLanguage);
941 config.SaveFile(FileName);
942 config.Free();
943 end;
945 procedure g_Options_Write_Video(FileName: String);
946 var
947 config: TConfig;
948 sW, sH: Integer;
949 begin
950 e_WriteLog('Writing resolution to config', TMsgType.Notify);
952 config := TConfig.CreateFile(FileName);
954 if gWinMaximized and (not gFullscreen) then
955 begin
956 sW := gWinSizeX;
957 sH := gWinSizeY;
958 end
959 else
960 begin
961 sW := gScreenWidth;
962 sH := gScreenHeight;
963 end;
964 e_LogWritefln(' (ws=%dx%d) (ss=%dx%d)', [gWinSizeX, gWinSizeY, gScreenWidth, gScreenHeight]);
966 config.WriteInt('Video', 'ScreenWidth', sW);
967 config.WriteInt('Video', 'ScreenHeight', sH);
968 config.WriteInt('Video', 'WinPosX', gWinRealPosX);
969 config.WriteInt('Video', 'WinPosY', gWinRealPosY);
970 config.WriteBool('Video', 'Fullscreen', gFullscreen);
971 config.WriteBool('Video', 'Maximized', gWinMaximized);
973 config.WriteStr('Player1', 'Name', gPlayer1Settings.Name);
974 config.WriteStr('Player2', 'Name', gPlayer2Settings.Name);
976 config.SaveFile(FileName);
977 config.Free();
978 end;
980 procedure g_Options_Write_Gameplay_Custom(FileName: String);
981 var
982 config: TConfig;
983 begin
984 e_WriteLog('Writing custom gameplay config', TMsgType.Notify);
986 config := TConfig.CreateFile(FileName);
988 config.WriteStr ('GameplayCustom', 'Map', gcMap);
989 config.WriteStr ('GameplayCustom', 'GameMode', gcGameMode);
990 config.WriteInt ('GameplayCustom', 'TimeLimit', gcTimeLimit);
991 config.WriteInt ('GameplayCustom', 'GoalLimit', gcGoalLimit);
992 config.WriteInt ('GameplayCustom', 'MaxLives', gcMaxLives);
993 config.WriteInt ('GameplayCustom', 'Players', gcPlayers);
994 config.WriteBool('GameplayCustom', 'TeamDamage', gcTeamDamage);
995 config.WriteBool('GameplayCustom', 'AllowExit', gcAllowExit);
996 config.WriteBool('GameplayCustom', 'WeaponStay', gcWeaponStay);
997 config.WriteBool('GameplayCustom', 'Monsters', gcMonsters);
998 config.WriteStr ('GameplayCustom', 'BotsVS', gcBotsVS);
1000 config.SaveFile(FileName);
1001 config.Free();
1002 end;
1004 procedure g_Options_Write_Gameplay_Net(FileName: String);
1005 var
1006 config: TConfig;
1007 begin
1008 e_WriteLog('Writing network gameplay config', TMsgType.Notify);
1010 config := TConfig.CreateFile(FileName);
1012 config.WriteStr ('GameplayNetwork', 'Map', gnMap);
1013 config.WriteStr ('GameplayNetwork', 'GameMode', gnGameMode);
1014 config.WriteInt ('GameplayNetwork', 'TimeLimit', gnTimeLimit);
1015 config.WriteInt ('GameplayNetwork', 'GoalLimit', gnGoalLimit);
1016 config.WriteInt ('GameplayNetwork', 'MaxLives', gnMaxLives);
1017 config.WriteInt ('GameplayNetwork', 'Players', gnPlayers);
1018 config.WriteBool('GameplayNetwork', 'TeamDamage', gnTeamDamage);
1019 config.WriteBool('GameplayNetwork', 'AllowExit', gnAllowExit);
1020 config.WriteBool('GameplayNetwork', 'WeaponStay', gnWeaponStay);
1021 config.WriteBool('GameplayNetwork', 'Monsters', gnMonsters);
1022 config.WriteStr ('GameplayNetwork', 'BotsVS', gnBotsVS);
1024 config.SaveFile(FileName);
1025 config.Free();
1026 end;
1028 procedure g_Options_Write_Net_Server(FileName: String);
1029 var
1030 config: TConfig;
1031 begin
1032 e_WriteLog('Writing server config', TMsgType.Notify);
1034 config := TConfig.CreateFile(FileName);
1036 config.WriteStr ('Server', 'Name', NetServerName);
1037 config.WriteStr ('Server', 'Password', NetPassword);
1038 config.WriteInt ('Server', 'Port', NetPort);
1039 config.WriteInt ('Server', 'MaxClients', NetMaxClients);
1040 config.WriteBool('Server', 'SyncWithMaster', NetUseMaster);
1041 config.WriteBool('Server', 'ForwardPorts', NetForwardPorts);
1043 config.SaveFile(FileName);
1044 config.Free();
1045 end;
1047 procedure g_Options_Write_Net_Client(FileName: String);
1048 var
1049 config: TConfig;
1050 begin
1051 e_WriteLog('Writing client config', TMsgType.Notify);
1053 config := TConfig.CreateFile(FileName);
1055 config.WriteStr('Client', 'LastIP', NetClientIP);
1056 config.WriteInt('Client', 'LastPort', NetClientPort);
1058 config.SaveFile(FileName);
1059 config.Free();
1060 end;
1062 initialization
1063 machine := Random(10000)
1064 end.