1 /*
2 options.c
3
4 The options screen loop.
5
6 Copyright 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010.
7 Authors: Bill Kendrick, David Bruce, Tim Holy, Brendan Luchen.
8 Project email: <tuxmath-devel@lists.sourceforge.net>
9 Project website: http://tux4kids.alioth.debian.org
10
11 options.c is part of "Tux, of Math Command", a.k.a. "tuxmath".
12
13 Tuxmath is free software: you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 3 of the License, or
16 (at your option) any later version.
17
18 Tuxmath is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program. If not, see <http://www.gnu.org/licenses/>. */
25
26
27
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 //#include "SDL.h"
34
35 #include "mathcards.h"
36
37 #include "options.h"
38 #include "fileops.h"
39 #include "setup.h"
40 #include "game.h"
41 #include "globals.h"
42 //#include "tuxmath.h"
43
44 /* FIXME figure out what oper_override is supposed to do and make sure */
45 /* this file behaves accordingly! */
46
47 //int opers[NUM_OPERS], range_enabled[NUM_Q_RANGES];
48
49 /* global debug masks */
50 //int debug_status;
51
52 /* bitmasks for debugging options */
53 #define dstart (1 << (START_CUSTOM_DEBUG))
54 const int debug_setup = dstart << 0;
55 const int debug_fileops = dstart << 1;
56 const int debug_multiplayer = dstart << 2;
57 const int debug_titlescreen = dstart << 3;
58 const int debug_options = dstart << 4;
59 const int debug_text_and_intl = dstart << 5;
60 const int debug_game = dstart << 6;
61 const int debug_factoroids = dstart << 7;
62 const int debug_lan = dstart << 8;
63 const int debug_mathcards = dstart << 9;
64 const int debug_highscore = dstart << 10;
65 const int debug_lessons = dstart << 11;
66
67 /* extern'd constants */
68
69 const char* const OPTION_TEXT[NUM_GLOBAL_OPTS+1] = {
70 "PER_USER_CONFIG",
71 "USE_SOUND",
72 "MENU_SOUND",
73 "MENU_MUSIC",
74 "FULLSCREEN",
75 "USE_KEYPAD",
76 "USE_IGLOOS",
77 "END_OF_OPTS"
78 };
79
80 const int DEFAULT_GLOBAL_OPTS[NUM_GLOBAL_OPTS] = {
81 1,
82 1,
83 1,
84 1,
85 1,
86 0,
87 1
88 };
89
90
91 /* file scope only now that accessor functions used: */
92 static game_option_type* game_options = NULL;
93 static global_option_type* global_options = NULL;
94
95 /*local function prototypes: */
96 static int int_to_bool(int i);
97 //static int find_and_set_option(const char* name, int val);
98
99
100 /********************************************************************/
101 /* "Public Methods" for options struct: */
102 /********************************************************************/
103
Opts_Initialize(void)104 int Opts_Initialize(void)
105 {
106 int i;
107
108 /* Only allocate game_options if not already done: */
109 if(!game_options)
110 game_options = (game_option_type*)malloc(sizeof(game_option_type));
111 /* bail out if somehow malloc failed: */
112 if (!game_options)
113 return 0;
114
115 /* Same routine for global options: */
116 if(!global_options)
117 global_options = (global_option_type*)malloc(sizeof(global_option_type));
118 if(!global_options)
119 return 0;
120
121 /* set global program options */
122 for (i = 0; i < NUM_GLOBAL_OPTS; ++i)
123 global_options->iopts[i] = DEFAULT_GLOBAL_OPTS[i];
124
125 /* set general game options */
126 global_options->iopts[PER_USER_CONFIG] = DEFAULT_PER_USER_CONFIG;
127 global_options->iopts[USE_SOUND] = DEFAULT_USE_SOUND;
128 global_options->iopts[MENU_SOUND] = DEFAULT_MENU_SOUND;
129 global_options->iopts[MENU_MUSIC] = DEFAULT_MENU_MUSIC;
130 global_options->iopts[FULLSCREEN] = DEFAULT_FULLSCREEN;
131 global_options->iopts[USE_KEYPAD] = DEFAULT_USE_KEYPAD;
132 global_options->iopts[USE_IGLOOS] = DEFAULT_USE_IGLOOS;
133 strncpy(game_options->lesson_title, DEFAULT_LESSON_TITLE,
134 sizeof(game_options->lesson_title));
135 strncpy(game_options->current_font_name, DEFAULT_FONT_NAME,
136 sizeof(game_options->current_font_name));
137 game_options->lan_mode = DEFAULT_LAN_MODE;
138 game_options->use_bkgd = DEFAULT_USE_BKGD;
139 game_options->help_mode = DEFAULT_HELP_MODE;
140 game_options->demo_mode = DEFAULT_DEMO_MODE;
141 game_options->oper_override = DEFAULT_OPER_OVERRIDE;
142 game_options->allow_pause = DEFAULT_ALLOW_PAUSE;
143 game_options->bonus_comet_interval = DEFAULT_BONUS_COMET_INTERVAL;
144 game_options->bonus_speed_ratio = DEFAULT_BONUS_SPEED_RATIO;
145 game_options->speed = DEFAULT_SPEED;
146 game_options->allow_speedup = DEFAULT_ALLOW_SPEEDUP;
147 game_options->speedup_factor = DEFAULT_SPEEDUP_FACTOR;
148 game_options->max_speed = DEFAULT_MAX_SPEED;
149 game_options->slow_after_wrong = DEFAULT_SLOW_AFTER_WRONG;
150 game_options->starting_comets = DEFAULT_STARTING_COMETS;
151 game_options->extra_comets_per_wave = DEFAULT_EXTRA_COMETS_PER_WAVE;
152 game_options->max_comets = DEFAULT_MAX_COMETS;
153 game_options->use_powerup_comets = DEFAULT_USE_POWERUP_COMETS;
154 game_options->powerup_freq = DEFAULT_POWERUP_FREQ;
155 game_options->save_summary = DEFAULT_SAVE_SUMMARY;
156 game_options->sound_hw_available = DEFAULT_SOUND_HW_AVAILABLE;
157 game_options->use_feedback = DEFAULT_USE_FEEDBACK;
158 game_options->danger_level = DEFAULT_DANGER_LEVEL;
159 game_options->danger_level_speedup = DEFAULT_DANGER_LEVEL_SPEEDUP;
160 game_options->danger_level_max = DEFAULT_DANGER_LEVEL_MAX;
161 game_options->city_expl_handicap = DEFAULT_CITY_EXPL_HANDICAP;
162 game_options->last_score = DEFAULT_LAST_SCORE;
163
164 game_options->num_cities = DEFAULT_NUM_CITIES; /* MUST BE AN EVEN NUMBER! */
165 game_options->max_city_colors = DEFAULT_MAX_CITY_COLORS;
166
167 DEBUGCODE(debug_options)
168 print_game_options(stdout, 0);
169
170 return 1;
171 }
172
173
Opts_Cleanup(void)174 void Opts_Cleanup(void)
175 {
176 if (game_options)
177 {
178 free(game_options);
179 game_options = 0;
180 }
181 }
182
183
184 //* "Set" functions for tuxmath options struct: */
Opts_MapTextToIndex(const char * text)185 unsigned int Opts_MapTextToIndex(const char* text)
186 {
187 int i;
188 for (i = 0; i < NUM_GLOBAL_OPTS; ++i)
189 {
190 if (0 == strcasecmp(text, OPTION_TEXT[i]) )
191 {
192 return i;
193 }
194 }
195 DEBUGMSG(debug_options, "'%s' isn't a global option\n", text);
196 return -1;
197 }
198
Opts_GetGlobalOp(const char * text)199 int Opts_GetGlobalOp(const char* text)
200 {
201 int index = Opts_MapTextToIndex(text);
202 if (index < NUM_GLOBAL_OPTS)
203 return Opts_GetGlobalOpt(index);
204 return 0;
205 }
206
Opts_GetGlobalOpt(unsigned int index)207 int Opts_GetGlobalOpt(unsigned int index)
208 {
209 if (index < NUM_GLOBAL_OPTS)
210 return global_options->iopts[index];
211 DEBUGMSG(debug_options, "Invalid global option index: %d\n", index);
212 return 0;
213 }
214
Opts_SetGlobalOp(const char * text,int val)215 void Opts_SetGlobalOp(const char* text, int val)
216 {
217 int index = Opts_MapTextToIndex(text);
218 if (index < NUM_GLOBAL_OPTS)
219 Opts_SetGlobalOpt(index, val);
220 }
221
Opts_SetGlobalOpt(unsigned int index,int val)222 void Opts_SetGlobalOpt(unsigned int index, int val)
223 {
224 if (index < NUM_GLOBAL_OPTS)
225 {
226 //Need to make sure we don't turn on sound options if sound
227 //system couldn't be set up:
228 if(index == USE_SOUND || index == MENU_SOUND || index == MENU_MUSIC)
229 {
230 if(!Opts_SoundHWAvailable())
231 val = 0;
232 }
233 global_options->iopts[index] = val;
234 }
235 else
236 DEBUGMSG(debug_options, "Invalid global option index: %d\n", index);
237 }
238
239
240 //void Opts_SetPerUserConfig(int val)
241 //{
242 // global_options->iopts[PER_USER_CONFIG] = int_to_bool(val);
243 //}
244 //
245 //
246 //void Opts_SetUseSound(int val)
247 //{
248 // if (val == -1)
249 // global_options->iopts[USE_SOUND] = val;
250 // else if (global_options->iopts[USE_SOUND] != -1)
251 // global_options->iopts[USE_SOUND] = int_to_bool(val);
252 //}
253 //
254 //
255 //void Opts_SetMenuSound(int val)
256 //{
257 // global_options->iopts[MENU_SOUND] = int_to_bool(val);
258 //}
259 //
260 //
261 //void Opts_SetMenuMusic(int val)
262 //{
263 // global_options->iopts[MENU_MUSIC] = int_to_bool(val);
264 //}
265
266
267 ///* FIXME need to actually change screen resolution when this is called */
268 //void Opts_SetFullscreen(int val)
269 //{
270 // global_options->iopts[FULLSCREEN] = int_to_bool(val);
271 //}
272
Opts_SetLanMode(int val)273 void Opts_SetLanMode(int val)
274 {
275 game_options->lan_mode = int_to_bool(val);
276 }
277
Opts_SetLessonTitle(char * title)278 void Opts_SetLessonTitle(char* title)
279 {
280 if (title && title[0] != '\0')
281 strncpy(game_options->lesson_title, title, sizeof(game_options->lesson_title));
282 }
283
Opts_SetFontName(char * font_name)284 void Opts_SetFontName(char* font_name)
285 {
286 if (font_name && font_name[0] != '\0')
287 strncpy(game_options->current_font_name, font_name, sizeof(game_options->current_font_name));
288 }
289
Opts_SetUseBkgd(int val)290 void Opts_SetUseBkgd(int val)
291 {
292 game_options->use_bkgd = int_to_bool(val);
293 }
294
295
Opts_SetHelpMode(int val)296 void Opts_SetHelpMode(int val)
297 {
298 game_options->help_mode = int_to_bool(val);
299 }
300
301
Opts_SetDemoMode(int val)302 void Opts_SetDemoMode(int val)
303 {
304 game_options->demo_mode = int_to_bool(val);
305 }
306
307
Opts_SetOperOverride(int val)308 void Opts_SetOperOverride(int val)
309 {
310 game_options->oper_override = int_to_bool(val);
311 }
312
313
314 //void Opts_SetUseKeypad(int val)
315 //{
316 // global_options->iopts[USE_KEYPAD] = int_to_bool(val);
317 //}
318
319
Opts_SetAllowPause(int val)320 void Opts_SetAllowPause(int val)
321 {
322 game_options->allow_pause = int_to_bool(val);
323 }
324
325
326 //void Opts_SetUseIgloos(int val)
327 //{
328 // global_options->iopts[USE_IGLOOS] = int_to_bool(val);
329 //}
330
331
Opts_SetBonusCometInterval(int val)332 void Opts_SetBonusCometInterval(int val)
333 {
334 if (val < 0)
335 val = 0;
336 game_options->bonus_comet_interval = val;
337 }
338
339
Opts_SetBonusSpeedRatio(float val)340 void Opts_SetBonusSpeedRatio(float val)
341 {
342 if (val < 1)
343 {
344 val = 1;
345 fprintf(stderr,"bonus_speed_ratio must be at least 1, resetting accordingly.\n");
346 }
347 if (val > MAX_BONUS_SPEED_RATIO)
348 {
349 val = MAX_BONUS_SPEED_RATIO;
350 fprintf(stderr,"Warning: requested bonus_speed_ratio above maximum, setting to %g.\n",MAX_BONUS_SPEED_RATIO);
351 }
352 game_options->bonus_speed_ratio = val;
353 }
354
355
Opts_SetSpeed(float val)356 void Opts_SetSpeed(float val)
357 {
358 if (val < MINIMUM_SPEED)
359 {
360 val = MINIMUM_SPEED;
361 fprintf(stderr,"Warning: requested speed below minimum, setting to %g.\n",MINIMUM_SPEED);
362 }
363 if (val > MAX_MAX_SPEED)
364 {
365 val = MAX_MAX_SPEED;
366 fprintf(stderr,"Warning: requested speed above Tuxmath's maximum, setting to %g.\n",MAX_MAX_SPEED);
367 }
368 if (val > Opts_MaxSpeed())
369 {
370 val = Opts_MaxSpeed();
371 fprintf(stderr,"Warning: requested speed above currently selected maximum, setting to %g.\n",
372 Opts_MaxSpeed());
373 }
374 game_options->speed = val;
375 }
376
377
Opts_SetAllowSpeedup(int val)378 void Opts_SetAllowSpeedup(int val)
379 {
380 game_options->allow_speedup = int_to_bool(val);
381 }
382
383
Opts_SetSpeedupFactor(float val)384 void Opts_SetSpeedupFactor(float val)
385 {
386 if (val < MIN_SPEEDUP_FACTOR)
387 {
388 val = MIN_SPEEDUP_FACTOR;
389 fprintf(stderr,"Warning: requested speedup factor below Tuxmath's minimum, setting to %g.\n",MIN_SPEEDUP_FACTOR);
390 }
391 if (val > MAX_SPEEDUP_FACTOR)
392 {
393 val = MAX_SPEEDUP_FACTOR;
394 fprintf(stderr,"Warning: requested speedup factor above Tuxmath's maximum, setting to %g.\n",MAX_SPEEDUP_FACTOR);
395 }
396 game_options->speedup_factor = val;
397 }
398
399
Opts_SetMaxSpeed(float val)400 void Opts_SetMaxSpeed(float val)
401 {
402 if (val < MINIMUM_SPEED)
403 {
404 val = MINIMUM_SPEED;
405 fprintf(stderr,"Warning: requested max speed below minimum, setting to %g.\n",
406 MINIMUM_SPEED);
407 }
408 if (val > MAX_MAX_SPEED)
409 {
410 val = MAX_MAX_SPEED;
411 fprintf(stderr,"Warning: requested max speed above Tuxmath's maximum, setting to %g.\n",
412 MAX_MAX_SPEED);
413 }
414 if (val < Opts_Speed())
415 {
416 val = Opts_Speed();
417 fprintf(stderr,"Warning: requested max speed less than current speed, setting to %g.\n",
418 Opts_MaxSpeed());
419 }
420 game_options->max_speed = val;
421 }
422
423
Opts_SetSlowAfterWrong(int val)424 void Opts_SetSlowAfterWrong(int val)
425 {
426 game_options->slow_after_wrong = int_to_bool(val);
427 }
428
429
Opts_SetStartingComets(int val)430 void Opts_SetStartingComets(int val)
431 {
432 if (val < MIN_COMETS)
433 {
434 val = MIN_COMETS;
435 fprintf(stderr,"Warning: requested starting comets below Tuxmath's minimum, setting to %d.\n",
436 MIN_COMETS);
437 }
438 if (val > MAX_MAX_COMETS)
439 {
440 val = MAX_MAX_COMETS;
441 fprintf(stderr,"Warning: requested starting comets above Tuxmath's maximum, setting to %d.\n",
442 MAX_MAX_COMETS);
443 }
444 if (val > Opts_MaxComets())
445 {
446 val = Opts_MaxComets();
447 fprintf(stderr,"Warning: requested starting comets above currently selected maximum, setting to %d.\n",
448 Opts_MaxComets());
449 }
450 game_options->starting_comets = val;
451 }
452
453
Opts_SetExtraCometsPerWave(int val)454 void Opts_SetExtraCometsPerWave(int val)
455 {
456 if (val < 0)
457 {
458 val = 0;
459 fprintf(stderr,"Warning: requested extra comets below Tuxmath's minimum, setting to %d.\n",
460 0);
461 }
462 if (val > MAX_MAX_COMETS)
463 {
464 val = MAX_MAX_COMETS;
465 fprintf(stderr,"Warning: requested extra comets above Tuxmath's maximum, setting to %d.\n",
466 MAX_MAX_COMETS);
467 }
468 if (val > Opts_MaxComets())
469 {
470 val = Opts_MaxComets();
471 fprintf(stderr,"Warning: requested extra comets above currently selected maximum, setting to %d.\n",
472 Opts_MaxComets());
473 }
474 game_options->extra_comets_per_wave = val;
475 }
476
477
Opts_SetMaxComets(int val)478 void Opts_SetMaxComets(int val)
479 {
480 if (val < MIN_COMETS)
481 {
482 val = MIN_COMETS;
483 fprintf(stderr,"Warning: requested max comets below Tuxmath's minimum, setting to %d.\n",
484 MIN_COMETS);
485 }
486 if (val > MAX_MAX_COMETS)
487 {
488 val = MAX_MAX_COMETS;
489 fprintf(stderr,"Warning: requested max comets above Tuxmath's maximum, setting to %d.\n",
490 MAX_MAX_COMETS);
491 }
492 game_options->max_comets = val;
493 }
494
Opts_SetUsePowerupComets(int val)495 void Opts_SetUsePowerupComets(int val)
496 {
497 game_options->use_powerup_comets = int_to_bool(val);
498 }
499
Opts_SetPowerupFreq(int val)500 void Opts_SetPowerupFreq(int val)
501 {
502 if(val > 0)
503 game_options->powerup_freq = val;
504 else
505 fprintf(stderr,"Warning: requested powerup frequency illegal, setting to %d.\n",
506 DEFAULT_POWERUP_FREQ);
507
508 }
509
510
Opts_SetNextMission(char * str)511 void Opts_SetNextMission(char* str)
512 {
513 int len = strlen(str);
514 if (len < PATH_MAX)
515 {
516 strcpy(game_options->next_mission, str);
517 }
518 else
519 {
520 fprintf(stderr,"Warning: Opts_SetNextMission() - string invalid or overflow\n");
521 }
522 }
523
524
Opts_SetSaveSummary(int val)525 void Opts_SetSaveSummary(int val)
526 {
527 game_options->save_summary = int_to_bool(val);
528 }
529
530
Opts_SetUseFeedback(int val)531 void Opts_SetUseFeedback(int val)
532 {
533 game_options->use_feedback = int_to_bool(val);
534 }
535
536
Opts_SetDangerLevel(float val)537 void Opts_SetDangerLevel(float val)
538 {
539 if (val < 0)
540 {
541 val = 0;
542 fprintf(stderr,"Warning: danger level must be between 0 and 1, setting to 0.\n");
543 }
544 if (val > 1)
545 {
546 val = 1;
547 fprintf(stderr,"Warning: danger level must be between 0 and 1, setting to 1.\n");
548 }
549 game_options->danger_level = val;
550 }
551
552
Opts_SetDangerLevelSpeedup(float val)553 void Opts_SetDangerLevelSpeedup(float val)
554 {
555 if (val < 1)
556 {
557 val = 1;
558 fprintf(stderr,"Warning: danger_level_speedup must be at least 1, setting to 1.\n");
559 }
560 game_options->danger_level_speedup = val;
561 }
562
563
Opts_SetDangerLevelMax(float val)564 void Opts_SetDangerLevelMax(float val)
565 {
566 if (val < 0)
567 {
568 val = 0;
569 fprintf(stderr,"Warning: danger level max must be between 0 and 1, setting to 0.\n");
570 }
571 if (val > 1)
572 {
573 val = 1;
574 fprintf(stderr,"Warning: danger level max must be between 0 and 1, setting to 1.\n");
575 }
576 game_options->danger_level_max = val;
577 }
578
579
Opts_SetCityExplHandicap(float val)580 void Opts_SetCityExplHandicap(float val)
581 {
582 if (val < 0)
583 {
584 val = 0;
585 fprintf(stderr,"Warning: city_explode_handicap level set below minimum, setting to 0.\n");
586 }
587 game_options->city_expl_handicap = val;
588 }
589
590
591
592 /* whether sound system is successfully initialized and sound files loaded: */
593 /* this flag is set by the program, not the user, and is not in the config file. */
Opts_SetSoundHWAvailable(int val)594 void Opts_SetSoundHWAvailable(int val)
595 {
596 game_options->sound_hw_available = int_to_bool(val);
597 }
598
599 /* Allows game() to store score for high score table code: */
Opts_SetLastScore(int val)600 void Opts_SetLastScore(int val)
601 {
602 game_options->last_score = val;
603 }
604
Opts_SetKeepScore(int val)605 void Opts_SetKeepScore(int val)
606 {
607 game_options->keep_score = val;
608 }
609
610
611 /* "Get" functions for tuxmath options struct: */
612 //int Opts_PerUserConfig(void)
613 //{
614 // if (!game_options)
615 // {
616 // fprintf(stderr, "\nOpts_PerUserConfig(): game_options not valid!\n");
617 // return GAME_OPTS_INVALID;
618 // }
619 // return global_options->iopts[PER_USER_CONFIG];
620 //}
621 //
622 //
623 //int Opts_UseSound(void)
624 //{
625 // if (!game_options)
626 // {
627 // fprintf(stderr, "\nOpts_UseSound(): game_options not valid!\n");
628 // return GAME_OPTS_INVALID;
629 // }
630 // return global_options->iopts[USE_SOUND] > 0;
631 //}
632 //
633 //
634 //int Opts_MenuSound(void)
635 //{
636 // if (!game_options)
637 // {
638 // fprintf(stderr, "\nOpts_MenuSound(): game_options not valid!\n");
639 // return GAME_OPTS_INVALID;
640 // }
641 // return global_options->iopts[MENU_SOUND];
642 //}
643 //
644 //
645 //int Opts_MenuMusic(void)
646 //{
647 // if (!game_options)
648 // {
649 // fprintf(stderr, "\nOpts_MenuMusic(): game_options not valid!\n");
650 // return GAME_OPTS_INVALID;
651 // }
652 // return global_options->iopts[MENU_MUSIC];
653 //}
654 //
655 //
656 //int Opts_Fullscreen(void)
657 //{
658 // if (!game_options)
659 // {
660 // fprintf(stderr, "\nOpts_Fullscreen(): game_options not valid!\n");
661 // return GAME_OPTS_INVALID;
662 // }
663 // return global_options->iopts[FULLSCREEN];
664 //}
665
666
Opts_LanMode(void)667 int Opts_LanMode(void)
668 {
669 if (!game_options)
670 {
671 fprintf(stderr, "\nOpts_LanMode(): game_options not valid!\n");
672 return GAME_OPTS_INVALID;
673 }
674 return game_options->lan_mode;
675 }
676
677
Opts_LessonTitle(void)678 const char* Opts_LessonTitle(void)
679 {
680 if (!game_options)
681 {
682 fprintf(stderr, "\nOpts_LessonTitle(): game_options not valid!\n");
683 return NULL;
684 }
685 return (const char*) game_options->lesson_title;
686 }
687
688
Opts_FontName(void)689 const char* Opts_FontName(void)
690 {
691 if (!game_options)
692 {
693 fprintf(stderr, "\nOpts_FontName(): game_options not valid!\n");
694 return NULL;
695 }
696 return (const char*) game_options->current_font_name;
697 }
698
Opts_UseBkgd(void)699 int Opts_UseBkgd(void)
700 {
701 if (!game_options)
702 {
703 fprintf(stderr, "\nOpts_UserBkgd(): game_options not valid!\n");
704 return GAME_OPTS_INVALID;
705 }
706 return game_options->use_bkgd;
707 }
708
709
Opts_HelpMode(void)710 int Opts_HelpMode(void)
711 {
712 if (!game_options)
713 {
714 fprintf(stderr, "\nOpts_HelpMode(): game_options not valid!\n");
715 return GAME_OPTS_INVALID;
716 }
717 return game_options->help_mode;
718 }
719
720
Opts_DemoMode(void)721 int Opts_DemoMode(void)
722 {
723 if (!game_options)
724 {
725 fprintf(stderr, "\nOpts_DemoMode(): game_options not valid!\n");
726 return GAME_OPTS_INVALID;
727 }
728 return game_options->demo_mode;
729 }
730
731
Opts_OperOverride(void)732 int Opts_OperOverride(void)
733 {
734 if (!game_options)
735 {
736 fprintf(stderr, "\nOpts_OperOverride(): game_options not valid!\n");
737 return GAME_OPTS_INVALID;
738 }
739 return game_options->oper_override;
740 }
741
742
743 //int Opts_UseKeypad(void)
744 //{
745 // if (!game_options)
746 // {
747 // fprintf(stderr, "\nOpts_UseKeypad(): game_options not valid!\n");
748 // return GAME_OPTS_INVALID;
749 // }
750 // return global_options->iopts[USE_KEYPAD];
751 //}
752 //
753 //
Opts_AllowPause(void)754 int Opts_AllowPause(void)
755 {
756 if (!game_options)
757 {
758 fprintf(stderr, "\nOpts_AllowPause(): game_options not valid!\n");
759 return GAME_OPTS_INVALID;
760 }
761 return game_options->allow_pause;
762 }
763
764
765 //int Opts_UseIgloos(void)
766 //{
767 // if (!game_options)
768 // {
769 // fprintf(stderr, "\nOpts_UseIgloos(): game_options not valid!\n");
770 // return GAME_OPTS_INVALID;
771 // }
772 // return global_options->iopts[USE_IGLOOS];
773 //}
774
Opts_BonusCometInterval(void)775 int Opts_BonusCometInterval(void)
776 {
777 if (!game_options)
778 {
779 fprintf(stderr, "\nOpts_BonusCometInterval(): game_options not valid!\n");
780 return GAME_OPTS_INVALID;
781 }
782 return game_options->bonus_comet_interval;
783 }
784
785
Opts_BonusSpeedRatio(void)786 float Opts_BonusSpeedRatio(void)
787 {
788 if (!game_options)
789 {
790 fprintf(stderr, "\nOpts_BonusSpeedRatio(): game_options not valid!\n");
791 return GAME_OPTS_INVALID;
792 }
793 return game_options->bonus_speed_ratio;
794 }
795
796
Opts_Speed(void)797 float Opts_Speed(void)
798 {
799 if (!game_options)
800 {
801 fprintf(stderr, "\nOpts_Speed(): game_options not valid!\n");
802 return GAME_OPTS_INVALID;
803 }
804 return game_options->speed;
805 }
806
807
Opts_AllowSpeedup(void)808 int Opts_AllowSpeedup(void)
809 {
810 if (!game_options)
811 {
812 fprintf(stderr, "\nOpts_AllowSpeedup(): game_options not valid!\n");
813 return GAME_OPTS_INVALID;
814 }
815 return game_options->allow_speedup;
816 }
817
818
Opts_SpeedupFactor(void)819 float Opts_SpeedupFactor(void)
820 {
821 if (!game_options)
822 {
823 fprintf(stderr, "\nOpts_SpeedupFactor(): game_options not valid!\n");
824 return GAME_OPTS_INVALID;
825 }
826 return game_options->speedup_factor;
827 }
828
829
Opts_MaxSpeed(void)830 float Opts_MaxSpeed(void)
831 {
832 if (!game_options)
833 {
834 fprintf(stderr, "\nOpts_MaxSpeed(): game_options not valid!\n");
835 return GAME_OPTS_INVALID;
836 }
837 return game_options->max_speed;
838 }
839
840
Opts_SlowAfterWrong(void)841 int Opts_SlowAfterWrong(void)
842 {
843 if (!game_options)
844 {
845 fprintf(stderr, "\nOpts_SlowAfterWrong(): game_options not valid!\n");
846 return GAME_OPTS_INVALID;
847 }
848 return game_options->slow_after_wrong;
849 }
850
851
Opts_StartingComets(void)852 int Opts_StartingComets(void)
853 {
854 if (!game_options)
855 {
856 fprintf(stderr, "\nOpts_StartingComets(): game_options not valid!\n");
857 return GAME_OPTS_INVALID;
858 }
859 return game_options->starting_comets;
860 }
861
862
Opts_ExtraCometsPerWave(void)863 int Opts_ExtraCometsPerWave(void)
864 {
865 if (!game_options)
866 {
867 fprintf(stderr, "\nOpts_ExtraCometsPerWave(): game_options not valid!\n");
868 return GAME_OPTS_INVALID;
869 }
870 return game_options->extra_comets_per_wave;
871 }
872
873
Opts_MaxComets(void)874 int Opts_MaxComets(void)
875 {
876 if (!game_options)
877 {
878 fprintf(stderr, "\nOpts_MaxComets(): game_options not valid!\n");
879 return GAME_OPTS_INVALID;
880 }
881 return game_options->max_comets;
882 }
883
Opts_UsePowerupComets(void)884 int Opts_UsePowerupComets(void)
885 {
886 if (!game_options)
887 {
888 fprintf(stderr, "\nOpts_UsePowerupComets(): game_options not valid!\n");
889 return GAME_OPTS_INVALID;
890 }
891 return game_options->use_powerup_comets;
892 }
893
Opts_PowerupFreq(void)894 int Opts_PowerupFreq(void)
895 {
896 if (!game_options)
897 {
898 fprintf(stderr, "\nOpts_PowerupFreq(): game_options not valid!\n");
899 return GAME_OPTS_INVALID;
900 }
901 return game_options->powerup_freq;
902 }
903
Opts_NextMission(void)904 const char* Opts_NextMission(void)
905 {
906 if (!game_options)
907 {
908 fprintf(stderr, "\nOpts_NextMission(): game_options not valid!\n");
909 return NULL;
910 }
911 return (const char*) game_options->next_mission;
912 }
913
914
Opts_SaveSummary(void)915 int Opts_SaveSummary(void)
916 {
917 if (!game_options)
918 {
919 fprintf(stderr, "\nOpts_SaveSummary(): game_options not valid!\n");
920 return GAME_OPTS_INVALID;
921 }
922 return game_options->save_summary;
923 }
924
925
Opts_LastScore(void)926 int Opts_LastScore(void)
927 {
928 if (!game_options)
929 {
930 fprintf(stderr, "\nOpts_LastScore(): game_options not valid!\n");
931 return GAME_OPTS_INVALID;
932 }
933 return game_options->last_score;
934 }
935
936
Opts_UseFeedback(void)937 int Opts_UseFeedback(void)
938 {
939 if (!game_options)
940 {
941 fprintf(stderr, "\nOpts_UseFeedback(): game_options not valid!\n");
942 return GAME_OPTS_INVALID;
943 }
944 return game_options->use_feedback;
945 }
946
947
Opts_DangerLevel(void)948 float Opts_DangerLevel(void)
949 {
950 if (!game_options)
951 {
952 fprintf(stderr, "\nOpts_DangerLevel(): game_options not valid!\n");
953 return GAME_OPTS_INVALID;
954 }
955 return game_options->danger_level;
956 }
957
958
Opts_DangerLevelSpeedup(void)959 float Opts_DangerLevelSpeedup(void)
960 {
961 if (!game_options)
962 {
963 fprintf(stderr, "\nOpts_DangerLevelSpeedup(): game_options not valid!\n");
964 return GAME_OPTS_INVALID;
965 }
966 return game_options->danger_level_speedup;
967 }
968
969
Opts_DangerLevelMax(void)970 float Opts_DangerLevelMax(void)
971 {
972 if (!game_options)
973 {
974 fprintf(stderr, "\nOpts_DangerLevelMax(): game_options not valid!\n");
975 return GAME_OPTS_INVALID;
976 }
977 return game_options->danger_level_max;
978 }
979
980
Opts_CityExplHandicap(void)981 float Opts_CityExplHandicap(void)
982 {
983 if (!game_options)
984 {
985 fprintf(stderr, "\nOpts_CityExplHandicap(): game_options not valid!\n");
986 return GAME_OPTS_INVALID;
987 }
988 return game_options->city_expl_handicap;
989 }
990
991
992
993 /* whether sound system is successfully initialized and sound files loaded: */
994 /* this flag is set by the program, not the user, and is not in the config file. */
Opts_SoundHWAvailable(void)995 int Opts_SoundHWAvailable(void)
996 {
997 if (!game_options)
998 {
999 fprintf(stderr, "\nOpts_SoundHWAvailable(): game_options not valid!\n");
1000 return GAME_OPTS_INVALID;
1001 }
1002 return game_options->sound_hw_available;
1003 }
1004
1005
1006 /* Returns true if only if the player wants to use sound */
1007 /* and the sound system is actually available: */
Opts_UsingSound(void)1008 int Opts_UsingSound(void)
1009 {
1010 if (!game_options)
1011 {
1012 fprintf(stderr, "\nOpts_UsingSound(): game_options not valid!\n");
1013 return GAME_OPTS_INVALID;
1014 }
1015 return (global_options->iopts[USE_SOUND]>0 && game_options->sound_hw_available);
1016 }
1017
Opts_KeepScore(void)1018 int Opts_KeepScore(void)
1019 {
1020 if (!game_options)
1021 {
1022 fprintf(stderr, "\nOpts_KeepScore(): game_options not valid!\n");
1023 return GAME_OPTS_INVALID;
1024 }
1025 return game_options->keep_score;
1026 }
1027 /********************************************************************/
1028 /* "private methods" (static functions only visible in options.c) */
1029 /********************************************************************/
1030
1031
1032
1033
1034
1035 /* to prevent option settings in math_opts from getting set to */
1036 /* values other than 0 or 1 */
int_to_bool(int i)1037 int int_to_bool(int i)
1038 {
1039 if (i)
1040 return 1;
1041 else
1042 return 0;
1043 }
1044
1045 ///* determine which option class a name belongs to, and set it */
1046 ///* accordingly. Returns 1 on success, 0 on failure */
1047 //static int find_and_set_option(const char* name, int val)
1048 //{
1049 // int index = -1;
1050 //
1051 // if ((index = MC_MapTextToIndex(name)) != -1) //is it a math opt?
1052 // MC_SetOpt(index, val);
1053 // else if ((index = Opts_MapTextToIndex(name)) != -1) //is it a global opt?
1054 // Opts_SetGlobalOpt(index, val);
1055 // else //no? oh well.
1056 // return 0;
1057 //
1058 // return 1;
1059 //}
1060
1061 /* prints struct to stream: */
print_game_options(FILE * fp,int verbose)1062 void print_game_options(FILE* fp, int verbose)
1063 {
1064 /* bail out if no struct */
1065 if (!game_options)
1066 {
1067 fprintf(stderr, "print_game_options(): invalid game_option_type struct");
1068 return;
1069 }
1070
1071 if(verbose)
1072 {
1073 fprintf (fp, "\n############################################################\n"
1074 "# #\n"
1075 "# General Game Options #\n"
1076 "# #\n"
1077 "# The following options are boolean (true/false) variables #\n"
1078 "# that control various aspects of Tuxmath's behavior. #\n"
1079 "# The program writes the values to the file as either '0' #\n"
1080 "# or '1'. However, the program accepts 'n', 'no', 'f', and #\n"
1081 "# 'false' as synonyms for '0', and similarly accepts 'y', #\n"
1082 "# 'yes', 't', and 'true' as synonyms for '1' (all case- #\n"
1083 "# insensitive). #\n"
1084 "############################################################\n\n");
1085 }
1086
1087 if(verbose)
1088 {
1089 fprintf (fp, "############################################################\n"
1090 "# 'PER_USER_CONFIG' determines whether Tuxmath will look #\n"
1091 "# in the user's home directory for settings. Default is 1 #\n"
1092 "# (yes). If deselected, the program will ignore the user's #\n"
1093 "# .tuxmath file and use the the global settings in the #\n"
1094 "# installation-wide config file. #\n"
1095 "# This setting cannot be changed by an ordinary user. #\n"
1096 "############################################################\n");
1097 }
1098 fprintf(fp, "PER_USER_CONFIG = %d\n", global_options->iopts[PER_USER_CONFIG]);
1099
1100 if(verbose)
1101 {
1102 fprintf (fp, "\n# Self-explanatory, default is 1:\n");
1103 }
1104 fprintf(fp, "USE_SOUND = %d\n", global_options->iopts[USE_SOUND]>0);
1105
1106 if(verbose)
1107 {
1108 fprintf (fp, "\n# Use FULLSCREEN at 640x480 resolution instead of\n"
1109 "640x480 window. Default is 1 (FULLSCREEN). Change to 0\n"
1110 "if SDL has trouble with FULLSCREEN on your system.\n");
1111 }
1112 fprintf(fp, "FULLSCREEN = %d\n", global_options->iopts[FULLSCREEN]);
1113
1114 if(verbose)
1115 {
1116 fprintf (fp, "\n# Use 640x480 jpg image for background; default is 1.\n");
1117 }
1118 fprintf(fp, "use_bkgd = %d\n", game_options->use_bkgd);
1119
1120 if(verbose)
1121 {
1122 fprintf (fp, "\n# Program runs as demo; default is 0.\n");
1123 }
1124 fprintf(fp, "demo_mode = %d\n", game_options->demo_mode);
1125
1126 if(verbose)
1127 {
1128 fprintf (fp, "\n# Use operator selection from command line; default is 0.\n");
1129 }
1130 fprintf(fp, "oper_override = %d\n", game_options->oper_override);
1131
1132 if(verbose)
1133 {
1134 fprintf (fp, "\n# Display onscreen numeric keypad; default is 0.\n");
1135 }
1136 fprintf(fp, "USE_KEYPAD = %d\n", global_options->iopts[USE_KEYPAD]);
1137
1138 if(verbose)
1139 {
1140 fprintf (fp, "\n############################################################\n"
1141 "# The next settings determine the speed and number #\n"
1142 "# of comets. The speed settings are float numbers (mean- #\n"
1143 "# ing decimals allowed). The comet settings are integers. #\n"
1144 "# #\n"
1145 "# Starting comet speed and max comet speed are generally #\n"
1146 "# applicable. The main choice is whether you want to use #\n"
1147 "# feedback, i.e., to adjust the speed automatically based #\n"
1148 "# on the player's performance. #\n"
1149 "# #\n"
1150 "# Without feedback, the speed increases by a user- #\n"
1151 "# settable factor ('speedup_factor'), with an option #\n"
1152 "# ('slow_after_wrong') to go back to the starting speed #\n"
1153 "# when a city gets hit. #\n"
1154 "# #\n"
1155 "# With feedback, you set a desired 'danger level,' which #\n"
1156 "# determines how close the comets should typically #\n"
1157 "# approach the cities before the player succeeds in #\n"
1158 "# destroying them. The game will adjust its speed #\n"
1159 "# accordingly, getting faster when the player is easily #\n"
1160 "# stopping the comets, and slowing down when there are #\n"
1161 "# too many close calls or hits. You can also have the #\n"
1162 "# danger level increase with each wave. #\n"
1163 "############################################################\n");
1164 }
1165
1166 if(verbose)
1167 {
1168 fprintf (fp, "\n# Whether to increase speed and number of comets with \n"
1169 "# each wave. May want to turn this off for smaller kids.\n"
1170 "# Default is 1 (allow game to speed up)\n");
1171 }
1172 fprintf(fp, "allow_speedup = %d\n", game_options->allow_speedup);
1173
1174
1175 fprintf(fp, "slow_after_wrong = %d\n", game_options->slow_after_wrong);
1176
1177 if(verbose)
1178 {
1179 fprintf (fp, "\n# Starting comet speed. Default is 1.\n");
1180 }
1181 fprintf(fp, "speed = %f\n", game_options->speed);
1182
1183 if(verbose)
1184 {
1185 fprintf (fp, "\n# If feedback is not used but 'allow_speedup' is\n"
1186 "# enabled, the comet speed will be\n"
1187 "# multiplied by this factor with each new wave.\n"
1188 "# Default is 1.2 (i.e. 20 percent increase per wave)\n");
1189 }
1190 fprintf(fp, "speedup_factor = %f\n", game_options->speedup_factor);
1191
1192 if(verbose)
1193 {
1194 fprintf (fp, "\n# Maximum speed. Default is 10.\n");
1195 }
1196 fprintf(fp, "max_speed = %f\n", game_options->max_speed);
1197
1198 if(verbose)
1199 {
1200 fprintf (fp, "\n# Number of comets for first wave. Default is 2.\n");
1201 }
1202 fprintf(fp, "starting_comets = %d\n", game_options->starting_comets);
1203
1204 if(verbose)
1205 {
1206 fprintf (fp, "\n# Comets to add for each successive wave. Default is 2.\n");
1207 }
1208 fprintf(fp, "extra_comets_per_wave = %d\n", game_options->extra_comets_per_wave);
1209
1210 if(verbose)
1211 {
1212 fprintf (fp, "\n# Maximum number of comets. Default is 10.\n");
1213 }
1214 fprintf(fp, "max_comets = %d\n", game_options->max_comets);
1215
1216 if(verbose)
1217 {
1218 fprintf (fp, "\n# Use feedback? Default (for now) is false, 0.\n");
1219 }
1220 fprintf(fp, "use_feedback = %d\n", game_options->use_feedback);
1221
1222
1223 if(verbose)
1224 {
1225 fprintf (fp, "\n# (Feedback) Set the desired danger level.\n"
1226 "# 0 = too safe, comets typically exploded right at the very top\n"
1227 "# 1 = too dangerous, comets typically exploded at the moment they hit cities\n"
1228 "# Set it somewhere between these extremes. As a guideline, early\n"
1229 "# elementary kids might feel comfortable around 0.2-0.3, older kids\n"
1230 "# at around 0.4-0.6. Default 0.35.\n");
1231 }
1232 fprintf(fp, "danger_level = %f\n", game_options->danger_level);
1233
1234 if(verbose)
1235 {
1236 fprintf (fp, "\n# (Feedback) Set danger level speedup.\n"
1237 "# The margin of safety will decrease by this factor each wave.\n"
1238 "# Default 1.1. Note 1 = no increase in danger level.\n");
1239 }
1240 fprintf(fp, "danger_level_speedup = %f\n", game_options->danger_level_speedup);
1241
1242 if(verbose)
1243 {
1244 fprintf (fp, "\n# (Feedback) Set the maximum danger level.\n"
1245 "# Default 0.9.\n");
1246 }
1247 fprintf(fp, "danger_level_max = %f\n", game_options->danger_level_max);
1248
1249 if (verbose)
1250 {
1251 fprintf (fp, "\n# (Feedback) Set the handicap for hitting cities.\n"
1252 "# When bigger than 0, this causes the game to slow down\n"
1253 "# by an extra amount after a wave in which one or more\n"
1254 "# cities get hit. Note that this is similar to slow_after_wrong,\n"
1255 "# but allows for more gradual changes.\n"
1256 "# Default 0 (no extra handicap).\n");
1257 }
1258 fprintf(fp, "city_explode_handicap = %f\n", game_options->city_expl_handicap);
1259
1260 /*
1261 fprintf(fp, "num_cities = %d\n", game_options->num_cities);
1262 fprintf(fp, "num_bkgds = %d\n", game_options->num_bkgds);
1263 fprintf(fp, "max_city_colors = %d\n", game_options->max_city_colors);
1264 */
1265 }
1266