1 /*
2 	C-Dogs SDL
3 	A port of the legendary (and fun) action/arcade cdogs.
4 
5 	Copyright (c) 2013-2014, 2021 Cong Xu
6 	All rights reserved.
7 
8 	Redistribution and use in source and binary forms, with or without
9 	modification, are permitted provided that the following conditions are met:
10 
11 	Redistributions of source code must retain the above copyright notice, this
12 	list of conditions and the following disclaimer.
13 	Redistributions in binary form must reproduce the above copyright notice,
14 	this list of conditions and the following disclaimer in the documentation
15 	and/or other materials provided with the distribution.
16 
17 	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 	ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 	LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 	CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 	POSSIBILITY OF SUCH DAMAGE.
28 */
29 #pragma once
30 
31 #include <stdbool.h>
32 #include <stdio.h>
33 
34 #include "c_array.h"
35 
36 #define CONFIG_FILE "options.cnf"
37 
38 typedef enum
39 {
40 	DIFFICULTY_VERYEASY = 1,
41 	DIFFICULTY_EASY,
42 	DIFFICULTY_NORMAL,
43 	DIFFICULTY_HARD,
44 	DIFFICULTY_VERYHARD
45 } difficulty_e;
46 
47 const char *DifficultyStr(int d);
48 int StrDifficulty(const char *str);
49 
50 typedef enum
51 {
52 	FIREMOVE_STOP = 0,
53 	FIREMOVE_NORMAL,
54 	FIREMOVE_STRAFE
55 } FireMoveStyle;
56 const char *FireMoveStyleStr(int s);
57 int StrFireMoveStyle(const char *s);
58 
59 typedef enum
60 {
61 	SWITCHMOVE_SLIDE = 0,
62 	SWITCHMOVE_STRAFE,
63 	SWITCHMOVE_NONE
64 } SwitchMoveStyle;
65 const char *SwitchMoveStyleStr(int s);
66 int StrSwitchMoveStyle(const char *s);
67 
68 typedef enum
69 {
70 	SCALE_MODE_NN,
71 	SCALE_MODE_BILINEAR
72 } ScaleMode;
73 const char *ScaleModeStr(int q);
74 int StrScaleMode(const char *str);
75 
76 typedef enum
77 {
78 	GORE_NONE,
79 	GORE_LOW,
80 	GORE_MEDIUM,
81 	GORE_HIGH
82 } GoreAmount;
83 const char *GoreAmountStr(int g);
84 int StrGoreAmount(const char *s);
85 
86 typedef enum
87 {
88 	LASER_SIGHT_NONE,
89 	LASER_SIGHT_PLAYERS,
90 	LASER_SIGHT_ALL
91 } LaserSight;
92 const char *LaserSightStr(int l);
93 int StrLaserSight(const char *s);
94 
95 typedef enum
96 {
97 	SPLITSCREEN_NORMAL,
98 	SPLITSCREEN_ALWAYS,
99 	SPLITSCREEN_NEVER
100 } SplitscreenStyle;
101 
102 const char *SplitscreenStyleStr(int s);
103 int StrSplitscreenStyle(const char *str);
104 
105 typedef enum
106 {
107 	AICHATTER_NONE,
108 	AICHATTER_SELDOM,
109 	AICHATTER_OFTEN,
110 	AICHATTER_ALWAYS
111 } AIChatterFrequency;
112 const char *AIChatterStr(int c);
113 int StrAIChatter(const char *str);
114 
115 typedef enum
116 {
117 	QUICKPLAY_QUANTITY_ANY,
118 	QUICKPLAY_QUANTITY_SMALL,
119 	QUICKPLAY_QUANTITY_MEDIUM,
120 	QUICKPLAY_QUANTITY_LARGE
121 } QuickPlayQuantity;
122 const char *QuickPlayQuantityStr(int s);
123 int StrQuickPlayQuantity(const char *str);
124 
125 typedef enum
126 {
127 	CONFIG_TYPE_STRING,
128 	CONFIG_TYPE_INT,
129 	CONFIG_TYPE_FLOAT,
130 	CONFIG_TYPE_BOOL,
131 	CONFIG_TYPE_ENUM,
132 	CONFIG_TYPE_GROUP
133 } ConfigType;
134 
135 // Generic config entry
136 typedef struct
137 {
138 	char *Name;
139 	ConfigType Type;
140 	union {
141 #define VALUES(_name, _type)                                                  \
142 	struct                                                                    \
143 	{                                                                         \
144 		_type Value;                                                          \
145 		_type Last;                                                           \
146 		_type Default;                                                        \
147 		_type Min;                                                            \
148 		_type Max;                                                            \
149 		_type Increment;                                                      \
150 	} _name
151 		VALUES(String, char *);
152 		VALUES(Float, double);
153 		VALUES(Bool, bool);
154 #undef VALUES
155 #define FORMATTED_VALUES(_name, _type, _toStrType)                            \
156 	struct                                                                    \
157 	{                                                                         \
158 		_type Value;                                                          \
159 		_type Last;                                                           \
160 		_type Default;                                                        \
161 		_type Min;                                                            \
162 		_type Max;                                                            \
163 		_type Increment;                                                      \
164 		_type (*StrTo##_name)(const char *);                                  \
165 		_toStrType *(*_name##ToStr)(_type);                                   \
166 	} _name
167 		FORMATTED_VALUES(Int, int, char);
168 		FORMATTED_VALUES(Enum, int, const char);
169 #undef FORMATTED_VALUES
170 		CArray Group; // of Config
171 	} u;
172 } Config;
173 
174 Config ConfigNewString(const char *name, const char *defaultValue);
175 Config ConfigNewInt(
176 	const char *name, const int defaultValue, const int minValue,
177 	const int maxValue, const int increment, int (*strToInt)(const char *),
178 	char *(*intToStr)(int));
179 Config ConfigNewFloat(
180 	const char *name, const double defaultValue, const double minValue,
181 	const double maxValue, const double increment);
182 Config ConfigNewBool(const char *name, const bool defaultValue);
183 Config ConfigNewEnum(
184 	const char *name, const int defaultValue, const int minValue,
185 	const int maxValue, int (*strToEnum)(const char *),
186 	const char *(*enumToStr)(int));
187 Config ConfigNewGroup(const char *name);
188 void ConfigDestroy(Config *c);
189 bool ConfigChangedAndApply(Config *c);
190 
191 void ConfigGroupAdd(Config *group, Config child);
192 
193 extern Config gConfig;
194 
195 Config ConfigDefault(void);
196 
197 // Find all config entries that begin with a prefix
198 // Returns array of ConfigEntry *
199 CArray ConfigFind(const Config *c, const char *prefix);
200 
201 // Get a child config
202 // Note: child configs can be searched using dot-separated notation
203 // e.g. Foo.Bar.Baz
204 Config *ConfigGet(Config *c, const char *name);
205 
206 // Check if this config, or any of its children, have changed
207 bool ConfigChanged(const Config *c);
208 // Reset the changed value to the last value
209 void ConfigResetChanged(Config *c);
210 // Set the last value to the current value
211 void ConfigSetChanged(Config *c);
212 // Reset the config values to default
213 void ConfigResetDefault(Config *c);
214 
215 // Get the value of a config
216 // The type must be correct
217 // Note: child configs can be searched using dot-separated notation
218 // e.g. Foo.Bar.Baz
219 const char *ConfigGetString(Config *c, const char *name);
220 int ConfigGetInt(Config *c, const char *name);
221 double ConfigGetFloat(Config *c, const char *name);
222 bool ConfigGetBool(Config *c, const char *name);
223 int ConfigGetEnum(Config *c, const char *name);
224 CArray *ConfigGetGroup(Config *c, const char *name);
225 
226 // Set config value
227 // Min/max range is also checked and enforced
228 void ConfigSetInt(Config *c, const char *name, const int value);
229 void ConfigSetFloat(Config *c, const char *name, const double value);
230 // Try to set config value from a string; return success
231 bool ConfigTrySetFromString(Config *c, const char *name, const char *value);
232 
233 bool ConfigApply(Config *config, bool *resetBg);
234 int ConfigGetVersion(FILE *f);
235