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