1 /*
2  * This file is part of TONG.              http://www.nongnu.org/tong
3  * Copyright 2004, 2007 Owen Swerkstrom
4  *
5  * TONG is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * Tong is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "option.h"
20 
Option()21 Option::Option() {
22 	char* path=getenv("HOME");
23 #ifdef GP2X
24 	path = NULL;
25 #endif
26 	//  DIR* musicdir;
27 	//  dirent* musicfile;
28 	int i, j;
29 
30 	for(i=0; i<SCORE_TYPES; i++) {
31 		for(j=0; j<10; j++) {
32 			if(i==SCORE_MARATHON) {
33 				highscores[i][j]=0;
34 			} else {
35 				highscores[i][j]=-9999999;
36 			}
37 			switch(j) {
38 			case 0:
39 				strcpy(highscorenames[i][j], "TONG!");
40 				break;
41 			case 1:
42 				strcpy(highscorenames[i][j], "v1.3");
43 				break;
44 			case 2:
45 				strcpy(highscorenames[i][j], "2014");
46 				break;
47 			case 3:
48 				strcpy(highscorenames[i][j], "Owen");
49 				break;
50 			case 4:
51 				strcpy(highscorenames[i][j], "Swerk");
52 				break;
53 			case 5:
54 				strcpy(highscorenames[i][j], "strom");
55 				break;
56 			case 6:
57 				strcpy(highscorenames[i][j], "pend-");
58 				break;
59 			case 7:
60 				strcpy(highscorenames[i][j], "-uin-");
61 				break;
62 			case 8:
63 				strcpy(highscorenames[i][j], "-bits");
64 				break;
65 			case 9:
66 			default:
67 				strcpy(highscorenames[i][j], " :^)");
68 				break;
69 			}
70 		}
71 	}
72 	strcpy(highscoretext, "  High Scores");
73 	if(path) {
74 		configfile=new char[strlen(path)+strlen(CONFIG_FILENAME)+2];
75 		configfile[0]='\0';
76 		strcat(configfile, path);
77 		strcat(configfile, "/");
78 		strcat(configfile, CONFIG_FILENAME);
79 	} else {
80 		configfile=new char[strlen(CONFIG_FILENAME)+1];
81 		strcpy(configfile, CONFIG_FILENAME);
82 	}
83 
84 	optionmenu=new Menu();
85 	optionmenu->SetPos(112 / POSRATIO, 80 / POSRATIO);
86 	optionmenu->AddChoice("Full Screen       = ?", NORMAL);
87 	optionmenu->AddChoice("Color Depth       = ?", NORMAL);
88 	optionmenu->AddChoice("Frames/Sec Limit  = ?", NORMAL);
89 	optionmenu->AddChoice("Background Scroll = ?", NORMAL);
90 	optionmenu->AddChoice("Audio Buffers     = ?", NORMAL);
91 	optionmenu->AddChoice("Audio Frequency   = ?", NORMAL);
92 	optionmenu->AddChoice("Sound Effects     = ?", NORMAL);
93 	optionmenu->AddChoice("Background Music...", NORMAL);
94 	optionmenu->AddChoice("Graphical Theme...", NORMAL);
95 	optionmenu->AddChoice("Back to Main Menu", NORMAL);
96 
97 	custommenu=new Menu();
98 	custommenu->SetPos(48 / POSRATIO, 48 / POSRATIO);
99 	custommenu->AddChoice("Difficulty Level        = ??????", NORMAL);
100 	custommenu->AddChoice("Pong Paddle Placement   = ?", NORMAL);
101 	custommenu->AddChoice("Pong Paddle Size        = ?", NORMAL);
102 	custommenu->AddChoice("Tetris Pieces Speed Up  = ?", NORMAL);
103 	custommenu->AddChoice("Pong Ball Speeds Up     = ?", NORMAL);
104 	custommenu->AddChoice("Begin with Random Rules = ?", NORMAL);
105 	custommenu->AddChoice("New Rules Every         = ?", NORMAL);
106 	custommenu->AddChoice("Speed                   = ?", NORMAL);
107 	custommenu->AddChoice("Begin with Stack Junk   = ?", NORMAL);
108 	custommenu->AddChoice("Allowed Ball+Tetrad Reactions...  ", NORMAL);
109 	custommenu->AddChoice("Allowed Ball+Stack  Reactions...  ", NORMAL);
110 	custommenu->AddChoice("Back to Main Menu", NORMAL);
111 
112 	ballstackmenu=new Menu();
113 	ballstackmenu->SetPos(144 / POSRATIO, 96 / POSRATIO);
114 	ballstackmenu->AddChoice("No Reaction      = ?", NORMAL);
115 	ballstackmenu->AddChoice("Kill Ball        = ?", NORMAL);
116 	ballstackmenu->AddChoice("Bounce Ball      = ?", NORMAL);
117 	ballstackmenu->AddChoice("Join Together    = ?", NORMAL);
118 	ballstackmenu->AddChoice("Kill Stack       = ?", NORMAL);
119 	ballstackmenu->AddChoice("Break Stack      = ?", NORMAL);
120 	ballstackmenu->AddChoice("Break a Line     = ?", NORMAL);
121 	ballstackmenu->AddChoice("Back to Rules Menu", NORMAL);
122 
123 	balltetradmenu=new Menu();
124 	balltetradmenu->SetPos(144 / POSRATIO, 64 / POSRATIO);
125 	balltetradmenu->AddChoice("No Reaction      = ?", NORMAL);
126 	balltetradmenu->AddChoice("Kill Ball        = ?", NORMAL);
127 	balltetradmenu->AddChoice("Bounce Ball      = ?", NORMAL);
128 	balltetradmenu->AddChoice("Kill Tetrad      = ?", NORMAL);
129 	balltetradmenu->AddChoice("Join Together    = ?", NORMAL);
130 	balltetradmenu->AddChoice("Break Tetrad     = ?", NORMAL);
131 	balltetradmenu->AddChoice("Drop Tetrad      = ?", NORMAL);
132 	balltetradmenu->AddChoice("Push Tetrad      = ?", NORMAL);
133 	balltetradmenu->AddChoice("Rotate Tetrad    = ?", NORMAL);
134 	balltetradmenu->AddChoice("Back to Rules Menu", NORMAL);
135 
136 	musicmenu=new Menu();
137 	musicmenu->SetPos(80 / POSRATIO, 32 / POSRATIO);
138 	musicmenu->AddChoice("None", NORMAL);
139 	musicmenu->AddChoice("Shuffle", NORMAL);
140 	musicmenu->AddChoice("TONG Theme by Marcus Hirt", NORMAL);
141 	musicmenu->AddChoice("Beta Beat", NORMAL);
142 	musicmenu->AddChoice("Stuck in a Mailbox", NORMAL);
143 	musicmenu->AddChoice("The Diplomat", NORMAL);
144 	musicmenu->AddChoice("Fanfare for the Common Rabbit", NORMAL);
145 	musicmenu->AddChoice("Beyond 2000", NORMAL);
146 	musicmenu->AddChoice("Donkey Rhubarb", NORMAL);
147 	musicmenu->AddChoice("Flock", NORMAL);
148 	musicmenu->AddChoice("One-liner", NORMAL);
149 	musicmenu->AddChoice("Reach Reach", NORMAL);
150 	musicmenu->AddChoice("Squib", NORMAL);
151 
152 	controlmenu=new Menu();
153 	controlmenu->SetPos(64 / POSRATIO, 112 / POSRATIO);
154 	controlmenu->AddChoice("Reset to Defaults              ", NORMAL);
155 	controlmenu->AddChoice("Tetrad Move Left  = ?", NORMAL);
156 	controlmenu->AddChoice("Tetrad Move Right = ?", NORMAL);
157 	controlmenu->AddChoice("Tetrad Move Down  = ?", NORMAL);
158 	controlmenu->AddChoice("Tetrad Rotate CW  = ?", NORMAL);
159 	controlmenu->AddChoice("Tetrad Rotate CCW = ?", NORMAL);
160 	controlmenu->AddChoice("Paddle Movement   = Mouse", DISABLED);
161 	controlmenu->AddChoice("Back to Main Menu", NORMAL);
162 	controlmenu->SetActive(true);
163 
164 	thememenu=new Menu();
165 	thememenu->SetPos(256 / POSRATIO, 192 / POSRATIO);
166 	thememenu->AddChoice("Default", NORMAL);
167 	thememenu->AddChoice("Shiny", NORMAL);
168 	thememenu->AddChoice("X-Mas", NORMAL);
169 	thememenu->AddChoice("8-Bit", NORMAL);
170 	thememenu->AddChoice("Space", NORMAL);
171 	thememenu->AddChoice("Clean", NORMAL);
172 
173 	SetMusic(MUSIC_SHUFFLE);
174 	SetSoundFx(true);
175 	SetLevel(LEVEL_NORMAL);
176 	SetTheme(THEME_DEFAULT);
177 	SetBgScroll(true);
178 
179 	SetVideoFlags(0
180 #ifndef GP2X
181 				  |SDL_DOUBLEBUF
182 				  |SDL_RLEACCEL
183 #endif
184 				  //|SDL_ANYFORMAT //this usually makes win32 fullscreen slow
185 				  //|SDL_FULLSCREEN //eh, let's not default to it.
186 				  );
187 #if defined GP2X || WII
188 	SetVideoBpp(16); //16, 24, 32
189 	SetAudioFreq(22050); //22050, 44100
190 #else
191 	SetVideoBpp(24); //16, 24, 32
192 	SetFpsLimit(FPS_60);
193 	SetAudioFreq(44100); //22050, 44100
194 #endif
195 	SetAudioBuffers(512); //512, 1024, 2048, 4096
196 
197 	DefaultRules();
198 	DefaultSettings();
199 	DefaultControls();
200 	SetStart();
201 }
202 
~Option()203 Option::~Option() {
204 	delete optionmenu;
205 	delete custommenu;
206 	delete ballstackmenu;
207 	delete balltetradmenu;
208 	delete musicmenu;
209 	delete controlmenu;
210 	delete thememenu;
211 }
212 
InsertScore(long int score,char * name,int type)213 bool Option::InsertScore(long int score, char* name, int type) {
214 	int i;
215 	long int bumpedscore=0, tempscore=0;
216 	char bumpedname[6]="\0", tempname[6]="\0";
217 	bool inserted=false;
218 	for(i=0; i<10; i++) {
219 		if(inserted) {
220 			tempscore=highscores[type][i];
221 			strcpy(tempname, highscorenames[type][i]);
222 			highscores[type][i]=bumpedscore;
223 			strcpy(highscorenames[type][i], bumpedname);
224 			bumpedscore=tempscore;
225 			strcpy(bumpedname, tempname);
226 		} else if(score>highscores[type][i]) {
227 			bumpedscore=highscores[type][i];
228 			strcpy(bumpedname, highscorenames[type][i]);
229 			highscores[type][i]=score;
230 			strcpy(highscorenames[type][i], name);
231 			inserted=true;
232 		}
233 	}
234 	return inserted;
235 }
236 
GetHighScore(int type,int pos)237 long int Option::GetHighScore(int type, int pos) {
238 	return highscores[type][pos];
239 }
240 
GetHighScoreText(int type)241 const char* Option::GetHighScoreText(int type) {
242 	int i;
243 	char tempstring[20];
244 	strcpy(highscoretext, "  High Scores\n");
245 	switch(type) {
246 	case SCORE_MARATHON:
247 		strcat(highscoretext, " Marathon Mode\n");
248 		break;
249 	case SCORE_2_MIN:
250 		strcat(highscoretext, " 2 Minute Mode\n");
251 		break;
252 	case SCORE_5_MIN:
253 		strcat(highscoretext, " 5 Minute Mode\n");
254 		break;
255 	case SCORE_10_MIN:
256 	default:
257 		strcat(highscoretext, "10 Minute  Mode\n");
258 		break;
259 	}
260 	strcat(highscoretext, "\n");
261 	for(i=0; i<10; i++) {
262 		sprintf(tempstring, "%08li  %s\n",
263 				highscores[type][i], highscorenames[type][i]);
264 		strcat(highscoretext, tempstring);
265 	}
266 	return highscoretext;
267 }
268 
DefaultRules()269 void Option::DefaultRules() {
270 	ruleballstack=BALL_BREAKS_STACK;
271 	ruleballtetrad=BALL_MOVES_TETRAD;
272 	rulestackball=STACK_BOUNCES_BALL;
273 	ruletetradball=TETRAD_BOUNCES_BALL;
274 
275 	AllowRule(NO_REACTION|RULETYPE_BALLSTACK);
276 	AllowRule(NO_REACTION|RULETYPE_STACKBALL);
277 	AllowRule(STACK_KILLS_BALL|RULETYPE_STACKBALL);
278 	AllowRule(STACK_BOUNCES_BALL|RULETYPE_STACKBALL);
279 	AllowRule(BALL_JOINS_STACK|RULETYPE_BALLSTACK);
280 	DenyRule(BALL_KILLS_STACK|RULETYPE_BALLSTACK);
281 	AllowRule(BALL_BREAKS_STACK|RULETYPE_BALLSTACK);
282 	AllowRule(BALL_LINEBREAK_STACK|RULETYPE_BALLSTACK);
283 
284 	AllowRule(NO_REACTION|RULETYPE_BALLTETRAD);
285 	AllowRule(NO_REACTION|RULETYPE_TETRADBALL);
286 	AllowRule(TETRAD_KILLS_BALL|RULETYPE_TETRADBALL);
287 	AllowRule(TETRAD_BOUNCES_BALL|RULETYPE_TETRADBALL);
288 	AllowRule(BALL_JOINS_TETRAD|RULETYPE_BALLTETRAD);
289 	AllowRule(BALL_BREAKS_TETRAD|RULETYPE_BALLTETRAD);
290 	AllowRule(BALL_KILLS_TETRAD|RULETYPE_BALLTETRAD);
291 	AllowRule(BALL_DROPS_TETRAD|RULETYPE_BALLTETRAD);
292 	AllowRule(BALL_MOVES_TETRAD|RULETYPE_BALLTETRAD);
293 	AllowRule(BALL_ROTATES_TETRAD|RULETYPE_BALLTETRAD);
294 
295 	strcpy(ruletext, "Default rules");
296 	return;
297 }
298 
DefaultSettings()299 void Option::DefaultSettings() {
300 	SetMarathon(true);
301 	SetSpeed(SPEED_NORMAL);
302 	SetPadPlacement(PADS_ALL);
303 	SetPadSize(PADS_NORMAL);
304 	SetJunk(JUNK_NONE);
305 	SetTetSpeedUp(true);
306 	SetBallSpeedsUp(true);
307 	SetRandomRule(false);
308 	SetRuleFrequency(EVERY_0_30);
309 
310 	return;
311 }
312 
DefaultControls()313 void Option::DefaultControls() {
314 	mapkeys[KEY_TETLEFT]=SDLK_LEFT;
315 	mapkeys[KEY_TETRIGHT]=SDLK_RIGHT;
316 	mapkeys[KEY_TETDOWN]=SDLK_DOWN;
317 	mapkeys[KEY_TETCW]=SDLK_UP;
318 	mapkeys[KEY_TETCCW]=SDLK_SPACE;
319 	settingkey=-1;
320 	UpdateKeys();
321 	return;
322 }
323 
SetStart()324 void Option::SetStart() {
325 	int i;
326 
327 	//set each rule to first available, try to skip 0==no reaction
328 	for(i=0; i<BALL_STACK_RULES; i++) {
329 		if(allowballstack[i]) {
330 			ruleballstack=i;
331 			if(i>0) {
332 				break;
333 			}
334 		}
335 	}
336 	for(i=0; i<BALL_TETRAD_RULES; i++) {
337 		if(allowballtetrad[i]) {
338 			ruleballtetrad=i;
339 			if(i>0) {
340 				break;
341 			}
342 		}
343 	}
344 	for(i=0; i<STACK_BALL_RULES; i++) {
345 		if(allowstackball[i]) {
346 			rulestackball=i;
347 			if(i>0) {
348 				break;
349 			}
350 		}
351 	}
352 	for(i=0; i<TETRAD_BALL_RULES; i++) {
353 		if(allowtetradball[i]) {
354 			ruletetradball=i;
355 			if(i>0) {
356 				break;
357 			}
358 		}
359 	}
360 	for(i=0; i<10; i++) {
361 		NewRule();
362 	}
363 
364 	return;
365 }
366 
367 //FIXME: obsolete?
Reset()368 void Option::Reset() {
369 	printf("option::reset is obsolete...\n");
370 	ruleballstack=startballstack;
371 	ruleballtetrad=startballtetrad;
372 	rulestackball=startstackball;
373 	ruletetradball=starttetradball;
374 	return;
375 }
376 
377 //allow a rule, which is a specific rule OR'd with a ruletype
AllowRule(int whichrule)378 void Option::AllowRule(int whichrule) {
379 	if((whichrule & RULETYPE_BALLSTACK) &&
380 	   (whichrule & RULETYPE_MASK) < BALL_STACK_RULES) {
381 		allowballstack[whichrule & RULETYPE_MASK]=true;
382 		switch(whichrule & RULETYPE_MASK) {
383 		case NO_REACTION:
384 			ballstackmenu->ModChoice("No Reaction      = ON", 1);
385 			break;
386 		case BALL_JOINS_STACK:
387 			ballstackmenu->ModChoice("Join Together    = ON", 4);
388 			break;
389 		case BALL_KILLS_STACK:
390 			ballstackmenu->ModChoice("Kill Stack       = ON", 5);
391 			break;
392 		case BALL_BREAKS_STACK:
393 			ballstackmenu->ModChoice("Break Stack      = ON", 6);
394 			break;
395 		case BALL_LINEBREAK_STACK:
396 			ballstackmenu->ModChoice("Break a Line     = ON", 7);
397 			break;
398 		default:
399 			break;
400 		}
401 	} else if((whichrule & RULETYPE_BALLTETRAD) &&
402 			  (whichrule & RULETYPE_MASK) < BALL_TETRAD_RULES) {
403 		allowballtetrad[whichrule & RULETYPE_MASK]=true;
404 		switch(whichrule & RULETYPE_MASK) {
405 		case NO_REACTION:
406 			balltetradmenu->ModChoice("No Reaction      = ON", 1);
407 			break;
408 		case BALL_KILLS_TETRAD:
409 			balltetradmenu->ModChoice("Kill Tetrad      = ON", 4);
410 			break;
411 		case BALL_JOINS_TETRAD:
412 			balltetradmenu->ModChoice("Join Together    = ON", 5);
413 			break;
414 		case BALL_BREAKS_TETRAD:
415 			balltetradmenu->ModChoice("Break Tetrad     = ON", 6);
416 			break;
417 		case BALL_DROPS_TETRAD:
418 			balltetradmenu->ModChoice("Drop Tetrad      = ON", 7);
419 			break;
420 		case BALL_MOVES_TETRAD:
421 			balltetradmenu->ModChoice("Push Tetrad      = ON", 8);
422 			break;
423 		case BALL_ROTATES_TETRAD:
424 			balltetradmenu->ModChoice("Rotate Tetrad    = ON", 9);
425 			break;
426 		default:
427 			break;
428 		}
429 	} else if((whichrule & RULETYPE_STACKBALL) &&
430 			  (whichrule & RULETYPE_MASK) < STACK_BALL_RULES) {
431 		allowstackball[whichrule & RULETYPE_MASK]=true;
432 		switch(whichrule & RULETYPE_MASK) {
433 		case NO_REACTION:
434 			ballstackmenu->ModChoice("No Reaction      = ON", 1);
435 			break;
436 		case STACK_KILLS_BALL:
437 			ballstackmenu->ModChoice("Kill Ball        = ON", 2);
438 			break;
439 		case STACK_BOUNCES_BALL:
440 			ballstackmenu->ModChoice("Bounce Ball      = ON", 3);
441 			break;
442 		default:
443 			break;
444 		}
445 	} else if((whichrule & RULETYPE_TETRADBALL) &&
446 			  (whichrule & RULETYPE_MASK) < TETRAD_BALL_RULES) {
447 		allowtetradball[whichrule & RULETYPE_MASK]=true;
448 		switch(whichrule & RULETYPE_MASK) {
449 		case NO_REACTION:
450 			balltetradmenu->ModChoice("No Reaction      = ON", 1);
451 			break;
452 		case TETRAD_KILLS_BALL:
453 			balltetradmenu->ModChoice("Kill Ball        = ON", 2);
454 			break;
455 		case TETRAD_BOUNCES_BALL:
456 			balltetradmenu->ModChoice("Bounce Ball      = ON", 3);
457 			break;
458 		default:
459 			break;
460 		}
461 	}
462 	SetStart();
463 	return;
464 }
465 
DenyRule(int whichrule)466 void Option::DenyRule(int whichrule) {
467 	if((whichrule & RULETYPE_BALLSTACK) &&
468 	   (whichrule & RULETYPE_MASK) < BALL_STACK_RULES) {
469 		allowballstack[whichrule & RULETYPE_MASK]=false;
470 		switch(whichrule & RULETYPE_MASK) {
471 		case NO_REACTION:
472 			ballstackmenu->ModChoice("No Reaction      = OFF", 1);
473 			break;
474 		case BALL_JOINS_STACK:
475 			ballstackmenu->ModChoice("Join Together    = OFF", 4);
476 			break;
477 		case BALL_KILLS_STACK:
478 			ballstackmenu->ModChoice("Kill Stack       = OFF", 5);
479 			break;
480 		case BALL_BREAKS_STACK:
481 			ballstackmenu->ModChoice("Break Stack      = OFF", 6);
482 			break;
483 		case BALL_LINEBREAK_STACK:
484 			ballstackmenu->ModChoice("Break a Line     = OFF", 7);
485 			break;
486 		default:
487 			break;
488 		}
489 	} else if((whichrule & RULETYPE_BALLTETRAD) &&
490 			  (whichrule & RULETYPE_MASK) < BALL_TETRAD_RULES) {
491 		allowballtetrad[whichrule & RULETYPE_MASK]=false;
492 		switch(whichrule & RULETYPE_MASK) {
493 		case NO_REACTION:
494 			balltetradmenu->ModChoice("No Reaction      = OFF", 1);
495 			break;
496 		case BALL_KILLS_TETRAD:
497 			balltetradmenu->ModChoice("Kill Tetrad      = OFF", 4);
498 			break;
499 		case BALL_JOINS_TETRAD:
500 			balltetradmenu->ModChoice("Join Together    = OFF", 5);
501 			break;
502 		case BALL_BREAKS_TETRAD:
503 			balltetradmenu->ModChoice("Break Tetrad     = OFF", 6);
504 			break;
505 		case BALL_DROPS_TETRAD:
506 			balltetradmenu->ModChoice("Drop Tetrad      = OFF", 7);
507 			break;
508 		case BALL_MOVES_TETRAD:
509 			balltetradmenu->ModChoice("Push Tetrad      = OFF", 8);
510 			break;
511 		case BALL_ROTATES_TETRAD:
512 			balltetradmenu->ModChoice("Rotate Tetrad    = OFF", 9);
513 			break;
514 		default:
515 			break;
516 		}
517 	} else if((whichrule & RULETYPE_STACKBALL) &&
518 			  (whichrule & RULETYPE_MASK) < STACK_BALL_RULES) {
519 		allowstackball[whichrule & RULETYPE_MASK]=false;
520 		switch(whichrule & RULETYPE_MASK) {
521 		case NO_REACTION:
522 			ballstackmenu->ModChoice("No Reaction      = OFF", 1);
523 			break;
524 		case STACK_KILLS_BALL:
525 			ballstackmenu->ModChoice("Kill Ball        = OFF", 2);
526 			break;
527 		case STACK_BOUNCES_BALL:
528 			ballstackmenu->ModChoice("Bounce Ball      = OFF", 3);
529 			break;
530 		default:
531 			break;
532 		}
533 	} else if((whichrule & RULETYPE_TETRADBALL) &&
534 			  (whichrule & RULETYPE_MASK) < TETRAD_BALL_RULES) {
535 		allowtetradball[whichrule & RULETYPE_MASK]=false;
536 		switch(whichrule & RULETYPE_MASK) {
537 		case NO_REACTION:
538 			balltetradmenu->ModChoice("No Reaction      = OFF", 1);
539 			break;
540 		case TETRAD_KILLS_BALL:
541 			balltetradmenu->ModChoice("Kill Ball        = OFF", 2);
542 			break;
543 		case TETRAD_BOUNCES_BALL:
544 			balltetradmenu->ModChoice("Bounce Ball      = OFF", 3);
545 			break;
546 		default:
547 			break;
548 		}
549 	}
550 	SetStart();
551 	return;
552 }
553 
IsAllowed(int whichrule)554 bool Option::IsAllowed(int whichrule) {
555 	bool isallowed=false;
556 	if((whichrule & RULETYPE_BALLSTACK) &&
557 	   (whichrule & RULETYPE_MASK) < BALL_STACK_RULES) {
558 		isallowed=allowballstack[whichrule & RULETYPE_MASK];
559 	} else if((whichrule & RULETYPE_BALLTETRAD) &&
560 			  (whichrule & RULETYPE_MASK) < BALL_TETRAD_RULES) {
561 		isallowed=allowballtetrad[whichrule & RULETYPE_MASK];
562 	} else if((whichrule & RULETYPE_STACKBALL) &&
563 			  (whichrule & RULETYPE_MASK) < STACK_BALL_RULES) {
564 		isallowed=allowstackball[whichrule & RULETYPE_MASK];
565 	} else if((whichrule & RULETYPE_TETRADBALL) &&
566 			  (whichrule & RULETYPE_MASK) < TETRAD_BALL_RULES) {
567 		isallowed=allowtetradball[whichrule & RULETYPE_MASK];
568 	}
569 	//  printf("is %d allowed? %d\n", whichrule, isallowed);
570 	return isallowed;
571 }
572 
ReadConfig()573 bool Option::ReadConfig() {
574 	char key[80];
575 	int value;
576 	char val2[80];
577 	int matches;
578 	bool success=false;
579 	FILE *config=fopen(configfile, "r");
580 	if(config) {
581 		success=true;
582 		matches=fscanf(config, "%79s = %d : %5s\n", key, &value, val2);
583 		while(matches==2 || matches==3) {
584 			if(!strcmp(key, "fullscreen")) {
585 				if(value==0) {
586 					SetVideoFlags(videoflags&(videoflags^SDL_FULLSCREEN));
587 				} else {
588 					SetVideoFlags(videoflags|SDL_FULLSCREEN);
589 				}
590 			} else if(!strcmp(key, "theme")) {
591 				if(value>=THEME_DEFAULT && value<=THEME_LAST) {
592 					SetTheme(value);
593 				}
594 			} else if(!strcmp(key, "bgscroll")) {
595 				if(value==0) {
596 					SetBgScroll(false);
597 				} else {
598 					SetBgScroll(true);
599 				}
600 			} else if(!strcmp(key, "music")) {
601 				if(value>=MUSIC_NONE && value<=MUSIC_LAST) {
602 					SetMusic(value);
603 				}
604 			} else if(!strcmp(key, "soundfx")) {
605 				if(value==0) {
606 					SetSoundFx(false);
607 				} else {
608 					SetSoundFx(true);
609 				}
610 			} else if(!strcmp(key, "marathon")) {
611 				if(value==0) {
612 					SetMarathon(false);
613 				} else {
614 					SetMarathon(true);
615 				}
616 			} else if(!strcmp(key, "level")) {
617 				if(value>=LEVEL_EASY && value<=LEVEL_CUSTOM) {
618 					SetLevel(value);
619 				}
620 			} else if(!strcmp(key, "speed")) {
621 				if(value>=SPEED_SLOW && value<=SPEED_FAST) {
622 					SetSpeed(value);
623 				}
624 			} else if(!strcmp(key, "junk")) {
625 				if(value==JUNK_NONE || value==JUNK_2 ||
626 				   value==JUNK_4 || value==JUNK_6) {
627 					SetJunk(value);
628 				}
629 			} else if(!strcmp(key, "padplacement")) {
630 				if(value==PADS_ALL || value==PADS_SIDES || value==PADS_TOPBOT) {
631 					SetPadPlacement(value);
632 				}
633 			} else if(!strcmp(key, "padsize")) {
634 				if(value>=PADS_SMALL && value<=PADS_12) {
635 					SetPadSize(value);
636 				}
637 			} else if(!strcmp(key, "tetspeedup")) {
638 				SetTetSpeedUp(value!=0);
639 			} else if(!strcmp(key, "ballspeedsup")) {
640 				SetBallSpeedsUp(value!=0);
641 			} else if(!strcmp(key, "randomrule")) {
642 				SetRandomRule(value!=0);
643 			} else if(!strcmp(key, "rulefrequency")) {
644 				if(value>=EVERY_0_15 && value<=EVERY_5_LINES) {
645 					SetRuleFrequency(value);
646 				}
647 			} else if(!strcmp(key, "videobpp")) {
648 				if(value==16 || value==24 || value==32) {
649 					SetVideoBpp(value);
650 				}
651 			} else if(!strcmp(key, "fpslimit")) {
652 				if(value==FPS_UNLIMITED || value==FPS_120 || value==FPS_60 ||
653 				   value==FPS_30 || value==FPS_24) {
654 					SetFpsLimit(value);
655 				}
656 			} else if(!strcmp(key, "audiobuffers")) {
657 				if(value==512 || value==1024 || value==2048 || value==4096) {
658 					SetAudioBuffers(value);
659 				}
660 			} else if(!strcmp(key, "audiofreq")) {
661 				if(value==22050 || value==44100) {
662 					SetAudioFreq(value);
663 				}
664 			} else if(!strcmp(key, "keytetleft")) {
665 				mapkeys[KEY_TETLEFT]=(SDLKey)value;
666 			} else if(!strcmp(key, "keytetright")) {
667 				mapkeys[KEY_TETRIGHT]=(SDLKey)value;
668 			} else if(!strcmp(key, "keytetdown")) {
669 				mapkeys[KEY_TETDOWN]=(SDLKey)value;
670 			} else if(!strcmp(key, "keytetcw")) {
671 				mapkeys[KEY_TETCW]=(SDLKey)value;
672 			} else if(!strcmp(key, "keytetccw")) {
673 				mapkeys[KEY_TETCCW]=(SDLKey)value;
674 			} else if(!strcmp(key, "ballstacknone")) {
675 				if(value) {
676 					AllowRule(NO_REACTION|RULETYPE_BALLSTACK);
677 					AllowRule(NO_REACTION|RULETYPE_STACKBALL);
678 				} else {
679 					DenyRule(NO_REACTION|RULETYPE_BALLSTACK);
680 					DenyRule(NO_REACTION|RULETYPE_STACKBALL);
681 				}
682 			} else if(!strcmp(key, "stackkillsball")) {
683 				if(value) {
684 					AllowRule(STACK_KILLS_BALL|RULETYPE_STACKBALL);
685 				} else {
686 					DenyRule(STACK_KILLS_BALL|RULETYPE_STACKBALL);
687 				}
688 			} else if(!strcmp(key, "stackbouncesball")) {
689 				if(value) {
690 					AllowRule(STACK_BOUNCES_BALL|RULETYPE_STACKBALL);
691 				} else {
692 					DenyRule(STACK_BOUNCES_BALL|RULETYPE_STACKBALL);
693 				}
694 			} else if(!strcmp(key, "balljoinsstack")) {
695 				if(value) {
696 					AllowRule(BALL_JOINS_STACK|RULETYPE_BALLSTACK);
697 				} else {
698 					DenyRule(BALL_JOINS_STACK|RULETYPE_BALLSTACK);
699 				}
700 			} else if(!strcmp(key, "ballkillsstack")) {
701 				if(value) {
702 					AllowRule(BALL_KILLS_STACK|RULETYPE_BALLSTACK);
703 				} else {
704 					DenyRule(BALL_KILLS_STACK|RULETYPE_BALLSTACK);
705 				}
706 			} else if(!strcmp(key, "ballbreaksstack")) {
707 				if(value) {
708 					AllowRule(BALL_BREAKS_STACK|RULETYPE_BALLSTACK);
709 				} else {
710 					DenyRule(BALL_BREAKS_STACK|RULETYPE_BALLSTACK);
711 				}
712 			} else if(!strcmp(key, "balllinebreakstack")) {
713 				if(value) {
714 					AllowRule(BALL_LINEBREAK_STACK|RULETYPE_BALLSTACK);
715 				} else {
716 					DenyRule(BALL_LINEBREAK_STACK|RULETYPE_BALLSTACK);
717 				}
718 			} else if(!strcmp(key, "balltetradnone")) {
719 				if(value) {
720 					AllowRule(NO_REACTION|RULETYPE_BALLTETRAD);
721 					AllowRule(NO_REACTION|RULETYPE_TETRADBALL);
722 				} else {
723 					DenyRule(NO_REACTION|RULETYPE_BALLTETRAD);
724 					DenyRule(NO_REACTION|RULETYPE_TETRADBALL);
725 				}
726 			} else if(!strcmp(key, "tetradkillsball")) {
727 				if(value) {
728 					AllowRule(TETRAD_KILLS_BALL|RULETYPE_TETRADBALL);
729 				} else {
730 					DenyRule(TETRAD_KILLS_BALL|RULETYPE_TETRADBALL);
731 				}
732 			} else if(!strcmp(key, "tetradbouncesball")) {
733 				if(value) {
734 					AllowRule(TETRAD_BOUNCES_BALL|RULETYPE_TETRADBALL);
735 				} else {
736 					DenyRule(TETRAD_BOUNCES_BALL|RULETYPE_TETRADBALL);
737 				}
738 			} else if(!strcmp(key, "balljoinstetrad")) {
739 				if(value) {
740 					AllowRule(BALL_JOINS_TETRAD|RULETYPE_BALLTETRAD);
741 				} else {
742 					DenyRule(BALL_JOINS_TETRAD|RULETYPE_BALLTETRAD);
743 				}
744 			} else if(!strcmp(key, "ballbreakstetrad")) {
745 				if(value) {
746 					AllowRule(BALL_BREAKS_TETRAD|RULETYPE_BALLTETRAD);
747 				} else {
748 					DenyRule(BALL_BREAKS_TETRAD|RULETYPE_BALLTETRAD);
749 				}
750 			} else if(!strcmp(key, "ballkillstetrad")) {
751 				if(value) {
752 					AllowRule(BALL_KILLS_TETRAD|RULETYPE_BALLTETRAD);
753 				} else {
754 					DenyRule(BALL_KILLS_TETRAD|RULETYPE_BALLTETRAD);
755 				}
756 			} else if(!strcmp(key, "balldropstetrad")) {
757 				if(value) {
758 					AllowRule(BALL_DROPS_TETRAD|RULETYPE_BALLTETRAD);
759 				} else {
760 					DenyRule(BALL_DROPS_TETRAD|RULETYPE_BALLTETRAD);
761 				}
762 			} else if(!strcmp(key, "ballmovestetrad")) {
763 				if(value) {
764 					AllowRule(BALL_MOVES_TETRAD|RULETYPE_BALLTETRAD);
765 				} else {
766 					DenyRule(BALL_MOVES_TETRAD|RULETYPE_BALLTETRAD);
767 				}
768 			} else if(!strcmp(key, "ballrotatestetrad")) {
769 				if(value) {
770 					AllowRule(BALL_ROTATES_TETRAD|RULETYPE_BALLTETRAD);
771 				} else {
772 					DenyRule(BALL_ROTATES_TETRAD|RULETYPE_BALLTETRAD);
773 				}
774 			} else if(!strcmp(key, "scoremarathon")) {
775 				InsertScore(value, val2, SCORE_MARATHON);
776 			} else if(!strcmp(key,  "score2min")) {
777 				InsertScore(value, val2, SCORE_2_MIN);
778 			} else if(!strcmp(key, "score5min")) {
779 				InsertScore(value, val2, SCORE_5_MIN);
780 			} else if(!strcmp(key, "score10min")) {
781 				InsertScore(value, val2, SCORE_10_MIN);
782 			}
783 			matches=fscanf(config, "%79s = %d : %5s\n", key, &value, val2);
784 		}
785 		UpdateKeys();
786 	}
787 	if(config) {
788 		fclose(config);
789 	}
790 	return success;
791 }
792 
WriteConfig()793 bool Option::WriteConfig() {
794 	bool success=false;
795 	int i, j;
796 	FILE *config;
797 
798 	config=fopen(configfile, "w");
799 	if(config) {
800 		fprintf(config, "WARNING:_Edit_this_file_at_your_own_risk! = 0\n");
801 		fprintf(config, "fullscreen = %d\n", videoflags&SDL_FULLSCREEN?1:0);
802 		fprintf(config, "music = %d\n", music);
803 		fprintf(config, "theme = %d\n", theme);
804 		fprintf(config, "bgscroll = %d\n", bgscroll?1:0);
805 		fprintf(config, "soundfx = %d\n", soundfx);
806 		fprintf(config, "marathon = %d\n", marathon);
807 		fprintf(config, "level = %d\n", level);
808 		fprintf(config, "speed = %d\n", speed);
809 		fprintf(config, "junk = %d\n", junk);
810 		fprintf(config, "padplacement = %d\n", padplacement);
811 		fprintf(config, "padsize = %d\n", padsize);
812 		fprintf(config, "tetspeedup = %d\n", tetspeedup);
813 		fprintf(config, "ballspeedsup = %d\n", ballspeedsup);
814 		fprintf(config, "randomrule = %d\n", randomrule);
815 		fprintf(config, "rulefrequency = %d\n", rulefrequency);
816 		fprintf(config, "videobpp = %d\n", videobpp);
817 		fprintf(config, "fpslimit = %d\n", fpslimit);
818 		fprintf(config, "audiobuffers = %d\n", audiobuffers);
819 		fprintf(config, "audiofreq = %d\n", audiofreq);
820 
821 		fprintf(config, "keytetleft = %d\n", (int)mapkeys[KEY_TETLEFT]);
822 		fprintf(config, "keytetright = %d\n", (int)mapkeys[KEY_TETRIGHT]);
823 		fprintf(config, "keytetdown = %d\n", (int)mapkeys[KEY_TETDOWN]);
824 		fprintf(config, "keytetcw = %d\n", (int)mapkeys[KEY_TETCW]);
825 		fprintf(config, "keytetccw = %d\n", (int)mapkeys[KEY_TETCCW]);
826 
827 		fprintf(config, "ballstacknone = %d\n", allowballstack[NO_REACTION]);
828 		fprintf(config, "stackkillsball = %d\n", allowstackball[STACK_KILLS_BALL]);
829 		fprintf(config, "stackbouncesball = %d\n",
830 				allowstackball[STACK_BOUNCES_BALL]);
831 		fprintf(config, "balljoinsstack = %d\n", allowballstack[BALL_JOINS_STACK]);
832 		fprintf(config, "ballkillsstack = %d\n", allowballstack[BALL_KILLS_STACK]);
833 		fprintf(config, "ballbreaksstack = %d\n",
834 				allowballstack[BALL_BREAKS_STACK]);
835 		fprintf(config, "balllinebreakstack = %d\n",
836 				allowballstack[BALL_LINEBREAK_STACK]);
837 
838 		fprintf(config, "balltetradnone = %d\n", allowballtetrad[NO_REACTION]);
839 		fprintf(config, "tetradkillsball = %d\n",
840 				allowtetradball[TETRAD_KILLS_BALL]);
841 		fprintf(config, "tetradbouncesball = %d\n",
842 				allowtetradball[TETRAD_BOUNCES_BALL]);
843 		fprintf(config, "balljoinstetrad = %d\n",
844 				allowballtetrad[BALL_JOINS_TETRAD]);
845 		fprintf(config, "ballbreakstetrad = %d\n",
846 				allowballtetrad[BALL_BREAKS_TETRAD]);
847 		fprintf(config, "ballkillstetrad = %d\n",
848 				allowballtetrad[BALL_KILLS_TETRAD]);
849 		fprintf(config, "balldropstetrad = %d\n",
850 				allowballtetrad[BALL_DROPS_TETRAD]);
851 		fprintf(config, "ballmovestetrad = %d\n",
852 				allowballtetrad[BALL_MOVES_TETRAD]);
853 		fprintf(config, "ballrotatestetrad = %d\n",
854 				allowballtetrad[BALL_ROTATES_TETRAD]);
855 		for(i=0; i<SCORE_TYPES; i++) {
856 			for(j=0; j<10; j++) {
857 				switch(i) {
858 				case SCORE_MARATHON:
859 					fprintf(config, "scoremarathon = %li : %s\n", highscores[i][j],
860 							highscorenames[i][j]);
861 					break;
862 				case SCORE_2_MIN:
863 					fprintf(config, "score2min = %li : %s\n", highscores[i][j],
864 							highscorenames[i][j]);
865 					break;
866 				case SCORE_5_MIN:
867 					fprintf(config, "score5min = %li : %s\n", highscores[i][j],
868 							highscorenames[i][j]);
869 					break;
870 				case SCORE_10_MIN:
871 				default:
872 					fprintf(config, "score10min = %li : %s\n", highscores[i][j],
873 							highscorenames[i][j]);
874 					break;
875 				}
876 			}
877 		}
878 		fclose(config);
879 		success=true;
880 	}
881 	return success;
882 }
883 
SetKey()884 void Option::SetKey() {
885 	settingkey=controlmenu->GetChoice();
886 	controlmenu->SetState(settingkey, HIGHLIGHTED);
887 	return;
888 }
889 
SetKey(SDLKey newkey)890 bool Option::SetKey(SDLKey newkey) {
891 	int i;
892 	bool mapped=true;
893 	for(i=0; i<KEY_TYPES; i++) {
894 		if(i==settingkey-2) { //ok to set a key to the same value
895 			continue;
896 		}
897 		if(mapkeys[i]==newkey) { //swap if they use a duplicate
898 			mapkeys[i]=mapkeys[settingkey-2];
899 			//      mapped=false;
900 		}
901 	}
902 	if(mapped) {
903 		mapkeys[settingkey-2]=newkey;
904 		controlmenu->SetState(settingkey, NORMAL);
905 		settingkey=-1;
906 	}
907 	UpdateKeys();
908 	return mapped;
909 }
910 
GetKey(int which)911 SDLKey Option::GetKey(int which) {
912 	return mapkeys[which];
913 }
914 
IsSettingKey()915 bool Option::IsSettingKey() {
916 	return (settingkey!=-1);
917 }
918 
CancelSetKey()919 void Option::CancelSetKey() {
920 	controlmenu->SetState(settingkey, NORMAL);
921 	UpdateKeys();
922 	settingkey=-1;
923 	return;
924 }
925 
UpdateKeys()926 void Option::UpdateKeys() {
927 	char tempstring[40];
928 	strcpy(tempstring, "Tetrad Move Left  = ");
929 	strcat(tempstring, SDL_GetKeyName(mapkeys[KEY_TETLEFT]));
930 	controlmenu->ModChoice(tempstring, 2);
931 	strcpy(tempstring, "Tetrad Move Right = ");
932 	strcat(tempstring, SDL_GetKeyName(mapkeys[KEY_TETRIGHT]));
933 	controlmenu->ModChoice(tempstring, 3);
934 	strcpy(tempstring, "Tetrad Move Down  = ");
935 	strcat(tempstring, SDL_GetKeyName(mapkeys[KEY_TETDOWN]));
936 	controlmenu->ModChoice(tempstring, 4);
937 	strcpy(tempstring, "Tetrad Rotate CW  = ");
938 	strcat(tempstring, SDL_GetKeyName(mapkeys[KEY_TETCW]));
939 	controlmenu->ModChoice(tempstring, 5);
940 	strcpy(tempstring, "Tetrad Rotate CCW = ");
941 	strcat(tempstring, SDL_GetKeyName(mapkeys[KEY_TETCCW]));
942 	controlmenu->ModChoice(tempstring, 6);
943 	return;
944 }
945 
SetBallSpeedsUp(bool newballspeedsup)946 void Option::SetBallSpeedsUp(bool newballspeedsup) {
947 	ballspeedsup=newballspeedsup;
948 	if(ballspeedsup) {
949 		custommenu->ModChoice("Pong Ball Speeds Up     = YES", 5);
950 	} else {
951 		custommenu->ModChoice("Pong Ball Speeds Up     = NO", 5);
952 	}
953 	return;
954 }
955 
GetBallSpeedsUp()956 bool Option::GetBallSpeedsUp() {
957 	return ballspeedsup;
958 }
959 
GetRuleBallStack()960 int Option::GetRuleBallStack() {
961 	return ruleballstack;
962 }
963 
GetRuleBallTetrad()964 int Option::GetRuleBallTetrad() {
965 	return ruleballtetrad;
966 }
967 
GetRuleStackBall()968 int Option::GetRuleStackBall() {
969 	return rulestackball;
970 }
971 
GetRuleTetradBall()972 int Option::GetRuleTetradBall() {
973 	return ruletetradball;
974 }
975 
GetRuleText()976 const char* Option::GetRuleText() {
977 	return ruletext;
978 }
979 
NewRule()980 void Option::NewRule() {
981 	int random=rand()%4;
982 	int tries=0; //try to change rule but not forever
983 	if(ruleballstack==BALL_KILLS_STACK) {
984 		random=0;          //this rule sucks after too long
985 	}
986 	switch(random) {     //change one of four rule types
987 	case 0:                //change ball/stack rule
988 		random=ruleballstack;
989 		while((random==ruleballstack || !allowballstack[random]) && tries++<10) {
990 			random=rand()%BALL_STACK_RULES;
991 		}
992 		if(tries<10) {
993 			ruleballstack=random;
994 			switch(random) {
995 			case BALL_BREAKS_STACK:
996 				strcpy(ruletext, "Ball breaks stack!");
997 				break;
998 			case BALL_LINEBREAK_STACK:
999 				strcpy(ruletext, "Ball clears line!");
1000 				break;
1001 			case BALL_KILLS_STACK:
1002 				strcpy(ruletext, "Ball kills stack!");
1003 				break;
1004 			case BALL_JOINS_STACK:
1005 				strcpy(ruletext, "Ball joins stack!");
1006 			case NO_REACTION:
1007 			default:
1008 				strcpy(ruletext, "Ball ignores stack!");
1009 				break;
1010 			}
1011 		} else {
1012 			strcpy(ruletext, "Same rules!");
1013 		}
1014 		break;
1015 	case 1:                //change ball/tetrad rule
1016 		random=ruleballtetrad;
1017 		while((random==ruleballtetrad || !allowballtetrad[random]) && tries++<10) {
1018 			random=rand()%BALL_TETRAD_RULES;
1019 		}
1020 		if(tries<10) {
1021 			ruleballtetrad=random;
1022 			switch(random) {
1023 			case BALL_BREAKS_TETRAD:
1024 				strcpy(ruletext, "Ball breaks tetrad!");
1025 				break;
1026 			case BALL_MOVES_TETRAD:
1027 				strcpy(ruletext, "Ball moves tetrad!");
1028 				break;
1029 			case BALL_ROTATES_TETRAD:
1030 				strcpy(ruletext, "Ball rotates tetrad!");
1031 				break;
1032 			case BALL_DROPS_TETRAD:
1033 				strcpy(ruletext, "Ball drops tetrad!");
1034 				break;
1035 			case BALL_KILLS_TETRAD:
1036 				strcpy(ruletext, "Ball kills tetrad!");
1037 				break;
1038 			case BALL_JOINS_TETRAD:
1039 				strcpy(ruletext, "Ball joins tetrad!");
1040 				break;
1041 			case NO_REACTION:
1042 			default:
1043 				strcpy(ruletext, "Ball ignores tetrad!");
1044 				break;
1045 			}
1046 		} else {
1047 			strcpy(ruletext, "Same rules!");
1048 		}
1049 		break;
1050 	case 2:                //change stack/ball rule
1051 		random=rulestackball;
1052 		while((random==rulestackball || !allowstackball[random]) && tries++<10) {
1053 			random=rand()%STACK_BALL_RULES;
1054 		}
1055 		if(tries<10) {
1056 			rulestackball=random;
1057 			if(ruleballstack==BALL_JOINS_STACK) {
1058 				ruleballstack=NO_REACTION;
1059 			}
1060 			switch(random) {
1061 			case STACK_BOUNCES_BALL:
1062 				ruleballstack=NO_REACTION;
1063 				strcpy(ruletext, "Stack bounces ball!");
1064 				break;
1065 			case STACK_KILLS_BALL:
1066 				strcpy(ruletext, "Stack kills ball!");
1067 				break;
1068 			case NO_REACTION:
1069 			default:
1070 				strcpy(ruletext, "Stack Ignores ball!");
1071 				break;
1072 			}
1073 		} else {
1074 			strcpy(ruletext, "Same rules!");
1075 		}
1076 		break;
1077 	case 3:                //change tetrad/ball rule
1078 		random=ruletetradball;
1079 		while((random==ruletetradball || !allowtetradball[random]) && tries++<10) {
1080 			random=rand()%TETRAD_BALL_RULES;
1081 		}
1082 		if(tries<10) {
1083 			ruletetradball=random;
1084 			if(ruleballtetrad==BALL_JOINS_TETRAD) {
1085 				ruleballtetrad=NO_REACTION;
1086 			}
1087 			switch(random) {
1088 			case TETRAD_BOUNCES_BALL:
1089 				ruleballtetrad=NO_REACTION;
1090 				strcpy(ruletext, "Tetrad bounces ball!");
1091 				break;
1092 			case TETRAD_KILLS_BALL:
1093 				strcpy(ruletext, "Tetrad kills ball!");
1094 				break;
1095 			case NO_REACTION:
1096 			default:
1097 				strcpy(ruletext, "Tetrad ignores ball!");
1098 				break;
1099 			}
1100 		} else {
1101 			strcpy(ruletext, "Same rules!");
1102 		}
1103 	default:
1104 		break;
1105 	}
1106 	return;
1107 }
1108 
GetLevel()1109 int Option::GetLevel() {
1110 	return level;
1111 }
1112 
GetJunk()1113 int Option::GetJunk() {
1114 	return junk;
1115 }
1116 
GetPadPlacement()1117 int Option::GetPadPlacement() {
1118 	return padplacement;
1119 }
1120 
GetPadSize()1121 int Option::GetPadSize() {
1122 	return padsize;
1123 }
1124 
GetPadSizeX()1125 int Option::GetPadSizeX() {
1126 	int padsizex;
1127 	if(padplacement==PADS_SIDES) {
1128 		padsizex=10;
1129 	} else {
1130 		switch(padsize) {
1131 		case PADS_BIG:
1132 			padsizex=6;
1133 			break;
1134 		case PADS_SMALL:
1135 			padsizex=2;
1136 			break;
1137 		case PADS_15:
1138 			padsizex=2;
1139 			break;
1140 		case PADS_13:
1141 			padsizex=3;
1142 			break;
1143 		case PADS_NORMAL:
1144 		default:
1145 			padsizex=4;
1146 			break;
1147 		}
1148 	}
1149 	return padsizex;
1150 }
1151 
GetPadSizeY()1152 int Option::GetPadSizeY() {
1153 	int padsizey;
1154 	if(padplacement==PADS_TOPBOT) {
1155 		padsizey=20;
1156 	} else {
1157 		switch(padsize) {
1158 		case PADS_BIG:
1159 			padsizey=6;
1160 			break;
1161 		case PADS_SMALL:
1162 			padsizey=2;
1163 			break;
1164 		case PADS_15:
1165 			padsizey=4;
1166 			break;
1167 		case PADS_13:
1168 			padsizey=6;
1169 			break;
1170 		case PADS_NORMAL:
1171 		default:
1172 			padsizey=4;
1173 			break;
1174 		}
1175 	}
1176 	return padsizey;
1177 }
1178 
GetTetSpeedUp()1179 bool Option::GetTetSpeedUp() {
1180 	return tetspeedup;
1181 }
1182 
GetMusic()1183 int Option::GetMusic() {
1184 	return music;
1185 }
1186 
GetTheme()1187 int Option::GetTheme() {
1188 	return theme;
1189 }
1190 
GetBgScroll()1191 bool Option::GetBgScroll() {
1192 	return bgscroll;
1193 }
1194 
GetThemeString()1195 const char* Option::GetThemeString() {
1196 	switch(theme) {
1197 	case THEME_SHINY:
1198 		return "-shiny";
1199 		break;
1200 	case THEME_XMAS:
1201 		return "-xmas";
1202 		break;
1203 	case THEME_8BIT:
1204 		return "-8bit";
1205 		break;
1206 	case THEME_SPACE:
1207 		return "-space";
1208 		break;
1209 	case THEME_CLEAN:
1210 		return "-clean";
1211 		break;
1212 	case THEME_DEFAULT:
1213 	default:
1214 		return "";
1215 		break;
1216 	}
1217 }
1218 
GetMusicFile()1219 const char* Option::GetMusicFile() {
1220 	int song=music;
1221 	if(music==MUSIC_SHUFFLE) {
1222 		song=(rand()%11)+2;
1223 		curmusic=song;
1224 	}
1225 	switch(song) {
1226 	case MUSIC_TONG:
1227 		return "media/tong.ogg";
1228 		break;
1229 	case MUSIC_I12:
1230 		return "media/i12bpvd.ogg";
1231 		break;
1232 	case MUSIC_STUCK:
1233 		return "media/stuck-in-a-mailbox.ogg";
1234 		break;
1235 	case MUSIC_DIPLOMAT:
1236 		return "media/the-diplomat.ogg";
1237 		break;
1238 	case MUSIC_FANFARE:
1239 		return "media/fanfare.ogg";
1240 		break;
1241 	case MUSIC_BEYOND:
1242 		return "media/beyond2000.ogg";
1243 		break;
1244 	case MUSIC_DONKEY:
1245 		return "media/donkeyrhubarb.ogg";
1246 		break;
1247 	case MUSIC_FLOCK:
1248 		return "media/flock.ogg";
1249 		break;
1250 	case MUSIC_ONELINER:
1251 		return "media/one-liner.ogg";
1252 		break;
1253 	case MUSIC_REACH:
1254 		return "media/reachreach.ogg";
1255 		break;
1256 	case MUSIC_SQUIB:
1257 		return "media/squib.ogg";
1258 		break;
1259 	case MUSIC_SHUFFLE:
1260 		printf("GetMusicFile: shouldn't ever get here...\n");
1261 	case MUSIC_NONE:
1262 	default:
1263 		break;
1264 	}
1265 	return NULL;
1266 }
1267 
GetCurrentMusicFile()1268 const char* Option::GetCurrentMusicFile() {
1269 	if(music==MUSIC_SHUFFLE) {
1270 		music=curmusic;
1271 		strcpy(tempmusic, GetMusicFile());
1272 		music=MUSIC_SHUFFLE;
1273 	} else {
1274 		strcpy(tempmusic, GetMusicFile());
1275 	}
1276 	return (const char*)tempmusic;
1277 }
1278 
GetRandomRule()1279 bool Option::GetRandomRule() {
1280 	return randomrule;
1281 }
1282 
GetRuleFrequency()1283 int Option::GetRuleFrequency() {
1284 	return rulefrequency;
1285 }
1286 
GetVideoFlags()1287 Uint32 Option::GetVideoFlags() {
1288 	return videoflags;
1289 }
1290 
GetVideoBpp()1291 int Option::GetVideoBpp() {
1292 	return videobpp;
1293 }
1294 
GetFpsLimit()1295 int Option::GetFpsLimit() {
1296 	return fpslimit;
1297 }
1298 
GetAudioBuffers()1299 int Option::GetAudioBuffers() {
1300 	return audiobuffers;
1301 }
1302 
GetAudioFreq()1303 int Option::GetAudioFreq() {
1304 	return audiofreq;
1305 }
1306 
GetMarathon()1307 bool Option::GetMarathon() {
1308 	return marathon;
1309 }
1310 
GetSpeed()1311 int Option::GetSpeed() {
1312 	return speed;
1313 }
1314 
GetSpeedTetrad()1315 int Option::GetSpeedTetrad() {
1316 	int tetspeed; //inverted really, number of msecs 'til it drops one space
1317 	switch(speed) {
1318 	case SPEED_SLOW:
1319 		tetspeed=1500;
1320 		break;
1321 	case SPEED_NORMAL:
1322 		tetspeed=1000;
1323 		break;
1324 	case SPEED_FAST:
1325 	default:
1326 		tetspeed=500;
1327 		break;
1328 	}
1329 	return tetspeed;
1330 }
1331 
GetSpeedBall()1332 float Option::GetSpeedBall() {
1333 	float ballspeed;
1334 	switch(speed) {
1335 	case SPEED_SLOW:
1336 		ballspeed=48;
1337 		break;
1338 	case SPEED_NORMAL:
1339 		ballspeed=64;
1340 		break;
1341 	case SPEED_FAST:
1342 	default:
1343 		ballspeed=96;
1344 		break;
1345 	}
1346 	return ballspeed;;
1347 }
1348 
GetSoundFx()1349 bool Option::GetSoundFx() {
1350 	return soundfx;
1351 }
1352 
SetLevel()1353 void Option::SetLevel() {
1354 	if(level>=LEVEL_CUSTOM) {
1355 		SetLevel(LEVEL_EASY);
1356 	} else {
1357 		SetLevel(level+1);
1358 	}
1359 	return;
1360 }
1361 
SetLevel(int newlevel)1362 void Option::SetLevel(int newlevel) {
1363 	level=newlevel;
1364 	switch(level) {
1365 	case LEVEL_EASY:
1366 		SetPadPlacement(PADS_SIDES);
1367 		SetPadSize(PADS_BIG);
1368 		SetTetSpeedUp(false);
1369 		SetBallSpeedsUp(false);
1370 		SetRandomRule(false);
1371 		SetRuleFrequency(EVERY_0_45);
1372 		SetSpeed(SPEED_SLOW);
1373 		SetJunk(JUNK_NONE);
1374 		DenyRule(NO_REACTION|RULETYPE_BALLSTACK);
1375 		DenyRule(NO_REACTION|RULETYPE_STACKBALL);
1376 		AllowRule(STACK_KILLS_BALL|RULETYPE_STACKBALL);
1377 		AllowRule(STACK_BOUNCES_BALL|RULETYPE_STACKBALL);
1378 		DenyRule(BALL_JOINS_STACK|RULETYPE_BALLSTACK);
1379 		DenyRule(BALL_KILLS_STACK|RULETYPE_BALLSTACK);
1380 		AllowRule(BALL_BREAKS_STACK|RULETYPE_BALLSTACK);
1381 		AllowRule(BALL_LINEBREAK_STACK|RULETYPE_BALLSTACK);
1382 		DenyRule(NO_REACTION|RULETYPE_BALLTETRAD);
1383 		DenyRule(NO_REACTION|RULETYPE_TETRADBALL);
1384 		AllowRule(TETRAD_KILLS_BALL|RULETYPE_TETRADBALL);
1385 		AllowRule(TETRAD_BOUNCES_BALL|RULETYPE_TETRADBALL);
1386 		DenyRule(BALL_JOINS_TETRAD|RULETYPE_BALLTETRAD);
1387 		DenyRule(BALL_BREAKS_TETRAD|RULETYPE_BALLTETRAD);
1388 		AllowRule(BALL_KILLS_TETRAD|RULETYPE_BALLTETRAD);
1389 		DenyRule(BALL_DROPS_TETRAD|RULETYPE_BALLTETRAD);
1390 		AllowRule(BALL_MOVES_TETRAD|RULETYPE_BALLTETRAD);
1391 		AllowRule(BALL_ROTATES_TETRAD|RULETYPE_BALLTETRAD);
1392 		custommenu->ModChoice("Difficulty Level        = Easy", 1);
1393 		break;
1394 	case LEVEL_NORMAL:
1395 		SetPadPlacement(PADS_ALL);
1396 		SetPadSize(PADS_NORMAL);
1397 		SetTetSpeedUp(true);
1398 		SetBallSpeedsUp(false);
1399 		SetRandomRule(true);
1400 		SetRuleFrequency(EVERY_0_30);
1401 		SetSpeed(SPEED_NORMAL);
1402 		SetJunk(JUNK_2);
1403 		AllowRule(NO_REACTION|RULETYPE_BALLSTACK);
1404 		AllowRule(NO_REACTION|RULETYPE_STACKBALL);
1405 		AllowRule(STACK_KILLS_BALL|RULETYPE_STACKBALL);
1406 		AllowRule(STACK_BOUNCES_BALL|RULETYPE_STACKBALL);
1407 		AllowRule(BALL_JOINS_STACK|RULETYPE_BALLSTACK);
1408 		DenyRule(BALL_KILLS_STACK|RULETYPE_BALLSTACK);
1409 		AllowRule(BALL_BREAKS_STACK|RULETYPE_BALLSTACK);
1410 		AllowRule(BALL_LINEBREAK_STACK|RULETYPE_BALLSTACK);
1411 		AllowRule(NO_REACTION|RULETYPE_BALLTETRAD);
1412 		AllowRule(NO_REACTION|RULETYPE_TETRADBALL);
1413 		AllowRule(TETRAD_KILLS_BALL|RULETYPE_TETRADBALL);
1414 		AllowRule(TETRAD_BOUNCES_BALL|RULETYPE_TETRADBALL);
1415 		AllowRule(BALL_JOINS_TETRAD|RULETYPE_BALLTETRAD);
1416 		AllowRule(BALL_BREAKS_TETRAD|RULETYPE_BALLTETRAD);
1417 		AllowRule(BALL_KILLS_TETRAD|RULETYPE_BALLTETRAD);
1418 		AllowRule(BALL_DROPS_TETRAD|RULETYPE_BALLTETRAD);
1419 		AllowRule(BALL_MOVES_TETRAD|RULETYPE_BALLTETRAD);
1420 		AllowRule(BALL_ROTATES_TETRAD|RULETYPE_BALLTETRAD);
1421 		custommenu->ModChoice("Difficulty Level        = Normal", 1);
1422 		break;
1423 	case LEVEL_HARD:
1424 		SetPadPlacement(PADS_ALL);
1425 		SetPadSize(PADS_NORMAL);
1426 		SetTetSpeedUp(true);
1427 		SetBallSpeedsUp(true);
1428 		SetRandomRule(true);
1429 		SetRuleFrequency(EVERY_0_15);
1430 		SetSpeed(SPEED_FAST);
1431 		SetJunk(JUNK_4);
1432 		AllowRule(NO_REACTION|RULETYPE_BALLSTACK);
1433 		AllowRule(NO_REACTION|RULETYPE_STACKBALL);
1434 		AllowRule(STACK_KILLS_BALL|RULETYPE_STACKBALL);
1435 		AllowRule(STACK_BOUNCES_BALL|RULETYPE_STACKBALL);
1436 		AllowRule(BALL_JOINS_STACK|RULETYPE_BALLSTACK);
1437 		AllowRule(BALL_KILLS_STACK|RULETYPE_BALLSTACK);
1438 		AllowRule(BALL_BREAKS_STACK|RULETYPE_BALLSTACK);
1439 		AllowRule(BALL_LINEBREAK_STACK|RULETYPE_BALLSTACK);
1440 		AllowRule(NO_REACTION|RULETYPE_BALLTETRAD);
1441 		AllowRule(NO_REACTION|RULETYPE_TETRADBALL);
1442 		AllowRule(TETRAD_KILLS_BALL|RULETYPE_TETRADBALL);
1443 		AllowRule(TETRAD_BOUNCES_BALL|RULETYPE_TETRADBALL);
1444 		AllowRule(BALL_JOINS_TETRAD|RULETYPE_BALLTETRAD);
1445 		AllowRule(BALL_BREAKS_TETRAD|RULETYPE_BALLTETRAD);
1446 		AllowRule(BALL_KILLS_TETRAD|RULETYPE_BALLTETRAD);
1447 		AllowRule(BALL_DROPS_TETRAD|RULETYPE_BALLTETRAD);
1448 		AllowRule(BALL_MOVES_TETRAD|RULETYPE_BALLTETRAD);
1449 		AllowRule(BALL_ROTATES_TETRAD|RULETYPE_BALLTETRAD);
1450 		custommenu->ModChoice("Difficulty Level        = Hard", 1);
1451 		break;
1452 	case LEVEL_INSANE:
1453 		SetPadPlacement(PADS_ALL);
1454 		SetPadSize(PADS_SMALL);
1455 		SetTetSpeedUp(true);
1456 		SetBallSpeedsUp(true);
1457 		SetRandomRule(true);
1458 		SetRuleFrequency(EVERY_BALL);
1459 		SetSpeed(SPEED_FAST);
1460 		SetJunk(JUNK_6);
1461 		AllowRule(NO_REACTION|RULETYPE_BALLSTACK);
1462 		AllowRule(NO_REACTION|RULETYPE_STACKBALL);
1463 		AllowRule(STACK_KILLS_BALL|RULETYPE_STACKBALL);
1464 		AllowRule(STACK_BOUNCES_BALL|RULETYPE_STACKBALL);
1465 		AllowRule(BALL_JOINS_STACK|RULETYPE_BALLSTACK);
1466 		AllowRule(BALL_KILLS_STACK|RULETYPE_BALLSTACK);
1467 		AllowRule(BALL_BREAKS_STACK|RULETYPE_BALLSTACK);
1468 		DenyRule(BALL_LINEBREAK_STACK|RULETYPE_BALLSTACK);
1469 		AllowRule(NO_REACTION|RULETYPE_BALLTETRAD);
1470 		AllowRule(NO_REACTION|RULETYPE_TETRADBALL);
1471 		AllowRule(TETRAD_KILLS_BALL|RULETYPE_TETRADBALL);
1472 		AllowRule(TETRAD_BOUNCES_BALL|RULETYPE_TETRADBALL);
1473 		AllowRule(BALL_JOINS_TETRAD|RULETYPE_BALLTETRAD);
1474 		AllowRule(BALL_BREAKS_TETRAD|RULETYPE_BALLTETRAD);
1475 		AllowRule(BALL_KILLS_TETRAD|RULETYPE_BALLTETRAD);
1476 		AllowRule(BALL_DROPS_TETRAD|RULETYPE_BALLTETRAD);
1477 		AllowRule(BALL_MOVES_TETRAD|RULETYPE_BALLTETRAD);
1478 		AllowRule(BALL_ROTATES_TETRAD|RULETYPE_BALLTETRAD);
1479 		custommenu->ModChoice("Difficulty Level        = Insane", 1);
1480 		break;
1481 	case LEVEL_CUSTOM:
1482 		DefaultSettings();
1483 		DefaultRules();
1484 		custommenu->ModChoice("Difficulty Level        = Custom", 1);
1485 		break;
1486 	}
1487 	if(level==LEVEL_CUSTOM) {
1488 		custommenu->SetState(2, NORMAL);
1489 		custommenu->SetState(3, NORMAL);
1490 		custommenu->SetState(4, NORMAL);
1491 		custommenu->SetState(5, NORMAL);
1492 		custommenu->SetState(6, NORMAL);
1493 		custommenu->SetState(7, NORMAL);
1494 		custommenu->SetState(8, NORMAL);
1495 		custommenu->SetState(9, NORMAL);
1496 		ballstackmenu->SetState(1, NORMAL);
1497 		ballstackmenu->SetState(2, NORMAL);
1498 		ballstackmenu->SetState(3, NORMAL);
1499 		ballstackmenu->SetState(4, NORMAL);
1500 		ballstackmenu->SetState(5, NORMAL);
1501 		ballstackmenu->SetState(6, NORMAL);
1502 		ballstackmenu->SetState(7, NORMAL);
1503 		ballstackmenu->MoveCursor(SOUTH);
1504 		balltetradmenu->SetState(1, NORMAL);
1505 		balltetradmenu->SetState(2, NORMAL);
1506 		balltetradmenu->SetState(3, NORMAL);
1507 		balltetradmenu->SetState(4, NORMAL);
1508 		balltetradmenu->SetState(5, NORMAL);
1509 		balltetradmenu->SetState(6, NORMAL);
1510 		balltetradmenu->SetState(7, NORMAL);
1511 		balltetradmenu->SetState(8, NORMAL);
1512 		balltetradmenu->SetState(9, NORMAL);
1513 		balltetradmenu->MoveCursor(SOUTH);
1514 	} else {
1515 		custommenu->SetState(2, DISABLED);
1516 		custommenu->SetState(3, DISABLED);
1517 		custommenu->SetState(4, DISABLED);
1518 		custommenu->SetState(5, DISABLED);
1519 		custommenu->SetState(6, DISABLED);
1520 		custommenu->SetState(7, DISABLED);
1521 		custommenu->SetState(8, DISABLED);
1522 		custommenu->SetState(9, DISABLED);
1523 		ballstackmenu->SetState(1, DISABLED);
1524 		ballstackmenu->SetState(2, DISABLED);
1525 		ballstackmenu->SetState(3, DISABLED);
1526 		ballstackmenu->SetState(4, DISABLED);
1527 		ballstackmenu->SetState(5, DISABLED);
1528 		ballstackmenu->SetState(6, DISABLED);
1529 		ballstackmenu->SetState(7, DISABLED);
1530 		ballstackmenu->MoveCursor(SOUTH);
1531 		balltetradmenu->SetState(1, DISABLED);
1532 		balltetradmenu->SetState(2, DISABLED);
1533 		balltetradmenu->SetState(3, DISABLED);
1534 		balltetradmenu->SetState(4, DISABLED);
1535 		balltetradmenu->SetState(5, DISABLED);
1536 		balltetradmenu->SetState(6, DISABLED);
1537 		balltetradmenu->SetState(7, DISABLED);
1538 		balltetradmenu->SetState(8, DISABLED);
1539 		balltetradmenu->SetState(9, DISABLED);
1540 		balltetradmenu->MoveCursor(SOUTH);
1541 	}
1542 	return;
1543 }
1544 
SetPadPlacement(int newpadplacement)1545 void Option::SetPadPlacement(int newpadplacement) {
1546 	padplacement=newpadplacement;
1547 	switch(padplacement) {
1548 	case PADS_SIDES:
1549 		custommenu->ModChoice("Pong Paddle Placement   = Sides", 2);
1550 		break;
1551 	case PADS_TOPBOT:
1552 		custommenu->ModChoice("Pong Paddle Placement   = Top&Bot", 2);
1553 		break;
1554 	case PADS_ALL:
1555 		custommenu->ModChoice("Pong Paddle Placement   = All", 2);
1556 		break;
1557 	default:
1558 		break;
1559 	}
1560 	return;
1561 }
1562 
SetPadSize(int newpadsize)1563 void Option::SetPadSize(int newpadsize) {
1564 	padsize=newpadsize;
1565 	switch(padsize) {
1566 	case PADS_NORMAL:
1567 		custommenu->ModChoice("Pong Paddle Size        = Normal", 3);
1568 		break;
1569 	case PADS_BIG:
1570 		custommenu->ModChoice("Pong Paddle Size        = Big", 3);
1571 		break;
1572 	case PADS_15:
1573 		custommenu->ModChoice("Pong Paddle Size        = 1/5", 3);
1574 		break;
1575 	case PADS_13:
1576 		custommenu->ModChoice("Pong Paddle Size        = 1/3", 3);
1577 		break;
1578 	case PADS_12:
1579 		custommenu->ModChoice("Pong Paddle Size        = 1/2", 3);
1580 		break;
1581 	case PADS_SMALL:
1582 		custommenu->ModChoice("Pong Paddle Size        = Small", 3);
1583 		break;
1584 	default:
1585 		break;
1586 	}
1587 	return;
1588 }
1589 
SetTetSpeedUp(bool newtetspeedup)1590 void Option::SetTetSpeedUp(bool newtetspeedup) {
1591 	tetspeedup=newtetspeedup;
1592 	if(tetspeedup) {
1593 		custommenu->ModChoice("Tetris Pieces Speed Up  = YES", 4);
1594 	} else {
1595 		custommenu->ModChoice("Tetris Pieces Speed Up  = NO", 4);
1596 	}
1597 	return;
1598 }
1599 
SetMusic(int newmusic)1600 void Option::SetMusic(int newmusic) {
1601 	music=newmusic;
1602 	curmusic=music;
1603 	musicmenu->SetChoice(music+1);
1604 	musicmenu->SetState(music+1, HIGHLIGHTED);
1605 	return;
1606 }
1607 
SetTheme(int newtheme)1608 void Option::SetTheme(int newtheme) {
1609 	theme=newtheme;
1610 	thememenu->SetChoice(theme+1);
1611 	thememenu->SetState(theme+1, HIGHLIGHTED);
1612 	return;
1613 }
1614 
SetRandomRule(bool newrandomrule)1615 void Option::SetRandomRule(bool newrandomrule) {
1616 	randomrule=newrandomrule;
1617 	if(randomrule) {
1618 		strcpy(ruletext, "Random rules");
1619 		custommenu->ModChoice("Begin with Random Rules = YES", 6);
1620 	} else {
1621 		custommenu->ModChoice("Begin with Random Rules = NO", 6);
1622 	}
1623 	return;
1624 }
1625 
SetRuleFrequency(int newrulefrequency)1626 void Option::SetRuleFrequency(int newrulefrequency) {
1627 	rulefrequency=newrulefrequency;
1628 	switch(rulefrequency) {
1629 	case EVERY_0_15:
1630 		custommenu->ModChoice("New Rules Every         = 0:15", 7);
1631 		break;
1632 	case EVERY_0_30:
1633 		custommenu->ModChoice("New Rules Every         = 0:30", 7);
1634 		break;
1635 	case EVERY_0_45:
1636 		custommenu->ModChoice("New Rules Every         = 0:45", 7);
1637 		break;
1638 	case EVERY_1_00:
1639 		custommenu->ModChoice("New Rules Every         = 1:00", 7);
1640 		break;
1641 	case EVERY_BALL:
1642 		custommenu->ModChoice("New Rules Every         = Ball", 7);
1643 		break;
1644 	case EVERY_3_BALLS:
1645 		custommenu->ModChoice("New Rules Every         = 3 Balls", 7);
1646 		break;
1647 	case EVERY_LINE:
1648 		custommenu->ModChoice("New Rules Every         = Line", 7);
1649 		break;
1650 	case EVERY_5_LINES:
1651 		custommenu->ModChoice("New Rules Every         = 5 Lines", 7);
1652 		break;
1653 	default:
1654 		break;
1655 	}
1656 	return;
1657 }
1658 
SetVideoFlags(Uint32 newvideoflags)1659 void Option::SetVideoFlags(Uint32 newvideoflags) {
1660 	videoflags=newvideoflags;
1661 	if(videoflags & SDL_FULLSCREEN) {
1662 		optionmenu->ModChoice("Full Screen       = ON", 1);
1663 	} else {
1664 		optionmenu->ModChoice("Full Screen       = OFF", 1);
1665 	}
1666 	return;
1667 }
1668 
SetBgScroll(bool newbgscroll)1669 void Option::SetBgScroll(bool newbgscroll) {
1670 	bgscroll=newbgscroll;
1671 	if(bgscroll) {
1672 		optionmenu->ModChoice("Background Scroll = ON", 4);
1673 	} else {
1674 		optionmenu->ModChoice("Background Scroll = OFF", 4);
1675 	}
1676 	return;
1677 }
1678 
SetVideoBpp(int newvideobpp)1679 void Option::SetVideoBpp(int newvideobpp) {
1680 	char tempstring[40];
1681 
1682 	videobpp=newvideobpp;
1683 	sprintf(tempstring, "Color Depth       = %d", videobpp);
1684 	optionmenu->ModChoice(tempstring, 2);
1685 	return;
1686 }
1687 
SetFpsLimit(int newfpslimit)1688 void Option::SetFpsLimit(int newfpslimit) {
1689 	char tempstring[40];
1690 
1691 	fpslimit=newfpslimit;
1692 	if(fpslimit == FPS_24) {
1693 		sprintf(tempstring, "Frames/Sec Limit  = 24");
1694 	} else if(fpslimit == FPS_30) {
1695 		sprintf(tempstring, "Frames/Sec Limit  = 30");
1696 	} else if(fpslimit == FPS_60) {
1697 		sprintf(tempstring, "Frames/Sec Limit  = 60");
1698 	} else if(fpslimit == FPS_120) {
1699 		sprintf(tempstring, "Frames/Sec Limit  = 120");
1700 	} else {
1701 		sprintf(tempstring, "Frames/Sec Limit  = OFF");
1702 	}
1703 	optionmenu->ModChoice(tempstring, 3);
1704 	return;
1705 }
1706 
SetAudioBuffers(int newaudiobuffers)1707 void Option::SetAudioBuffers(int newaudiobuffers) {
1708 	char tempstring[40];
1709 
1710 	audiobuffers=newaudiobuffers;
1711 	sprintf(tempstring, "Audio Buffers     = %d", audiobuffers);
1712 	optionmenu->ModChoice(tempstring, 5);
1713 	return;
1714 }
1715 
SetAudioFreq(int newaudiofreq)1716 void Option::SetAudioFreq(int newaudiofreq) {
1717 	char tempstring[40];
1718 
1719 	audiofreq=newaudiofreq;
1720 	sprintf(tempstring, "Audio Frequency   = %d", audiofreq);
1721 	optionmenu->ModChoice(tempstring, 6);
1722 	return;
1723 }
1724 
SetMarathon(bool newmarathon)1725 void Option::SetMarathon(bool newmarathon) {
1726 	marathon=newmarathon;
1727 	return;
1728 }
1729 
SetSpeed()1730 void Option::SetSpeed() {
1731 	if(speed>=SPEED_FAST) {
1732 		SetSpeed(SPEED_SLOW);
1733 	} else {
1734 		SetSpeed(speed+1);
1735 	}
1736 	return;
1737 }
1738 
SetSpeed(int newspeed)1739 void Option::SetSpeed(int newspeed) {
1740 	speed=newspeed;
1741 	switch(speed) {
1742 	case SPEED_SLOW:
1743 		custommenu->ModChoice("Speed                   = Slow", 8);
1744 		break;
1745 	case SPEED_NORMAL:
1746 		custommenu->ModChoice("Speed                   = Normal", 8);
1747 		break;
1748 	case SPEED_FAST:
1749 		custommenu->ModChoice("Speed                   = Fast", 8);
1750 		break;
1751 	default:
1752 		break;
1753 	}
1754 	return;
1755 }
1756 
SetJunk()1757 void Option::SetJunk() {
1758 	if(junk>=JUNK_6) {
1759 		SetJunk(JUNK_NONE);
1760 	} else {
1761 		SetJunk(junk+2);
1762 	}
1763 	return;
1764 }
1765 
SetJunk(int newjunk)1766 void Option::SetJunk(int newjunk) {
1767 	junk=newjunk;
1768 	switch(junk) {
1769 	case JUNK_NONE:
1770 		custommenu->ModChoice("Begin with Stack Junk   = None", 9);
1771 		break;
1772 	case JUNK_2:
1773 		custommenu->ModChoice("Begin with Stack Junk   = 2 Lines", 9);
1774 		break;
1775 	case JUNK_4:
1776 		custommenu->ModChoice("Begin with Stack Junk   = 4 Lines", 9);
1777 		break;
1778 	case JUNK_6:
1779 	default:
1780 		custommenu->ModChoice("Begin with Stack Junk   = 6 Lines", 9);
1781 		break;
1782 	}
1783 	return;
1784 }
1785 
SetSoundFx(bool newsoundfx)1786 void Option::SetSoundFx(bool newsoundfx) {
1787 	soundfx=newsoundfx;
1788 	if(soundfx) {
1789 		optionmenu->ModChoice("Sound Effects     = ON", 7);
1790 	} else {
1791 		optionmenu->ModChoice("Sound Effects     = OFF", 7);
1792 	}
1793 	return;
1794 }
1795 
RuleFrequencyInit()1796 void Option::RuleFrequencyInit() {
1797 	rulefreqballs=0;
1798 	rulefreqlines=0;
1799 	lastrule=SDL_GetTicks();
1800 	return;
1801 }
1802 
RuleFrequencyPause()1803 void Option::RuleFrequencyPause() {
1804 	lastrule=SDL_GetTicks()-lastrule;
1805 	return;
1806 }
1807 
RuleFrequencyResume()1808 void Option::RuleFrequencyResume() {
1809 	lastrule=SDL_GetTicks()-lastrule;
1810 	return;
1811 }
1812 
RuleFrequencyAddLines(int lines)1813 void Option::RuleFrequencyAddLines(int lines) {
1814 	rulefreqlines+=lines;
1815 	return;
1816 }
1817 
RuleFrequencyAddBall()1818 void Option::RuleFrequencyAddBall() {
1819 	rulefreqballs++;
1820 	return;
1821 }
1822 
RuleFrequencyNow()1823 bool Option::RuleFrequencyNow() {
1824 	bool changerule=false;
1825 	switch(rulefrequency) {
1826 	case EVERY_0_15:
1827 		if(SDL_GetTicks()-lastrule>15000) {
1828 			changerule=true;
1829 			lastrule+=15000;
1830 		}
1831 		break;
1832 	case EVERY_0_30:
1833 		if(SDL_GetTicks()-lastrule>30000) {
1834 			changerule=true;
1835 			lastrule=lastrule+30000;
1836 		}
1837 		break;
1838 	case EVERY_0_45:
1839 		if(SDL_GetTicks()-lastrule>45000) {
1840 			changerule=true;
1841 			lastrule=lastrule+45000;
1842 		}
1843 		break;
1844 	case EVERY_1_00:
1845 		if(SDL_GetTicks()-lastrule>60000) {
1846 			changerule=true;
1847 			lastrule=lastrule+60000;
1848 		}
1849 		break;
1850 	case EVERY_BALL:
1851 		if(rulefreqballs>0) {
1852 			changerule=true;
1853 			rulefreqballs=0;
1854 		}
1855 		break;
1856 	case EVERY_3_BALLS:
1857 		if(rulefreqballs>2) {
1858 			changerule=true;
1859 			rulefreqballs=0;
1860 		}
1861 		break;
1862 	case EVERY_LINE:
1863 		if(rulefreqlines>0) {
1864 			changerule=true;
1865 			rulefreqlines=0;
1866 		}
1867 		break;
1868 	case EVERY_5_LINES:
1869 		if(rulefreqlines>4) {
1870 			changerule=true;
1871 			rulefreqlines=0;
1872 		}
1873 		break;
1874 	}
1875 	return changerule;
1876 }
1877