1 /*	Quantum Minigolf, a computer game illustrating quantum mechanics
2 	Copyright (C) 2007 Friedemann Reinhard <friedemann.reinhard@gmail.com>
3 
4 	This program is free software; you can redistribute it and/or modify
5 	it under the terms of the GNU General Public License as published by
6 	the Free Software Foundation; either version 2 of the License, or
7 	(at your option) any later version.
8 
9 	This program is distributed in the hope that it will be useful,
10 	but WITHOUT ANY WARRANTY; without even the implied warranty of
11 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 	GNU General Public License for more details.
13 
14 	You should have received a copy of the GNU General Public License
15 	along with this program; if not, write to the Free Software
16 	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18 
19 #include "TrackSelector.h"
20 
21 // TrackSelector constructor: preload the desired track bitmaps
22 // and store them in the track list
TrackSelector(Renderer * renderer,ClassicSimulator * csimulator)23 TrackSelector::TrackSelector(Renderer *renderer, ClassicSimulator *csimulator)
24 {
25 	this->renderer = renderer;
26 	this->csimulator = csimulator;
27 	this->width = renderer->width;
28 	this->height = renderer->height;
29 
30 	char line[80];
31 	char V[80];
32 	char hard[80];
33 	char soft[80];
34 	string fname;
35 
36 	SDL_Surface *bmp;
37 
38 	trackrecord *entry;
39 
40 	help = true;
41 
42 	/*read the config file, load the track bitmaps and store
43 	them in the track vector*/
44 	FILE *conf = fopen("/usr/local/share/quantumminigolf/tracks/tracks.cfg", "r");
45 	//load an empty dummy track, if there is no config file present
46 	if(conf == NULL){
47 		cout << "Cannot open track config file" << endl;
48 			entry = new trackrecord;
49 			tracks.push_back(entry);
50 			entry->V = BlackTrack();
51 			entry->hard = BlackTrack();
52 			entry->soft = BlackTrack();
53 	}
54 	//config file present: load all tracks mentioned in the config file
55 	else{
56 		cout << "preloading tracks... " << endl;
57 		while(fgets(line, 79, conf)){
58 			for(int i=0; i<80-1; i++){
59 				hard[i] = ' '; soft[i] = ' ';
60 			}
61 			sscanf(line, "%s %s %s\n", V, hard, soft);
62 			fname = string("/usr/local/share/quantumminigolf/tracks/");
63 			fname.append(V);
64 			cout <<  fname << "...";
65 			bmp = (SDL_Surface *)SDL_LoadBMP(fname.c_str());
66 
67 			/*if bitmap cannot be loaded or has the wrong format, skip it*/
68 			if(bmp == NULL || bmp->w != width || bmp->h != height){
69 				cout << "failed: no quantum track found" << endl;
70 				SDL_FreeSurface(bmp);
71 				bmp = BlackTrack();
72 			}
73 			entry = new trackrecord;
74 			tracks.push_back(entry);
75 			entry->V = SDL_ConvertSurface(bmp, renderer->screen->format, SDL_SWSURFACE);
76 
77 			fname = string("/usr/local/share/quantumminigolf/tracks/");
78 			fname.append(hard);
79 			bmp = (SDL_Surface *)SDL_LoadBMP(fname.c_str());
80 			/*if bitmap cannot be loaded or has the wrong format, skip it*/
81 			if(bmp == NULL || bmp->w != width || bmp->h != height){
82 				cout << fname << ":failed to load hardcore potential " << endl;
83 				SDL_FreeSurface(bmp);
84 				bmp = BlackTrack();
85 			}
86 			entry->hard = SDL_ConvertSurface(bmp, renderer->screen->format, SDL_SWSURFACE);
87 
88 			fname = string("/usr/local/share/quantumminigolf/tracks/");
89 			fname.append(soft);
90 			bmp = (SDL_Surface *)SDL_LoadBMP(fname.c_str());
91 			/*if bitmap cannot be loaded or has the wrong format, skip it*/
92 			if(bmp == NULL || bmp->w != width || bmp->h != height){
93 				cout << fname << ":failed to load softcore potential" << endl;
94 				SDL_FreeSurface(bmp);
95 				bmp = BlackTrack();
96 			}
97 			entry->soft = SDL_ConvertSurface(bmp, renderer->screen->format, SDL_SWSURFACE);
98 
99 			cout << "done" << endl;
100 		}
101 	}
102 	trackiterator = tracks.begin();
103 	renderer->V = (*trackiterator)->V;
104 	csimulator->hard = (*trackiterator)->hard;
105 	csimulator->soft = (*trackiterator)->soft;
106 	renderer->RenderTrack();
107 	renderer->Blit();
108 }
109 
~TrackSelector(void)110 TrackSelector::~TrackSelector(void)
111 {
112 	list<trackrecord *>::iterator l;
113 	for(l=tracks.begin(); l!=tracks.end(); ++l){
114 		SDL_FreeSurface((*l)->V);
115 		SDL_FreeSurface((*l)->hard);
116 		SDL_FreeSurface((*l)->soft);
117 		delete *l;
118 	}
119 }
120 
121 
122 //TrackSelector::GetTrack
123 // take control of the renderer and generate the track choice menu
124 // release control of the renderer only when the user has chosen a track
125 // or quit the game
GetTrack(bool * quantum)126 int TrackSelector::GetTrack(bool *quantum){
127     SDL_Event dummyevent;
128 
129 	int finished = 0;
130 
131 	SDL_EventState(SDL_MOUSEBUTTONUP, SDL_IGNORE);
132 	SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_IGNORE);
133 
134 	renderer->V = (*trackiterator)->V;
135 	renderer->RenderTrack();
136 	if(help)renderer->RenderMenu(*quantum);
137 	renderer->Blit();
138 
139 	while(!finished){
140 		if(SDL_PollEvent(&dummyevent)==0)
141 			continue;
142 
143 		switch(dummyevent.type){
144 			case SDL_KEYDOWN:
145 				switch(dummyevent.key.keysym.sym){
146 					case SDLK_ESCAPE: //Esc - quit
147 						return 0;
148 						break;
149 					case SDLK_RETURN: // RET or Space - start a game on the current track
150 					case SDLK_SPACE:
151 						SDL_EventState(SDL_MOUSEBUTTONUP, SDL_ENABLE);
152 						SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_ENABLE);
153 						return 1;
154 						break;
155 					case SDLK_LEFT: // left or right - cycle tracks
156 						if(trackiterator == tracks.begin()){
157 							trackiterator = tracks.end();
158 							--trackiterator;
159 						}
160 						else
161 							--trackiterator;
162 						renderer->V = (*trackiterator)->V;
163 						csimulator->hard = (*trackiterator)->hard;
164 						csimulator->soft = (*trackiterator)->soft;
165 						renderer->RenderTrack();
166 						if(help)renderer->RenderMenu(*quantum);
167 						renderer->Blit();
168 						break;
169 					case SDLK_RIGHT:
170 						++trackiterator;
171 						if(trackiterator == tracks.end())
172 							trackiterator = tracks.begin();
173 						renderer->V = (*trackiterator)->V;
174 						csimulator->hard = (*trackiterator)->hard;
175 						csimulator->soft = (*trackiterator)->soft;
176 						renderer->RenderTrack();
177 						if(help)renderer->RenderMenu(*quantum);
178 						renderer->Blit();
179 						break;
180 					case SDLK_q: // q - toggle quantum mode
181 						*quantum = !*quantum;
182 						renderer->RenderTrack();
183 						if(help)renderer->RenderMenu(*quantum);
184 						renderer->Blit();
185 						break;
186 					case SDLK_h: // h - toggle help overlay
187 						help = !help;
188 						renderer->RenderTrack();
189 						if(help)renderer->RenderMenu(*quantum);
190 						renderer->Blit();
191 						break;
192 					case SDLK_c: // c - toggle color map
193 					    renderer->ToggleCmap();
194 					    renderer->RenderTrack();
195 					    if(help)renderer->RenderMenu(*quantum);
196 					    renderer->Blit();
197 					    break;
198 				}
199 				break;
200 			default:
201 				renderer->Blit();
202 				break;
203 		}
204 	}
205 }
206 
207 //BlackTrack -- generate an empty track surface
BlackTrack(void)208 SDL_Surface * TrackSelector::BlackTrack(void){
209 	SDL_Surface *result = NULL;
210 
211 	result = SDL_CreateRGBSurface( SDL_SWSURFACE, width,
212 				height,
213 				renderer->screen->format->BitsPerPixel,
214 				renderer->screen->format->Rmask,
215 				renderer->screen->format->Gmask,
216 				renderer->screen->format->Bmask,
217 				renderer->screen->format->Amask);
218 	if (result == NULL){
219 		cout << "failed to create software surface" << endl;
220 		exit(1);
221 	}
222 	Uint32 *pdata = ((Uint32 *)(result->pixels));
223 	for(int i=0; i<width; i++)
224 		for(int j=0; j<height; j++){
225 			pdata[j*width+i] = 0;
226 		}
227 	return result;
228 }
229 
230