2 * Copyright (C) 2003 Robert Kooima
4 * NEVERBALL is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
16 #include <SDL_mixer.h>
27 /*---------------------------------------------------------------------------*/
29 /* Define the mkdir symbol. */
37 /*---------------------------------------------------------------------------*/
39 static int option_d[CONFIG_OPTION_D_COUNT];
40 static char *option_s[CONFIG_OPTION_S_COUNT];
44 /*---------------------------------------------------------------------------*/
46 static void config_key(const char *s, int i, int d)
52 for (c = 0; c < SDLK_LAST; c++)
53 if (strcmp(s, SDL_GetKeyName(c)) == 0)
60 /*---------------------------------------------------------------------------*/
62 void config_init(void)
64 memset(option_d, 0, sizeof (option_d));
65 memset(option_s, 0, sizeof (option_s));
67 config_set_d(CONFIG_FULLSCREEN, DEFAULT_FULLSCREEN);
68 config_set_d(CONFIG_WIDTH, DEFAULT_WIDTH);
69 config_set_d(CONFIG_HEIGHT, DEFAULT_HEIGHT);
70 config_set_d(CONFIG_STEREO, DEFAULT_STEREO);
71 config_set_d(CONFIG_CAMERA, DEFAULT_CAMERA);
72 config_set_d(CONFIG_TEXTURES, DEFAULT_TEXTURES);
73 config_set_d(CONFIG_GEOMETRY, DEFAULT_GEOMETRY);
74 config_set_d(CONFIG_REFLECTION, DEFAULT_REFLECTION);
75 config_set_d(CONFIG_MULTISAMPLE, DEFAULT_MULTISAMPLE);
76 config_set_d(CONFIG_BACKGROUND, DEFAULT_BACKGROUND);
77 config_set_d(CONFIG_SHADOW, DEFAULT_SHADOW);
78 config_set_d(CONFIG_AUDIO_RATE, DEFAULT_AUDIO_RATE);
79 config_set_d(CONFIG_AUDIO_BUFF, DEFAULT_AUDIO_BUFF);
80 config_set_d(CONFIG_MOUSE_SENSE, DEFAULT_MOUSE_SENSE);
81 config_set_d(CONFIG_MOUSE_INVERT, DEFAULT_MOUSE_INVERT);
82 config_set_d(CONFIG_NICE, DEFAULT_NICE);
83 config_set_d(CONFIG_FPS, DEFAULT_FPS);
84 config_set_d(CONFIG_SOUND_VOLUME, DEFAULT_SOUND_VOLUME);
85 config_set_d(CONFIG_MUSIC_VOLUME, DEFAULT_MUSIC_VOLUME);
86 config_set_d(CONFIG_JOYSTICK, DEFAULT_JOYSTICK);
87 config_set_d(CONFIG_JOYSTICK_DEVICE, DEFAULT_JOYSTICK_DEVICE);
88 config_set_d(CONFIG_JOYSTICK_AXIS_X, DEFAULT_JOYSTICK_AXIS_X);
89 config_set_d(CONFIG_JOYSTICK_AXIS_Y, DEFAULT_JOYSTICK_AXIS_Y);
90 config_set_d(CONFIG_JOYSTICK_BUTTON_A, DEFAULT_JOYSTICK_BUTTON_A);
91 config_set_d(CONFIG_JOYSTICK_BUTTON_B, DEFAULT_JOYSTICK_BUTTON_B);
92 config_set_d(CONFIG_JOYSTICK_BUTTON_L, DEFAULT_JOYSTICK_BUTTON_L);
93 config_set_d(CONFIG_JOYSTICK_BUTTON_R, DEFAULT_JOYSTICK_BUTTON_R);
94 config_set_d(CONFIG_JOYSTICK_BUTTON_EXIT, DEFAULT_JOYSTICK_BUTTON_EXIT);
95 config_set_d(CONFIG_JOYSTICK_CAMERA_1, DEFAULT_JOYSTICK_CAMERA_1);
96 config_set_d(CONFIG_JOYSTICK_CAMERA_2, DEFAULT_JOYSTICK_CAMERA_2);
97 config_set_d(CONFIG_JOYSTICK_CAMERA_3, DEFAULT_JOYSTICK_CAMERA_3);
98 config_set_d(CONFIG_KEY_CAMERA_1, DEFAULT_KEY_CAMERA_1);
99 config_set_d(CONFIG_KEY_CAMERA_2, DEFAULT_KEY_CAMERA_2);
100 config_set_d(CONFIG_KEY_CAMERA_3, DEFAULT_KEY_CAMERA_3);
101 config_set_d(CONFIG_KEY_CAMERA_R, DEFAULT_KEY_CAMERA_R);
102 config_set_d(CONFIG_KEY_CAMERA_L, DEFAULT_KEY_CAMERA_L);
103 config_set_d(CONFIG_VIEW_FOV, DEFAULT_VIEW_FOV);
104 config_set_d(CONFIG_VIEW_DP, DEFAULT_VIEW_DP);
105 config_set_d(CONFIG_VIEW_DC, DEFAULT_VIEW_DC);
106 config_set_d(CONFIG_VIEW_DZ, DEFAULT_VIEW_DZ);
107 config_set_d(CONFIG_ROTATE_FAST, DEFAULT_ROTATE_FAST);
108 config_set_d(CONFIG_ROTATE_SLOW, DEFAULT_ROTATE_SLOW);
109 config_set_d(CONFIG_MODE, DEFAULT_MODE);
110 config_set_d(CONFIG_CHEAT, DEFAULT_CHEAT);
111 config_set_s(CONFIG_PLAYER, DEFAULT_PLAYER);
112 config_set_s(CONFIG_BALL, DEFAULT_BALL);
113 config_set_s(CONFIG_BALL_BONUS, DEFAULT_BALL_BONUS);
114 config_set_s(CONFIG_LANG, DEFAULT_LANG);
117 void config_load(void)
121 if ((fp = fopen(config_user(USER_CONFIG_FILE), "r")))
127 while (fgets(buf, MAXSTR, fp))
128 if (sscanf(buf, "%s %s", key, val) == 2)
130 if (strcmp(key, "fullscreen") == 0)
131 config_set_d(CONFIG_FULLSCREEN, atoi(val));
132 else if (strcmp(key, "width") == 0)
133 config_set_d(CONFIG_WIDTH, atoi(val));
134 else if (strcmp(key, "height") == 0)
135 config_set_d(CONFIG_HEIGHT, atoi(val));
136 else if (strcmp(key, "stereo") == 0)
137 config_set_d(CONFIG_STEREO, atoi(val));
138 else if (strcmp(key, "camera") == 0)
139 config_set_d(CONFIG_CAMERA, atoi(val));
140 else if (strcmp(key, "textures") == 0)
141 config_set_d(CONFIG_TEXTURES, atoi(val));
142 else if (strcmp(key, "geometry") == 0)
143 config_set_d(CONFIG_GEOMETRY, atoi(val));
144 else if (strcmp(key, "reflection") == 0)
145 config_set_d(CONFIG_REFLECTION, atoi(val));
146 else if (strcmp(key, "multisample") == 0)
147 config_set_d(CONFIG_MULTISAMPLE, atoi(val));
148 else if (strcmp(key, "background") == 0)
149 config_set_d(CONFIG_BACKGROUND, atoi(val));
150 else if (strcmp(key, "shadow") == 0)
151 config_set_d(CONFIG_SHADOW, atoi(val));
152 else if (strcmp(key, "audio_rate") == 0)
153 config_set_d(CONFIG_AUDIO_RATE, atoi(val));
154 else if (strcmp(key, "audio_buff") == 0)
155 config_set_d(CONFIG_AUDIO_BUFF, atoi(val));
156 else if (strcmp(key, "mouse_sense") == 0)
157 config_set_d(CONFIG_MOUSE_SENSE, atoi(val));
158 else if (strcmp(key, "mouse_invert") == 0)
159 config_set_d(CONFIG_MOUSE_INVERT, atoi(val));
160 else if (strcmp(key, "nice") == 0)
161 config_set_d(CONFIG_NICE, atoi(val));
162 else if (strcmp(key, "fps") == 0)
163 config_set_d(CONFIG_FPS, atoi(val));
164 else if (strcmp(key, "sound_volume") == 0)
165 config_set_d(CONFIG_SOUND_VOLUME, atoi(val));
166 else if (strcmp(key, "music_volume") == 0)
167 config_set_d(CONFIG_MUSIC_VOLUME, atoi(val));
168 else if (strcmp(key, "joystick") == 0)
169 config_set_d(CONFIG_JOYSTICK, atoi(val));
170 else if (strcmp(key, "joystick_device") == 0)
171 config_set_d(CONFIG_JOYSTICK_DEVICE, atoi(val));
172 else if (strcmp(key, "joystick_axis_x") == 0)
173 config_set_d(CONFIG_JOYSTICK_AXIS_X, atoi(val));
174 else if (strcmp(key, "joystick_axis_y") == 0)
175 config_set_d(CONFIG_JOYSTICK_AXIS_Y, atoi(val));
176 else if (strcmp(key, "joystick_button_a") == 0)
177 config_set_d(CONFIG_JOYSTICK_BUTTON_A, atoi(val));
178 else if (strcmp(key, "joystick_button_b") == 0)
179 config_set_d(CONFIG_JOYSTICK_BUTTON_B, atoi(val));
180 else if (strcmp(key, "joystick_button_r") == 0)
181 config_set_d(CONFIG_JOYSTICK_BUTTON_R, atoi(val));
182 else if (strcmp(key, "joystick_button_l") == 0)
183 config_set_d(CONFIG_JOYSTICK_BUTTON_L, atoi(val));
184 else if (strcmp(key, "joystick_button_exit") == 0)
185 config_set_d(CONFIG_JOYSTICK_BUTTON_EXIT, atoi(val));
186 else if (strcmp(key, "joystick_camera_1") == 0)
187 config_set_d(CONFIG_JOYSTICK_CAMERA_1, atoi(val));
188 else if (strcmp(key, "joystick_camera_2") == 0)
189 config_set_d(CONFIG_JOYSTICK_CAMERA_2, atoi(val));
190 else if (strcmp(key, "joystick_camera_3") == 0)
191 config_set_d(CONFIG_JOYSTICK_CAMERA_3, atoi(val));
192 else if (strcmp(key, "view_fov") == 0)
193 config_set_d(CONFIG_VIEW_FOV, atoi(val));
194 else if (strcmp(key, "view_dp") == 0)
195 config_set_d(CONFIG_VIEW_DP, atoi(val));
196 else if (strcmp(key, "view_dc") == 0)
197 config_set_d(CONFIG_VIEW_DC, atoi(val));
198 else if (strcmp(key, "view_dz") == 0)
199 config_set_d(CONFIG_VIEW_DZ, atoi(val));
200 else if (strcmp(key, "rotate_fast") == 0)
201 config_set_d(CONFIG_ROTATE_FAST, atoi(val));
202 else if (strcmp(key, "rotate_slow") == 0)
203 config_set_d(CONFIG_ROTATE_SLOW, atoi(val));
204 else if (strcmp(key, "mode") == 0)
205 config_set_d(CONFIG_MODE, atoi(val));
206 else if (strcmp(key, "cheat") == 0 && ALLOW_CHEAT)
207 config_set_d(CONFIG_CHEAT, atoi(val));
209 else if (strcmp(key, "key_camera_1") == 0)
210 config_key(val, CONFIG_KEY_CAMERA_1, DEFAULT_KEY_CAMERA_1);
211 else if (strcmp(key, "key_camera_2") == 0)
212 config_key(val, CONFIG_KEY_CAMERA_2, DEFAULT_KEY_CAMERA_2);
213 else if (strcmp(key, "key_camera_3") == 0)
214 config_key(val, CONFIG_KEY_CAMERA_3, DEFAULT_KEY_CAMERA_3);
215 else if (strcmp(key, "key_camera_r") == 0)
216 config_key(val, CONFIG_KEY_CAMERA_R, DEFAULT_KEY_CAMERA_R);
217 else if (strcmp(key, "key_camera_l") == 0)
218 config_key(val, CONFIG_KEY_CAMERA_L, DEFAULT_KEY_CAMERA_L);
220 else if (strcmp(key, "player") == 0)
221 config_set_s(CONFIG_PLAYER, val);
222 else if (strcmp(key, "ball") == 0)
223 config_set_s(CONFIG_BALL, val);
224 else if (strcmp(key, "ball_bonus") == 0)
225 config_set_s(CONFIG_BALL_BONUS, val);
226 else if (strcmp(key, "lang") == 0)
227 config_set_s(CONFIG_LANG, val);
236 void config_save(void)
240 if (dirty && (fp = fopen(config_user(USER_CONFIG_FILE), "w")))
242 fprintf(fp, "fullscreen %d\n",
243 option_d[CONFIG_FULLSCREEN]);
244 fprintf(fp, "width %d\n",
245 option_d[CONFIG_WIDTH]);
246 fprintf(fp, "height %d\n",
247 option_d[CONFIG_HEIGHT]);
248 fprintf(fp, "stereo %d\n",
249 option_d[CONFIG_STEREO]);
250 fprintf(fp, "camera %d\n",
251 option_d[CONFIG_CAMERA]);
252 fprintf(fp, "textures %d\n",
253 option_d[CONFIG_TEXTURES]);
254 fprintf(fp, "geometry %d\n",
255 option_d[CONFIG_GEOMETRY]);
256 fprintf(fp, "reflection %d\n",
257 option_d[CONFIG_REFLECTION]);
258 fprintf(fp, "multisample %d\n",
259 option_d[CONFIG_MULTISAMPLE]);
260 fprintf(fp, "background %d\n",
261 option_d[CONFIG_BACKGROUND]);
262 fprintf(fp, "shadow %d\n",
263 option_d[CONFIG_SHADOW]);
264 fprintf(fp, "audio_rate %d\n",
265 option_d[CONFIG_AUDIO_RATE]);
266 fprintf(fp, "audio_buff %d\n",
267 option_d[CONFIG_AUDIO_BUFF]);
268 fprintf(fp, "mouse_sense %d\n",
269 option_d[CONFIG_MOUSE_SENSE]);
270 fprintf(fp, "mouse_invert %d\n",
271 option_d[CONFIG_MOUSE_INVERT]);
272 fprintf(fp, "nice %d\n",
273 option_d[CONFIG_NICE]);
274 fprintf(fp, "fps %d\n",
275 option_d[CONFIG_FPS]);
276 fprintf(fp, "sound_volume %d\n",
277 option_d[CONFIG_SOUND_VOLUME]);
278 fprintf(fp, "music_volume %d\n",
279 option_d[CONFIG_MUSIC_VOLUME]);
280 fprintf(fp, "joystick %d\n",
281 option_d[CONFIG_JOYSTICK]);
282 fprintf(fp, "joystick_device %d\n",
283 option_d[CONFIG_JOYSTICK_DEVICE]);
284 fprintf(fp, "joystick_axis_x %d\n",
285 option_d[CONFIG_JOYSTICK_AXIS_X]);
286 fprintf(fp, "joystick_axis_y %d\n",
287 option_d[CONFIG_JOYSTICK_AXIS_Y]);
288 fprintf(fp, "joystick_button_a %d\n",
289 option_d[CONFIG_JOYSTICK_BUTTON_A]);
290 fprintf(fp, "joystick_button_b %d\n",
291 option_d[CONFIG_JOYSTICK_BUTTON_B]);
292 fprintf(fp, "joystick_button_r %d\n",
293 option_d[CONFIG_JOYSTICK_BUTTON_R]);
294 fprintf(fp, "joystick_button_l %d\n",
295 option_d[CONFIG_JOYSTICK_BUTTON_L]);
296 fprintf(fp, "joystick_button_exit %d\n",
297 option_d[CONFIG_JOYSTICK_BUTTON_EXIT]);
298 fprintf(fp, "joystick_camera_1 %d\n",
299 option_d[CONFIG_JOYSTICK_CAMERA_1]);
300 fprintf(fp, "joystick_camera_2 %d\n",
301 option_d[CONFIG_JOYSTICK_CAMERA_2]);
302 fprintf(fp, "joystick_camera_3 %d\n",
303 option_d[CONFIG_JOYSTICK_CAMERA_3]);
304 fprintf(fp, "view_fov %d\n",
305 option_d[CONFIG_VIEW_FOV]);
306 fprintf(fp, "view_dp %d\n",
307 option_d[CONFIG_VIEW_DP]);
308 fprintf(fp, "view_dc %d\n",
309 option_d[CONFIG_VIEW_DC]);
310 fprintf(fp, "view_dz %d\n",
311 option_d[CONFIG_VIEW_DZ]);
312 fprintf(fp, "rotate_fast %d\n",
313 option_d[CONFIG_ROTATE_FAST]);
314 fprintf(fp, "rotate_slow %d\n",
315 option_d[CONFIG_ROTATE_SLOW]);
316 fprintf(fp, "mode %d\n",
317 option_d[CONFIG_MODE]);
319 if (option_d[CONFIG_CHEAT])
322 option_d[CONFIG_CHEAT]);
324 fprintf(fp, "key_camera_1 %s\n",
325 SDL_GetKeyName(option_d[CONFIG_KEY_CAMERA_1]));
326 fprintf(fp, "key_camera_2 %s\n",
327 SDL_GetKeyName(option_d[CONFIG_KEY_CAMERA_2]));
328 fprintf(fp, "key_camera_3 %s\n",
329 SDL_GetKeyName(option_d[CONFIG_KEY_CAMERA_3]));
330 fprintf(fp, "key_camera_r %s\n",
331 SDL_GetKeyName(option_d[CONFIG_KEY_CAMERA_R]));
332 fprintf(fp, "key_camera_l %s\n",
333 SDL_GetKeyName(option_d[CONFIG_KEY_CAMERA_L]));
335 fprintf(fp, "player %s\n", option_s[CONFIG_PLAYER]);
336 fprintf(fp, "ball %s\n", option_s[CONFIG_BALL]);
337 fprintf(fp, "ball_bonus %s\n", option_s[CONFIG_BALL_BONUS]);
338 fprintf(fp, "lang %s\n", option_s[CONFIG_LANG]);
346 /*---------------------------------------------------------------------------*/
348 int check_extension(const char *needle)
350 const GLubyte *haystack, *c;
352 /* Search for the given string in the OpenGL extension strings. */
354 for (haystack = glGetString(GL_EXTENSIONS); *haystack; haystack++)
356 for (c = (const GLubyte *) needle; *c && *haystack; c++, haystack++)
360 if ((*c == 0) && (*haystack == ' ' || *haystack == '\0'))
367 int config_mode(int f, int w, int h)
369 int stereo = config_get_d(CONFIG_STEREO) ? 1 : 0;
370 int stencil = config_get_d(CONFIG_REFLECTION) ? 1 : 0;
371 int buffers = config_get_d(CONFIG_MULTISAMPLE) ? 1 : 0;
372 int samples = config_get_d(CONFIG_MULTISAMPLE);
374 SDL_GL_SetAttribute(SDL_GL_STEREO, stereo);
375 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencil);
376 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, buffers);
377 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, samples);
379 /* Try to set the currently specified mode. */
381 if (SDL_SetVideoMode(w, h, 0, SDL_OPENGL | (f ? SDL_FULLSCREEN : 0)))
383 config_set_d(CONFIG_FULLSCREEN, f);
384 config_set_d(CONFIG_WIDTH, w);
385 config_set_d(CONFIG_HEIGHT, h);
387 glViewport(0, 0, w, h);
388 glClearColor(0.0f, 0.0f, 0.1f, 0.0f);
390 glEnable(GL_NORMALIZE);
391 glEnable(GL_CULL_FACE);
392 glEnable(GL_DEPTH_TEST);
393 glEnable(GL_TEXTURE_2D);
394 glEnable(GL_LIGHTING);
396 /* If GL supports multisample, and SDL got a multisample buffer... */
398 #ifdef GL_ARB_multisample
399 if (check_extension("ARB_multisample"))
401 SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &buffers);
403 glEnable(GL_MULTISAMPLE_ARB);
410 /* If the mode failed, try it without stereo. */
414 config_set_d(CONFIG_STEREO, 0);
415 return config_mode(f, w, h);
418 /* If the mode failed, try decreasing the level of multisampling. */
422 config_set_d(CONFIG_MULTISAMPLE, samples / 2);
423 return config_mode(f, w, h);
426 /* If that mode failed, try it without reflections. */
430 config_set_d(CONFIG_REFLECTION, 0);
431 return config_mode(f, w, h);
434 /* If THAT mode failed, punt. */
439 /*---------------------------------------------------------------------------*/
441 void config_set_d(int i, int d)
447 void config_tgl_d(int i)
449 option_d[i] = (option_d[i] ? 0 : 1);
453 int config_tst_d(int i, int d)
455 return (option_d[i] == d) ? 1 : 0;
458 int config_get_d(int i)
463 /*---------------------------------------------------------------------------*/
465 void config_set_s(int i, const char *src)
467 int len = (int) strlen(src);
472 if ((option_s[i] = (char *) malloc(len + 1)))
473 strncpy(option_s[i], src, len + 1);
478 void config_get_s(int i, char *dst, int len)
480 strncpy(dst, option_s[i], len);
483 const char *config_simple_get_s(int i)
488 /*---------------------------------------------------------------------------*/
490 static int grabbed = 0;
491 static int paused = 0;
493 void config_set_grab(void)
495 SDL_WarpMouse(config_get_d(CONFIG_WIDTH) / 2,
496 config_get_d(CONFIG_HEIGHT) / 2);
497 SDL_WM_GrabInput(SDL_GRAB_ON);
498 SDL_ShowCursor(SDL_DISABLE);
502 void config_clr_grab(void)
504 SDL_WM_GrabInput(SDL_GRAB_OFF);
505 SDL_ShowCursor(SDL_ENABLE);
509 int config_get_grab(void)
514 int config_get_pause(void)
519 void config_set_pause(void)
526 SDL_ShowCursor(SDL_ENABLE);
527 SDL_WM_GrabInput(SDL_GRAB_OFF);
531 void config_clr_pause(void)
538 SDL_WM_GrabInput(SDL_GRAB_ON);
539 SDL_ShowCursor(SDL_DISABLE);
543 void config_tgl_pause(void)
550 /*---------------------------------------------------------------------------*/
552 void config_push_persp(float fov, float n, float f)
556 GLdouble r = fov / 2 * V_PI / 180;
558 GLdouble c = cos(r) / s;
560 GLdouble a = ((GLdouble) option_d[CONFIG_WIDTH] /
561 (GLdouble) option_d[CONFIG_HEIGHT]);
563 glMatrixMode(GL_PROJECTION);
578 m[2][2] = -(f + n) / (f - n);
582 m[3][2] = -2.0 * n * f / (f - n);
585 glMultMatrixd(&m[0][0]);
587 glMatrixMode(GL_MODELVIEW);
590 void config_push_ortho(void)
592 GLdouble w = (GLdouble) option_d[CONFIG_WIDTH];
593 GLdouble h = (GLdouble) option_d[CONFIG_HEIGHT];
595 glMatrixMode(GL_PROJECTION);
599 glOrtho(0.0, w, 0.0, h, -1.0, +1.0);
601 glMatrixMode(GL_MODELVIEW);
604 void config_pop_matrix(void)
606 glMatrixMode(GL_PROJECTION);
610 glMatrixMode(GL_MODELVIEW);
613 void config_clear(void)
615 if (option_d[CONFIG_REFLECTION])
616 glClear(GL_COLOR_BUFFER_BIT |
617 GL_DEPTH_BUFFER_BIT |
618 GL_STENCIL_BUFFER_BIT);
620 glClear(GL_COLOR_BUFFER_BIT |
621 GL_DEPTH_BUFFER_BIT);
624 /*---------------------------------------------------------------------------*/