1 /*
2 	This file is part of Warzone 2100.
3 	Copyright (C) 1999-2004  Eidos Interactive
4 	Copyright (C) 2005-2020  Warzone 2100 Project
5 
6 	Warzone 2100 is free software; you can redistribute it and/or modify
7 	it under the terms of the GNU General Public License as published by
8 	the Free Software Foundation; either version 2 of the License, or
9 	(at your option) any later version.
10 
11 	Warzone 2100 is distributed in the hope that it will be useful,
12 	but WITHOUT ANY WARRANTY; without even the implied warranty of
13 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 	GNU General Public License for more details.
15 
16 	You should have received a copy of the GNU General Public License
17 	along with Warzone 2100; if not, write to the Free Software
18 	Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 /**
21  * @file warzoneconfig.c
22  *
23  * Warzone Global configuration functions.
24  */
25 
26 #include "lib/framework/frame.h"
27 #include "warzoneconfig.h"
28 #include "lib/ivis_opengl/piestate.h"
29 #include "lib/ivis_opengl/piepalette.h"
30 #include "lib/sound/sounddefs.h"
31 #include "advvis.h"
32 #include "component.h"
33 #include "display.h"
34 #include "keybind.h"
35 #include "radar.h"
36 #include "activity.h"
37 
38 /***************************************************************************/
39 
40 struct WARZONE_GLOBALS
41 {
42 	FMV_MODE FMVmode = FMV_FULLSCREEN;
43 	UDWORD width = 1024;
44 	UDWORD height = 768;
45 	UDWORD videoBufferDepth = 32;
46 	int displayScale = 100;
47 	int screen = 0;
48 	int8_t SPcolor = 0;
49 	int MPcolour = -1;
50 	int antialiasing = 0;
51 	WINDOW_MODE Fullscreen = WINDOW_MODE::windowed; // Leave this to windowed, some system will fail and they can't see the system popup dialog!
52 	bool soundEnabled = true;
53 	bool trapCursor = false;
54 	int vsync = 1;
55 	bool pauseOnFocusLoss = false;
56 	bool ColouredCursor = true;
57 	bool MusicEnabled = true;
58 	HRTFMode hrtfMode = HRTFMode::Auto;
59 	int mapZoom = STARTDISTANCE;
60 	int mapZoomRate = MAP_ZOOM_RATE_DEFAULT;
61 	int radarZoom = DEFAULT_RADARZOOM;
62 	int cameraSpeed = CAMERASPEED_DEFAULT;
63 	int scrollEvent = 0; // map/radar zoom
64 	bool radarJump = false;
65 	video_backend gfxBackend = video_backend::opengl; // the actual default value is determined in loadConfig()
66 	JS_BACKEND jsBackend = (JS_BACKEND)0;
67 	bool autoAdjustDisplayScale = true;
68 };
69 
70 static WARZONE_GLOBALS warGlobs;
71 
72 /***************************************************************************/
73 
74 std::string js_backend_names[] =
75 {
76 	"quickjs",
77 	"invalid" // Must be last!
78 };
79 
80 static_assert((size_t)JS_BACKEND::num_backends == (sizeof(js_backend_names) / sizeof(std::string)) - 1, "js_backend_names must match JS_BACKEND enum");
81 
js_backend_from_str(const char * str,JS_BACKEND & output_backend)82 bool js_backend_from_str(const char *str, JS_BACKEND &output_backend)
83 {
84 	for (size_t i = 0; i < (size_t)JS_BACKEND::num_backends; i++)
85 	{
86 		if (strcasecmp(js_backend_names[i].c_str(), str) == 0)
87 		{
88 			output_backend = (JS_BACKEND)i;
89 			return true;
90 		}
91 	}
92 	return false;
93 }
94 
to_string(JS_BACKEND backend)95 std::string to_string(JS_BACKEND backend)
96 {
97 	return js_backend_names[(size_t)backend];
98 }
99 
100 
101 /***************************************************************************/
102 
war_SetDefaultStates()103 void war_SetDefaultStates()
104 {
105 	warGlobs = WARZONE_GLOBALS();
106 }
107 
war_SetSPcolor(int color)108 void war_SetSPcolor(int color)
109 {
110 	if (color >= 1 && color <= 3)		// only 0,4,5,6,7 are allowed for SP games, AI uses the other colors.
111 	{
112 		color = 0;
113 	}
114 	warGlobs.SPcolor = color;
115 	setPlayerColour(0, color);
116 	ActivityManager::instance().changedSetting("SPcolor", std::to_string(color));
117 }
118 
war_GetSPcolor()119 int8_t war_GetSPcolor()
120 {
121 	return warGlobs.SPcolor;
122 }
123 
war_setMPcolour(int colour)124 void war_setMPcolour(int colour)
125 {
126 	warGlobs.MPcolour = colour;
127 	ActivityManager::instance().changedSetting("MPcolour", std::to_string(colour));
128 }
129 
war_getMPcolour()130 int war_getMPcolour()
131 {
132 	return warGlobs.MPcolour;
133 }
134 
war_setWindowMode(WINDOW_MODE b)135 void war_setWindowMode(WINDOW_MODE b)
136 {
137 	warGlobs.Fullscreen = b;
138 }
139 
war_getWindowMode()140 WINDOW_MODE war_getWindowMode()
141 {
142 	return warGlobs.Fullscreen;
143 }
144 
war_setAntialiasing(int antialiasing)145 void war_setAntialiasing(int antialiasing)
146 {
147 	if (antialiasing > 16)
148 	{
149 		debug(LOG_WARNING, "Antialising set to value > 16, which can cause crashes.");
150 	}
151 	warGlobs.antialiasing = antialiasing;
152 	ActivityManager::instance().changedSetting("antialiasing", std::to_string(antialiasing));
153 }
154 
war_getAntialiasing()155 int war_getAntialiasing()
156 {
157 	return warGlobs.antialiasing;
158 }
159 
war_SetTrapCursor(bool b)160 void war_SetTrapCursor(bool b)
161 {
162 	warGlobs.trapCursor = b;
163 	ActivityManager::instance().changedSetting("trapCursor", std::to_string(b));
164 }
165 
war_GetTrapCursor()166 bool war_GetTrapCursor()
167 {
168 	return warGlobs.trapCursor;
169 }
170 
war_SetVsync(int value)171 void war_SetVsync(int value)
172 {
173 	warGlobs.vsync = value;
174 }
175 
war_GetVsync()176 int war_GetVsync()
177 {
178 	return warGlobs.vsync;
179 }
180 
war_GetDisplayScale()181 unsigned int war_GetDisplayScale()
182 {
183 	return warGlobs.displayScale;
184 }
185 
war_SetDisplayScale(unsigned int scale)186 void war_SetDisplayScale(unsigned int scale)
187 {
188 	warGlobs.displayScale = scale;
189 	ActivityManager::instance().changedSetting("displayScale", std::to_string(scale));
190 }
191 
war_SetWidth(UDWORD width)192 void war_SetWidth(UDWORD width)
193 {
194 	warGlobs.width = width;
195 }
196 
war_GetWidth()197 UDWORD war_GetWidth()
198 {
199 	return warGlobs.width;
200 }
201 
war_SetHeight(UDWORD height)202 void war_SetHeight(UDWORD height)
203 {
204 	warGlobs.height = height;
205 }
206 
war_GetHeight()207 UDWORD war_GetHeight()
208 {
209 	return warGlobs.height;
210 }
211 
war_SetVideoBufferDepth(UDWORD videoBufferDepth)212 void war_SetVideoBufferDepth(UDWORD videoBufferDepth)
213 {
214 	warGlobs.videoBufferDepth = videoBufferDepth;
215 }
216 
war_GetVideoBufferDepth()217 UDWORD war_GetVideoBufferDepth()
218 {
219 	return warGlobs.videoBufferDepth;
220 }
221 
war_SetScreen(int screen)222 void war_SetScreen(int screen)
223 {
224 	warGlobs.screen = screen;
225 }
226 
war_GetScreen()227 int war_GetScreen()
228 {
229 	return warGlobs.screen;
230 }
231 
war_SetFMVmode(FMV_MODE mode)232 void war_SetFMVmode(FMV_MODE mode)
233 {
234 	warGlobs.FMVmode = (FMV_MODE)(mode % FMV_MAX);
235 }
236 
war_GetFMVmode()237 FMV_MODE war_GetFMVmode()
238 {
239 	return  warGlobs.FMVmode;
240 }
241 
war_setScanlineMode(SCANLINE_MODE mode)242 void war_setScanlineMode(SCANLINE_MODE mode)
243 {
244 	debug(LOG_VIDEO, "%d", mode);
245 	seq_setScanlineMode(mode);
246 }
247 
war_getScanlineMode()248 SCANLINE_MODE war_getScanlineMode()
249 {
250 	debug(LOG_VIDEO, "%d", seq_getScanlineMode());
251 	return seq_getScanlineMode();
252 }
253 
war_SetPauseOnFocusLoss(bool enabled)254 void war_SetPauseOnFocusLoss(bool enabled)
255 {
256 	warGlobs.pauseOnFocusLoss = enabled;
257 	ActivityManager::instance().changedSetting("pauseOnFocusLoss", std::to_string(enabled));
258 }
259 
war_GetPauseOnFocusLoss()260 bool war_GetPauseOnFocusLoss()
261 {
262 	return warGlobs.pauseOnFocusLoss;
263 }
264 
war_SetColouredCursor(bool enabled)265 void war_SetColouredCursor(bool enabled)
266 {
267 	warGlobs.ColouredCursor = enabled;
268 	ActivityManager::instance().changedSetting("ColouredCursor", std::to_string(enabled));
269 }
270 
war_GetColouredCursor()271 bool war_GetColouredCursor()
272 {
273 	return warGlobs.ColouredCursor;
274 }
275 
war_setSoundEnabled(bool soundEnabled)276 void war_setSoundEnabled(bool soundEnabled)
277 {
278 	warGlobs.soundEnabled = soundEnabled;
279 	ActivityManager::instance().changedSetting("soundEnabled", std::to_string(soundEnabled));
280 }
281 
war_getSoundEnabled()282 bool war_getSoundEnabled()
283 {
284 	return warGlobs.soundEnabled;
285 }
286 
war_GetMusicEnabled()287 bool war_GetMusicEnabled()
288 {
289 	return warGlobs.MusicEnabled;
290 }
291 
war_SetMusicEnabled(bool enabled)292 void war_SetMusicEnabled(bool enabled)
293 {
294 	warGlobs.MusicEnabled = enabled;
295 	ActivityManager::instance().changedSetting("musicEnabled", std::to_string(enabled));
296 }
297 
war_GetHRTFMode()298 HRTFMode war_GetHRTFMode()
299 {
300 	return warGlobs.hrtfMode;
301 }
302 
war_SetHRTFMode(HRTFMode mode)303 void war_SetHRTFMode(HRTFMode mode)
304 {
305 	warGlobs.hrtfMode = mode;
306 	ActivityManager::instance().changedSetting("hrtfMode", std::to_string(static_cast<typename std::underlying_type<HRTFMode>::type>(mode)));
307 }
308 
war_GetMapZoom()309 int war_GetMapZoom()
310 {
311 	return warGlobs.mapZoom;
312 }
313 
war_SetMapZoom(int mapZoom)314 void war_SetMapZoom(int mapZoom)
315 {
316 	if (mapZoom % MAP_ZOOM_CONFIG_STEP == 0 && ! (mapZoom < MINDISTANCE_CONFIG || mapZoom > MAXDISTANCE))
317 	{
318 		warGlobs.mapZoom = mapZoom;
319 		ActivityManager::instance().changedSetting("mapZoom", std::to_string(mapZoom));
320 	}
321 }
322 
war_GetMapZoomRate()323 int war_GetMapZoomRate()
324 {
325 	return warGlobs.mapZoomRate;
326 }
327 
war_SetMapZoomRate(int mapZoomRate)328 void war_SetMapZoomRate(int mapZoomRate)
329 {
330 	if (mapZoomRate % MAP_ZOOM_RATE_STEP == 0 && ! (mapZoomRate < MAP_ZOOM_RATE_MIN || mapZoomRate > MAP_ZOOM_RATE_MAX))
331 	{
332 		warGlobs.mapZoomRate = mapZoomRate;
333 		ActivityManager::instance().changedSetting("mapZoomRate", std::to_string(mapZoomRate));
334 	}
335 }
336 
war_GetRadarZoom()337 int war_GetRadarZoom()
338 {
339 	return warGlobs.radarZoom;
340 }
341 
war_SetRadarZoom(int radarZoom)342 void war_SetRadarZoom(int radarZoom)
343 {
344 	if (radarZoom % RADARZOOM_STEP == 0 && ! (radarZoom < MIN_RADARZOOM || radarZoom > MAX_RADARZOOM))
345 	{
346 		warGlobs.radarZoom = radarZoom;
347 		ActivityManager::instance().changedSetting("radarZoom", std::to_string(radarZoom));
348 	}
349 }
350 
war_GetCameraSpeed()351 int war_GetCameraSpeed()
352 {
353 	return warGlobs.cameraSpeed;
354 }
355 
war_SetCameraSpeed(int cameraSpeed)356 void war_SetCameraSpeed(int cameraSpeed)
357 {
358 	if (cameraSpeed % CAMERASPEED_STEP == 0 && ! (cameraSpeed < CAMERASPEED_MIN || cameraSpeed > CAMERASPEED_MAX))
359 	{
360 		warGlobs.cameraSpeed = cameraSpeed;
361 		ActivityManager::instance().changedSetting("cameraSpeed", std::to_string(cameraSpeed));
362 	}
363 }
364 
war_GetScrollEvent()365 int war_GetScrollEvent()
366 {
367 	return warGlobs.scrollEvent;
368 }
369 
war_SetScrollEvent(int scrollEvent)370 void war_SetScrollEvent(int scrollEvent)
371 {
372 	warGlobs.scrollEvent = scrollEvent;
373 }
374 
war_GetRadarJump()375 bool war_GetRadarJump()
376 {
377 	return warGlobs.radarJump;
378 }
379 
war_SetRadarJump(bool radarJump)380 void war_SetRadarJump(bool radarJump)
381 {
382 	warGlobs.radarJump = radarJump;
383 	ActivityManager::instance().changedSetting("radarJump", std::to_string(radarJump));
384 }
385 
war_getGfxBackend()386 video_backend war_getGfxBackend()
387 {
388 	return warGlobs.gfxBackend;
389 }
390 
war_setGfxBackend(video_backend backend)391 void war_setGfxBackend(video_backend backend)
392 {
393 	warGlobs.gfxBackend = backend;
394 }
395 
war_getJSBackend()396 JS_BACKEND war_getJSBackend()
397 {
398 	return warGlobs.jsBackend;
399 }
400 
war_setJSBackend(JS_BACKEND backend)401 void war_setJSBackend(JS_BACKEND backend)
402 {
403 	warGlobs.jsBackend = backend;
404 }
405 
war_getAutoAdjustDisplayScale()406 bool war_getAutoAdjustDisplayScale()
407 {
408 	return warGlobs.autoAdjustDisplayScale;
409 }
410 
war_setAutoAdjustDisplayScale(bool autoAdjustDisplayScale)411 void war_setAutoAdjustDisplayScale(bool autoAdjustDisplayScale)
412 {
413 	warGlobs.autoAdjustDisplayScale = autoAdjustDisplayScale;
414 }
415