DEADSOFTWARE

server: build headless with completely disabled render, system driver and menus
[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, version 3 of the License ONLY.
6 *
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.
11 *
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/>.
14 *)
15 {$INCLUDE ../shared/a_modes.inc}
16 unit g_options;
18 interface
20 uses
21 g_language, g_weapons, utils;
23 function GenPlayerName (n: Integer): String;
25 procedure g_Options_SetDefault;
26 procedure g_Options_SetDefaultVideo;
27 procedure g_Options_ApplyGameSettings;
29 const DF_Default_Megawad_Start = 'megawads/DOOM2D.WAD:\MAP01';
31 var
32 gBPP: Integer;
33 gFreq: Byte;
34 gFullscreen: Boolean;
35 gWinSizeX, gWinSizeY: Integer;
36 gWinMaximized: Boolean;
37 gVSync: Boolean;
38 glLegacyNPOT: Boolean;
39 glRenderToFBO: Boolean = True;
40 gTextureFilter: Boolean;
41 gLerpActors: Boolean = True;
42 gFrameTime: Integer = 5;
43 gMaxFPS: Integer = 200;
44 gNoSound: Boolean;
45 gSoundLevel: Integer;
46 gMusicLevel: Integer;
47 gMaxSimSounds: Integer;
48 gMuteWhenInactive: Boolean;
49 gAdvCorpses: Boolean;
50 gAdvBlood: Boolean;
51 gAdvGibs: Boolean;
52 gGibsCount: Integer;
53 gBloodCount: Integer;
54 gFlash: Integer;
55 gDrawBackGround: Boolean;
56 gShowMessages: Boolean;
57 gRevertPlayers: Boolean;
58 gLanguage: String;
59 gAskLanguage: Boolean;
60 gSaveStats: Boolean = False;
61 gScreenshotStats: Boolean = False;
62 gsSDLSampleRate: Integer;
63 gsSDLBufferSize: Integer;
64 gDefaultMegawadStart: AnsiString;
65 glNPOTOverride: Boolean = false;
67 (* Latched game settings *)
68 gsMap: String;
69 gsGameMode: String;
70 gsTimeLimit: Word;
71 gsScoreLimit: Word;
72 gsMaxLives: Byte;
73 gsPlayers: Byte;
74 gsGameFlags: LongWord;
75 gsSpawnInvul: Integer = 0;
76 gsItemRespawnTime: Word = 60;
77 gsWarmupTime: Word = 30;
79 {$IFDEF HEADLESS}
80 e_NoGraphics: Boolean = True;
81 {$ELSE}
82 e_NoGraphics: Boolean = False;
83 {$ENDIF}
84 e_FastScreenshots: Boolean = true; // it's REALLY SLOW with `false`
85 g_dbg_scale: Single = 1.0;
86 r_pixel_scale: Single = 1.0;
88 gwin_has_stencil: Boolean = false;
89 gwin_k8_enable_light_experiments: Boolean = false;
90 g_dbg_aimline_on: Boolean = false;
91 g_dbg_input: Boolean = False;
93 {--- Read-only dirs ---}
94 GameWAD: string;
95 DataDirs: SSArray;
96 ModelDirs: SSArray;
97 MegawadDirs: SSArray;
98 MapDirs: SSArray;
99 WadDirs: SSArray;
100 AllMapDirs: SSArray; // Maps + Megawads
102 {--- Read-Write dirs ---}
103 LogFileName: string;
104 LogDirs: SSArray;
105 SaveDirs: SSArray;
106 CacheDirs: SSArray;
107 ConfigDirs: SSArray;
108 ScreenshotDirs: SSArray;
109 StatsDirs: SSArray;
110 MapDownloadDirs: SSArray;
111 WadDownloadDirs: SSArray;
113 GameWADName: string = 'GAME';
115 implementation
117 uses
118 {$IFDEF USE_SDL2}
119 SDL2,
120 {$ENDIF}
121 e_log, e_input, g_console, g_sound, g_gfx, g_player, Math,
122 g_map, g_net, g_netmaster, SysUtils, CONFIG, g_game,
123 g_items, wadreader, envvars;
125 var
126 machine: Integer;
128 function GenPlayerName (n: Integer): String;
129 begin
130 ASSERT(n >= 1);
131 Result := GetUserName;
132 if Result = '' then
133 Result := 'Player' + IntToStr(machine MOD 10000);
134 if n = 1 then
135 Result := Copy(Result, 1, 12) + ' '
136 else
137 Result := Copy(Result, 1, 10) + ' ' + IntToStr(n)
138 end;
140 {$IFDEF USE_SDL2}
141 procedure g_Options_SetDefaultVideo;
142 var display: TSDL_DisplayMode;
143 {$IFNDEF ANDROID}
144 var target, closest: TSDL_DisplayMode; percentage: Integer;
145 {$ENDIF}
146 begin
147 (* Display 0 = Primary display *)
148 gScreenWidth := 640;
149 gScreenHeight := 480;
150 gWinSizeX := 640;
151 gWinSizeY := 480;
152 //gBPP := SDL_BITSPERPIXEL(display.format);
153 gBPP := 32;
154 {$IFDEF ANDROID}
155 gFullScreen := True; (* rotation not allowed? *)
156 {$ELSE}
157 gFullScreen := False;
158 {$ENDIF}
159 if SDL_GetDesktopDisplayMode(0, @display) = 0 then
160 begin
161 {$IFDEF ANDROID}
162 gWinSizeX := display.w;
163 gWinSizeY := display.h;
164 {$ELSE}
165 (* Window must be smaller than display *)
166 closest.w := display.w;
167 closest.h := display.h;
168 percentage := 75;
169 while (display.w - closest.w < 48) or (display.h - closest.h < 48) do
170 begin
171 if percentage < 25 then
172 begin
173 closest.w := display.w * 75 div 100;
174 closest.h := display.h * 75 div 100;
175 break;
176 end;
177 target.w := display.w * percentage div 100;
178 target.h := display.h * percentage div 100;
179 target.format := 0; (* didn't care *)
180 target.refresh_rate := 0; (* didn't care *)
181 target.driverdata := nil; (* init *)
182 SDL_GetClosestDisplayMode(0, @target, @closest);
183 Dec(percentage);
184 end;
185 gWinSizeX := closest.w;
186 gWinSizeY := closest.h;
187 //gBPP := SDL_BITSPERPIXEL(closest.format); (* Resolution list didn't work for some reason *)
188 {$ENDIF}
189 end
190 else
191 begin
192 e_LogWritefln('SDL: Failed to get desktop display mode: %s', [SDL_GetError])
193 end;
194 (* Must be positioned on primary display *)
195 gWinMaximized := False;
196 gVSync := True;
197 gTextureFilter := True;
198 glLegacyNPOT := False;
199 gRC_Width := gWinSizeX;
200 gRC_Height := gWinSizeY;
201 gRC_FullScreen := gFullScreen;
202 gRC_Maximized := gWinMaximized;
203 e_LogWriteLn('g_Options_SetDefaultVideo: w = ' + IntToStr(gWinSizeX) + ' h = ' + IntToStr(gWinSizeY));
204 g_Console_ResetBinds;
205 end;
206 {$ELSE}
207 procedure g_Options_SetDefaultVideo;
208 begin
209 gWinSizeX := 640;
210 gWinSizeY := 480;
211 gBPP := 32;
212 gFullScreen := False;
213 gWinMaximized := False;
214 gVSync := True;
215 gTextureFilter := True;
216 glLegacyNPOT := False;
217 gScreenWidth := gWinSizeX;
218 gScreenHeight := gWinSizeY;
219 gRC_Width := gWinSizeX;
220 gRC_Height := gWinSizeY;
221 gRC_FullScreen := gFullScreen;
222 gRC_Maximized := gWinMaximized;
223 e_LogWriteLn('g_Options_SetDefaultVideo: w = ' + IntToStr(gWinSizeX) + ' h = ' + IntToStr(gWinSizeY));
224 g_Console_ResetBinds;
225 end;
226 {$ENDIF}
228 procedure g_Options_SetDefault();
229 var
230 i: Integer;
231 begin
232 (* section Sound *)
233 gNoSound := False;
234 gSoundLevel := 75;
235 gMusicLevel := 65;
236 gMaxSimSounds := 8;
237 gMuteWhenInactive := False;
238 gAnnouncer := ANNOUNCE_MEPLUS;
239 gSoundEffectsDF := True;
240 gUseChatSounds := True;
241 gsSDLSampleRate := 44100;
242 gsSDLBufferSize := 2048;
244 g_Sound_SetupAllVolumes(gSoundLevel, gMusicLevel);
246 with gPlayer1Settings do
247 begin
248 Name := GenPlayerName(1);
249 Model := STD_PLAYER_MODEL;
250 Color.R := PLAYER1_DEF_COLOR.R;
251 Color.G := PLAYER1_DEF_COLOR.G;
252 Color.B := PLAYER1_DEF_COLOR.B;
253 Team := TEAM_RED;
254 end;
256 with gPlayer2Settings do
257 begin
258 Name := GenPlayerName(2);
259 Model := STD_PLAYER_MODEL;
260 Color.R := PLAYER2_DEF_COLOR.R;
261 Color.G := PLAYER2_DEF_COLOR.G;
262 Color.B := PLAYER2_DEF_COLOR.B;
263 Team := TEAM_BLUE;
264 end;
266 (* section Joysticks *)
267 for i := 0 to e_MaxJoys - 1 do
268 begin
269 e_JoystickDeadzones[i] := 8192
270 end;
272 (* section Game *)
273 g_GFX_SetMax(2000);
274 g_Shells_SetMax(300);
275 g_Gibs_SetMax(150);
276 g_Corpses_SetMax(20);
277 gGibsCount := 32;
278 gBloodCount := 4;
279 gAdvBlood := True;
280 gAdvCorpses := True;
281 gAdvGibs := True;
282 gFlash := 1;
283 gDrawBackGround := True;
284 gShowMessages := True;
285 gRevertPlayers := False;
286 gChatBubble := 4;
287 wadoptDebug := False;
288 wadoptFast := False;
289 e_FastScreenshots := True;
290 gDefaultMegawadStart := DF_Default_Megawad_Start;
291 g_dbg_scale := 1.0;
292 gSaveStats := False;
294 gAskLanguage := True;
295 gLanguage := LANGUAGE_ENGLISH;
297 gsMap := '';
298 gsGameMode := _lc[I_MENU_GAME_TYPE_DM];
299 gsTimeLimit := 0;
300 gsScoreLimit := 0;
301 gsMaxLives := 0;
302 gsPlayers := 1;
303 gsSpawnInvul := 0;
304 gsItemRespawnTime := 60;
305 gsGameFlags := GAME_OPTION_ALLOWEXIT or GAME_OPTION_DMKEYS or
306 GAME_OPTION_BOTVSPLAYER or GAME_OPTION_BOTVSMONSTER or
307 GAME_OPTION_TEAMHITTRACE or GAME_OPTION_TEAMHITPROJECTILE or
308 GAME_OPTION_ALLOWDROPFLAG;
309 gsPlayers := 1;
311 if not gGameOn then
312 g_Options_ApplyGameSettings;
314 (* section MasterServer *)
315 NetMasterList := 'mpms.doom2d.org:25665, deadsoftware.ru:25665, terminalcorner.ru:25665';
316 g_Net_Slist_Set(NetMasterList);
318 (* section Server *)
319 NetServerName := 'Unnamed Server';
320 NetPassword := '';
321 NetPort := 25666;
322 NetMaxClients := 16;
323 NetAllowRCON := False;
324 NetRCONPassword := 'default';
325 NetUseMaster := True;
326 NetUpdateRate := 0;
327 NetRelupdRate := 18;
328 NetMasterRate := 60000;
329 NetForwardPorts := False;
331 (* section Client *)
332 NetInterpLevel := 2;
333 NetForcePlayerUpdate := False;
334 NetPredictSelf := True;
335 NetClientIP := '127.0.0.1';
336 NetClientPort := NetPort;
337 end;
339 procedure g_Options_ApplyGameSettings;
340 begin
341 with gGameSettings do
342 begin
343 GameMode := g_Game_TextToMode(gsGameMode);
344 if GameMode = GM_NONE then
345 GameMode := GM_DM;
346 if GameMode = GM_SINGLE then
347 GameMode := GM_COOP;
348 TimeLimit := gsTimeLimit;
349 ScoreLimit := gsScoreLimit;
350 MaxLives := gsMaxLives;
351 SpawnInvul := gsSpawnInvul;
352 ItemRespawnTime := gsItemRespawnTime;
353 WarmupTime := gsWarmupTime;
354 Options := gsGameFlags;
355 end;
356 end;
358 initialization
359 Randomize;
360 machine := Random(10000);
362 (* Video *)
363 conRegVar('r_width', @gRC_Width, '', '');
364 conRegVar('r_height', @gRC_Height, '', '');
365 conRegVar('r_fullscreen', @gRC_FullScreen, '', '');
366 conRegVar('r_maximized', @gRC_Maximized, '', '');
367 conRegVar('r_bpp', @gBPP, '', '');
368 conRegVar('r_vsync', @gVSync, '', '');
369 conRegVar('r_texfilter', @gTextureFilter, '', '');
370 conRegVar('r_npot', @glNPOTOverride, '', '');
371 conRegVar('r_interp', @gLerpActors, '', 'interpolate actors');
372 conRegVar('r_scale', @g_dbg_scale, 0.01, 100.0, 'render scale', '', false);
373 conRegVar('r_resolution_scale', @r_pixel_scale, 0.01, 100.0, 'upscale factor', '', false);
375 (* Sound *)
376 conRegVar('s_nosound', @gNoSound, '', '');
377 conRegVar('s_soundvolume', @gSoundLevel, '', '');
378 conRegVar('s_musicvolume', @gMusicLevel, '', '');
379 conRegVar('s_maxsim', @gMaxSimSounds, '', ''); // e_sound_fmod/sdl?
380 conRegVar('s_muteinactive', @gMuteWhenInactive, '', '');
381 conRegVar('s_announcer', @gAnnouncer, '', '');
382 conRegVar('s_sfx', @gSoundEffectsDF, '', '');
383 conRegVar('s_chatsounds', @gUseChatSounds, '', '');
384 {$IFDEF USE_SDLMIXER}
385 conRegVar('sdl_mixer_samplerate', @gsSDLSampleRate, '', '');
386 conRegVar('sdl_mixer_buffersize', @gsSDLBufferSize, '', '');
387 {$ENDIF}
389 (* Game *)
390 conRegVar('g_gibs_count', @gGibsCount, '', '');
391 conRegVar('g_blood_count', @gBloodCount, '', '');
392 conRegVar('g_adv_blood', @gAdvBlood, '', '');
393 conRegVar('g_adv_corpses', @gAdvCorpses, '', '');
394 conRegVar('g_adv_gibs', @gAdvGibs, '', '');
395 conRegVar('r_flash', @gFlash, '', '');
396 conRegVar('r_background', @gDrawBackGround, '', '');
397 conRegVar('g_show_messages', @gShowMessages, '', '');
398 conRegVar('r_revert_players', @gRevertPlayers, '', '');
399 conRegVar('r_chat_bubble', @gChatBubble, '', '');
400 conRegVar('sfs_debug', @wadoptDebug, '', '');
401 conRegVar('sfs_fastmode', @wadoptFast, '', '');
402 conRegVar('g_fast_screenshots', @e_FastScreenshots, '', '');
403 conRegVar('g_default_megawad', @gDefaultMegawadStart, '', '');
404 conRegVar('g_save_stats', @gSaveStats, '', '');
405 conRegVar('g_screenshot_stats', @gScreenshotStats, '', '');
406 conRegVar('g_lastmap', @gsMap, '', '');
408 conRegVar('d_input', @g_dbg_input, '', '')
409 end.