author | andyq <andyq> | 2003-01-20 23:11:56 (UTC) |
---|---|---|
committer | andyq <andyq> | 2003-01-20 23:11:56 (UTC) |
commit | 92419b025aa5d82bb7592281af5505ff931c2e58 (patch) (unidiff) | |
tree | 374ee9ca86ef716ce388c8a28e38261f6a04ce7a | |
parent | 02090d2e63ad8398c0a8a9f1fb895a9c6e42514b (diff) | |
download | opie-92419b025aa5d82bb7592281af5505ff931c2e58.zip opie-92419b025aa5d82bb7592281af5505ff931c2e58.tar.gz opie-92419b025aa5d82bb7592281af5505ff931c2e58.tar.bz2 |
Initial Revision
41 files changed, 4954 insertions, 0 deletions
diff --git a/noncore/games/sfcave-sdl/animatedimage.cpp b/noncore/games/sfcave-sdl/animatedimage.cpp new file mode 100644 index 0000000..d9d6ff6 --- a/dev/null +++ b/noncore/games/sfcave-sdl/animatedimage.cpp | |||
@@ -0,0 +1,68 @@ | |||
1 | #include "SDL.h" | ||
2 | #include "SDL_image.h" | ||
3 | |||
4 | #include "constants.h" | ||
5 | #include "animatedimage.h" | ||
6 | |||
7 | AnimatedImage :: AnimatedImage( QString file, int nFrames ) | ||
8 | { | ||
9 | nrFrames = nFrames; | ||
10 | currentFrame = 0; | ||
11 | |||
12 | // Load image | ||
13 | image = IMG_Load( (const char *)file.c_str() ); | ||
14 | if ( !image ) | ||
15 | { | ||
16 | nrFrames = 0; | ||
17 | image = 0; | ||
18 | return; | ||
19 | } | ||
20 | |||
21 | SDL_SetColorKey(image, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB( image->format, 0, 0, 0 ) ); | ||
22 | //image = SDL_DisplayFormat( tmp ); | ||
23 | |||
24 | //SDL_FreeSurface( tmp ); | ||
25 | frameWidth = image->w/nrFrames; | ||
26 | frameHeight = image->h; | ||
27 | } | ||
28 | |||
29 | AnimatedImage :: ~AnimatedImage() | ||
30 | { | ||
31 | if ( image != 0 ) | ||
32 | SDL_FreeSurface( image ); | ||
33 | } | ||
34 | |||
35 | bool AnimatedImage :: nextFrame() | ||
36 | { | ||
37 | bool rc = true; | ||
38 | currentFrame ++; | ||
39 | if ( currentFrame >= nrFrames ) | ||
40 | { | ||
41 | currentFrame --; | ||
42 | rc = false; | ||
43 | } | ||
44 | |||
45 | return rc; | ||
46 | } | ||
47 | |||
48 | void AnimatedImage :: draw( SDL_Surface *screen, int x, int y ) | ||
49 | { | ||
50 | SDL_Rect dst; | ||
51 | dst.x = currentFrame * frameWidth; | ||
52 | dst.y = 0; | ||
53 | dst.w = frameWidth; | ||
54 | dst.h = frameHeight; | ||
55 | |||
56 | SDL_Rect dst2; | ||
57 | dst2.x = x - (frameWidth/2); | ||
58 | dst2.y = y - (frameHeight/2);; | ||
59 | SDL_BlitSurface( image, &dst, screen, &dst2 ); | ||
60 | } | ||
61 | |||
62 | bool AnimatedImage :: AtEnd() | ||
63 | { | ||
64 | if ( currentFrame +1 >= nrFrames || image == 0 ) | ||
65 | return true; | ||
66 | return false; | ||
67 | } | ||
68 | |||
diff --git a/noncore/games/sfcave-sdl/animatedimage.h b/noncore/games/sfcave-sdl/animatedimage.h new file mode 100644 index 0000000..1b38e6d --- a/dev/null +++ b/noncore/games/sfcave-sdl/animatedimage.h | |||
@@ -0,0 +1,25 @@ | |||
1 | #ifndef __ANIMATED_IMAGE_H | ||
2 | #define __ANIMATED_IMAGE_H | ||
3 | |||
4 | #include "SDL.h" | ||
5 | |||
6 | class AnimatedImage | ||
7 | { | ||
8 | public: | ||
9 | AnimatedImage( QString file, int nFrames ); | ||
10 | ~AnimatedImage(); | ||
11 | |||
12 | bool nextFrame(); | ||
13 | void draw( SDL_Surface *screen, int x, int y ); | ||
14 | bool AtEnd(); | ||
15 | void reset() { currentFrame = 0; } | ||
16 | private: | ||
17 | |||
18 | SDL_Surface *image; | ||
19 | int nrFrames; | ||
20 | int currentFrame; | ||
21 | |||
22 | int frameWidth; | ||
23 | int frameHeight; | ||
24 | }; | ||
25 | #endif | ||
diff --git a/noncore/games/sfcave-sdl/bfont.cpp b/noncore/games/sfcave-sdl/bfont.cpp new file mode 100644 index 0000000..0f29104 --- a/dev/null +++ b/noncore/games/sfcave-sdl/bfont.cpp | |||
@@ -0,0 +1,443 @@ | |||
1 | /***********************************************************/ | ||
2 | /* */ | ||
3 | /* BFONT.c v. 1.0.2 - Billi Font Library by Diego Billi */ | ||
4 | /* BFONT++ C++ port by Gianluigi Davassi */ | ||
5 | /***********************************************************/ | ||
6 | #include "iostream" | ||
7 | using namespace std; | ||
8 | #include "string.h" | ||
9 | #include "stdlib.h" | ||
10 | #include "stdarg.h" | ||
11 | |||
12 | #include "SDL_image.h" | ||
13 | #include "bfont.h" | ||
14 | |||
15 | void BFont::InitFont() | ||
16 | { | ||
17 | int x = 0, i = '!'; | ||
18 | Uint32 sentry = GetPixel(0,0); | ||
19 | |||
20 | if (SDL_MUSTLOCK(Surface)) | ||
21 | SDL_LockSurface(Surface); | ||
22 | |||
23 | while ( x < (Surface->w-1)) | ||
24 | { | ||
25 | if(GetPixel(x,0) != sentry) | ||
26 | { | ||
27 | Chars[i].x = x; | ||
28 | Chars[i].y = 1; | ||
29 | Chars[i].h = Surface->h; | ||
30 | for (; GetPixel(x, 0) != sentry && x < (Surface->w); ++x) ; | ||
31 | Chars[i].w = (x - Chars[i].x); | ||
32 | i++; | ||
33 | } else | ||
34 | { x++; } | ||
35 | } | ||
36 | Chars[' '].x = 0; | ||
37 | Chars[' '].y = 0; | ||
38 | Chars[' '].h = Surface->h; | ||
39 | Chars[' '].w = Chars['!'].w; | ||
40 | |||
41 | if (SDL_MUSTLOCK(Surface)) | ||
42 | SDL_UnlockSurface(Surface); | ||
43 | |||
44 | h = Surface->h; | ||
45 | |||
46 | SDL_SetColorKey(Surface, SDL_SRCCOLORKEY, GetPixel(0, Surface->h-1)); | ||
47 | } | ||
48 | |||
49 | |||
50 | /* Load the font and stores it in the BFont_Info structure */ | ||
51 | void BFont::LoadFont (const char *filename) | ||
52 | { | ||
53 | SDL_Surface *surface(NULL); | ||
54 | int x; | ||
55 | // tutta roba inutile in C++.... :-) | ||
56 | /* BFont_Info *Font=NULL; | ||
57 | Font = (BFont_Info *) malloc(sizeof(BFont_Info));*/ | ||
58 | |||
59 | if ((filename != NULL ) && (this != NULL)) | ||
60 | { | ||
61 | surface = IMG_Load( filename ); | ||
62 | |||
63 | if (surface != NULL) | ||
64 | { | ||
65 | Surface = surface; | ||
66 | for (x=0; x<256; x++) | ||
67 | { | ||
68 | Chars[x].x = 0; | ||
69 | Chars[x].y = 0; | ||
70 | Chars[x].h = 0; | ||
71 | Chars[x].w = 0; | ||
72 | } | ||
73 | InitFont(); // Init the font | ||
74 | } | ||
75 | } | ||
76 | else | ||
77 | { | ||
78 | cerr << "Error! The font has not been loaded!" << endl; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | BFont * BFont :: SetFontColor(Uint8 r, Uint8 g, Uint8 b) | ||
83 | { | ||
84 | int x,y; | ||
85 | |||
86 | BFont *newfont; | ||
87 | SDL_Surface *surface = NULL; | ||
88 | |||
89 | Uint32 pixel; | ||
90 | Uint8 old_r, old_g, old_b; | ||
91 | Uint8 new_r, new_g, new_b; | ||
92 | Uint32 color_key; | ||
93 | |||
94 | newfont = new BFont(NULL); | ||
95 | |||
96 | if (newfont != NULL) { | ||
97 | |||
98 | newfont->h = h; | ||
99 | |||
100 | for (x=0; x<256; x++) { | ||
101 | newfont->Chars[x].x = Chars[x].x; | ||
102 | newfont->Chars[x].y = Chars[x].y; | ||
103 | newfont->Chars[x].h = Chars[x].h; | ||
104 | newfont->Chars[x].w = Chars[x].w; | ||
105 | } | ||
106 | |||
107 | surface = SDL_CreateRGBSurface(SDL_SWSURFACE, Surface->w, Surface->h, 32, | ||
108 | 0x000000ff,0x0000ff00, 0x00ff0000, 0xff000000); | ||
109 | if (surface != NULL) { | ||
110 | |||
111 | if (SDL_MUSTLOCK(surface)) SDL_LockSurface(surface); | ||
112 | if (SDL_MUSTLOCK(Surface)) SDL_LockSurface(Surface); | ||
113 | |||
114 | color_key = xGetPixel(Surface, 0, Surface->h-1); | ||
115 | |||
116 | printf("looking...\n"); | ||
117 | for( x=0; x < Surface->w; x++) { | ||
118 | for( y=0; y < Surface->h; y++) { | ||
119 | old_r = old_g = old_b = 0; | ||
120 | pixel = xGetPixel(Surface,x,y); | ||
121 | |||
122 | if (pixel != color_key) { | ||
123 | SDL_GetRGB(pixel, Surface->format, &old_r,&old_g,&old_b); | ||
124 | |||
125 | new_r = (Uint8) ((old_r * r) / 255); | ||
126 | new_g = (Uint8) ((old_g * g) / 255); | ||
127 | new_b = (Uint8) ((old_b * b) / 255); | ||
128 | |||
129 | pixel = SDL_MapRGB(surface->format,new_r,new_g,new_b); | ||
130 | } | ||
131 | PutPixel(surface,x,y,pixel); | ||
132 | } | ||
133 | } | ||
134 | printf("unlooking...\n"); | ||
135 | if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface); | ||
136 | if (SDL_MUSTLOCK(Surface)) SDL_UnlockSurface(Surface); | ||
137 | |||
138 | SDL_SetColorKey(surface, SDL_SRCCOLORKEY, color_key); | ||
139 | } | ||
140 | |||
141 | newfont->Surface = surface; | ||
142 | } | ||
143 | return newfont; | ||
144 | } | ||
145 | |||
146 | |||
147 | /* Puts a single char on the surface with the specified font */ | ||
148 | int BFont::PutChar(SDL_Surface *screen, int x, int y, char c) | ||
149 | { | ||
150 | int r=0; | ||
151 | SDL_Rect dest; | ||
152 | |||
153 | dest.w = CharWidth(' '); | ||
154 | dest.h = FontHeight(); | ||
155 | dest.x = x; | ||
156 | dest.y = y; | ||
157 | |||
158 | if (c != ' ') | ||
159 | SDL_BlitSurface( Surface, &Chars[c], screen, &dest); | ||
160 | |||
161 | r = dest.w; | ||
162 | return r; | ||
163 | } | ||
164 | |||
165 | |||
166 | void BFont::PutString(SDL_Surface *screen, int x, int y, const char *text) | ||
167 | { | ||
168 | int i(0); | ||
169 | while (text[i]!='\0') | ||
170 | { | ||
171 | x += PutChar(screen,x,y,text[i]); | ||
172 | i++; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | int BFont::TextWidth(const char *text) | ||
177 | { | ||
178 | int i(0),x(0); | ||
179 | |||
180 | while (text[i]!='\0') | ||
181 | { | ||
182 | x += CharWidth(text[i]); | ||
183 | i++; | ||
184 | } | ||
185 | return x; | ||
186 | } | ||
187 | |||
188 | |||
189 | /* counts the spaces of the strings */ | ||
190 | int BFont::count (const char *text) | ||
191 | { | ||
192 | char *p(NULL); | ||
193 | int pos(-1),i(0); | ||
194 | |||
195 | /* Calculate the space occupied by the text without spaces */ | ||
196 | while ((p=strchr(&text[pos+1],' ')) != NULL) | ||
197 | { | ||
198 | i++; | ||
199 | pos = p - text; | ||
200 | } | ||
201 | return i; | ||
202 | } | ||
203 | |||
204 | |||
205 | void BFont::JustifiedPutString( SDL_Surface *screen, int y, const char *text) | ||
206 | { | ||
207 | int spaces(0),gap,single_gap,dif; | ||
208 | char *strtmp,*p; | ||
209 | int pos(-1),xpos(0); | ||
210 | |||
211 | |||
212 | if (strchr(text,' ') == NULL) | ||
213 | { | ||
214 | PutString(screen, 0, y, text); | ||
215 | } | ||
216 | else { | ||
217 | gap = (screen->w-1) - TextWidth(text); | ||
218 | |||
219 | if (gap <= 0) { | ||
220 | PutString(screen, 0,y,text); | ||
221 | } else { | ||
222 | spaces = count(text); | ||
223 | dif = gap % spaces; | ||
224 | single_gap = (gap - dif) / spaces; | ||
225 | xpos=0; | ||
226 | pos = -1; | ||
227 | while ( spaces > 0 ) | ||
228 | { | ||
229 | p = strstr(&text[pos+1]," "); | ||
230 | strtmp = NULL; | ||
231 | strtmp = (char *) calloc ( (p - &text[pos+1]) + 1,sizeof(char)); | ||
232 | if (strtmp != NULL) | ||
233 | { | ||
234 | strncpy (strtmp, &text[pos+1], (p - &text[pos+1])); | ||
235 | PutString(screen, xpos, y, strtmp); | ||
236 | xpos = xpos + TextWidth(strtmp) + single_gap + CharWidth(' '); | ||
237 | if (dif >= 0) | ||
238 | { | ||
239 | xpos ++; | ||
240 | dif--; | ||
241 | } | ||
242 | pos = p - text; | ||
243 | spaces--; | ||
244 | free(strtmp); | ||
245 | } | ||
246 | } | ||
247 | strtmp = NULL; | ||
248 | strtmp = (char *) calloc ( strlen( &text[pos+1]) + 1,sizeof(char)); | ||
249 | |||
250 | if (strtmp != NULL) { | ||
251 | strncpy (strtmp, &text[pos+1], strlen( &text[pos+1])); | ||
252 | PutString(screen, xpos, y, strtmp); | ||
253 | free(strtmp); | ||
254 | } | ||
255 | } | ||
256 | } | ||
257 | } | ||
258 | |||
259 | |||
260 | void BFont::CenteredPutString(SDL_Surface *screen, int y, const char *text) | ||
261 | { | ||
262 | printf( "xpos - %d, %d <%s>\n", screen->w/2-TextWidth(text)/2, TextWidth(text), text ); | ||
263 | PutString( screen, screen->w/2-TextWidth(text)/2, y, text); | ||
264 | } | ||
265 | |||
266 | |||
267 | void BFont::RightPutString(SDL_Surface *screen, int y, const char *text) | ||
268 | { | ||
269 | PutString( screen, screen->w - TextWidth(text) - 1, y, text); | ||
270 | } | ||
271 | |||
272 | void BFont::LeftPutString(SDL_Surface *screen, int y, const char *text) | ||
273 | { | ||
274 | PutString( screen, 0, y, text); | ||
275 | } | ||
276 | |||
277 | /******/ | ||
278 | |||
279 | void BFont::PrintString (SDL_Surface *screen, int x, int y, char *fmt, ...) | ||
280 | { | ||
281 | va_list args; | ||
282 | char *temp; | ||
283 | va_start (args,fmt); | ||
284 | |||
285 | if ( (temp = (char *) malloc(1000+1)) != NULL) { | ||
286 | vsprintf(temp,fmt,args); | ||
287 | PutString(screen, x, y, temp); | ||
288 | free (temp); | ||
289 | } | ||
290 | va_end(args); | ||
291 | } | ||
292 | |||
293 | void BFont::CenteredPrintString(SDL_Surface *screen, int y, char *fmt, ...) | ||
294 | { | ||
295 | va_list args; | ||
296 | char *temp; | ||
297 | va_start (args,fmt); | ||
298 | |||
299 | if ( (temp = (char *) malloc(1000+1)) != NULL) { | ||
300 | vsprintf(temp,fmt,args); | ||
301 | CenteredPutString(screen, y, temp); | ||
302 | free (temp); | ||
303 | } | ||
304 | va_end(args); | ||
305 | } | ||
306 | |||
307 | void BFont::RightPrintString(SDL_Surface *screen, int y, char *fmt, ...) | ||
308 | { | ||
309 | va_list args; | ||
310 | char *temp; | ||
311 | va_start (args,fmt); | ||
312 | |||
313 | if ( (temp = (char *) malloc(1000+1)) != NULL) { | ||
314 | vsprintf(temp,fmt,args); | ||
315 | RightPutString(screen, y, temp); | ||
316 | free (temp); | ||
317 | } | ||
318 | va_end(args); | ||
319 | } | ||
320 | |||
321 | void BFont::LeftPrintString( SDL_Surface *screen, int y, char *fmt, ...) | ||
322 | { | ||
323 | va_list args; | ||
324 | char *temp; | ||
325 | va_start (args,fmt); | ||
326 | |||
327 | if ( (temp = (char *) malloc(1000+1)) != NULL) { | ||
328 | vsprintf(temp,fmt,args); | ||
329 | LeftPutString(screen, y, temp); | ||
330 | free (temp); | ||
331 | } | ||
332 | va_end(args); | ||
333 | } | ||
334 | |||
335 | void BFont::JustifiedPrintString( SDL_Surface *screen, int y, char *fmt, ...) | ||
336 | { | ||
337 | va_list args; | ||
338 | char *temp; | ||
339 | va_start (args,fmt); | ||
340 | |||
341 | if ( (temp = (char *) malloc(1000+1)) != NULL) { | ||
342 | vsprintf(temp,fmt,args); | ||
343 | JustifiedPutString( screen, y,temp); | ||
344 | free (temp); | ||
345 | } | ||
346 | va_end(args); | ||
347 | } | ||
348 | |||
349 | |||
350 | void BFont::PutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) | ||
351 | { | ||
352 | int bpp = surface->format->BytesPerPixel; | ||
353 | /* Here p is the address to the pixel we want to set */ | ||
354 | Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; | ||
355 | |||
356 | switch(bpp) { | ||
357 | case 1: | ||
358 | *p = pixel; | ||
359 | break; | ||
360 | |||
361 | case 2: | ||
362 | *(Uint16 *)p = pixel; | ||
363 | break; | ||
364 | |||
365 | case 3: | ||
366 | if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { | ||
367 | p[0] = (pixel >> 16) & 0xff; | ||
368 | p[1] = (pixel >> 8) & 0xff; | ||
369 | p[2] = pixel & 0xff; | ||
370 | } else { | ||
371 | p[0] = pixel & 0xff; | ||
372 | p[1] = (pixel >> 8) & 0xff; | ||
373 | p[2] = (pixel >> 16) & 0xff; | ||
374 | } | ||
375 | break; | ||
376 | |||
377 | case 4: | ||
378 | *(Uint32 *)p = pixel; | ||
379 | break; | ||
380 | } | ||
381 | } | ||
382 | |||
383 | Uint32 BFont :: xGetPixel(SDL_Surface *surface, int x, int y) | ||
384 | { | ||
385 | int bpp = surface->format->BytesPerPixel; | ||
386 | /* Here p is the address to the pixel we want to retrieve */ | ||
387 | Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; | ||
388 | |||
389 | switch(bpp) { | ||
390 | case 1: | ||
391 | return *p; | ||
392 | |||
393 | case 2: | ||
394 | return *(Uint16 *)p; | ||
395 | |||
396 | case 3: | ||
397 | if(SDL_BYTEORDER == SDL_BIG_ENDIAN) | ||
398 | return p[0] << 16 | p[1] << 8 | p[2]; | ||
399 | else | ||
400 | return p[0] | p[1] << 8 | p[2] << 16; | ||
401 | |||
402 | case 4: | ||
403 | return *(Uint32 *)p; | ||
404 | |||
405 | default: | ||
406 | return 0; /* shouldn't happen, but avoids warnings */ | ||
407 | } | ||
408 | } | ||
409 | |||
410 | Uint32 BFont::GetPixel( Sint32 X, Sint32 Y) | ||
411 | { | ||
412 | |||
413 | Uint8 *bits; | ||
414 | Uint32 Bpp; | ||
415 | |||
416 | if (X<0) puts("x too small in GetPixel!"); | ||
417 | if (X>=Surface->w) puts("x too big in GetPixel!"); | ||
418 | |||
419 | Bpp = Surface->format->BytesPerPixel; | ||
420 | |||
421 | bits = ((Uint8 *)Surface->pixels)+Y*Surface->pitch+X*Bpp; | ||
422 | |||
423 | // Get the pixel | ||
424 | switch(Bpp) { | ||
425 | case 1: | ||
426 | return *((Uint8 *)Surface->pixels + Y * Surface->pitch + X); | ||
427 | break; | ||
428 | case 2: | ||
429 | return *((Uint16 *)Surface->pixels + Y * Surface->pitch/2 + X); | ||
430 | break; | ||
431 | case 3: { // Format/endian independent | ||
432 | Uint8 r, g, b; | ||
433 | r = *((bits)+Surface->format->Rshift/8); | ||
434 | g = *((bits)+Surface->format->Gshift/8); | ||
435 | b = *((bits)+Surface->format->Bshift/8); | ||
436 | return SDL_MapRGB(Surface->format, r, g, b); | ||
437 | } | ||
438 | break; | ||
439 | case 4: | ||
440 | return *((Uint32 *)Surface->pixels + Y * Surface->pitch/4 + X); | ||
441 | break; | ||
442 | } | ||
443 | } | ||
diff --git a/noncore/games/sfcave-sdl/bfont.h b/noncore/games/sfcave-sdl/bfont.h new file mode 100644 index 0000000..dee97f1 --- a/dev/null +++ b/noncore/games/sfcave-sdl/bfont.h | |||
@@ -0,0 +1,70 @@ | |||
1 | |||
2 | /************************************************************ | ||
3 | |||
4 | BFONT v. 1.0.2 - Billi Font Library by Diego Billi | ||
5 | BFONT++ C++ port by Gianluigi Davassi | ||
6 | ************************************************************/ | ||
7 | |||
8 | #ifndef __BFONT_HEADER_H__ | ||
9 | #define __BFONT_HEADER_H__ | ||
10 | |||
11 | #include <iostream> | ||
12 | #include "SDL.h" | ||
13 | |||
14 | class BFont | ||
15 | { | ||
16 | int h; // font height | ||
17 | SDL_Surface *Surface; // font surface | ||
18 | SDL_Rect Chars[256]; // characters width | ||
19 | const char* name; // font name | ||
20 | |||
21 | BFont(const BFont&); | ||
22 | |||
23 | void InitFont(); | ||
24 | int count(const char *text); | ||
25 | public: | ||
26 | |||
27 | BFont(const char *__filename) // generator bill | ||
28 | : name(__filename) | ||
29 | { LoadFont(__filename); } | ||
30 | |||
31 | ~BFont() | ||
32 | { SDL_FreeSurface(Surface); } // screen must be free by application | ||
33 | |||
34 | int FontHeight () // Returns the font height | ||
35 | { return h; } | ||
36 | |||
37 | void SetFontHeight (int height) // Change the font height | ||
38 | { h = height ; } | ||
39 | |||
40 | int CharWidth (char c) // Returns the character width of the specified font | ||
41 | { return Chars[c].w; } | ||
42 | |||
43 | void LoadFont (const char *filename); // Load and store le font in the BFont structure | ||
44 | int PutChar (SDL_Surface *screen, int x, int y, char c); // Write a single character on the "Surface" with the current font | ||
45 | int TextWidth (const char *text ); // Returns the width, in pixels, of the text calculated with the current font | ||
46 | |||
47 | BFont *SetFontColor(Uint8 r, Uint8 g, Uint8 b); // Returns a new font colored with the color (r,g,b) | ||
48 | |||
49 | void PutString ( SDL_Surface *screen, int x, int y, const char *text); // Write a string on the "Surface" with the specified font | ||
50 | void LeftPutString ( SDL_Surface *screen, int y, const char *text); // Write a left-aligned string on the "Surface" with the specified font | ||
51 | void CenteredPutString ( SDL_Surface *screen, int y, const char *text); // Write a center-aligned string on the "Surface" with the specified font | ||
52 | void RightPutString ( SDL_Surface *screen, int y, const char *text); // Write a right-aligned string on the "Surface" with the specified font | ||
53 | void JustifiedPutString ( SDL_Surface *screen, int y, const char *text); // Write a justify-aligned string on the "Surface" with the specified font | ||
54 | |||
55 | // The following functions do the same task but have the classic "printf" sintax | ||
56 | void PrintString ( SDL_Surface *screen, int x, int y, char *fmt, ...); | ||
57 | void CenteredPrintString ( SDL_Surface *screen, int y, char *fmt, ...); | ||
58 | void RightPrintString ( SDL_Surface *screen, int y, char *fmt, ...); | ||
59 | void LeftPrintString ( SDL_Surface *screen, int y, char *fmt, ...); | ||
60 | void JustifiedPrintString ( SDL_Surface *screen, int y, char *fmt, ...); | ||
61 | |||
62 | private: | ||
63 | Uint32 GetPixel( Sint32 X, Sint32 Y); | ||
64 | Uint32 xGetPixel(SDL_Surface *surface, int x, int y); | ||
65 | void PutPixel( SDL_Surface *,int x, int y, Uint32 pixel); | ||
66 | |||
67 | }; | ||
68 | |||
69 | #endif // __BFONT_HEADER_H__ | ||
70 | |||
diff --git a/noncore/games/sfcave-sdl/config.in b/noncore/games/sfcave-sdl/config.in new file mode 100644 index 0000000..9d56c0c --- a/dev/null +++ b/noncore/games/sfcave-sdl/config.in | |||
@@ -0,0 +1,5 @@ | |||
1 | config SFCAVE-SDL | ||
2 | boolean "sfcave-sdl" | ||
3 | default "y" | ||
4 | depends ( LIBQPE || LIBQPE-X11 ) && LIBOPIE | ||
5 | string "sfcave-sdl (warning: requires libsdl)" | ||
diff --git a/noncore/games/sfcave-sdl/constants.h b/noncore/games/sfcave-sdl/constants.h new file mode 100644 index 0000000..8fadae4 --- a/dev/null +++ b/noncore/games/sfcave-sdl/constants.h | |||
@@ -0,0 +1,67 @@ | |||
1 | #ifndef __CONSTANTS_H | ||
2 | #define __CONSTANTS_H | ||
3 | |||
4 | #include <string> | ||
5 | using namespace std; | ||
6 | #define QString string | ||
7 | |||
8 | #ifdef QWS | ||
9 | #define IMAGES_PATH "/opt/QtPalmtop/pics/sfcave/data/" | ||
10 | #define SOUND_PATH "/opt/QtPalmtop/sounds/sfcave/" | ||
11 | #else | ||
12 | #define IMAGES_PATH "./images/" | ||
13 | #define SOUND_PATH "./sounds/" | ||
14 | #endif | ||
15 | |||
16 | // Width and height of app | ||
17 | #define WIDTH240 | ||
18 | #define HEIGHT320 | ||
19 | |||
20 | //Number of map segments | ||
21 | #define MAPSIZE 51 | ||
22 | |||
23 | // Maximum number of blocks visible on screen at any one time | ||
24 | #define BLOCKSIZE 6 | ||
25 | |||
26 | // length of players trail | ||
27 | #define TRAILSIZE 60 | ||
28 | |||
29 | // Game States | ||
30 | #define STATE_QUIT -1 | ||
31 | #define STATE_PLAYING 0 | ||
32 | #define STATE_CRASHING 1 | ||
33 | #define STATE_CRASHED 2 | ||
34 | #define STATE_NEWGAME 3 | ||
35 | #define STATE_MENU 4 | ||
36 | #define STATE_REPLAY 5 | ||
37 | #define STATE_HELP 6 | ||
38 | |||
39 | // Menu Options | ||
40 | #define MENU_STARTGAME 1 | ||
41 | #define MENU_REPLAYS 2 | ||
42 | #define MENU_OPTIONS 3 | ||
43 | #define MENU_HELP 4 | ||
44 | #define MENU_QUIT 5 | ||
45 | #define MENU_PLAY_REPLAY 6 | ||
46 | #define MENU_LOAD_REPLAY 7 | ||
47 | #define MENU_SAVE_REPLAY 8 | ||
48 | #define MENU_BACK 9 | ||
49 | #define MENU_GAME_TYPE 10 | ||
50 | #define MENU_DIFFICULTY 11 | ||
51 | #define MENU_CLEAR_SCORES 12 | ||
52 | #define MENU_GAME_SFCAVE13 | ||
53 | #define MENU_GAME_GATES 14 | ||
54 | #define MENU_GAME_FLY 15 | ||
55 | #define MENU_DIFFICULTY_EASY16 | ||
56 | #define MENU_DIFFICULTY_NORMAL17 | ||
57 | #define MENU_DIFFICULTY_HARD18 | ||
58 | #define MENU_SOUNDS 19 | ||
59 | #define MENU_SOUND_ON 20 | ||
60 | #define MENU_SOUND_OFF 21 | ||
61 | #define MENU_MUSIC_ON 22 | ||
62 | #define MENU_MUSIC_OFF 23 | ||
63 | |||
64 | // Sounds | ||
65 | #define SND_EXPLOSION 0 | ||
66 | #define SND_THRUST 1 | ||
67 | #endif | ||
diff --git a/noncore/games/sfcave-sdl/fly_game.cpp b/noncore/games/sfcave-sdl/fly_game.cpp new file mode 100644 index 0000000..f5ab401 --- a/dev/null +++ b/noncore/games/sfcave-sdl/fly_game.cpp | |||
@@ -0,0 +1,103 @@ | |||
1 | #include "SDL_gfxPrimitives.h" | ||
2 | |||
3 | #include "constants.h" | ||
4 | #include "fly_game.h" | ||
5 | #include "random.h" | ||
6 | |||
7 | FlyGame :: FlyGame( SFCave *p, int w, int h, int diff ) | ||
8 | : Game( p, w, h, diff ) | ||
9 | { | ||
10 | gameName = "Fly"; | ||
11 | difficulty = MENU_DIFFICULTY_EASY; | ||
12 | |||
13 | terrain = new FlyTerrain( w, h ); | ||
14 | player = new Player( w, h ); | ||
15 | highScore = 0; | ||
16 | } | ||
17 | |||
18 | FlyGame :: ~FlyGame() | ||
19 | { | ||
20 | } | ||
21 | |||
22 | void FlyGame :: init() | ||
23 | { | ||
24 | Game :: init(); | ||
25 | |||
26 | switch( difficulty ) | ||
27 | { | ||
28 | case MENU_DIFFICULTY_EASY: | ||
29 | player->setMovementInfo( 0.3, 0.2, 1.5, 1.5 ); | ||
30 | break; | ||
31 | case MENU_DIFFICULTY_NORMAL: | ||
32 | player->setMovementInfo( 0.35, 0.4, 2.5, 3 ); | ||
33 | break; | ||
34 | case MENU_DIFFICULTY_HARD: | ||
35 | player->setMovementInfo( 0.4, 0.6, 4, 5 ); | ||
36 | break; | ||
37 | } | ||
38 | |||
39 | startScoring = false; | ||
40 | } | ||
41 | |||
42 | void FlyGame :: update( int state ) | ||
43 | { | ||
44 | Game::update( state ); | ||
45 | |||
46 | if ( state == STATE_PLAYING ) | ||
47 | { | ||
48 | |||
49 | if ( nrFrames % 3 == 0 ) | ||
50 | { | ||
51 | int diff = terrain->getMapBottom( 10 ) - player->getY(); | ||
52 | int tmpScore = ((FlyTerrain *)terrain)->getScore( 1, diff ); | ||
53 | // printf( "diff - %d score - %d\n", diff, tmpScore ); | ||
54 | if ( !startScoring ) | ||
55 | { | ||
56 | if ( tmpScore > 0 ) | ||
57 | startScoring = true; | ||
58 | } | ||
59 | |||
60 | if ( startScoring ) | ||
61 | { | ||
62 | // Update score | ||
63 | // get distance between landscape and ship | ||
64 | |||
65 | // the closer the difference is to 0 means more points | ||
66 | score += tmpScore; | ||
67 | } | ||
68 | } | ||
69 | |||
70 | if ( checkCollisions() ) | ||
71 | { | ||
72 | // printf( "Crashed!\n" ); | ||
73 | parent->changeState( STATE_CRASHING ); | ||
74 | return; | ||
75 | } | ||
76 | |||
77 | // Game logic goes here | ||
78 | terrain->moveTerrain( 5 ); | ||
79 | player->move( press ); | ||
80 | } | ||
81 | } | ||
82 | |||
83 | void FlyGame :: draw( SDL_Surface *screen ) | ||
84 | { | ||
85 | Game::preDraw( screen ); | ||
86 | |||
87 | // Screen drawing goes here | ||
88 | terrain->drawTerrain( screen ); | ||
89 | |||
90 | player->draw( screen ); | ||
91 | |||
92 | Game::draw( screen ); | ||
93 | } | ||
94 | |||
95 | |||
96 | bool FlyGame :: checkCollisions() | ||
97 | { | ||
98 | bool ret = false; | ||
99 | |||
100 | // Check collision with landscape | ||
101 | |||
102 | return terrain->checkCollision( player->getX(), player->getY(), player->getHeight() ); | ||
103 | } | ||
diff --git a/noncore/games/sfcave-sdl/fly_game.h b/noncore/games/sfcave-sdl/fly_game.h new file mode 100644 index 0000000..1ab081a --- a/dev/null +++ b/noncore/games/sfcave-sdl/fly_game.h | |||
@@ -0,0 +1,28 @@ | |||
1 | #ifndef __FLY_GAME_H | ||
2 | #define __FLY_GAME_H | ||
3 | |||
4 | #include "sfcave.h" | ||
5 | #include "flyterrain.h" | ||
6 | #include "player.h" | ||
7 | #include "game.h" | ||
8 | #include "SDL.h" | ||
9 | |||
10 | class FlyGame : public Game | ||
11 | { | ||
12 | public: | ||
13 | FlyGame( SFCave *p, int w, int h, int diff ); | ||
14 | ~FlyGame(); | ||
15 | |||
16 | void init(); | ||
17 | void update( int state ); | ||
18 | void draw( SDL_Surface *screen ); | ||
19 | |||
20 | private: | ||
21 | |||
22 | //int movePlayer; | ||
23 | bool startScoring; | ||
24 | |||
25 | bool checkCollisions(); | ||
26 | }; | ||
27 | |||
28 | #endif | ||
diff --git a/noncore/games/sfcave-sdl/flyterrain.cpp b/noncore/games/sfcave-sdl/flyterrain.cpp new file mode 100644 index 0000000..b1b8db5 --- a/dev/null +++ b/noncore/games/sfcave-sdl/flyterrain.cpp | |||
@@ -0,0 +1,103 @@ | |||
1 | |||
2 | #include "SDL_gfxPrimitives.h" | ||
3 | |||
4 | #include "constants.h" | ||
5 | #include "flyterrain.h" | ||
6 | #include "random.h" | ||
7 | |||
8 | |||
9 | int FlyTerrain :: flyScoreZones[][3] = { { 0, 20, 5 }, | ||
10 | { 20, 30, 2 }, | ||
11 | { 30, 40, 0 }, | ||
12 | { 40, 100, -1 }, | ||
13 | { 100, 300, -2 }, | ||
14 | { -1, -1, -1 } }; | ||
15 | |||
16 | FlyTerrain :: FlyTerrain( int w, int h ) | ||
17 | : Terrain( w, h, false, true ) | ||
18 | { | ||
19 | showScoreZones = true; | ||
20 | } | ||
21 | |||
22 | FlyTerrain :: ~FlyTerrain() | ||
23 | { | ||
24 | } | ||
25 | |||
26 | void FlyTerrain :: setPoint( int point ) | ||
27 | { | ||
28 | static int fly_difficulty_levels[] = { 5, 10, 15 }; | ||
29 | if ( nextInt(100) >= 75 ) | ||
30 | dir *= -1; | ||
31 | |||
32 | int prevPoint = mapBottom[point-1]; | ||
33 | |||
34 | int nextPoint = prevPoint + (dir * nextInt( fly_difficulty_levels[0] ) ); | ||
35 | |||
36 | if ( nextPoint > sHeight ) | ||
37 | { | ||
38 | nextPoint = sHeight; | ||
39 | dir *= -1; | ||
40 | } | ||
41 | else if ( nextPoint < maxHeight ) | ||
42 | { | ||
43 | nextPoint = maxHeight; | ||
44 | dir *= 1; | ||
45 | } | ||
46 | |||
47 | mapBottom[point] = nextPoint; | ||
48 | } | ||
49 | |||
50 | void FlyTerrain :: drawTerrain( SDL_Surface *screen ) | ||
51 | { | ||
52 | Terrain::drawTerrain( screen ); | ||
53 | int tmpOffset = offset + speed*segSize; | ||
54 | |||
55 | for ( int i = 0 ; i < MAPSIZE -1; ++i ) | ||
56 | { | ||
57 | |||
58 | if ( showScoreZones ) | ||
59 | { | ||
60 | int r = 0; | ||
61 | int g = 0; | ||
62 | int b = 0; | ||
63 | for ( int j = 1 ; flyScoreZones[j][0] != -1 ; ++j ) | ||
64 | { | ||
65 | if ( flyScoreZones[j][2] == 0 ) | ||
66 | { | ||
67 | g = 255; | ||
68 | b = r = 0; | ||
69 | } | ||
70 | else if ( flyScoreZones[j][2] < 0 ) | ||
71 | { | ||
72 | r = 255; | ||
73 | b = g = 0; | ||
74 | } | ||
75 | else | ||
76 | { | ||
77 | b = 255; | ||
78 | r = g = 0; | ||
79 | } | ||
80 | |||
81 | lineRGBA( screen, (i*segSize) - tmpOffset, mapBottom[i]-flyScoreZones[j][0], ((i+1)*segSize)-tmpOffset, mapBottom[i+1]-flyScoreZones[j][0], r, g, b, 255 ); | ||
82 | |||
83 | } | ||
84 | |||
85 | } | ||
86 | } | ||
87 | } | ||
88 | |||
89 | int FlyTerrain :: getScore( int difficulty, int dist ) | ||
90 | { | ||
91 | int score = 0; | ||
92 | for ( int i = 0 ; flyScoreZones[i][0] != -1 ; ++i ) | ||
93 | { | ||
94 | if ( flyScoreZones[i][0] <= dist && flyScoreZones[i][1] > dist ) | ||
95 | { | ||
96 | score = flyScoreZones[i][2]; | ||
97 | break; | ||
98 | } | ||
99 | } | ||
100 | |||
101 | return score; | ||
102 | } | ||
103 | |||
diff --git a/noncore/games/sfcave-sdl/flyterrain.h b/noncore/games/sfcave-sdl/flyterrain.h new file mode 100644 index 0000000..63b5731 --- a/dev/null +++ b/noncore/games/sfcave-sdl/flyterrain.h | |||
@@ -0,0 +1,29 @@ | |||
1 | #ifndef __FLYTERRAIN_H | ||
2 | #define __FLYTERRAIN_H | ||
3 | |||
4 | #include <SDL.h> | ||
5 | |||
6 | #include "terrain.h" | ||
7 | |||
8 | class FlyTerrain : public Terrain | ||
9 | { | ||
10 | public: | ||
11 | FlyTerrain( int w, int h ); | ||
12 | ~FlyTerrain(); | ||
13 | |||
14 | void drawTerrain( SDL_Surface *screen ); | ||
15 | int getScore( int difficulty, int dist ); | ||
16 | |||
17 | void displayScoreZones( bool val ) { showScoreZones = val; } | ||
18 | |||
19 | protected: | ||
20 | bool showScoreZones; | ||
21 | |||
22 | static int flyScoreZones[][3]; | ||
23 | |||
24 | void setPoint( int point ); | ||
25 | }; | ||
26 | |||
27 | |||
28 | #endif | ||
29 | |||
diff --git a/noncore/games/sfcave-sdl/font.cpp b/noncore/games/sfcave-sdl/font.cpp new file mode 100644 index 0000000..2976d48 --- a/dev/null +++ b/noncore/games/sfcave-sdl/font.cpp | |||
@@ -0,0 +1,72 @@ | |||
1 | #include "font.h" | ||
2 | |||
3 | #include "constants.h" | ||
4 | |||
5 | BFont *FontHandler :: menuSelFont; | ||
6 | BFont *FontHandler :: menuUnSelFont; | ||
7 | BFont *FontHandler :: whiteFont; | ||
8 | BFont *FontHandler :: colouredFont; | ||
9 | BFont *FontHandler :: helpFont; | ||
10 | |||
11 | void FontHandler :: init() | ||
12 | { | ||
13 | // Load font images | ||
14 | // Convert to fonts | ||
15 | menuSelFont = new BFont( IMAGES_PATH "sel_menu_font.bmp" ); | ||
16 | menuUnSelFont = new BFont( IMAGES_PATH "unsel_menu_font.bmp" ); | ||
17 | whiteFont = new BFont( IMAGES_PATH "score_font.bmp" ); | ||
18 | helpFont = new BFont( IMAGES_PATH "help_font.bmp" ); | ||
19 | colouredFont = 0; | ||
20 | } | ||
21 | |||
22 | void FontHandler :: cleanUp() | ||
23 | { | ||
24 | delete menuSelFont; | ||
25 | delete menuUnSelFont; | ||
26 | delete whiteFont; | ||
27 | delete helpFont; | ||
28 | |||
29 | if ( colouredFont ) | ||
30 | delete colouredFont; | ||
31 | } | ||
32 | |||
33 | int FontHandler :: TextWidth( int font, const char *text ) | ||
34 | { | ||
35 | return getFont( font )->TextWidth( text ); | ||
36 | } | ||
37 | |||
38 | int FontHandler :: FontHeight( int font ) | ||
39 | { | ||
40 | return getFont( font )->FontHeight(); | ||
41 | } | ||
42 | |||
43 | void FontHandler :: draw( SDL_Surface *screen, int font, const char *text, int x, int y ) | ||
44 | { | ||
45 | if ( x == -1 ) | ||
46 | getFont( font )->CenteredPutString( screen, y, text ); | ||
47 | else | ||
48 | getFont( font )->PutString( screen, x, y, text ); | ||
49 | } | ||
50 | |||
51 | void FontHandler :: changeColor( int font, int r, int g, int b ) | ||
52 | { | ||
53 | if ( colouredFont ) | ||
54 | delete colouredFont; | ||
55 | |||
56 | colouredFont = getFont( font )->SetFontColor( r, g, b ); | ||
57 | } | ||
58 | |||
59 | |||
60 | BFont *FontHandler :: getFont( int font ) | ||
61 | { | ||
62 | if ( font == FONT_MENU_HIGHLIGHTED ) | ||
63 | return menuSelFont; | ||
64 | else if ( font == FONT_MENU_UNHIGHLIGHTED ) | ||
65 | return menuUnSelFont; | ||
66 | else if ( font == FONT_COLOURED_TEXT ) | ||
67 | return colouredFont; | ||
68 | else if ( font == FONT_HELP_FONT ) | ||
69 | return helpFont; | ||
70 | else | ||
71 | return whiteFont; | ||
72 | } | ||
diff --git a/noncore/games/sfcave-sdl/font.h b/noncore/games/sfcave-sdl/font.h new file mode 100644 index 0000000..e5bb707 --- a/dev/null +++ b/noncore/games/sfcave-sdl/font.h | |||
@@ -0,0 +1,33 @@ | |||
1 | #ifndef __FONT_H | ||
2 | #define __FONT_H | ||
3 | |||
4 | #include "SDL.h" | ||
5 | #include "bfont.h" | ||
6 | |||
7 | #define FONT_MENU_HIGHLIGHTED 1 | ||
8 | #define FONT_MENU_UNHIGHLIGHTED 2 | ||
9 | #define FONT_WHITE_TEXT 3 | ||
10 | #define FONT_COLOURED_TEXT 4 | ||
11 | #define FONT_HELP_FONT 5 | ||
12 | |||
13 | class FontHandler | ||
14 | { | ||
15 | public: | ||
16 | static void init(); | ||
17 | static void cleanUp(); | ||
18 | |||
19 | static int TextWidth( int font, const char *text ); | ||
20 | static int FontHeight( int font ); | ||
21 | static void draw( SDL_Surface *screen, int font, const char *text, int x, int y ); | ||
22 | static void changeColor( int font, int r, int g, int b ); | ||
23 | |||
24 | static BFont *getFont( int font ); | ||
25 | private: | ||
26 | static BFont *menuSelFont; | ||
27 | static BFont *menuUnSelFont; | ||
28 | static BFont *whiteFont; | ||
29 | static BFont *colouredFont; | ||
30 | static BFont *helpFont; | ||
31 | }; | ||
32 | |||
33 | #endif | ||
diff --git a/noncore/games/sfcave-sdl/game.cpp b/noncore/games/sfcave-sdl/game.cpp new file mode 100644 index 0000000..a644696 --- a/dev/null +++ b/noncore/games/sfcave-sdl/game.cpp | |||
@@ -0,0 +1,332 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <time.h> | ||
3 | |||
4 | #include <SDL.h> | ||
5 | #include <SDL_image.h> | ||
6 | |||
7 | #include "font.h" | ||
8 | |||
9 | #include "constants.h" | ||
10 | #include "game.h" | ||
11 | #include "player.h" | ||
12 | #include "random.h" | ||
13 | #include "sound.h" | ||
14 | #include "stringtokenizer.h" | ||
15 | |||
16 | #include "sfcave_game.h" | ||
17 | #include "gates_game.h" | ||
18 | #include "fly_game.h" | ||
19 | #include "starfield.h" | ||
20 | |||
21 | Game :: Game( SFCave *p, int w, int h, int diff ) | ||
22 | { | ||
23 | parent = p; | ||
24 | sHeight = h; | ||
25 | sWidth = w; | ||
26 | difficulty = diff; | ||
27 | replayIt = 0; | ||
28 | replay = false; | ||
29 | terrain = 0; | ||
30 | player = 0; | ||
31 | thrustChannel = -1; | ||
32 | } | ||
33 | |||
34 | Game :: ~Game() | ||
35 | { | ||
36 | if ( terrain ) | ||
37 | delete terrain; | ||
38 | |||
39 | if ( player ) | ||
40 | delete player; | ||
41 | |||
42 | replayList.clear(); | ||
43 | } | ||
44 | |||
45 | void Game :: init() | ||
46 | { | ||
47 | if ( replay ) | ||
48 | { | ||
49 | setSeed( currentSeed ); | ||
50 | replayIt = replayList.begin(); | ||
51 | } | ||
52 | else | ||
53 | { | ||
54 | setSeed( -1 ); | ||
55 | replayList.clear(); | ||
56 | } | ||
57 | |||
58 | score = 0; | ||
59 | nrFrames = 0; | ||
60 | press = false; | ||
61 | |||
62 | // Load highscore | ||
63 | string key = getGameName() + "_" + getGameDifficultyText() + "_highscore"; | ||
64 | highScore = atoi( parent->loadSetting( key, "0" ).c_str() ); | ||
65 | |||
66 | terrain->initTerrain(); | ||
67 | player->init(); | ||
68 | } | ||
69 | |||
70 | void Game :: handleKeys( SDL_KeyboardEvent &key ) | ||
71 | { | ||
72 | if ( !replay && key.keysym.sym == SDLK_SPACE ) | ||
73 | { | ||
74 | if ( key.type == SDL_KEYDOWN ) | ||
75 | { | ||
76 | if ( !press ) | ||
77 | replayList.push_back( nrFrames ); | ||
78 | press = true; | ||
79 | |||
80 | // if ( thrustChannel == -1 && parent->getState() == STATE_PLAYING ) | ||
81 | // thrustChannel = SoundHandler :: playSound( SND_THRUST, -1, -1, false ); | ||
82 | } | ||
83 | else | ||
84 | { | ||
85 | if ( press ) | ||
86 | replayList.push_back( nrFrames ); | ||
87 | press = false; | ||
88 | |||
89 | if ( thrustChannel != -1 ) | ||
90 | { | ||
91 | // SoundHandler :: stopSound( thrustChannel, true, 300 ); | ||
92 | // thrustChannel = -1; | ||
93 | } | ||
94 | } | ||
95 | } | ||
96 | } | ||
97 | |||
98 | |||
99 | |||
100 | QString Game :: getGameDifficultyText() | ||
101 | { | ||
102 | QString ret; | ||
103 | |||
104 | if ( difficulty == MENU_DIFFICULTY_EASY ) | ||
105 | ret = "Easy"; | ||
106 | else if ( difficulty == MENU_DIFFICULTY_NORMAL ) | ||
107 | ret = "Medium"; | ||
108 | else if ( difficulty == MENU_DIFFICULTY_HARD ) | ||
109 | ret = "Hard"; | ||
110 | |||
111 | return ret; | ||
112 | } | ||
113 | |||
114 | void Game :: setDifficulty( string diff ) | ||
115 | { | ||
116 | if ( diff == "Easy" ) | ||
117 | difficulty = MENU_DIFFICULTY_EASY; | ||
118 | else if ( diff == "Medium" ) | ||
119 | difficulty = MENU_DIFFICULTY_NORMAL; | ||
120 | else if ( diff == "Hard" ) | ||
121 | difficulty = MENU_DIFFICULTY_HARD; | ||
122 | } | ||
123 | |||
124 | void Game :: update( int state ) | ||
125 | { | ||
126 | nrFrames ++; | ||
127 | |||
128 | if ( score > highScore ) | ||
129 | highScore = score; | ||
130 | |||
131 | |||
132 | if ( state == STATE_PLAYING ) | ||
133 | { | ||
134 | if ( replay ) | ||
135 | { | ||
136 | while( replayIt != replayList.end() && (*replayIt) == nrFrames-1 ) | ||
137 | { | ||
138 | press = !press; | ||
139 | replayIt ++; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | if ( press && thrustChannel == -1 ) | ||
144 | thrustChannel = SoundHandler :: playSound( SND_THRUST, -1, -1, false ); | ||
145 | |||
146 | if ( !press &&thrustChannel != -1 ) | ||
147 | { | ||
148 | SoundHandler :: stopSound( thrustChannel, true, 300 ); | ||
149 | thrustChannel = -1; | ||
150 | } | ||
151 | } | ||
152 | |||
153 | if ( state == STATE_CRASHING || state == STATE_CRASHED ) | ||
154 | { | ||
155 | // fade out any trail marks remainin | ||
156 | if ( player->updateCrashing() ) | ||
157 | parent->changeState( STATE_CRASHED ); | ||
158 | |||
159 | } | ||
160 | } | ||
161 | |||
162 | void Game :: preDraw( SDL_Surface *screen ) | ||
163 | { | ||
164 | } | ||
165 | |||
166 | void Game :: draw( SDL_Surface *screen ) | ||
167 | { | ||
168 | char tmp[100]; | ||
169 | QString scoreText; | ||
170 | sprintf( tmp, "Score: %06ld High Score: %06ld", score, highScore ); | ||
171 | //printf( "%s\n", (const char *)scoreText ); | ||
172 | FontHandler::draw( screen, FONT_WHITE_TEXT, tmp, 3, 10 ); | ||
173 | |||
174 | if ( parent->getState() == STATE_CRASHED ) | ||
175 | { | ||
176 | QString crashText; | ||
177 | crashText = "Game Over"; | ||
178 | int x = (240 - FontHandler::TextWidth( FONT_WHITE_TEXT, (const char *)crashText.c_str() )) / 2; | ||
179 | FontHandler::draw( screen, FONT_WHITE_TEXT, (const char *)crashText.c_str(), x, 150 ); | ||
180 | |||
181 | int fontHeight = FontHandler::FontHeight( FONT_WHITE_TEXT ); | ||
182 | crashText = "Press Middle Button to play again"; | ||
183 | x = (240 - FontHandler::TextWidth( FONT_WHITE_TEXT, (const char *)crashText.c_str() )) / 2; | ||
184 | FontHandler::draw( screen, FONT_WHITE_TEXT, (const char *)crashText.c_str(), x, 150 + fontHeight ); | ||
185 | |||
186 | crashText = "or OK for menu"; | ||
187 | x = (240 - FontHandler::TextWidth( FONT_WHITE_TEXT, (const char *)crashText.c_str() )) / 2; | ||
188 | FontHandler::draw( screen, FONT_WHITE_TEXT, (const char *)crashText.c_str(), x, 150 + 2*fontHeight ); | ||
189 | } | ||
190 | |||
191 | if ( parent->showFPS() ) | ||
192 | { | ||
193 | sprintf( tmp, "FPS : %d", parent->getFPS() ); | ||
194 | FontHandler::draw( screen, FONT_WHITE_TEXT, tmp, 20, 300 ); | ||
195 | } | ||
196 | } | ||
197 | |||
198 | void Game :: stateChanged( int from, int to ) | ||
199 | { | ||
200 | if ( from != STATE_CRASHING && to == STATE_CRASHING ) | ||
201 | { | ||
202 | // play explosion sound | ||
203 | SoundHandler :: stopSound( -1, false ); | ||
204 | SoundHandler :: playSound( SND_EXPLOSION ); | ||
205 | |||
206 | // Check and save highscore | ||
207 | printf( "Got Highscore = %d\n", gotHighScore() ); | ||
208 | if ( gotHighScore() ) | ||
209 | { | ||
210 | string key = getGameName() + "_" + getGameDifficultyText() + "_highscore"; | ||
211 | parent->saveSetting( key, getHighScore() ); | ||
212 | } | ||
213 | |||
214 | } | ||
215 | } | ||
216 | |||
217 | void Game :: setSeed( int seed ) | ||
218 | { | ||
219 | if ( seed == -1 ) | ||
220 | currentSeed = ((unsigned long) time((time_t *) NULL)); | ||
221 | else | ||
222 | currentSeed = seed; | ||
223 | PutSeed( currentSeed ); | ||
224 | } | ||
225 | |||
226 | void Game :: saveReplay( QString file ) | ||
227 | { | ||
228 | FILE *out; | ||
229 | out = fopen( file.c_str(), "w" ); | ||
230 | if ( !out ) | ||
231 | { | ||
232 | printf( "Couldn't write to /home/root/%s\n", file.c_str() ); | ||
233 | parent->setMenuStatusText( "Couldn't save replay file" ); | ||
234 | return; | ||
235 | } | ||
236 | |||
237 | // Build up string of values | ||
238 | // Format is:: <landscape seed> <game type> <difficulty> <framenr> <framenr>....... | ||
239 | QString val; | ||
240 | char tmp[20]; | ||
241 | sprintf( tmp, "%d %d ", currentSeed, difficulty ); | ||
242 | val = tmp; | ||
243 | |||
244 | list<int>::iterator it = replayList.begin(); | ||
245 | while( it != replayList.end() ) | ||
246 | { | ||
247 | sprintf( tmp, "%d ", *it ); | ||
248 | val += tmp; | ||
249 | |||
250 | it++; | ||
251 | } | ||
252 | val += "\n"; | ||
253 | |||
254 | QString line; | ||
255 | sprintf( tmp, "%d\n", val.length() ); | ||
256 | line = tmp; | ||
257 | fwrite( line.c_str(), 1, line.length(), out ); | ||
258 | |||
259 | fwrite( val.c_str(), 1, val.length(), out ); | ||
260 | |||
261 | fclose( out ); | ||
262 | |||
263 | printf( "Replay saved to %s\n", (const char *)file.c_str() ); | ||
264 | |||
265 | } | ||
266 | |||
267 | void Game :: loadReplay( QString file ) | ||
268 | { | ||
269 | |||
270 | FILE *in = fopen( (const char *)file.c_str(), "r" ); | ||
271 | |||
272 | if ( in == 0 ) | ||
273 | { | ||
274 | printf( "Couldn't load replay file %s!\n", (const char *)file.c_str() ); | ||
275 | parent->setMenuStatusText( "Couldn't load replay file" ); | ||
276 | return; | ||
277 | } | ||
278 | |||
279 | // Read next line - contains the size of the options | ||
280 | char line[10+1]; | ||
281 | fgets( line, 10, in ); | ||
282 | |||
283 | int length = -1; | ||
284 | sscanf( line, "%d", &length ); | ||
285 | char *data = new char[length+1]; | ||
286 | |||
287 | fread( data, 1, length, in ); | ||
288 | // printf( "data - %s", data ); | ||
289 | |||
290 | QString sep = " "; | ||
291 | |||
292 | StringTokenizer st( data, sep ); | ||
293 | |||
294 | // print it out | ||
295 | vector<string>::iterator it = st.begin(); | ||
296 | currentSeed = atoi( (*it).c_str() ); | ||
297 | ++it; | ||
298 | difficulty = atoi( (*it).c_str() ); | ||
299 | ++it; | ||
300 | |||
301 | replayList.clear(); | ||
302 | for ( ; it != st.end(); ++it ) | ||
303 | { | ||
304 | int v = atoi( (*it).c_str() ); | ||
305 | replayList.push_back( v ); | ||
306 | } | ||
307 | |||
308 | delete data; | ||
309 | |||
310 | fclose( in ); | ||
311 | |||
312 | printf( "Replay loaded from %s\n", (const char *)file.c_str() ); | ||
313 | |||
314 | } | ||
315 | |||
316 | |||
317 | Game *Game :: createGame( SFCave *p, int w, int h, string game, string difficulty ) | ||
318 | { | ||
319 | Game *g; | ||
320 | |||
321 | if ( game == "SFCave" ) | ||
322 | g = new SFCaveGame( p, w, h, 0 ); | ||
323 | else if ( game == "Gates" ) | ||
324 | g = new GatesGame( p, w, h, 0 ); | ||
325 | else if ( game == "Fly" ) | ||
326 | g = new FlyGame( p, w, h, 0 ); | ||
327 | |||
328 | if ( g ) | ||
329 | g->setDifficulty( difficulty ); | ||
330 | |||
331 | return g; | ||
332 | } | ||
diff --git a/noncore/games/sfcave-sdl/game.h b/noncore/games/sfcave-sdl/game.h new file mode 100644 index 0000000..56fa6a1 --- a/dev/null +++ b/noncore/games/sfcave-sdl/game.h | |||
@@ -0,0 +1,82 @@ | |||
1 | #ifndef __GAME_H | ||
2 | #define __GAME_H | ||
3 | |||
4 | #include <list> | ||
5 | using namespace std; | ||
6 | |||
7 | #include "sfcave.h" | ||
8 | |||
9 | class Terrain; | ||
10 | class Player; | ||
11 | |||
12 | class Game | ||
13 | { | ||
14 | public: | ||
15 | Game( SFCave *p, int w, int h, int diff ); | ||
16 | virtual ~Game(); | ||
17 | |||
18 | virtual void init( ); | ||
19 | virtual void update( int state ); | ||
20 | virtual void preDraw( SDL_Surface * ); | ||
21 | virtual void draw( SDL_Surface * ); | ||
22 | |||
23 | virtual void stateChanged( int from, int to ); | ||
24 | |||
25 | void setReplay( bool val ) { replay = val; } | ||
26 | |||
27 | void handleKeys( SDL_KeyboardEvent &key ); | ||
28 | QString getGameName() { return gameName; } | ||
29 | int getDifficulty() { return difficulty; } | ||
30 | QString getGameDifficultyText(); | ||
31 | void setDifficulty( int diff ) { difficulty = diff; } | ||
32 | void setDifficulty( string diff ); | ||
33 | |||
34 | long getScore() { return score; } | ||
35 | long getHighScore() { return highScore; } | ||
36 | void increaseScore( long val ) { score += val; } | ||
37 | void clearScore() { score = 0; } | ||
38 | bool gotHighScore() { return (score >= highScore); } | ||
39 | bool isReplayAvailable() { return replayList.size() > 0; } | ||
40 | |||
41 | Terrain *getTerrain() { return terrain; } | ||
42 | |||
43 | void setSeed( int seed ); | ||
44 | void loadReplay( QString file ); | ||
45 | void saveReplay( QString file ); | ||
46 | |||
47 | static Game *createGame( SFCave *p, int w, int h, string game, string difficulty ); | ||
48 | |||
49 | protected: | ||
50 | QString gameName; | ||
51 | |||
52 | int thrustChannel; | ||
53 | |||
54 | int difficulty; | ||
55 | |||
56 | SFCave *parent; | ||
57 | Terrain *terrain; | ||
58 | Player *player; | ||
59 | |||
60 | int nrFrames; | ||
61 | |||
62 | bool press; | ||
63 | |||
64 | int sHeight; | ||
65 | int sWidth; | ||
66 | long score; | ||
67 | long highScore; | ||
68 | |||
69 | // Stuff for the replays | ||
70 | int currentSeed; | ||
71 | |||
72 | // QListIterator<int> *replayIt; | ||
73 | list<int> replayList; | ||
74 | list<int>::iterator replayIt; | ||
75 | //QList<int> replayList; | ||
76 | bool replay; | ||
77 | QString replayFile; | ||
78 | |||
79 | private: | ||
80 | }; | ||
81 | |||
82 | #endif | ||
diff --git a/noncore/games/sfcave-sdl/gates_game.cpp b/noncore/games/sfcave-sdl/gates_game.cpp new file mode 100644 index 0000000..1a9bc89 --- a/dev/null +++ b/noncore/games/sfcave-sdl/gates_game.cpp | |||
@@ -0,0 +1,188 @@ | |||
1 | #include "SDL_gfxPrimitives.h" | ||
2 | |||
3 | #include "constants.h" | ||
4 | #include "gates_game.h" | ||
5 | #include "random.h" | ||
6 | |||
7 | GatesGame :: GatesGame( SFCave *p, int w, int h, int diff ) | ||
8 | : Game( p, w, h, diff ) | ||
9 | { | ||
10 | gameName = "Gates"; | ||
11 | difficulty = MENU_DIFFICULTY_EASY; | ||
12 | blockUpdateRate = 200; | ||
13 | |||
14 | terrain = new Terrain( w, h ); | ||
15 | player = new Player( w, h ); | ||
16 | highScore = 0; | ||
17 | } | ||
18 | |||
19 | GatesGame :: ~GatesGame() | ||
20 | { | ||
21 | } | ||
22 | |||
23 | void GatesGame :: init() | ||
24 | { | ||
25 | Game :: init(); | ||
26 | |||
27 | blockHeight = 80; | ||
28 | blockWidth = 20; | ||
29 | lastGateBottomY = 0; | ||
30 | |||
31 | gateDistance = 75; | ||
32 | nextGate = nextInt( 50 ) + gateDistance; | ||
33 | gapHeight = 75; | ||
34 | |||
35 | switch( difficulty ) | ||
36 | { | ||
37 | case MENU_DIFFICULTY_EASY: | ||
38 | gapHeight = 75; | ||
39 | player->setMovementInfo( 0.4, 0.6, 4, 5 ); | ||
40 | break; | ||
41 | case MENU_DIFFICULTY_NORMAL: | ||
42 | gapHeight = 50; | ||
43 | player->setMovementInfo( 0.4, 0.6, 4, 5 ); | ||
44 | break; | ||
45 | case MENU_DIFFICULTY_HARD: | ||
46 | gapHeight = 25; | ||
47 | player->setMovementInfo( 0.6, 0.8, 6, 7 ); | ||
48 | break; | ||
49 | } | ||
50 | |||
51 | for ( int i = 0 ; i < BLOCKSIZE ; ++i ) | ||
52 | blocks[i].y( -1 ); | ||
53 | } | ||
54 | |||
55 | void GatesGame :: update( int state ) | ||
56 | { | ||
57 | Game::update( state ); | ||
58 | |||
59 | // Game logic goes here | ||
60 | if ( state == STATE_PLAYING ) | ||
61 | { | ||
62 | if ( nrFrames % 3 == 0 ) | ||
63 | score ++; | ||
64 | |||
65 | if ( nrFrames % 500 == 0 ) | ||
66 | { | ||
67 | if ( gapHeight > 75 ) | ||
68 | gapHeight -= 5; | ||
69 | } | ||
70 | |||
71 | // Slightly random gap distance | ||
72 | if ( nrFrames >= nextGate ) | ||
73 | { | ||
74 | nextGate = nrFrames + nextInt( 50 ) + gateDistance; | ||
75 | addGate(); | ||
76 | } | ||
77 | |||
78 | if ( checkCollisions() ) | ||
79 | { | ||
80 | // printf( "Crashed!\n" ); | ||
81 | parent->changeState( STATE_CRASHING ); | ||
82 | return; | ||
83 | } | ||
84 | |||
85 | terrain->moveTerrain( 5 ); | ||
86 | moveBlocks( 5 ); | ||
87 | player->move( press ); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | void GatesGame :: draw( SDL_Surface *screen ) | ||
92 | { | ||
93 | Game::preDraw( screen ); | ||
94 | |||
95 | if ( parent->getState() == STATE_PLAYING ) | ||
96 | { | ||
97 | // Screen drawing goes here | ||
98 | terrain->drawTerrain( screen ); | ||
99 | |||
100 | player->draw( screen ); | ||
101 | |||
102 | drawBlocks( screen ); | ||
103 | } | ||
104 | else | ||
105 | { | ||
106 | // Screen drawing goes here | ||
107 | terrain->drawTerrain( screen ); | ||
108 | |||
109 | drawBlocks( screen ); | ||
110 | |||
111 | player->draw( screen ); | ||
112 | } | ||
113 | |||
114 | Game::draw( screen ); | ||
115 | } | ||
116 | |||
117 | |||
118 | void GatesGame :: addGate() | ||
119 | { | ||
120 | printf( "gapHeight = %d\n", gapHeight ); | ||
121 | for ( int i = 0 ; i < BLOCKSIZE ; ++i ) | ||
122 | { | ||
123 | if ( blocks[i].y() == -1 ) | ||
124 | { | ||
125 | int x1 = sWidth; | ||
126 | int y1 = terrain->getMapTop(50); | ||
127 | int b1Height = nextInt(terrain->getMapBottom( 50 ) - terrain->getMapTop(50) - gapHeight); | ||
128 | |||
129 | // See if height between last gate and this one is too big | ||
130 | if ( b1Height - 100 > lastGateBottomY ) | ||
131 | b1Height -= 25; | ||
132 | else if ( b1Height + 100 < lastGateBottomY ) | ||
133 | b1Height += 25; | ||
134 | lastGateBottomY = b1Height; | ||
135 | |||
136 | |||
137 | int x2 = sWidth; | ||
138 | int y2 = y1 + b1Height + gapHeight; | ||
139 | int b2Height = terrain->getMapBottom( 50 ) - y2; | ||
140 | |||
141 | |||
142 | blocks[i].setRect( x1, y1, blockWidth, b1Height ); | ||
143 | blocks[i+1].setRect( x2, y2, blockWidth, b2Height ); | ||
144 | |||
145 | break; | ||
146 | } | ||
147 | } | ||
148 | } | ||
149 | |||
150 | void GatesGame :: moveBlocks( int amountToMove ) | ||
151 | { | ||
152 | for ( int i = 0 ; i < BLOCKSIZE ; ++i ) | ||
153 | { | ||
154 | if ( blocks[i].y() != -1 ) | ||
155 | { | ||
156 | blocks[i].moveBy( -amountToMove, 0 ); | ||
157 | if ( blocks[i].x() + blocks[i].y() < 0 ) | ||
158 | blocks[i].y( -1 ); | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | |||
163 | void GatesGame :: drawBlocks( SDL_Surface *screen ) | ||
164 | { | ||
165 | for ( int i = 0 ; i < BLOCKSIZE ; ++i ) | ||
166 | { | ||
167 | if ( blocks[i].y() != -1 ) | ||
168 | { | ||
169 | SDL_Rect r = blocks[i].getRect(); | ||
170 | SDL_FillRect( screen, &r, SDL_MapRGB( screen->format, 100, 100, 255 ) ); | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | |||
175 | bool GatesGame :: checkCollisions() | ||
176 | { | ||
177 | // Check collisions with blocks | ||
178 | for ( int i = 0 ; i < BLOCKSIZE ; ++i ) | ||
179 | { | ||
180 | if ( blocks[i].y() != -1 ) | ||
181 | { | ||
182 | if ( blocks[i].intersects( player->getPos() ) ) | ||
183 | return true; | ||
184 | } | ||
185 | } | ||
186 | // Check collision with landscape | ||
187 | return terrain->checkCollision( player->getX(), player->getY(), player->getHeight() ); | ||
188 | } | ||
diff --git a/noncore/games/sfcave-sdl/gates_game.h b/noncore/games/sfcave-sdl/gates_game.h new file mode 100644 index 0000000..8499ff9 --- a/dev/null +++ b/noncore/games/sfcave-sdl/gates_game.h | |||
@@ -0,0 +1,45 @@ | |||
1 | #ifndef __GATES_GAME_H | ||
2 | #define __GATES_GAME_H | ||
3 | |||
4 | #include "SDL.h" | ||
5 | |||
6 | #include "rect.h" | ||
7 | |||
8 | #include "sfcave.h" | ||
9 | #include "terrain.h" | ||
10 | #include "player.h" | ||
11 | #include "game.h" | ||
12 | |||
13 | class GatesGame : public Game | ||
14 | { | ||
15 | public: | ||
16 | GatesGame( SFCave *p, int w, int h, int diff ); | ||
17 | ~GatesGame(); | ||
18 | |||
19 | void init(); | ||
20 | void update( int state ); | ||
21 | void draw( SDL_Surface *screen ); | ||
22 | |||
23 | private: | ||
24 | |||
25 | int gapHeight; | ||
26 | |||
27 | int gateDistance; | ||
28 | int nextGate; | ||
29 | int lastGateBottomY; | ||
30 | |||
31 | int blockDistance; | ||
32 | int blockHeight; | ||
33 | int blockWidth; | ||
34 | int blockUpdateRate; | ||
35 | |||
36 | Rect blocks[BLOCKSIZE]; | ||
37 | |||
38 | void addGate(); | ||
39 | void moveBlocks( int amountToMove ); | ||
40 | void drawBlocks( SDL_Surface *screen ); | ||
41 | bool checkCollisions(); | ||
42 | |||
43 | }; | ||
44 | |||
45 | #endif | ||
diff --git a/noncore/games/sfcave-sdl/help.cpp b/noncore/games/sfcave-sdl/help.cpp new file mode 100644 index 0000000..91c62da --- a/dev/null +++ b/noncore/games/sfcave-sdl/help.cpp | |||
@@ -0,0 +1,237 @@ | |||
1 | #include "SDL.h" | ||
2 | #include "constants.h" | ||
3 | |||
4 | #include "font.h" | ||
5 | #include "help.h" | ||
6 | #include "sfcave.h" | ||
7 | #include "starfield.h" | ||
8 | |||
9 | Help :: Help( SFCave *p ) | ||
10 | { | ||
11 | parent = p; | ||
12 | stars = new StarField( false, 200 ); | ||
13 | |||
14 | loadText(); | ||
15 | |||
16 | init(); | ||
17 | } | ||
18 | |||
19 | Help :: ~Help() | ||
20 | { | ||
21 | delete stars; | ||
22 | } | ||
23 | |||
24 | void Help :: handleKeys( SDL_KeyboardEvent &key ) | ||
25 | { | ||
26 | if ( key.type == SDL_KEYDOWN ) | ||
27 | { | ||
28 | if ( key.keysym.sym == SDLK_SPACE ) | ||
29 | parent->changeState( STATE_MENU ); | ||
30 | else if ( key.keysym.sym == SDLK_DOWN ) | ||
31 | textSpeed = 5; | ||
32 | else if ( key.keysym.sym == SDLK_UP ) | ||
33 | { | ||
34 | if ( textSpeed > 0 ) | ||
35 | textSpeed = 0; | ||
36 | else textSpeed = 1; | ||
37 | } | ||
38 | |||
39 | } | ||
40 | else if ( key.type == SDL_KEYUP ) | ||
41 | { | ||
42 | if ( key.keysym.sym == SDLK_DOWN ) | ||
43 | textSpeed = 1; | ||
44 | } | ||
45 | } | ||
46 | void Help :: init() | ||
47 | { | ||
48 | startPos = 320; | ||
49 | currLine = 0; | ||
50 | textSpeed = 1; | ||
51 | |||
52 | // Create our coloured font | ||
53 | FontHandler :: changeColor( FONT_HELP_FONT, 0, 0, 255 ); | ||
54 | } | ||
55 | |||
56 | void Help :: draw( SDL_Surface *screen ) | ||
57 | { | ||
58 | stars->draw( screen ); | ||
59 | |||
60 | |||
61 | list<string>::iterator it = textList.begin(); | ||
62 | |||
63 | // Move to start of text | ||
64 | for ( int i = 0 ; i < currLine && it != textList.end() ; ++i ) | ||
65 | it++; | ||
66 | |||
67 | int pos = startPos; | ||
68 | while ( pos < 320 && it != textList.end() ) | ||
69 | { | ||
70 | // get next line | ||
71 | string text = *it; | ||
72 | |||
73 | // draw text | ||
74 | FontHandler::draw( screen, FONT_COLOURED_TEXT, text.c_str(), -1, pos ); | ||
75 | pos += FontHandler::FontHeight( FONT_COLOURED_TEXT ); | ||
76 | it ++; | ||
77 | } | ||
78 | |||
79 | } | ||
80 | |||
81 | void Help :: update() | ||
82 | { | ||
83 | stars->move(); | ||
84 | |||
85 | startPos -= textSpeed; | ||
86 | if ( startPos <= -FontHandler::FontHeight( FONT_COLOURED_TEXT ) ) | ||
87 | { | ||
88 | startPos = 0; | ||
89 | currLine ++; | ||
90 | |||
91 | if ( currLine > textList.size() ) | ||
92 | { | ||
93 | startPos = 320; | ||
94 | currLine = 0; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | } | ||
99 | |||
100 | void Help :: loadText() | ||
101 | { | ||
102 | textList.push_back( "SFCave" ); | ||
103 | textList.push_back( "Written By AndyQ" ); | ||
104 | textList.push_back( "" ); | ||
105 | textList.push_back( "Instructions" ); | ||
106 | textList.push_back( "To return to the menu" ); | ||
107 | textList.push_back( "press the space or " ); | ||
108 | textList.push_back( "middle button." ); | ||
109 | textList.push_back( "" ); | ||
110 | textList.push_back( "To speed up the text" ); | ||
111 | textList.push_back( "hold the down button" ); | ||
112 | textList.push_back( "(releasing will return" ); | ||
113 | textList.push_back( "to normal speed)" ); | ||
114 | textList.push_back( "" ); | ||
115 | textList.push_back( "" ); | ||
116 | textList.push_back( "SFCave is a flying game" ); | ||
117 | textList.push_back( "writtin originally for the" ); | ||
118 | textList.push_back( "Sharp Zaurus." ); | ||
119 | textList.push_back( "" ); | ||
120 | textList.push_back( "The aim is to stay alive" ); | ||
121 | textList.push_back( "for as long as possible," ); | ||
122 | textList.push_back( "and get the highest score" ); | ||
123 | textList.push_back( "you can." ); | ||
124 | textList.push_back( "" ); | ||
125 | textList.push_back( "There are currently three" ); | ||
126 | textList.push_back( "game types - SFCave," ); | ||
127 | textList.push_back( "Gates, and Fly." ); | ||
128 | textList.push_back( "" ); | ||
129 | textList.push_back( "SFCave is a remake of" ); | ||
130 | textList.push_back( "the classic SFCave game." ); | ||
131 | textList.push_back( "Fly through the cavern" ); | ||
132 | textList.push_back( "avoiding all the blocks" ); | ||
133 | textList.push_back( "that just happen to be" ); | ||
134 | textList.push_back( "hanging in mid-air" ); | ||
135 | textList.push_back( "" ); | ||
136 | textList.push_back( "Gates is similar to" ); | ||
137 | textList.push_back( "SFCave but instead of" ); | ||
138 | textList.push_back( "avoiding blocks you must" ); | ||
139 | textList.push_back( "fly through gates without" ); | ||
140 | textList.push_back( "crashing." ); | ||
141 | textList.push_back( "" ); | ||
142 | textList.push_back( "Fly is a different kettle of" ); | ||
143 | textList.push_back( "fish altogether. Instead," ); | ||
144 | textList.push_back( "you are flying in the " ); | ||
145 | textList.push_back( "open air above a" ); | ||
146 | textList.push_back( "scrolling landscape and" ); | ||
147 | textList.push_back( "the aim is to fly as close" ); | ||
148 | textList.push_back( "to the land as possible." ); | ||
149 | textList.push_back( "The closer to the land" ); | ||
150 | textList.push_back( "you fly the more points" ); | ||
151 | textList.push_back( "you score. But beware," ); | ||
152 | textList.push_back( "fly too high above the" ); | ||
153 | textList.push_back( "land and points get" ); | ||
154 | textList.push_back( "deducted." ); | ||
155 | textList.push_back( "" ); | ||
156 | textList.push_back( "How to play" ); | ||
157 | textList.push_back( "Press the space or middle" ); | ||
158 | textList.push_back( "button (Zaurus only) to " ); | ||
159 | textList.push_back( "apply thrust (makes you" ); | ||
160 | textList.push_back( "go up) and release it" ); | ||
161 | textList.push_back( "to go down." ); | ||
162 | textList.push_back( "" ); | ||
163 | textList.push_back( "Have fun" ); | ||
164 | textList.push_back( "AndyQ" ); | ||
165 | } | ||
166 | |||
167 | // Test | ||
168 | #ifdef DEBUG_HELP | ||
169 | SDL_Surface *screen; | ||
170 | Help *help; | ||
171 | |||
172 | void go() | ||
173 | { | ||
174 | FontHandler :: init(); | ||
175 | |||
176 | /* Initialize SDL */ | ||
177 | if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) | ||
178 | { | ||
179 | fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); | ||
180 | exit(1); | ||
181 | } | ||
182 | atexit(SDL_Quit); | ||
183 | |||
184 | int videoflags = SDL_SWSURFACE ; | ||
185 | |||
186 | if ( (screen=SDL_SetVideoMode(240, 320,32,videoflags)) == NULL ) | ||
187 | { | ||
188 | fprintf(stderr, "Couldn't set %ix%i video mode: %s\n",240,320,SDL_GetError()); | ||
189 | exit(2); | ||
190 | } | ||
191 | |||
192 | help = new Help(); | ||
193 | |||
194 | bool done = false; | ||
195 | while ( !done ) | ||
196 | { | ||
197 | SDL_FillRect( screen, 0, 0 ); | ||
198 | help->draw( screen ); | ||
199 | help->update( ); | ||
200 | |||
201 | SDL_Flip( screen ); | ||
202 | |||
203 | SDL_Delay( 10 ); | ||
204 | |||
205 | SDL_Event event; | ||
206 | while ( SDL_PollEvent(&event) ) | ||
207 | { | ||
208 | switch (event.type) | ||
209 | { | ||
210 | case SDL_KEYDOWN: | ||
211 | // Escape keypress quits the app | ||
212 | if ( event.key.keysym.sym != SDLK_ESCAPE ) | ||
213 | { | ||
214 | break; | ||
215 | } | ||
216 | case SDL_QUIT: | ||
217 | done = 1; | ||
218 | break; | ||
219 | default: | ||
220 | break; | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | } | ||
225 | |||
226 | |||
227 | |||
228 | |||
229 | #ifdef __cplusplus | ||
230 | extern "C" | ||
231 | #endif | ||
232 | int main( int argc, char *argv[] ) | ||
233 | { | ||
234 | go(); | ||
235 | } | ||
236 | |||
237 | #endif | ||
diff --git a/noncore/games/sfcave-sdl/help.h b/noncore/games/sfcave-sdl/help.h new file mode 100644 index 0000000..dc9e80e --- a/dev/null +++ b/noncore/games/sfcave-sdl/help.h | |||
@@ -0,0 +1,35 @@ | |||
1 | |||
2 | #ifndef __HELP_H | ||
3 | #define __help_h | ||
4 | |||
5 | #include <list> | ||
6 | #include <string> | ||
7 | using namespace std; | ||
8 | |||
9 | class SFCave; | ||
10 | class StarField; | ||
11 | |||
12 | class Help | ||
13 | { | ||
14 | public: | ||
15 | Help( SFCave *p ); | ||
16 | ~Help(); | ||
17 | |||
18 | void init(); | ||
19 | void handleKeys( SDL_KeyboardEvent &key ); | ||
20 | void draw( SDL_Surface *screen ); | ||
21 | void update(); | ||
22 | private: | ||
23 | |||
24 | SFCave *parent; | ||
25 | StarField *stars; | ||
26 | |||
27 | int textSpeed; | ||
28 | list<string> textList; | ||
29 | int startPos; | ||
30 | int currLine; | ||
31 | |||
32 | void loadText(); | ||
33 | }; | ||
34 | |||
35 | #endif | ||
diff --git a/noncore/games/sfcave-sdl/menu.cpp b/noncore/games/sfcave-sdl/menu.cpp new file mode 100644 index 0000000..0a7366f --- a/dev/null +++ b/noncore/games/sfcave-sdl/menu.cpp | |||
@@ -0,0 +1,337 @@ | |||
1 | #include <SDL_image.h> | ||
2 | #include "SDL_rotozoom.h" | ||
3 | |||
4 | #include "constants.h" | ||
5 | #include "sfcave.h" | ||
6 | #include "game.h" | ||
7 | #include "menu.h" | ||
8 | #include "font.h" | ||
9 | #include "starfield.h" | ||
10 | |||
11 | MenuOption :: MenuOption( QString text, int id ) | ||
12 | { | ||
13 | menuText = text; | ||
14 | menuId = id; | ||
15 | nextMenu = 0; | ||
16 | highlighted = false; | ||
17 | } | ||
18 | |||
19 | MenuOption :: ~MenuOption() | ||
20 | { | ||
21 | } | ||
22 | |||
23 | |||
24 | int MenuOption :: draw( SDL_Surface *screen, int y ) | ||
25 | { | ||
26 | if ( highlighted ) | ||
27 | { | ||
28 | int x = (240 - FontHandler::TextWidth( FONT_MENU_HIGHLIGHTED, (const char *)menuText.c_str() ))/2; | ||
29 | FontHandler::draw( screen, FONT_MENU_HIGHLIGHTED, (const char *)menuText.c_str(), x, y ); | ||
30 | return FontHandler::FontHeight( FONT_MENU_HIGHLIGHTED ); | ||
31 | } | ||
32 | else | ||
33 | { | ||
34 | int x = (240 - FontHandler::TextWidth( FONT_MENU_UNHIGHLIGHTED, (const char *)menuText.c_str() ))/2; | ||
35 | FontHandler::draw( screen, FONT_MENU_UNHIGHLIGHTED, (const char *)menuText.c_str(), x, y ); | ||
36 | return FontHandler::FontHeight( FONT_MENU_UNHIGHLIGHTED ); | ||
37 | } | ||
38 | } | ||
39 | |||
40 | void MenuOption :: setNextMenu( Menu *item, bool down ) | ||
41 | { | ||
42 | nextMenu = item; | ||
43 | downMenuTree = down; | ||
44 | } | ||
45 | |||
46 | |||
47 | |||
48 | //----------------- Menu Class ------------- | ||
49 | |||
50 | SDL_Surface * Menu :: sfcaveTextImage; | ||
51 | Menu *Menu :: mainMenu; | ||
52 | Menu *Menu :: currentMenu; | ||
53 | |||
54 | // This is the Master Menu constructor | ||
55 | Menu :: Menu( SFCave *p ) | ||
56 | { | ||
57 | parent = p; | ||
58 | parentMenu = 0; | ||
59 | statusText = ""; | ||
60 | |||
61 | //listItems.setAutoDelete( TRUE ); | ||
62 | |||
63 | SDL_Surface *tmp = IMG_Load( IMAGES_PATH "sfcave_text.bmp" ); | ||
64 | sfcaveTextImage = SDL_CreateRGBSurface(SDL_SWSURFACE, tmp->w, tmp->h, 32, | ||
65 | 0x000000ff,0x0000ff00, 0x00ff0000, 0xff000000); | ||
66 | SDL_BlitSurface(tmp, NULL, sfcaveTextImage, NULL); | ||
67 | SDL_FreeSurface(tmp); | ||
68 | |||
69 | // Create menu structure | ||
70 | // Top level menu has 5 items - Start Game, Replays, Options, Help, and Quit | ||
71 | // Replays, Option menu items hav submenus | ||
72 | MenuOption *replayMenu = 0; | ||
73 | MenuOption *optionsMenu = 0; | ||
74 | MenuOption *item = 0; | ||
75 | addMenuOption( "Start Game", MENU_STARTGAME ); | ||
76 | replayMenu = addMenuOption( "Replays", MENU_REPLAYS ); | ||
77 | optionsMenu = addMenuOption( "Options", MENU_OPTIONS ); | ||
78 | addMenuOption( "Help", MENU_HELP ); | ||
79 | addMenuOption( "Quit", MENU_QUIT ); | ||
80 | |||
81 | // Now deal with the Replays Menu | ||
82 | Menu *replay = new Menu( this ); | ||
83 | replay->addMenuOption( "Play Replay", MENU_PLAY_REPLAY ); | ||
84 | replay->addMenuOption( "Load Replay", MENU_LOAD_REPLAY ); | ||
85 | replay->addMenuOption( "Save Replay", MENU_SAVE_REPLAY ); | ||
86 | item = replay->addMenuOption( "Back", MENU_BACK ); | ||
87 | item->setNextMenu( this, false ); | ||
88 | replayMenu->setNextMenu( replay ); | ||
89 | |||
90 | // Now deal with the Options MenucurrentMenu->currentMenuOption->setHighlighted( false ); | ||
91 | listItems.front()->highlight( true ); | ||
92 | |||
93 | Menu *options = new Menu( this ); | ||
94 | MenuOption *typeMenu = 0; | ||
95 | MenuOption *difficultyMenu = 0; | ||
96 | MenuOption *soundsMenu = 0; | ||
97 | typeMenu = options->addMenuOption( "Game Type", MENU_GAME_TYPE ); | ||
98 | difficultyMenu = options->addMenuOption( "Difficulty", MENU_DIFFICULTY ); | ||
99 | soundsMenu = options->addMenuOption( "Sound", MENU_SOUNDS ); | ||
100 | options->addMenuOption( "Clear Scores", MENU_CLEAR_SCORES ); | ||
101 | item = options->addMenuOption( "Back", MENU_BACK ); | ||
102 | item->setNextMenu( this, false ); | ||
103 | optionsMenu->setNextMenu( options ); | ||
104 | |||
105 | // Game Type menu | ||
106 | Menu *gameType = new Menu( options ); | ||
107 | item = gameType->addMenuOption( "SFCave", MENU_GAME_SFCAVE ); | ||
108 | item->setNextMenu( options ); | ||
109 | item = gameType->addMenuOption( "Gates", MENU_GAME_GATES ); | ||
110 | item->setNextMenu( options ); | ||
111 | item = gameType->addMenuOption( "Fly", MENU_GAME_FLY ); | ||
112 | item->setNextMenu( options ); | ||
113 | item = gameType->addMenuOption( "Back", MENU_BACK ); | ||
114 | item->setNextMenu( options ); | ||
115 | typeMenu->setNextMenu( gameType ); | ||
116 | |||
117 | // Game Difficulty menu | ||
118 | Menu *gameDifficulty = new Menu( options ); | ||
119 | item = gameDifficulty->addMenuOption( "Easy", MENU_DIFFICULTY_EASY ); | ||
120 | item->setNextMenu( options, false ); | ||
121 | item = gameDifficulty->addMenuOption( "Normal", MENU_DIFFICULTY_NORMAL ); | ||
122 | item->setNextMenu( options, false ); | ||
123 | item = gameDifficulty->addMenuOption( "Hard", MENU_DIFFICULTY_HARD ); | ||
124 | item->setNextMenu( options, false ); | ||
125 | item = gameDifficulty->addMenuOption( "Back", MENU_BACK ); | ||
126 | item->setNextMenu( options, false ); | ||
127 | difficultyMenu->setNextMenu( gameDifficulty ); | ||
128 | |||
129 | // Sounds Menu | ||
130 | Menu *sounds = new Menu( options ); | ||
131 | sounds->addMenuOption( "Sound On", MENU_SOUND_ON ); | ||
132 | sounds->addMenuOption( "Sound Off", MENU_SOUND_OFF ); | ||
133 | sounds->addMenuOption( "Music On", MENU_MUSIC_ON ); | ||
134 | sounds->addMenuOption( "Music Off", MENU_MUSIC_OFF ); | ||
135 | item = sounds->addMenuOption( "Back", MENU_BACK ); | ||
136 | item->setNextMenu( options, false ); | ||
137 | soundsMenu->setNextMenu( sounds ); | ||
138 | |||
139 | // Set static variables for menu selection up | ||
140 | mainMenu = this; | ||
141 | currentMenuOption = 0; | ||
142 | |||
143 | resetToTopMenu(); | ||
144 | |||
145 | angle = 0; | ||
146 | |||
147 | stars = new StarField; | ||
148 | } | ||
149 | |||
150 | // This is a private constructor used for creating sub menus - only called by the Master Menu | ||
151 | Menu :: Menu( Menu *p ) | ||
152 | { | ||
153 | parentMenu = p; | ||
154 | //listItems.setAutoDelete( TRUE ); | ||
155 | currentMenuOption = 0; | ||
156 | } | ||
157 | |||
158 | Menu :: ~Menu() | ||
159 | { | ||
160 | if ( this == mainMenu ) | ||
161 | { | ||
162 | SDL_FreeSurface( sfcaveTextImage ); | ||
163 | delete stars; | ||
164 | } | ||
165 | } | ||
166 | |||
167 | void Menu :: draw( SDL_Surface *screen ) | ||
168 | { | ||
169 | // draw stafield | ||
170 | stars->draw( screen ); | ||
171 | stars->move( ); | ||
172 | |||
173 | // Draw the spinning SFCave logo | ||
174 | SDL_Surface *rotozoom_pic; | ||
175 | SDL_Rect dest; | ||
176 | |||
177 | angle += 2; | ||
178 | if ( angle > 359 ) | ||
179 | angle = 0; | ||
180 | if ((rotozoom_pic=rotozoomSurface (sfcaveTextImage, angle*1, 1, SMOOTHING_ON))!=NULL) | ||
181 | { | ||
182 | dest.x = (screen->w - rotozoom_pic->w)/2; | ||
183 | dest.y = 10; | ||
184 | dest.w = rotozoom_pic->w; | ||
185 | dest.h = rotozoom_pic->h; | ||
186 | SDL_BlitSurface( rotozoom_pic, NULL, screen, &dest ); | ||
187 | SDL_FreeSurface(rotozoom_pic); | ||
188 | } | ||
189 | |||
190 | // Draw what game is selected | ||
191 | char text[100]; | ||
192 | sprintf( text, "Current Game: %s", (const char *)parent->getCurrentGame()->getGameName().c_str() ); | ||
193 | //Menu::scoreFont.PutString( screen, (240 - Menu::scoreFont.TextWidth( (const char *)text ))/2, 120, (const char *)text ); | ||
194 | FontHandler::draw( screen, FONT_WHITE_TEXT, (const char *)text, (240 - FontHandler::TextWidth( FONT_WHITE_TEXT,(const char *)text ))/2, 120 ); | ||
195 | sprintf( text, "Difficulty: %s", (const char *)parent->getCurrentGame()->getGameDifficultyText().c_str() ); | ||
196 | //Menu::scoreFont.PutString( screen, (240 - Menu::scoreFont.TextWidth( (const char *)text ))/2, 120 + Menu::scoreFont.FontHeight()+2, (const char *)text ); | ||
197 | FontHandler::draw( screen, FONT_WHITE_TEXT, (const char *)text, (240 - FontHandler::TextWidth( FONT_WHITE_TEXT,(const char *)text ))/2, 120 + FontHandler::FontHeight( FONT_WHITE_TEXT ) ); | ||
198 | |||
199 | if ( statusText != "" ) | ||
200 | FontHandler::draw( screen, FONT_WHITE_TEXT, (const char *)statusText.c_str(), (240 - FontHandler::TextWidth( FONT_WHITE_TEXT,(const char *)statusText.c_str() ))/2, 120 + (2*FontHandler::FontHeight( FONT_WHITE_TEXT ))+6 ); | ||
201 | // Menu::scoreFont.PutString( screen, (240 - Menu::scoreFont.TextWidth( (const char *)statusText ))/2, 120 + (Menu::scoreFont.FontHeight()*2)+6, (const char *)statusText ); | ||
202 | |||
203 | |||
204 | // Loop round each menu option and draw it | ||
205 | int y = 155; | ||
206 | list<MenuOption *>::iterator it; | ||
207 | for ( it = currentMenu->listItems.begin(); it != currentMenu->listItems.end() ; ++it ) | ||
208 | { | ||
209 | y += (*it)->draw( screen, y ) + 2; | ||
210 | } | ||
211 | } | ||
212 | |||
213 | int Menu :: handleKeys( SDL_KeyboardEvent &key ) | ||
214 | { | ||
215 | if ( key.type != SDL_KEYDOWN ) | ||
216 | return -1; | ||
217 | |||
218 | statusText = ""; | ||
219 | switch( key.keysym.sym ) | ||
220 | { | ||
221 | case SDLK_DOWN: | ||
222 | { | ||
223 | // Move to next menu item | ||
224 | currentMenu->currentMenuOption->highlight( false ); | ||
225 | |||
226 | list<MenuOption *>::iterator it; | ||
227 | for ( it = currentMenu->listItems.begin(); it != currentMenu->listItems.end() ; ++it ) | ||
228 | { | ||
229 | if ( (*it) == currentMenu->currentMenuOption ) | ||
230 | { | ||
231 | it++; | ||
232 | break; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | if ( it == currentMenu->listItems.end() ) | ||
237 | it = currentMenu->listItems.begin(); | ||
238 | |||
239 | currentMenu->currentMenuOption = *it; | ||
240 | currentMenu->currentMenuOption->highlight( true ); | ||
241 | |||
242 | break; | ||
243 | } | ||
244 | case SDLK_UP: | ||
245 | { | ||
246 | // Move to previous menu item | ||
247 | currentMenu->currentMenuOption->highlight( false ); | ||
248 | list<MenuOption *>::iterator it; | ||
249 | bool reachedBeginning = false; | ||
250 | for ( it = (currentMenu->listItems).end()--; ; --it ) | ||
251 | { | ||
252 | if ( (*it) == currentMenu->currentMenuOption ) | ||
253 | { | ||
254 | |||
255 | if ( it == currentMenu->listItems.begin( ) ) | ||
256 | { | ||
257 | reachedBeginning = true; | ||
258 | break; | ||
259 | } | ||
260 | else | ||
261 | it--; | ||
262 | break; | ||
263 | } | ||
264 | |||
265 | } | ||
266 | |||
267 | if ( reachedBeginning ) | ||
268 | currentMenu->currentMenuOption = currentMenu->listItems.back(); | ||
269 | else | ||
270 | currentMenu->currentMenuOption = *it; | ||
271 | |||
272 | currentMenu->currentMenuOption->highlight( true ); | ||
273 | |||
274 | break; | ||
275 | } | ||
276 | case SDLK_LEFT: | ||
277 | if ( currentMenu->parentMenu != 0 ) | ||
278 | { | ||
279 | currentMenu = currentMenu->parentMenu; | ||
280 | printf( "HERE\n" ); | ||
281 | |||
282 | return -1; | ||
283 | } | ||
284 | break; | ||
285 | |||
286 | case SDLK_RETURN: | ||
287 | case SDLK_SPACE: | ||
288 | { | ||
289 | // select menu item | ||
290 | int id = currentMenu->currentMenuOption->getMenuId(); | ||
291 | // // if the current item has a child menu then move to that menu | ||
292 | Menu *next = currentMenu->currentMenuOption->getNextMenu(); | ||
293 | if ( next != 0 ) | ||
294 | { | ||
295 | bool down = currentMenu->currentMenuOption->isDownMenuTree(); | ||
296 | currentMenu = next; | ||
297 | if ( down ) | ||
298 | initCurrentMenu(); | ||
299 | // return -1; | ||
300 | } | ||
301 | // else | ||
302 | { | ||
303 | return id; | ||
304 | } | ||
305 | |||
306 | break; | ||
307 | } | ||
308 | |||
309 | default: | ||
310 | break; | ||
311 | } | ||
312 | |||
313 | return -1; | ||
314 | } | ||
315 | |||
316 | MenuOption *Menu :: addMenuOption( QString text, int id ) | ||
317 | { | ||
318 | MenuOption *item = new MenuOption( text, id ); | ||
319 | |||
320 | listItems.push_back( item ); | ||
321 | |||
322 | return item; | ||
323 | } | ||
324 | |||
325 | void Menu :: resetToTopMenu() | ||
326 | { | ||
327 | currentMenu = mainMenu; | ||
328 | initCurrentMenu(); | ||
329 | } | ||
330 | |||
331 | void Menu :: initCurrentMenu() | ||
332 | { | ||
333 | if ( currentMenu->currentMenuOption != 0 ) | ||
334 | currentMenu->currentMenuOption->highlight( false ); | ||
335 | currentMenu->currentMenuOption = currentMenu->listItems.front(); | ||
336 | currentMenu->currentMenuOption->highlight( true ); | ||
337 | } | ||
diff --git a/noncore/games/sfcave-sdl/menu.h b/noncore/games/sfcave-sdl/menu.h new file mode 100644 index 0000000..08f7528 --- a/dev/null +++ b/noncore/games/sfcave-sdl/menu.h | |||
@@ -0,0 +1,71 @@ | |||
1 | #ifndef __MENU_H | ||
2 | #define __MENU_H | ||
3 | |||
4 | #include <list> | ||
5 | using namespace std; | ||
6 | |||
7 | #include <SDL.h> | ||
8 | |||
9 | class SFCave; | ||
10 | class StarField; | ||
11 | class Menu; | ||
12 | |||
13 | class MenuOption | ||
14 | { | ||
15 | public: | ||
16 | MenuOption( QString text, int id ); | ||
17 | ~MenuOption(); | ||
18 | |||
19 | void highlight( bool val ) { highlighted = val; } | ||
20 | int draw( SDL_Surface *screen, int y ); | ||
21 | void setNextMenu( Menu *item, bool down = true ); | ||
22 | Menu *getNextMenu() { return nextMenu; } | ||
23 | int getMenuId() { return menuId; } | ||
24 | bool isDownMenuTree() { return downMenuTree; } | ||
25 | |||
26 | private: | ||
27 | int menuId; | ||
28 | QString menuText; | ||
29 | bool highlighted; | ||
30 | bool downMenuTree; | ||
31 | |||
32 | Menu *nextMenu; | ||
33 | }; | ||
34 | |||
35 | class Menu | ||
36 | { | ||
37 | public: | ||
38 | Menu( SFCave *p ); | ||
39 | ~Menu(); | ||
40 | |||
41 | void draw( SDL_Surface *screen ); | ||
42 | int handleKeys( SDL_KeyboardEvent & ); | ||
43 | MenuOption *addMenuOption( QString text, int id ); | ||
44 | void resetToTopMenu(); | ||
45 | void initCurrentMenu(); | ||
46 | |||
47 | void setStatusText( QString text ) { statusText = text; } | ||
48 | |||
49 | protected: | ||
50 | |||
51 | private: | ||
52 | static SDL_Surface * sfcaveTextImage; | ||
53 | int angle; | ||
54 | |||
55 | static Menu *mainMenu; | ||
56 | static Menu *currentMenu; | ||
57 | Menu *parentMenu; | ||
58 | |||
59 | StarField *stars; | ||
60 | |||
61 | QString statusText; | ||
62 | |||
63 | SFCave *parent; | ||
64 | list<MenuOption *> listItems; | ||
65 | MenuOption *currentMenuOption; | ||
66 | |||
67 | Menu( Menu* p ); | ||
68 | }; | ||
69 | |||
70 | |||
71 | #endif | ||
diff --git a/noncore/games/sfcave-sdl/player.cpp b/noncore/games/sfcave-sdl/player.cpp new file mode 100644 index 0000000..830ee78 --- a/dev/null +++ b/noncore/games/sfcave-sdl/player.cpp | |||
@@ -0,0 +1,162 @@ | |||
1 | #include <SDL.h> | ||
2 | #include "SDL_gfxPrimitives.h" | ||
3 | |||
4 | #include "constants.h" | ||
5 | #include "player.h" | ||
6 | #include "random.h" | ||
7 | #include "animatedimage.h" | ||
8 | |||
9 | Player :: Player( int w, int h ) | ||
10 | { | ||
11 | sWidth = w; | ||
12 | sHeight = h; | ||
13 | |||
14 | thrustUp = 0.4; | ||
15 | thrustDown = 0.6; | ||
16 | maxUpSpeed = 4.0; | ||
17 | maxDownSpeed = 5.0; | ||
18 | |||
19 | explosion = new AnimatedImage( IMAGES_PATH "explosion.bmp", 15 ); | ||
20 | init(); | ||
21 | } | ||
22 | |||
23 | Player :: ~Player() | ||
24 | { | ||
25 | if ( explosion ) | ||
26 | delete explosion; | ||
27 | } | ||
28 | |||
29 | void Player :: init() | ||
30 | { | ||
31 | // Set player position | ||
32 | pos.x( 50 ); | ||
33 | pos.y( sWidth/2 ); | ||
34 | pos.h( 2 ); | ||
35 | pos.w( 4 ); | ||
36 | thrust = 0; | ||
37 | crashing = false; | ||
38 | crashLineLength = 0; | ||
39 | crashed = false; | ||
40 | explosion->reset(); | ||
41 | allFaded = false; | ||
42 | expNextFrame = false; | ||
43 | |||
44 | // Reset Trail | ||
45 | for ( int i = 0 ; i < TRAILSIZE ; ++i ) | ||
46 | { | ||
47 | trail[i].x( -1 ); | ||
48 | trail[i].y( 0 ); | ||
49 | trail[i].w( 2 ); | ||
50 | trail[i].h( 2 ); | ||
51 | } | ||
52 | } | ||
53 | |||
54 | void Player :: draw( SDL_Surface *screen ) | ||
55 | { | ||
56 | if ( !crashing ) | ||
57 | { | ||
58 | // Draw Player | ||
59 | // ellipseRGBA( screen, pos.x(), pos.y(), pos.x()+ pos.width(), pos.y()+pos.height(), 0, 255, 255, 255 ); | ||
60 | filledEllipseRGBA( screen, pos.x() + pos.w(), pos.y(), pos.w(), pos.h(), 0, 255, 255, 255 ); | ||
61 | |||
62 | // Draw Trail | ||
63 | drawTrails( screen ); | ||
64 | } | ||
65 | else | ||
66 | { | ||
67 | drawTrails( screen ); | ||
68 | |||
69 | if ( !crashed ) | ||
70 | explosion->draw( screen, pos.x(), pos.y() ); | ||
71 | } | ||
72 | } | ||
73 | |||
74 | void Player :: drawTrails( SDL_Surface *screen ) | ||
75 | { | ||
76 | if ( allFaded && crashing ) | ||
77 | return; | ||
78 | |||
79 | for ( int i = 0 ; i < TRAILSIZE ; ++i ) | ||
80 | { | ||
81 | if ( trail[i].x() >= 0 ) | ||
82 | { | ||
83 | // int r = (int) ((255.0/pos.x()) * (trail[i].x)); | ||
84 | // int g = (int) ((150.0/pos.x()) * (trail[i].x)); | ||
85 | int c = (int)((150.0/50) * (50.0 - (pos.x() - trail[i].x() ) )); | ||
86 | // SDL_FillRect( screen, &trail[i], SDL_MapRGBA( screen->format, r, g, 0, 0 ) ); //(int)(1.5*c), 0, 255 ) ); | ||
87 | boxRGBA( screen, trail[i].x(), trail[i].y(), trail[i].x() + 2, trail[i].y() + 2, 255, (int)(1.5*c), 0, c ); | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | |||
92 | void Player :: move( bool up ) | ||
93 | { | ||
94 | // Find enpty trail and move others | ||
95 | moveTrails(); | ||
96 | |||
97 | if ( up ) | ||
98 | thrust -= thrustUp; | ||
99 | else | ||
100 | thrust += thrustDown; | ||
101 | |||
102 | if ( thrust > maxDownSpeed ) | ||
103 | thrust = maxDownSpeed; | ||
104 | else if ( thrust < -maxUpSpeed ) | ||
105 | thrust = -maxUpSpeed; | ||
106 | |||
107 | pos.moveBy( 0, (int)(thrust) ); | ||
108 | } | ||
109 | |||
110 | void Player :: moveTrails() | ||
111 | { | ||
112 | bool done = false; | ||
113 | bool stillVisible = false; | ||
114 | |||
115 | // Dont do anything here if all faded when were crashing | ||
116 | if ( allFaded && crashing ) | ||
117 | return; | ||
118 | |||
119 | for ( int i = 0 ; i < TRAILSIZE ; ++i ) | ||
120 | { | ||
121 | if ( trail[i].x() < 0 ) | ||
122 | { | ||
123 | stillVisible = true; | ||
124 | if ( !crashing && !done ) | ||
125 | { | ||
126 | trail[i].x( pos.x() - 5 ); | ||
127 | trail[i].y( pos.y() ); | ||
128 | done = true; | ||
129 | } | ||
130 | } | ||
131 | else | ||
132 | trail[i].x( trail[i].x() - 1 ); | ||
133 | } | ||
134 | |||
135 | if ( !stillVisible ) | ||
136 | allFaded = true; | ||
137 | } | ||
138 | |||
139 | bool Player :: updateCrashing() | ||
140 | { | ||
141 | crashing = true; | ||
142 | |||
143 | moveTrails(); | ||
144 | if ( expNextFrame ) | ||
145 | { | ||
146 | expNextFrame = false; | ||
147 | crashed = !explosion->nextFrame(); | ||
148 | } | ||
149 | else | ||
150 | expNextFrame = true; | ||
151 | |||
152 | return crashed; | ||
153 | } | ||
154 | |||
155 | void Player :: setMovementInfo( double up, double down, double maxUp, double maxDown ) | ||
156 | { | ||
157 | thrustUp = up; | ||
158 | thrustDown = down; | ||
159 | maxUpSpeed = maxUp; | ||
160 | maxDownSpeed = maxDown; | ||
161 | } | ||
162 | |||
diff --git a/noncore/games/sfcave-sdl/player.h b/noncore/games/sfcave-sdl/player.h new file mode 100644 index 0000000..e4c904a --- a/dev/null +++ b/noncore/games/sfcave-sdl/player.h | |||
@@ -0,0 +1,50 @@ | |||
1 | #ifndef __PLAYER_H | ||
2 | #define __PLAYER_H | ||
3 | |||
4 | #include "rect.h" | ||
5 | |||
6 | class SDL_Surface; | ||
7 | class AnimatedImage; | ||
8 | |||
9 | class Player | ||
10 | { | ||
11 | public: | ||
12 | Player( int w, int h ); | ||
13 | ~Player(); | ||
14 | |||
15 | void init(); | ||
16 | void draw( SDL_Surface *screen ); | ||
17 | void drawTrails( SDL_Surface *screen ); | ||
18 | void move( bool up ); | ||
19 | void moveTrails(); | ||
20 | Rect getPos() { return pos; } | ||
21 | int getX() { return pos.x(); } | ||
22 | int getY() { return pos.y(); } | ||
23 | int getHeight() { return pos.h(); } | ||
24 | bool updateCrashing(); | ||
25 | void setMovementInfo( double up, double down, double maxUp, double maxDown ); | ||
26 | |||
27 | private: | ||
28 | AnimatedImage *explosion; | ||
29 | |||
30 | int sWidth; | ||
31 | int sHeight; | ||
32 | |||
33 | bool expNextFrame; | ||
34 | bool allFaded; | ||
35 | bool crashing; | ||
36 | bool crashed; | ||
37 | int crashLineLength; | ||
38 | Rect pos; | ||
39 | double thrust; | ||
40 | |||
41 | double thrustUp; | ||
42 | double thrustDown; | ||
43 | double maxUpSpeed; | ||
44 | double maxDownSpeed; | ||
45 | |||
46 | Rect trail[TRAILSIZE]; | ||
47 | |||
48 | }; | ||
49 | |||
50 | #endif | ||
diff --git a/noncore/games/sfcave-sdl/random.cpp b/noncore/games/sfcave-sdl/random.cpp new file mode 100644 index 0000000..9f716f2 --- a/dev/null +++ b/noncore/games/sfcave-sdl/random.cpp | |||
@@ -0,0 +1,189 @@ | |||
1 | /* ------------------------------------------------------------------------- | ||
2 | * This is an ANSI C library for multi-stream random number generation. | ||
3 | * The use of this library is recommended as a replacement for the ANSI C | ||
4 | * rand() and srand() functions, particularly in simulation applications | ||
5 | * where the statistical 'goodness' of the random number generator is | ||
6 | * important. The library supplies 256 streams of random numbers; use | ||
7 | * SelectStream(s) to switch between streams indexed s = 0,1,...,255. | ||
8 | * | ||
9 | * The streams must be initialized. The recommended way to do this is by | ||
10 | * using the function PlantSeeds(x) with the value of x used to initialize | ||
11 | * the default stream and all other streams initialized automatically with | ||
12 | * values dependent on the value of x. The following convention is used | ||
13 | * to initialize the default stream: | ||
14 | * if x > 0 then x is the state | ||
15 | * if x < 0 then the state is obtained from the system clock | ||
16 | * if x = 0 then the state is to be supplied interactively. | ||
17 | * | ||
18 | * The generator used in this library is a so-called 'Lehmer random number | ||
19 | * generator' which returns a pseudo-random number uniformly distributed | ||
20 | * 0.0 and 1.0. The period is (m - 1) where m = 2,147,483,647 and the | ||
21 | * smallest and largest possible values are (1 / m) and 1 - (1 / m) | ||
22 | * respectively. For more details see: | ||
23 | * | ||
24 | * "Random Number Generators: Good Ones Are Hard To Find" | ||
25 | * Steve Park and Keith Miller | ||
26 | * Communications of the ACM, October 1988 | ||
27 | * | ||
28 | * Name : rngs.c (Random Number Generation - Multiple Streams) | ||
29 | * Authors : Steve Park & Dave Geyer | ||
30 | * Language : ANSI C | ||
31 | * Latest Revision : 09-22-98 | ||
32 | * ------------------------------------------------------------------------- | ||
33 | */ | ||
34 | |||
35 | #include <stdio.h> | ||
36 | #include <time.h> | ||
37 | |||
38 | #define __RANDOM_CPP | ||
39 | #include "random.h" | ||
40 | |||
41 | #define MODULUS 2147483647 /* DON'T CHANGE THIS VALUE */ | ||
42 | #define MULTIPLIER 48271 /* DON'T CHANGE THIS VALUE */ | ||
43 | #define CHECK 399268537 /* DON'T CHANGE THIS VALUE */ | ||
44 | #define STREAMS 256 /* # of streams, DON'T CHANGE THIS VALUE */ | ||
45 | #define A256 22925 /* jump multiplier, DON'T CHANGE THIS VALUE */ | ||
46 | #define DEFAULT 123456789 /* initial seed, use 0 < DEFAULT < MODULUS */ | ||
47 | |||
48 | static long seed[STREAMS] = {DEFAULT}; /* current state of each stream */ | ||
49 | static int stream = 0; /* stream index, 0 is the default */ | ||
50 | static int initialized = 0; /* test for stream initialization */ | ||
51 | |||
52 | |||
53 | double Random(void) | ||
54 | /* ---------------------------------------------------------------- | ||
55 | * Random returns a pseudo-random real number uniformly distributed | ||
56 | * between 0.0 and 1.0. | ||
57 | * ---------------------------------------------------------------- | ||
58 | */ | ||
59 | { | ||
60 | const long Q = MODULUS / MULTIPLIER; | ||
61 | const long R = MODULUS % MULTIPLIER; | ||
62 | long t; | ||
63 | |||
64 | t = MULTIPLIER * (seed[stream] % Q) - R * (seed[stream] / Q); | ||
65 | if (t > 0) | ||
66 | seed[stream] = t; | ||
67 | else | ||
68 | seed[stream] = t + MODULUS; | ||
69 | return ((double) seed[stream] / MODULUS); | ||
70 | } | ||
71 | |||
72 | |||
73 | void PlantSeeds(long x) | ||
74 | /* --------------------------------------------------------------------- | ||
75 | * Use this function to set the state of all the random number generator | ||
76 | * streams by "planting" a sequence of states (seeds), one per stream, | ||
77 | * with all states dictated by the state of the default stream. | ||
78 | * The sequence of planted states is separated one from the next by | ||
79 | * 8,367,782 calls to Random(). | ||
80 | * --------------------------------------------------------------------- | ||
81 | */ | ||
82 | { | ||
83 | const long Q = MODULUS / A256; | ||
84 | const long R = MODULUS % A256; | ||
85 | int j; | ||
86 | int s; | ||
87 | |||
88 | initialized = 1; | ||
89 | s = stream; /* remember the current stream */ | ||
90 | SelectStream(0); /* change to stream 0 */ | ||
91 | PutSeed(x); /* set seed[0] */ | ||
92 | stream = s; /* reset the current stream */ | ||
93 | for (j = 1; j < STREAMS; j++) { | ||
94 | x = A256 * (seed[j - 1] % Q) - R * (seed[j - 1] / Q); | ||
95 | if (x > 0) | ||
96 | seed[j] = x; | ||
97 | else | ||
98 | seed[j] = x + MODULUS; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | |||
103 | int nextInteger( int range,const char *file, int line ) | ||
104 | { | ||
105 | int val = (int)(Random( ) * range); | ||
106 | //printf( "nextInt() called from %s line %d - returning %d\n", file, line, val ); | ||
107 | |||
108 | return val; | ||
109 | |||
110 | } | ||
111 | void PutSeed(long x) | ||
112 | /* --------------------------------------------------------------- | ||
113 | * Use this function to set the state of the current random number | ||
114 | * generator stream according to the following conventions: | ||
115 | * if x > 0 then x is the state (unless too large) | ||
116 | * if x < 0 then the state is obtained from the system clock | ||
117 | * if x = 0 then the state is to be supplied interactively | ||
118 | * --------------------------------------------------------------- | ||
119 | */ | ||
120 | { | ||
121 | char ok = 0; | ||
122 | |||
123 | if (x > 0) | ||
124 | x = x % MODULUS; /* correct if x is too large */ | ||
125 | if (x < 0) | ||
126 | x = ((unsigned long) time((time_t *) NULL)) % MODULUS; | ||
127 | if (x == 0) | ||
128 | while (!ok) { | ||
129 | printf("\nEnter a positive integer seed (9 digits or less) >> "); | ||
130 | scanf("%ld", &x); | ||
131 | ok = (0 < x) && (x < MODULUS); | ||
132 | if (!ok) | ||
133 | printf("\nInput out of range ... try again\n"); | ||
134 | } | ||
135 | seed[stream] = x; | ||
136 | } | ||
137 | |||
138 | |||
139 | void GetSeed(long *x) | ||
140 | /* --------------------------------------------------------------- | ||
141 | * Use this function to get the state of the current random number | ||
142 | * generator stream. | ||
143 | * --------------------------------------------------------------- | ||
144 | */ | ||
145 | { | ||
146 | *x = seed[stream]; | ||
147 | } | ||
148 | |||
149 | |||
150 | void SelectStream(int index) | ||
151 | /* ------------------------------------------------------------------ | ||
152 | * Use this function to set the current random number generator | ||
153 | * stream -- that stream from which the next random number will come. | ||
154 | * ------------------------------------------------------------------ | ||
155 | */ | ||
156 | { | ||
157 | stream = ((unsigned int) index) % STREAMS; | ||
158 | if ((initialized == 0) && (stream != 0)) /* protect against */ | ||
159 | PlantSeeds(DEFAULT); /* un-initialized streams */ | ||
160 | } | ||
161 | |||
162 | |||
163 | void TestRandom(void) | ||
164 | /* ------------------------------------------------------------------ | ||
165 | * Use this (optional) function to test for a correct implementation. | ||
166 | * ------------------------------------------------------------------ | ||
167 | */ | ||
168 | { | ||
169 | long i; | ||
170 | long x; | ||
171 | double u; | ||
172 | char ok = 0; | ||
173 | |||
174 | SelectStream(0); /* select the default stream */ | ||
175 | PutSeed(1); /* and set the state to 1 */ | ||
176 | for(i = 0; i < 10000; i++) | ||
177 | u = Random(); | ||
178 | GetSeed(&x); /* get the new state value */ | ||
179 | ok = (x == CHECK); /* and check for correctness */ | ||
180 | |||
181 | SelectStream(1); /* select stream 1 */ | ||
182 | PlantSeeds(1); /* set the state of all streams */ | ||
183 | GetSeed(&x); /* get the state of stream 1 */ | ||
184 | ok = ok && (x == A256); /* x should be the jump multiplier */ | ||
185 | if (ok) | ||
186 | printf("\n The implementation of rngs.c is correct.\n\n"); | ||
187 | else | ||
188 | printf("\n\a ERROR -- the implementation of rngs.c is not correct.\n\n"); | ||
189 | } | ||
diff --git a/noncore/games/sfcave-sdl/random.h b/noncore/games/sfcave-sdl/random.h new file mode 100644 index 0000000..d416b59 --- a/dev/null +++ b/noncore/games/sfcave-sdl/random.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* ----------------------------------------------------------------------- | ||
2 | * Name : rngs.h (header file for the library file rngs.c) | ||
3 | * Author : Steve Park & Dave Geyer | ||
4 | * Language : ANSI C | ||
5 | * Latest Revision : 09-22-98 | ||
6 | * ----------------------------------------------------------------------- | ||
7 | */ | ||
8 | |||
9 | #if !defined( _RNGS_ ) | ||
10 | #define _RNGS_ | ||
11 | |||
12 | |||
13 | #define nextInt(x) nextInteger( (x),__FILE__, __LINE__ ) | ||
14 | //#define DEBUG_NEW new | ||
15 | |||
16 | double Random(void); | ||
17 | int nextInteger( int range,const char *file, int line); | ||
18 | void PlantSeeds(long x); | ||
19 | void GetSeed(long *x); | ||
20 | void PutSeed(long x); | ||
21 | void SelectStream(int index); | ||
22 | void TestRandom(void); | ||
23 | |||
24 | #endif | ||
diff --git a/noncore/games/sfcave-sdl/rect.h b/noncore/games/sfcave-sdl/rect.h new file mode 100644 index 0000000..dc9c9d5 --- a/dev/null +++ b/noncore/games/sfcave-sdl/rect.h | |||
@@ -0,0 +1,61 @@ | |||
1 | #ifndef __RECT_H | ||
2 | #define __RECT_H | ||
3 | |||
4 | #include "SDL.h" | ||
5 | |||
6 | class Rect | ||
7 | { | ||
8 | public: | ||
9 | Rect() { r.x = r.y = r.w = r.h = 0; } | ||
10 | Rect( int x, int y, int w, int h ) { setRect( x, y, w, h ); } | ||
11 | ~Rect() {} | ||
12 | |||
13 | void setRect( int x, int y, int w, int h ) { r.x = x; r.y = y; r.w = w; r.h = h; } | ||
14 | SDL_Rect getRect() { return r; } | ||
15 | int x() { return r.x; } | ||
16 | int y() { return r.y; } | ||
17 | int w() { return r.w; } | ||
18 | int h() { return r.h; } | ||
19 | |||
20 | void x( int x) { r.x = x; } | ||
21 | void y( int y) { r.y = y; } | ||
22 | void w( int w) { r.w = w; } | ||
23 | void h( int h) { r.h = h; } | ||
24 | |||
25 | void moveBy( int x, int y ) | ||
26 | { | ||
27 | r.x += x; | ||
28 | r.y += y; | ||
29 | } | ||
30 | |||
31 | bool intersects( Rect r2 ) | ||
32 | { | ||
33 | int tw = r.w; | ||
34 | int th = r.h; | ||
35 | int rw = r2.w(); | ||
36 | int rh = r2.h(); | ||
37 | if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0) { | ||
38 | return false; | ||
39 | } | ||
40 | int tx = r.x; | ||
41 | int ty = r.y; | ||
42 | int rx = r2.x(); | ||
43 | int ry = r2.y(); | ||
44 | rw += rx; | ||
45 | rh += ry; | ||
46 | tw += tx; | ||
47 | th += ty; | ||
48 | |||
49 | // overflow || intersect | ||
50 | return ((rw < rx || rw > tx) && | ||
51 | (rh < ry || rh > ty) && | ||
52 | (tw < tx || tw > rx) && | ||
53 | (th < ty || th > ry)); | ||
54 | } | ||
55 | |||
56 | private: | ||
57 | SDL_Rect r; | ||
58 | }; | ||
59 | |||
60 | #endif | ||
61 | |||
diff --git a/noncore/games/sfcave-sdl/settings.cpp b/noncore/games/sfcave-sdl/settings.cpp new file mode 100644 index 0000000..914c4ec --- a/dev/null +++ b/noncore/games/sfcave-sdl/settings.cpp | |||
@@ -0,0 +1,273 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <sys/stat.h> | ||
4 | #include <vector> | ||
5 | |||
6 | #include "settings.h" | ||
7 | |||
8 | |||
9 | #define DEFAULT_DIR "." | ||
10 | #define DEFAULT_FILE "Settings.cfg" | ||
11 | #define MAX_LINE_SIZE 2048 | ||
12 | |||
13 | |||
14 | Settings::Settings( char * env_file, char * env_dir ) | ||
15 | { | ||
16 | // Store the correct environment directory | ||
17 | if (env_dir == NULL) | ||
18 | { | ||
19 | char * homeDir = getenv( "HOME" );; | ||
20 | |||
21 | if ( homeDir ) | ||
22 | { | ||
23 | envFile.append(homeDir); | ||
24 | envFile.append("/"); | ||
25 | } | ||
26 | else | ||
27 | printf( "Environment var HOME not set!\n" ); | ||
28 | |||
29 | envFile.append(DEFAULT_DIR); | ||
30 | } | ||
31 | else | ||
32 | envFile.append(env_dir); | ||
33 | |||
34 | envFile.append("/"); | ||
35 | |||
36 | // Store the correct environment file | ||
37 | if (env_file == NULL) | ||
38 | envFile.append(DEFAULT_FILE); | ||
39 | else | ||
40 | envFile.append(env_file); | ||
41 | } | ||
42 | |||
43 | Settings::Settings() | ||
44 | { | ||
45 | char * homeDir = getenv("HOME"); | ||
46 | |||
47 | if ( homeDir) | ||
48 | { | ||
49 | envFile.append(homeDir); | ||
50 | envFile.append("/"); | ||
51 | } | ||
52 | else | ||
53 | printf( "Environment var HOME not set!\n" ); | ||
54 | |||
55 | envFile.append(DEFAULT_DIR); | ||
56 | envFile.append("/"); | ||
57 | |||
58 | envFile.append(DEFAULT_FILE); | ||
59 | } | ||
60 | |||
61 | Settings::~Settings() | ||
62 | { | ||
63 | } | ||
64 | |||
65 | bool Settings::readSetting(const string key_str,int& result) | ||
66 | { | ||
67 | string Buffer; | ||
68 | if (readSetting(key_str,Buffer)) | ||
69 | { | ||
70 | result = atoi(Buffer.c_str()); | ||
71 | return true; | ||
72 | } | ||
73 | else | ||
74 | return false; | ||
75 | } | ||
76 | |||
77 | bool Settings::readSetting(const string key_str,unsigned int& result) | ||
78 | { | ||
79 | string Buffer; | ||
80 | if (readSetting(key_str,Buffer)) | ||
81 | { | ||
82 | result = atoi(Buffer.c_str()); | ||
83 | return true; | ||
84 | } | ||
85 | else | ||
86 | return false; | ||
87 | } | ||
88 | |||
89 | bool Settings::readSetting(const string key_str,long int& result) | ||
90 | { | ||
91 | string Buffer; | ||
92 | if (readSetting(key_str,Buffer)) | ||
93 | { | ||
94 | result = atol(Buffer.c_str()); | ||
95 | return true; | ||
96 | } | ||
97 | else | ||
98 | return false; | ||
99 | } | ||
100 | |||
101 | bool Settings::readSetting(const string key_str,unsigned long& result) | ||
102 | { | ||
103 | string Buffer; | ||
104 | if (readSetting(key_str,Buffer)) | ||
105 | { | ||
106 | result = atol(Buffer.c_str()); | ||
107 | return true; | ||
108 | } | ||
109 | else | ||
110 | return false; | ||
111 | } | ||
112 | |||
113 | bool Settings::readSetting(const string key_str,bool& result) | ||
114 | { | ||
115 | string Buffer; | ||
116 | if (readSetting(key_str,Buffer)) | ||
117 | { | ||
118 | result = (Buffer == "true"); | ||
119 | return true; | ||
120 | } | ||
121 | else | ||
122 | return false; | ||
123 | } | ||
124 | |||
125 | bool Settings::readSetting(const string key_str,string& results) | ||
126 | { | ||
127 | // This function will read a string from the env file that corresponds to the | ||
128 | // key key_str passed in. | ||
129 | FILE * fd = 0; | ||
130 | char buf[MAX_LINE_SIZE]; | ||
131 | bool ret_flag = false; | ||
132 | char* key; | ||
133 | char* value; | ||
134 | |||
135 | // open file | ||
136 | fd = fopen(envFile.c_str(), "r"); | ||
137 | |||
138 | if (fd) | ||
139 | { | ||
140 | while (fgets(buf, MAX_LINE_SIZE-1, fd)) | ||
141 | { | ||
142 | key = strtok(buf, "\t"); | ||
143 | value = strtok(NULL, "\n"); | ||
144 | // find key in file | ||
145 | if (!strcasecmp(key,key_str.c_str())) | ||
146 | { | ||
147 | results = value; | ||
148 | ret_flag = true; | ||
149 | } | ||
150 | } | ||
151 | fclose(fd); | ||
152 | } | ||
153 | |||
154 | return(ret_flag); | ||
155 | } | ||
156 | |||
157 | void Settings::writeSetting(const string key_str,const bool value) | ||
158 | { | ||
159 | value ?writeSetting(key_str,string("true")) :writeSetting(key_str,string("false")); | ||
160 | } | ||
161 | |||
162 | void Settings::writeSetting(const string key_str,const int value) | ||
163 | { | ||
164 | char Buffer[30]; | ||
165 | |||
166 | sprintf(Buffer,"%i",value); | ||
167 | writeSetting(key_str,string(Buffer)); | ||
168 | } | ||
169 | |||
170 | void Settings::writeSetting(const string key_str,const unsigned int value) | ||
171 | { | ||
172 | char Buffer[30]; | ||
173 | |||
174 | sprintf(Buffer,"%i",value); | ||
175 | writeSetting(key_str,string(Buffer)); | ||
176 | } | ||
177 | |||
178 | void Settings::writeSetting(const string key_str,const long int value) | ||
179 | { | ||
180 | char Buffer[30]; | ||
181 | |||
182 | sprintf(Buffer,"%li",value); | ||
183 | writeSetting(key_str,string(Buffer)); | ||
184 | } | ||
185 | |||
186 | void Settings::writeSetting(const string key_str,const unsigned long value) | ||
187 | { | ||
188 | char Buffer[30]; | ||
189 | |||
190 | sprintf(Buffer,"%lu",value); | ||
191 | writeSetting(key_str,string(Buffer)); | ||
192 | } | ||
193 | |||
194 | void Settings::writeSetting(const string key_str,const string value) | ||
195 | { | ||
196 | // This function will write a value for the key key_str. If the key_str | ||
197 | // already exists then it will be overwritten. | ||
198 | |||
199 | std::vector<string> FileEntries; | ||
200 | FILE *fd=NULL,*ftemp=NULL; | ||
201 | char * dir_str; | ||
202 | char * dir_ptr; | ||
203 | char buf[MAX_LINE_SIZE]; | ||
204 | char tempname[12]; | ||
205 | |||
206 | dir_str = strdup(envFile.c_str()); | ||
207 | printf( "dir = %s, file - %s\n", dir_str, envFile.c_str() ); | ||
208 | if (dir_str) | ||
209 | { | ||
210 | // remove file from the directory string | ||
211 | dir_ptr = strrchr(dir_str, (int)'/'); | ||
212 | if (dir_ptr) | ||
213 | { | ||
214 | *dir_ptr = 0; | ||
215 | |||
216 | // make the directory path if it does not exist | ||
217 | // mkdir(dir_str, 777 ); | ||
218 | |||
219 | // if file exists we need to save contents | ||
220 | if ((fd = fopen(envFile.c_str(), "r")) != NULL) | ||
221 | { | ||
222 | while (fgets(buf, MAX_LINE_SIZE-1, fd)) | ||
223 | FileEntries.push_back(string(buf)); | ||
224 | fclose(fd); | ||
225 | } | ||
226 | |||
227 | char *home = getenv( "HOME" ); | ||
228 | string tmp; | ||
229 | if ( home ) | ||
230 | tmp = home + string( "/" ) + "tmpsfcave.dat"; | ||
231 | else | ||
232 | tmp = "./tmpsfcave.dat"; | ||
233 | strcpy(tempname,tmp.c_str() ); | ||
234 | printf( "tmp - %s\n", tempname ); | ||
235 | if ((ftemp = fopen(tempname,"w")) != NULL) | ||
236 | { | ||
237 | char *key1,*key2; | ||
238 | char buff1[80],buff2[80]; | ||
239 | |||
240 | strncpy(buff1,key_str.c_str(),80); | ||
241 | key1 = strtok(buff1,"\t"); | ||
242 | for (std::vector<string>::iterator iter = FileEntries.begin(); iter < FileEntries.end(); iter++) | ||
243 | { | ||
244 | strncpy(buff2,(*iter).c_str(),80); | ||
245 | key2 = strtok(buff2,"\t"); | ||
246 | // IF not the key string then write out to file | ||
247 | if (strcmp(key1,key2) != 0) | ||
248 | { | ||
249 | fprintf(ftemp,"%s",iter->c_str()); | ||
250 | fflush(ftemp); | ||
251 | } | ||
252 | } | ||
253 | |||
254 | fprintf(ftemp, "%s\t%s\n", key_str.c_str(),value.c_str()); | ||
255 | fflush(ftemp); | ||
256 | fclose(ftemp); | ||
257 | |||
258 | remove(envFile.c_str()); | ||
259 | |||
260 | rename( tempname, envFile.c_str() ); | ||
261 | } | ||
262 | else | ||
263 | printf( "Can't open file %s\n", envFile.c_str() ); | ||
264 | } | ||
265 | |||
266 | delete dir_str; | ||
267 | } | ||
268 | } | ||
269 | |||
270 | void Settings::deleteFile(void) | ||
271 | { | ||
272 | remove(envFile.c_str()); | ||
273 | } | ||
diff --git a/noncore/games/sfcave-sdl/settings.h b/noncore/games/sfcave-sdl/settings.h new file mode 100644 index 0000000..5e828ed --- a/dev/null +++ b/noncore/games/sfcave-sdl/settings.h | |||
@@ -0,0 +1,52 @@ | |||
1 | #ifndef __SETTINGS_H | ||
2 | #define __SETTINGS_H | ||
3 | |||
4 | // This class will create a .<name> directory in the users home directory or | ||
5 | // a directory for the users choice. It will then manage a set of key values | ||
6 | // that the programmer can search for. This allows programmers to save a users | ||
7 | // settings and then retrieve then at a latter time. It currently supports | ||
8 | // upto 1024 different settings. | ||
9 | // Two constructors are provided. They will dertermine what directory to look | ||
10 | // for the settings file and what the name of the file is. If the directory is | ||
11 | // not specified then a default directory of .<DEFAULT_DIR> will be created in | ||
12 | // the users home directory. A file will be created in this directory. The name | ||
13 | // will be the one specified by the caller. If none is specified then | ||
14 | // DEFAULT_FILE will be created. | ||
15 | // To retrieve and store strings into the file readSetting and writeSetting | ||
16 | // should be called. | ||
17 | |||
18 | #include <string> | ||
19 | using namespace std; | ||
20 | |||
21 | class Settings | ||
22 | { | ||
23 | |||
24 | public: | ||
25 | |||
26 | Settings( char * env_file = 0, char * env_dir = 0 ); | ||
27 | Settings(); | ||
28 | ~Settings(); | ||
29 | |||
30 | bool readSetting(const string key_str,string& results); | ||
31 | bool readSetting(const string key_str,int& result); | ||
32 | bool readSetting(const string key_str,unsigned int& result); | ||
33 | bool readSetting(const string key_str,long int& result); | ||
34 | bool readSetting(const string key_str,unsigned long& result); | ||
35 | bool readSetting(const string key_str,bool& result); | ||
36 | |||
37 | void writeSetting(const string key_str,const string value); | ||
38 | void writeSetting(const string key_str,const int value); | ||
39 | void writeSetting(const string key_str,const unsigned int result); | ||
40 | void writeSetting(const string key_str,const long int result); | ||
41 | void writeSetting(const string key_str,const unsigned long result); | ||
42 | void writeSetting(const string key_str,const bool value); | ||
43 | |||
44 | void deleteFile(void); | ||
45 | |||
46 | private: | ||
47 | |||
48 | string envFile; | ||
49 | }; | ||
50 | |||
51 | |||
52 | #endif | ||
diff --git a/noncore/games/sfcave-sdl/sfcave-sdl.pro b/noncore/games/sfcave-sdl/sfcave-sdl.pro new file mode 100644 index 0000000..e874f0d --- a/dev/null +++ b/noncore/games/sfcave-sdl/sfcave-sdl.pro | |||
@@ -0,0 +1,55 @@ | |||
1 | TEMPLATE= app | ||
2 | CONFIG += qt warn_on release | ||
3 | DESTDIR = $(OPIEDIR)/bin | ||
4 | TARGET = sfcave-sdl | ||
5 | |||
6 | DEFINES = _REENTRANT main=SDL_main | ||
7 | |||
8 | INCLUDEPATH += $(OPIEDIR)/include | ||
9 | INCLUDEPATH += $(OPIEDIR)/include/SDL | ||
10 | DEPENDPATH += $(OPIEDIR)/include | ||
11 | |||
12 | LIBS += -lqpe -L${SDLDIR}/lib -lSDL -lSDLmain -lSDL_gfx -lSDL_image -lSDL_mixer -lstdc++ | ||
13 | |||
14 | SOURCES = animatedimage.cpp \ | ||
15 | bfont.cpp \ | ||
16 | font.cpp \ | ||
17 | game.cpp \ | ||
18 | menu.cpp \ | ||
19 | help.cpp \ | ||
20 | player.cpp \ | ||
21 | random.cpp \ | ||
22 | sfcave.cpp \ | ||
23 | sfcave_game.cpp \ | ||
24 | gates_game.cpp \ | ||
25 | fly_game.cpp \ | ||
26 | flyterrain.cpp \ | ||
27 | sound.cpp \ | ||
28 | terrain.cpp \ | ||
29 | settings.cpp \ | ||
30 | starfield.cpp \ | ||
31 | util.cpp | ||
32 | |||
33 | HEADERS = animatedimage.h \ | ||
34 | bfont.h \ | ||
35 | constants.h \ | ||
36 | font.h \ | ||
37 | game.h \ | ||
38 | menu.h \ | ||
39 | player.h \ | ||
40 | random.h \ | ||
41 | rect.h \ | ||
42 | sfcave.h \ | ||
43 | help.h \ | ||
44 | sfcave_game.h \ | ||
45 | gates_game.h \ | ||
46 | fly_game.h \ | ||
47 | flyterrain.h \ | ||
48 | sound.h \ | ||
49 | terrain.h \ | ||
50 | stringtokenizer.h \ | ||
51 | settings.h \ | ||
52 | starfield.h \ | ||
53 | util.h | ||
54 | |||
55 | include ( ../../../include.pro ) \ No newline at end of file | ||
diff --git a/noncore/games/sfcave-sdl/sfcave.cpp b/noncore/games/sfcave-sdl/sfcave.cpp new file mode 100644 index 0000000..8d376a1 --- a/dev/null +++ b/noncore/games/sfcave-sdl/sfcave.cpp | |||
@@ -0,0 +1,546 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | |||
4 | #include <time.h> | ||
5 | #include <sys/timeb.h> | ||
6 | |||
7 | #include "SDL.h" | ||
8 | #include "SDL_gfxPrimitives.h" | ||
9 | |||
10 | #include "constants.h" | ||
11 | |||
12 | #include "sound.h" | ||
13 | #include "menu.h" | ||
14 | #include "help.h" | ||
15 | #include "game.h" | ||
16 | #include "terrain.h" | ||
17 | #include "random.h" | ||
18 | #include "sfcave.h" | ||
19 | #include "font.h" | ||
20 | #include "settings.h" | ||
21 | #include "util.h" | ||
22 | |||
23 | #include "sfcave_game.h" | ||
24 | #include "gates_game.h" | ||
25 | #include "fly_game.h" | ||
26 | |||
27 | void start( int argc, char *argv[] ) | ||
28 | { | ||
29 | FontHandler::init(); | ||
30 | SFCave app( argc, argv ); | ||
31 | FontHandler::cleanUp(); | ||
32 | } | ||
33 | |||
34 | #ifdef __cplusplus | ||
35 | extern "C" | ||
36 | #endif | ||
37 | int main(int argc, char *argv[]) | ||
38 | { | ||
39 | start( argc, argv ); | ||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | |||
44 | SFCave :: SFCave( int argc, char *argv[] ) | ||
45 | { | ||
46 | string diff = loadSetting( "GameDifficulty", "Easy" ); | ||
47 | string game = loadSetting( "GameType", "SFCave" ); | ||
48 | musicPath = loadSetting( "MusicPath", SOUND_PATH ); | ||
49 | printf( "musicPath %s\n", musicPath.c_str() ); | ||
50 | musicType = loadSetting( "MusicType", "mod,ogg" ); | ||
51 | if ( musicPath[musicPath.size()-1] != '/' ) | ||
52 | musicPath += "/"; | ||
53 | |||
54 | // Init main SDL Library | ||
55 | initSDL( argc, argv ); | ||
56 | |||
57 | // Init SoundHandler | ||
58 | if ( !SoundHandler :: init() ) | ||
59 | printf("Unable to open audio!\n"); | ||
60 | |||
61 | currentGame = Game::createGame( this, WIDTH, HEIGHT, game, diff ); | ||
62 | if ( !currentGame ) | ||
63 | currentGame = new SFCaveGame( this, WIDTH, HEIGHT, 0 ); | ||
64 | currentGame->setSeed(-1); | ||
65 | menu = new Menu( this ); | ||
66 | |||
67 | help = new Help( this ); | ||
68 | |||
69 | maxFPS = 50; | ||
70 | showFps = false; | ||
71 | mainEventLoop(); | ||
72 | |||
73 | SoundHandler :: cleanUp(); | ||
74 | SDL_Quit(); | ||
75 | } | ||
76 | |||
77 | SFCave :: ~SFCave() | ||
78 | { | ||
79 | if ( currentGame ) | ||
80 | delete currentGame; | ||
81 | |||
82 | if ( menu ) | ||
83 | delete menu; | ||
84 | |||
85 | SDL_FreeSurface( screen ); | ||
86 | } | ||
87 | |||
88 | |||
89 | void SFCave :: drawGameScreen( ) | ||
90 | { | ||
91 | //ClearScreen(screen, "Titletext"); | ||
92 | |||
93 | } | ||
94 | |||
95 | void SFCave :: initSDL( int argc, char *argv[] ) | ||
96 | { | ||
97 | const SDL_VideoInfo *info; | ||
98 | Uint8 video_bpp; | ||
99 | Uint32 videoflags; | ||
100 | |||
101 | |||
102 | |||
103 | /* Initialize SDL */ | ||
104 | if ( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0 ) { | ||
105 | fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); | ||
106 | exit(1); | ||
107 | } | ||
108 | atexit(SDL_Quit); | ||
109 | |||
110 | /* Alpha blending doesn't work well at 8-bit color */ | ||
111 | video_bpp = 16; | ||
112 | |||
113 | if ( !SDL_VideoModeOK(WIDTH, HEIGHT, 16, SDL_DOUBLEBUF) ) | ||
114 | printf( "No double buffering\n" ); | ||
115 | |||
116 | videoflags = SDL_HWSURFACE | SDL_SRCALPHA;//|| SDL_DOUBLEBUF;// | SDL_SRCALPHA | SDL_RESIZABLE; | ||
117 | while ( argc > 1 ) { | ||
118 | --argc; | ||
119 | if ( strcmp(argv[argc-1], "-bpp") == 0 ) { | ||
120 | video_bpp = atoi(argv[argc]); | ||
121 | --argc; | ||
122 | } else | ||
123 | if ( strcmp(argv[argc], "-hw") == 0 ) { | ||
124 | videoflags |= SDL_HWSURFACE; | ||
125 | } else | ||
126 | if ( strcmp(argv[argc], "-warp") == 0 ) { | ||
127 | videoflags |= SDL_HWPALETTE; | ||
128 | } else | ||
129 | if ( strcmp(argv[argc], "-fullscreen") == 0 ) { | ||
130 | videoflags |= SDL_FULLSCREEN; | ||
131 | } else { | ||
132 | fprintf(stderr, | ||
133 | "Usage: %s [-bpp N] [-warp] [-hw] [-fullscreen]\n", | ||
134 | argv[0]); | ||
135 | exit(1); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | /* Set 240x320 video mode */ | ||
140 | if ( (screen=SDL_SetVideoMode(WIDTH,HEIGHT,video_bpp,videoflags)) == NULL ) { | ||
141 | fprintf(stderr, "Couldn't set %ix%i video mode: %s\n",WIDTH,HEIGHT,SDL_GetError()); | ||
142 | exit(2); | ||
143 | } | ||
144 | |||
145 | /* Use alpha blending */ | ||
146 | SDL_SetAlpha(screen, SDL_RLEACCEL, 0); | ||
147 | |||
148 | /* Set title for window */ | ||
149 | SDL_WM_SetCaption("SFCave","SFCave"); | ||
150 | } | ||
151 | |||
152 | void SFCave :: mainEventLoop() | ||
153 | { | ||
154 | SDL_Event event; | ||
155 | int done; | ||
156 | |||
157 | /* Wait for a keystroke */ | ||
158 | done = 0; | ||
159 | state = 0; | ||
160 | state = STATE_CRASHED; | ||
161 | changeState( STATE_MENU ); | ||
162 | |||
163 | int FPS = 0; | ||
164 | bool limitFPS = true; | ||
165 | actualFPS = 0; | ||
166 | long time1 = 0; | ||
167 | long start; | ||
168 | long end; | ||
169 | //long nrTimes = 0; | ||
170 | struct timeb tp; | ||
171 | while ( !done ) | ||
172 | { | ||
173 | // calc FPS | ||
174 | ftime( &tp ); | ||
175 | start =(tp.time%10000)*10000 + tp.millitm; | ||
176 | // printf( "start = %ld, time1 - %d, st-tm - %d, tp.time - %ld\n", start, time1, start-time1, (tp.time%1000)*1000 ); | ||
177 | if ( start - time1 >= 1000 ) | ||
178 | { | ||
179 | actualFPS = FPS; | ||
180 | // printf( "%d FPS = %d\n", nrTimes++, actualFPS ); | ||
181 | FPS = 0; | ||
182 | time1 = start; | ||
183 | } | ||
184 | else | ||
185 | FPS ++; | ||
186 | |||
187 | SDL_FillRect( screen, 0, 0 ); | ||
188 | switch( state ) | ||
189 | { | ||
190 | case STATE_MENU: | ||
191 | SDL_FillRect( screen, 0, 0 ); | ||
192 | menu->draw( screen ); | ||
193 | break; | ||
194 | case STATE_HELP: | ||
195 | SDL_FillRect( screen, 0, 0 ); | ||
196 | help->update(); | ||
197 | help->draw( screen ); | ||
198 | break; | ||
199 | case STATE_NEWGAME: | ||
200 | printf( "STATE_NEWGAME\n" ); | ||
201 | currentGame->setReplay( false ); | ||
202 | currentGame->init(); | ||
203 | changeState( STATE_PLAYING ); | ||
204 | break; | ||
205 | |||
206 | case STATE_REPLAY: | ||
207 | printf( "STATE_NEWGAME\n" ); | ||
208 | currentGame->setReplay( true ); | ||
209 | currentGame->init(); | ||
210 | changeState( STATE_PLAYING ); | ||
211 | break; | ||
212 | |||
213 | case STATE_PLAYING: | ||
214 | case STATE_CRASHING: | ||
215 | currentGame->update( state ); | ||
216 | currentGame->draw( screen ); | ||
217 | break; | ||
218 | |||
219 | case STATE_CRASHED: | ||
220 | currentGame->update( state ); | ||
221 | currentGame->draw( screen ); | ||
222 | |||
223 | // Display Game Over message | ||
224 | break; | ||
225 | |||
226 | case STATE_QUIT: | ||
227 | done = 1; | ||
228 | break; | ||
229 | } | ||
230 | |||
231 | /* Show */ | ||
232 | // if ( state != STATE_CRASHED ) | ||
233 | SDL_Flip( screen ); | ||
234 | // SDL_UpdateRect(screen, 0, 0, 0, 0); | ||
235 | |||
236 | if ( limitFPS ) | ||
237 | { | ||
238 | /* Slow down polling - limit to x FPS*/ | ||
239 | ftime( &tp ); | ||
240 | end = abs((tp.time%10000)*10000 + tp.millitm); | ||
241 | if ( end-start < (1000/maxFPS) ) | ||
242 | { | ||
243 | // printf( "end - %ld, timetaken for frame = %ld, sleeping for %ld %d\n", end, end-start, (1000/maxFPS)-(end-start), actualFPS ); | ||
244 | if ( (1000/maxFPS)-(end-start) > 500 ) | ||
245 | { | ||
246 | // Should never happen but in case it does sleep for 5 seconds | ||
247 | printf( "WARNING WILL ROBINSON! delay = %ld - start %ld, end %ld\n", (1000/maxFPS)-(end-start), start, end ); | ||
248 | SDL_Delay( 5 ); | ||
249 | } | ||
250 | else | ||
251 | SDL_Delay((1000/maxFPS)-(end-start) ); | ||
252 | } | ||
253 | } | ||
254 | else | ||
255 | SDL_Delay( 5 ); | ||
256 | |||
257 | /* Check for events */ | ||
258 | while ( SDL_PollEvent(&event) ) | ||
259 | { | ||
260 | switch (event.type) | ||
261 | { | ||
262 | case SDL_KEYDOWN: | ||
263 | case SDL_KEYUP: | ||
264 | // Escape keypress quits the app | ||
265 | if ( event.key.keysym.sym != SDLK_ESCAPE ) | ||
266 | { | ||
267 | // printf( "Key Pressed was %d %s\n", event.key.keysym.sym, SDL_GetKeyName( event.key.keysym.sym ) ); | ||
268 | |||
269 | if ( state == STATE_MENU ) | ||
270 | { | ||
271 | int rc = menu->handleKeys( event.key ); | ||
272 | if ( rc != -1 ) | ||
273 | handleMenuSelect( rc ); | ||
274 | } | ||
275 | else if ( state == STATE_HELP ) | ||
276 | { | ||
277 | help->handleKeys( event.key ); | ||
278 | } | ||
279 | else if ( state == STATE_CRASHED ) | ||
280 | { | ||
281 | if ( event.type == SDL_KEYDOWN ) | ||
282 | { | ||
283 | if ( event.key.keysym.sym == SDLK_UP || | ||
284 | event.key.keysym.sym == SDLK_DOWN || | ||
285 | event.key.keysym.sym == SDLK_SPACE ) | ||
286 | changeState( STATE_NEWGAME ); | ||
287 | else if ( event.key.keysym.sym == SDLK_RETURN || event.key.keysym.sym == 0 ) | ||
288 | { | ||
289 | changeState( STATE_MENU ); | ||
290 | menu->resetToTopMenu(); | ||
291 | } | ||
292 | else if ( event.key.keysym.sym == SDLK_r ) | ||
293 | { | ||
294 | changeState( STATE_REPLAY ); | ||
295 | } | ||
296 | else if ( event.key.keysym.sym == SDLK_s ) | ||
297 | { | ||
298 | SoundHandler :: playSound( SND_EXPLOSION ); | ||
299 | } | ||
300 | } | ||
301 | } | ||
302 | else | ||
303 | { | ||
304 | switch ( event.key.keysym.sym ) | ||
305 | { | ||
306 | case SDLK_f: | ||
307 | printf( "showFPS - %d\n", showFps ); | ||
308 | if ( event.type == SDL_KEYDOWN ) | ||
309 | showFps = !showFps; | ||
310 | break; | ||
311 | case SDLK_l: | ||
312 | if ( event.type == SDL_KEYDOWN ) | ||
313 | limitFPS = !limitFPS; | ||
314 | break; | ||
315 | |||
316 | case SDLK_p: | ||
317 | if ( event.type == SDL_KEYDOWN ) | ||
318 | { | ||
319 | maxFPS ++; | ||
320 | printf( "maxFPS - %d\n", maxFPS ); | ||
321 | } | ||
322 | break; | ||
323 | |||
324 | case SDLK_o: | ||
325 | if ( event.type == SDL_KEYDOWN ) | ||
326 | { | ||
327 | maxFPS --; | ||
328 | printf( "maxFPS - %d\n", maxFPS ); | ||
329 | } | ||
330 | break; | ||
331 | |||
332 | case SDLK_n: | ||
333 | currentGame->getTerrain()->offset++; | ||
334 | break; | ||
335 | |||
336 | default: | ||
337 | currentGame->handleKeys( event.key ); | ||
338 | break; | ||
339 | } | ||
340 | } | ||
341 | |||
342 | break; | ||
343 | } | ||
344 | |||
345 | |||
346 | case SDL_QUIT: | ||
347 | done = 1; | ||
348 | break; | ||
349 | default: | ||
350 | break; | ||
351 | } | ||
352 | } | ||
353 | } | ||
354 | } | ||
355 | |||
356 | void SFCave :: changeState( int s ) | ||
357 | { | ||
358 | if ( state != s ) | ||
359 | currentGame->stateChanged( state, s ); | ||
360 | |||
361 | if ( state == STATE_MENU && s == STATE_HELP ) | ||
362 | help->init(); | ||
363 | if ( state == STATE_CRASHED && s == STATE_MENU ) | ||
364 | { | ||
365 | SoundHandler :: stopMusic( true ); | ||
366 | |||
367 | string musicFile = chooseRandomFile( musicPath, musicType ); | ||
368 | printf("playing music %s\n", musicFile.c_str() ); | ||
369 | SoundHandler :: setMusicVolume( 128 ); | ||
370 | SoundHandler :: playMusic( musicFile ); | ||
371 | } | ||
372 | else if ( state == STATE_MENU && (s == STATE_NEWGAME || s == STATE_REPLAY) ) | ||
373 | { | ||
374 | SoundHandler :: stopMusic( ); | ||
375 | |||
376 | // Start the in game music | ||
377 | string musicFile = SOUND_PATH "ingame.mod"; | ||
378 | SoundHandler :: playMusic( musicFile ); | ||
379 | SoundHandler :: setMusicVolume( 25 ); | ||
380 | } | ||
381 | |||
382 | state = s; | ||
383 | } | ||
384 | |||
385 | |||
386 | void SFCave :: handleMenuSelect( int menuId ) | ||
387 | { | ||
388 | switch( menuId ) | ||
389 | { | ||
390 | case MENU_STARTGAME: | ||
391 | changeState( STATE_NEWGAME ); | ||
392 | break; | ||
393 | |||
394 | case MENU_HELP: | ||
395 | changeState( STATE_HELP ); | ||
396 | break; | ||
397 | |||
398 | case MENU_QUIT: | ||
399 | changeState( STATE_QUIT ); | ||
400 | break; | ||
401 | |||
402 | case MENU_PLAY_REPLAY: | ||
403 | if ( currentGame->isReplayAvailable() ) | ||
404 | changeState( STATE_REPLAY ); | ||
405 | else | ||
406 | setMenuStatusText( "No replay available yet" ); | ||
407 | break; | ||
408 | |||
409 | case MENU_LOAD_REPLAY: | ||
410 | { | ||
411 | #ifdef QWS | ||
412 | QString replayFile = getenv( "HOME" ); | ||
413 | #else | ||
414 | QString replayFile = "."; | ||
415 | #endif | ||
416 | replayFile += string( "/" ) + currentGame->getGameName() + ".replay"; | ||
417 | |||
418 | currentGame->loadReplay( replayFile ); | ||
419 | |||
420 | break; | ||
421 | } | ||
422 | |||
423 | case MENU_SAVE_REPLAY: | ||
424 | { | ||
425 | |||
426 | if ( currentGame->isReplayAvailable() ) | ||
427 | { | ||
428 | #ifdef QWS | ||
429 | QString replayFile = getenv( "HOME" ); | ||
430 | #else | ||
431 | QString replayFile = "."; | ||
432 | #endif | ||
433 | replayFile += string( "/" ) + currentGame->getGameName() + ".replay"; | ||
434 | |||
435 | currentGame->saveReplay( replayFile ); | ||
436 | } | ||
437 | else | ||
438 | setMenuStatusText( "No replay available yet" ); | ||
439 | |||
440 | break; | ||
441 | } | ||
442 | case MENU_CLEAR_SCORES: | ||
443 | break; | ||
444 | |||
445 | case MENU_GAME_SFCAVE: | ||
446 | if ( currentGame->getGameName() != "SFCave" ) | ||
447 | { | ||
448 | int diff = currentGame->getDifficulty(); | ||
449 | delete currentGame; | ||
450 | currentGame = new SFCaveGame( this, WIDTH, HEIGHT, 0 ); | ||
451 | currentGame->setDifficulty( diff ); | ||
452 | |||
453 | saveSetting( "GameType", "SFCave" ); | ||
454 | } | ||
455 | break; | ||
456 | |||
457 | case MENU_GAME_GATES: | ||
458 | if ( currentGame->getGameName() != "Gates" ) | ||
459 | { | ||
460 | int diff = currentGame->getDifficulty(); | ||
461 | delete currentGame; | ||
462 | currentGame = new GatesGame( this, WIDTH, HEIGHT, 0 ); | ||
463 | currentGame->setDifficulty( diff ); | ||
464 | |||
465 | saveSetting( "GameType", "Gates" ); | ||
466 | } | ||
467 | break; | ||
468 | break; | ||
469 | |||
470 | case MENU_GAME_FLY: | ||
471 | if ( currentGame->getGameName() != "Fly" ) | ||
472 | { | ||
473 | int diff = currentGame->getDifficulty(); | ||
474 | delete currentGame; | ||
475 | currentGame = new FlyGame( this, WIDTH, HEIGHT, 0 ); | ||
476 | currentGame->setDifficulty( diff ); | ||
477 | |||
478 | saveSetting( "GameType", "Fly" ); | ||
479 | } | ||
480 | break; | ||
481 | |||
482 | case MENU_DIFFICULTY_EASY: | ||
483 | currentGame->setDifficulty( MENU_DIFFICULTY_EASY ); | ||
484 | saveSetting( "GameDifficulty", "Easy" ); | ||
485 | break; | ||
486 | |||
487 | case MENU_DIFFICULTY_NORMAL: | ||
488 | currentGame->setDifficulty( MENU_DIFFICULTY_NORMAL ); | ||
489 | saveSetting( "GameDifficulty", "Medium" ); | ||
490 | break; | ||
491 | |||
492 | case MENU_DIFFICULTY_HARD: | ||
493 | currentGame->setDifficulty( MENU_DIFFICULTY_HARD ); | ||
494 | saveSetting( "GameDifficulty", "Hard" ); | ||
495 | break; | ||
496 | |||
497 | case MENU_SOUND_ON: | ||
498 | SoundHandler :: setSoundsOn( true ); | ||
499 | break; | ||
500 | |||
501 | case MENU_SOUND_OFF: | ||
502 | SoundHandler :: setSoundsOn( false ); | ||
503 | break; | ||
504 | |||
505 | case MENU_MUSIC_ON: | ||
506 | SoundHandler :: setMusicOn( true ); | ||
507 | break; | ||
508 | |||
509 | case MENU_MUSIC_OFF: | ||
510 | SoundHandler :: setMusicOn( false ); | ||
511 | break; | ||
512 | |||
513 | default: | ||
514 | break; | ||
515 | } | ||
516 | } | ||
517 | |||
518 | void SFCave :: setMenuStatusText( string statusText ) | ||
519 | { | ||
520 | menu->setStatusText( statusText ); | ||
521 | } | ||
522 | |||
523 | |||
524 | void SFCave :: saveSetting( string key, string val ) | ||
525 | { | ||
526 | Settings cfg( "sfcave-sdl" ); | ||
527 | cfg.writeSetting( key, val ); | ||
528 | } | ||
529 | |||
530 | void SFCave :: saveSetting( string key, int val ) | ||
531 | { | ||
532 | Settings cfg( "sfcave-sdl" ); | ||
533 | cfg.writeSetting( key, val ); | ||
534 | } | ||
535 | |||
536 | string SFCave :: loadSetting( string key, string defaultVal ) | ||
537 | { | ||
538 | string val; | ||
539 | Settings cfg( "sfcave-sdl" ); | ||
540 | cfg.readSetting( key, val ); | ||
541 | |||
542 | if ( val == "" ) | ||
543 | val = defaultVal; | ||
544 | |||
545 | return val; | ||
546 | } | ||
diff --git a/noncore/games/sfcave-sdl/sfcave.h b/noncore/games/sfcave-sdl/sfcave.h new file mode 100644 index 0000000..96c2334 --- a/dev/null +++ b/noncore/games/sfcave-sdl/sfcave.h | |||
@@ -0,0 +1,50 @@ | |||
1 | #ifndef __SFCAVE_H | ||
2 | #define __SFCAVE_H | ||
3 | |||
4 | #include "SDL.h" | ||
5 | |||
6 | #include "terrain.h" | ||
7 | |||
8 | class Game; | ||
9 | class Menu; | ||
10 | class Help; | ||
11 | |||
12 | class SFCave | ||
13 | { | ||
14 | public: | ||
15 | SFCave( int argc, char *argv[] ); | ||
16 | ~SFCave(); | ||
17 | |||
18 | void drawGameScreen(); | ||
19 | void initSDL( int argc, char *argv[] ); | ||
20 | void mainEventLoop(); | ||
21 | |||
22 | void setCrashed( bool val ); | ||
23 | void changeState( int s ); | ||
24 | int getState() { return state; } | ||
25 | Game *getCurrentGame() { return currentGame; } | ||
26 | int getFPS() { return actualFPS; } | ||
27 | bool showFPS() { return showFps; } | ||
28 | |||
29 | void setMenuStatusText( string statusText ); | ||
30 | |||
31 | void saveSetting( string key, string val ); | ||
32 | void saveSetting( string key, int val ); | ||
33 | string loadSetting( string key, string defaultVal = "" ); | ||
34 | private: | ||
35 | SDL_Surface *screen; | ||
36 | |||
37 | Game *currentGame; | ||
38 | Menu *menu; | ||
39 | Help *help; | ||
40 | int state; | ||
41 | int maxFPS; | ||
42 | int actualFPS; | ||
43 | bool showFps; | ||
44 | string musicPath; | ||
45 | string musicType; | ||
46 | |||
47 | void handleMenuSelect( int menuId ); | ||
48 | }; | ||
49 | |||
50 | #endif | ||
diff --git a/noncore/games/sfcave-sdl/sfcave_game.cpp b/noncore/games/sfcave-sdl/sfcave_game.cpp new file mode 100644 index 0000000..72c5ce3 --- a/dev/null +++ b/noncore/games/sfcave-sdl/sfcave_game.cpp | |||
@@ -0,0 +1,167 @@ | |||
1 | #include "SDL_gfxPrimitives.h" | ||
2 | |||
3 | #include "constants.h" | ||
4 | #include "sfcave_game.h" | ||
5 | #include "random.h" | ||
6 | |||
7 | SFCaveGame :: SFCaveGame( SFCave *p, int w, int h, int diff ) | ||
8 | : Game( p, w, h, diff ) | ||
9 | { | ||
10 | gameName = "SFCave"; | ||
11 | difficulty = MENU_DIFFICULTY_EASY; | ||
12 | blockUpdateRate = 200; | ||
13 | |||
14 | terrain = new Terrain( w, h ); | ||
15 | player = new Player( w, h ); | ||
16 | highScore = 0; | ||
17 | } | ||
18 | |||
19 | SFCaveGame :: ~SFCaveGame() | ||
20 | { | ||
21 | } | ||
22 | |||
23 | void SFCaveGame :: init() | ||
24 | { | ||
25 | Game :: init(); | ||
26 | |||
27 | blockDistance = 50; | ||
28 | blockHeight = 80; | ||
29 | blockWidth = 20; | ||
30 | |||
31 | switch( difficulty ) | ||
32 | { | ||
33 | case MENU_DIFFICULTY_EASY: | ||
34 | blockDistance = 50; | ||
35 | break; | ||
36 | case MENU_DIFFICULTY_NORMAL: | ||
37 | blockDistance = 40; | ||
38 | break; | ||
39 | case MENU_DIFFICULTY_HARD: | ||
40 | blockDistance = 30; | ||
41 | break; | ||
42 | } | ||
43 | |||
44 | for ( int i = 0 ; i < BLOCKSIZE ; ++i ) | ||
45 | blocks[i].y( -1 ); | ||
46 | } | ||
47 | |||
48 | void SFCaveGame :: update( int state ) | ||
49 | { | ||
50 | Game::update( state ); | ||
51 | |||
52 | if ( state == STATE_PLAYING ) | ||
53 | { | ||
54 | if ( nrFrames % 3 == 0 ) | ||
55 | score ++; | ||
56 | |||
57 | if ( nrFrames % 200 == 0 ) | ||
58 | { | ||
59 | if ( terrain->getMaxHeight() < sHeight - 100 ) | ||
60 | { | ||
61 | terrain->increaseMaxHeight( 10 ); | ||
62 | |||
63 | // Reduce block height | ||
64 | if ( terrain->getMaxHeight() > sHeight - 150 ) | ||
65 | blockHeight -= 5; | ||
66 | } | ||
67 | } | ||
68 | |||
69 | if ( checkCollisions() ) | ||
70 | { | ||
71 | // printf( "Crashed!\n" ); | ||
72 | parent->changeState( STATE_CRASHING ); | ||
73 | return; | ||
74 | } | ||
75 | |||
76 | if ( nrFrames % blockDistance == 0 ) | ||
77 | addBlock(); | ||
78 | |||
79 | // Game logic goes here | ||
80 | terrain->moveTerrain( 5 ); | ||
81 | moveBlocks( 5 ); | ||
82 | player->move( press ); | ||
83 | } | ||
84 | } | ||
85 | |||
86 | void SFCaveGame :: draw( SDL_Surface *screen ) | ||
87 | { | ||
88 | Game::preDraw( screen ); | ||
89 | |||
90 | if ( parent->getState() == STATE_PLAYING ) | ||
91 | { | ||
92 | // Screen drawing goes here | ||
93 | terrain->drawTerrain( screen ); | ||
94 | |||
95 | player->draw( screen ); | ||
96 | |||
97 | drawBlocks( screen ); | ||
98 | } | ||
99 | else | ||
100 | { | ||
101 | // Screen drawing goes here | ||
102 | terrain->drawTerrain( screen ); | ||
103 | |||
104 | drawBlocks( screen ); | ||
105 | |||
106 | player->draw( screen ); | ||
107 | } | ||
108 | |||
109 | Game::draw( screen ); | ||
110 | } | ||
111 | |||
112 | void SFCaveGame :: addBlock() | ||
113 | { | ||
114 | for ( int i = 0 ; i < BLOCKSIZE ; ++i ) | ||
115 | { | ||
116 | if ( blocks[i].y() == -1 ) | ||
117 | { | ||
118 | int x = sWidth; | ||
119 | |||
120 | int y = terrain->getMapTop( MAPSIZE-1 ) + (int)(nextInt(terrain->getMapBottom( MAPSIZE-1 ) - terrain->getMapTop( MAPSIZE-1 ) - blockHeight)); | ||
121 | |||
122 | blocks[i].setRect( x, y, blockWidth, blockHeight ); | ||
123 | |||
124 | break; | ||
125 | } | ||
126 | } | ||
127 | } | ||
128 | |||
129 | void SFCaveGame :: moveBlocks( int amountToMove ) | ||
130 | { | ||
131 | for ( int i = 0 ; i < BLOCKSIZE ; ++i ) | ||
132 | { | ||
133 | if ( blocks[i].y() != -1 ) | ||
134 | { | ||
135 | blocks[i].moveBy( -amountToMove, 0 ); | ||
136 | if ( blocks[i].x() + blocks[i].y() < 0 ) | ||
137 | blocks[i].y( -1 ); | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | |||
142 | void SFCaveGame :: drawBlocks( SDL_Surface *screen ) | ||
143 | { | ||
144 | for ( int i = 0 ; i < BLOCKSIZE ; ++i ) | ||
145 | { | ||
146 | if ( blocks[i].y() != -1 ) | ||
147 | { | ||
148 | SDL_Rect r = blocks[i].getRect(); | ||
149 | SDL_FillRect( screen, &r, SDL_MapRGB( screen->format, 100, 100, 255 ) ); | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | |||
154 | bool SFCaveGame :: checkCollisions() | ||
155 | { | ||
156 | // Check collisions with blocks | ||
157 | for ( int i = 0 ; i < BLOCKSIZE ; ++i ) | ||
158 | { | ||
159 | if ( blocks[i].y() != -1 ) | ||
160 | { | ||
161 | if ( blocks[i].intersects( player->getPos() ) ) | ||
162 | return true; | ||
163 | } | ||
164 | } | ||
165 | // Check collision with landscape | ||
166 | return terrain->checkCollision( player->getX(), player->getY(), player->getHeight() ); | ||
167 | } | ||
diff --git a/noncore/games/sfcave-sdl/sfcave_game.h b/noncore/games/sfcave-sdl/sfcave_game.h new file mode 100644 index 0000000..92a0f5d --- a/dev/null +++ b/noncore/games/sfcave-sdl/sfcave_game.h | |||
@@ -0,0 +1,39 @@ | |||
1 | #ifndef __SFCAVE_GAME_H | ||
2 | #define __SFCAVE_GAME_H | ||
3 | |||
4 | #include "SDL.h" | ||
5 | |||
6 | #include "rect.h" | ||
7 | |||
8 | #include "sfcave.h" | ||
9 | #include "terrain.h" | ||
10 | #include "player.h" | ||
11 | #include "game.h" | ||
12 | |||
13 | class SFCaveGame : public Game | ||
14 | { | ||
15 | public: | ||
16 | SFCaveGame( SFCave *p, int w, int h, int diff ); | ||
17 | ~SFCaveGame(); | ||
18 | |||
19 | void init(); | ||
20 | void update( int state ); | ||
21 | void draw( SDL_Surface *screen ); | ||
22 | |||
23 | private: | ||
24 | |||
25 | int blockDistance; | ||
26 | int blockHeight; | ||
27 | int blockWidth; | ||
28 | int blockUpdateRate; | ||
29 | |||
30 | Rect blocks[BLOCKSIZE]; | ||
31 | |||
32 | void addBlock(); | ||
33 | void moveBlocks( int amountToMove ); | ||
34 | void drawBlocks( SDL_Surface *screen ); | ||
35 | bool checkCollisions(); | ||
36 | |||
37 | }; | ||
38 | |||
39 | #endif | ||
diff --git a/noncore/games/sfcave-sdl/sound.cpp b/noncore/games/sfcave-sdl/sound.cpp new file mode 100644 index 0000000..5fda859 --- a/dev/null +++ b/noncore/games/sfcave-sdl/sound.cpp | |||
@@ -0,0 +1,154 @@ | |||
1 | #include "constants.h" | ||
2 | #include "sound.h" | ||
3 | |||
4 | Mix_Chunk *SoundHandler :: sounds[NR_SOUNDS]; | ||
5 | Mix_Music *SoundHandler :: music; | ||
6 | int SoundHandler :: soundChannels[NR_SOUNDS]; | ||
7 | bool SoundHandler :: soundOn; | ||
8 | bool SoundHandler :: musicOn; | ||
9 | |||
10 | bool SoundHandler :: init( ) | ||
11 | { | ||
12 | // We're going to be requesting certain things from our audio | ||
13 | // device, so we set them up beforehand | ||
14 | int audio_rate = 22050; | ||
15 | Uint16 audio_format = AUDIO_S16; //AUDIO_S16; /* 16-bit stereo */ | ||
16 | int audio_channels = 2; | ||
17 | int audio_buffers = 1024;//4096; | ||
18 | |||
19 | // This is where we open up our audio device. Mix_OpenAudio takes | ||
20 | // as its parameters the audio format we'd /like/ to have. | ||
21 | if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers)) | ||
22 | { | ||
23 | printf("Unable to open audio!\n"); | ||
24 | return false; | ||
25 | } | ||
26 | |||
27 | // We're going to pre-load the sound effects that we need right here | ||
28 | sounds[SND_EXPLOSION] = Mix_LoadWAV( SOUND_PATH "explosion.wav"); | ||
29 | sounds[SND_THRUST] = Mix_LoadWAV( SOUND_PATH "thrust.wav"); | ||
30 | |||
31 | music = 0; | ||
32 | |||
33 | soundOn = true; | ||
34 | |||
35 | return true; | ||
36 | } | ||
37 | |||
38 | void SoundHandler :: cleanUp() | ||
39 | { | ||
40 | // Free audio sounds | ||
41 | Mix_FreeChunk( sounds[SND_EXPLOSION] ); | ||
42 | Mix_FreeChunk( sounds[SND_THRUST] ); | ||
43 | |||
44 | if ( music ) | ||
45 | Mix_FreeMusic( music ); | ||
46 | |||
47 | Mix_CloseAudio(); | ||
48 | } | ||
49 | |||
50 | int SoundHandler :: playSound( int soundNr, int channel, int nrLoops, int playBeforeFinished ) | ||
51 | { | ||
52 | if ( !soundOn ) | ||
53 | return -1; | ||
54 | |||
55 | if ( soundNr >= NR_SOUNDS ) | ||
56 | return -1; | ||
57 | |||
58 | Mix_Chunk *chunk = sounds[soundNr]; | ||
59 | if( channel == -1 || !Mix_Playing( channel ) ) | ||
60 | channel = Mix_PlayChannel(-1, sounds[soundNr], nrLoops); | ||
61 | |||
62 | Mix_Volume( channel, MIX_MAX_VOLUME ); | ||
63 | return channel; | ||
64 | } | ||
65 | |||
66 | void SoundHandler :: stopSound( int channel, bool fadeOut, int nrMilliSecs ) | ||
67 | { | ||
68 | if ( !soundOn ) | ||
69 | return; | ||
70 | |||
71 | if ( !fadeOut ) | ||
72 | Mix_HaltChannel( channel ); | ||
73 | else | ||
74 | { | ||
75 | Mix_FadeOutChannel( channel, nrMilliSecs ); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | void SoundHandler :: playMusic( string musicFile ) | ||
80 | { | ||
81 | if ( !soundOn ) | ||
82 | return; | ||
83 | |||
84 | // If music already exists - stop it playing if necessary and free it up | ||
85 | if ( music ) | ||
86 | { | ||
87 | stopMusic(); | ||
88 | Mix_FreeMusic( music ); | ||
89 | } | ||
90 | |||
91 | // Load music | ||
92 | music = Mix_LoadMUS( musicFile.c_str() ); | ||
93 | if(!music) | ||
94 | { | ||
95 | printf("Mix_LoadMUS(%s): %s\n", musicFile.c_str(), Mix_GetError()); | ||
96 | // this might be a critical error... | ||
97 | } | ||
98 | |||
99 | playMusic(); | ||
100 | } | ||
101 | |||
102 | void SoundHandler :: playMusic( bool fade ) | ||
103 | { | ||
104 | if ( !soundOn ) | ||
105 | return; | ||
106 | |||
107 | if ( music ) | ||
108 | { | ||
109 | Mix_VolumeMusic( MIX_MAX_VOLUME ); | ||
110 | Mix_RewindMusic(); | ||
111 | |||
112 | if ( fade ) | ||
113 | Mix_FadeInMusic( music, -1, 1000 ); | ||
114 | else | ||
115 | Mix_PlayMusic( music, -1 ); | ||
116 | |||
117 | } | ||
118 | } | ||
119 | |||
120 | void SoundHandler :: stopMusic( bool fadeOut ) | ||
121 | { | ||
122 | if ( !music || !Mix_PlayingMusic() ) | ||
123 | return; | ||
124 | |||
125 | if ( fadeOut && Mix_FadingMusic() == MIX_NO_FADING ) | ||
126 | { | ||
127 | Mix_FadeOutMusic( 1000 ); | ||
128 | } | ||
129 | else | ||
130 | { | ||
131 | Mix_HaltMusic(); | ||
132 | } | ||
133 | |||
134 | } | ||
135 | |||
136 | void SoundHandler :: setMusicVolume( int vol ) | ||
137 | { | ||
138 | Mix_VolumeMusic( vol ); | ||
139 | } | ||
140 | |||
141 | void SoundHandler :: setSoundsOn( bool val ) | ||
142 | { | ||
143 | soundOn = val; | ||
144 | } | ||
145 | |||
146 | void SoundHandler :: setMusicOn( bool val ) | ||
147 | { | ||
148 | musicOn = val; | ||
149 | |||
150 | if ( !musicOn ) | ||
151 | stopMusic(); | ||
152 | else | ||
153 | playMusic( true ); | ||
154 | } | ||
diff --git a/noncore/games/sfcave-sdl/sound.h b/noncore/games/sfcave-sdl/sound.h new file mode 100644 index 0000000..d46b5bc --- a/dev/null +++ b/noncore/games/sfcave-sdl/sound.h | |||
@@ -0,0 +1,35 @@ | |||
1 | #ifndef __SOUND_H | ||
2 | #define __SOUND_H | ||
3 | |||
4 | #include <SDL.h> | ||
5 | #include "SDL_mixer.h" | ||
6 | |||
7 | #define NR_SOUNDS 3 | ||
8 | |||
9 | class SoundHandler | ||
10 | { | ||
11 | public: | ||
12 | static bool init(); | ||
13 | static void cleanUp(); | ||
14 | |||
15 | static int playSound( int soundNr, int channel = -1, int nrLoops = 0, int playBeforeFinished = false ); | ||
16 | static void stopSound( int channel, bool fadeOut, int nrMilliSecs = 1000 ); | ||
17 | static void setSoundsOn( bool val ); | ||
18 | static void setMusicOn( bool val ); | ||
19 | static void playMusic( string musicFile ); | ||
20 | static void playMusic( bool fadeIn = false ); | ||
21 | static void stopMusic( bool fadeOut = false ); | ||
22 | static void setMusicVolume( int vol ); | ||
23 | |||
24 | |||
25 | private: | ||
26 | static Mix_Music *music; | ||
27 | static Mix_Chunk *sounds[NR_SOUNDS]; | ||
28 | static int soundChannels[NR_SOUNDS]; | ||
29 | static bool soundOn; | ||
30 | static bool musicOn; | ||
31 | |||
32 | SoundHandler() {} | ||
33 | }; | ||
34 | |||
35 | #endif | ||
diff --git a/noncore/games/sfcave-sdl/starfield.cpp b/noncore/games/sfcave-sdl/starfield.cpp new file mode 100644 index 0000000..c1f2d73 --- a/dev/null +++ b/noncore/games/sfcave-sdl/starfield.cpp | |||
@@ -0,0 +1,223 @@ | |||
1 | #include "SDL.h" | ||
2 | #include "SDL_gfxPrimitives.h" | ||
3 | |||
4 | #include <stdlib.h> | ||
5 | |||
6 | #include "starfield.h" | ||
7 | #include "random.h" | ||
8 | #include "util.h" | ||
9 | |||
10 | #define VERTICAL_VELOCITY 0 | ||
11 | |||
12 | StarField :: StarField( bool side, int nStars, int mx, int my, int minz, int maxz ) | ||
13 | { | ||
14 | nrStars = nStars; | ||
15 | maxX = mx; | ||
16 | maxY = my; | ||
17 | minZ = minz; | ||
18 | maxZ = maxz; | ||
19 | |||
20 | min_brightness = 50; | ||
21 | top_star_speed = 6; | ||
22 | |||
23 | sideways = side; | ||
24 | |||
25 | if ( !sideways ) | ||
26 | { | ||
27 | x = new int[nrStars]; | ||
28 | y = new int[nrStars]; | ||
29 | z = new int[nrStars]; | ||
30 | |||
31 | star_color = 0; | ||
32 | vel_x = 0; | ||
33 | vel_y = 0; | ||
34 | pos_x = 0; | ||
35 | pos_y = 0; | ||
36 | } | ||
37 | else | ||
38 | { | ||
39 | star_color = new int[nrStars]; | ||
40 | vel_x = new int[nrStars]; | ||
41 | vel_y = new int[nrStars]; | ||
42 | pos_x = new int[nrStars]; | ||
43 | pos_y = new int[nrStars]; | ||
44 | |||
45 | x = 0; | ||
46 | y = 0; | ||
47 | z = 0; | ||
48 | } | ||
49 | |||
50 | init(); | ||
51 | } | ||
52 | |||
53 | StarField :: ~StarField() | ||
54 | { | ||
55 | if ( star_color ) | ||
56 | delete []star_color; | ||
57 | if ( vel_x ) | ||
58 | delete []vel_x; | ||
59 | if ( vel_y ) | ||
60 | delete []vel_y; | ||
61 | if ( pos_x ) | ||
62 | delete []pos_x; | ||
63 | if ( pos_y ) | ||
64 | delete []pos_y; | ||
65 | |||
66 | if ( x ) | ||
67 | delete []x; | ||
68 | if ( y ) | ||
69 | delete []y; | ||
70 | if ( z ) | ||
71 | delete []z; | ||
72 | } | ||
73 | |||
74 | void StarField :: init() | ||
75 | { | ||
76 | if ( !sideways ) | ||
77 | { | ||
78 | for ( int i = 0 ; i < nrStars ; ++i ) | ||
79 | { | ||
80 | newStar( i ); | ||
81 | z[i] = (int)(Random() * (double)(maxZ - minZ)) + minZ; | ||
82 | } | ||
83 | } | ||
84 | else | ||
85 | { | ||
86 | int brightness; | ||
87 | |||
88 | //Initialise each star | ||
89 | for(int i = 0; i < nrStars ; i++) | ||
90 | { | ||
91 | //Inialise velocities | ||
92 | vel_x[i] = -(int)floor( (Random() * top_star_speed)+1 ); | ||
93 | vel_y[i] = VERTICAL_VELOCITY; | ||
94 | |||
95 | //Initialise positions randomly | ||
96 | pos_x[i] = (int)floor((Random() * 240)); | ||
97 | pos_y[i] = (int)floor((Random() * 320)); | ||
98 | |||
99 | //The Faster it goes, the Dimmer it is | ||
100 | if (vel_x[i] != 0) | ||
101 | { | ||
102 | brightness = (int)(255 / fabs(vel_x[i]) ); | ||
103 | if (brightness < min_brightness) | ||
104 | brightness = min_brightness; | ||
105 | } | ||
106 | else | ||
107 | brightness = 255; | ||
108 | |||
109 | star_color[i] = brightness; | ||
110 | } | ||
111 | } | ||
112 | } | ||
113 | |||
114 | void StarField :: newStar( int starNr ) | ||
115 | { | ||
116 | if ( !sideways ) | ||
117 | { | ||
118 | x[starNr] = (int)(Random() * (double)maxX) + 1; | ||
119 | y[starNr] = (int)(Random() * (double)maxY) + 1; | ||
120 | z[starNr] = maxZ; | ||
121 | |||
122 | int i = (int)(Random() * 4.0); | ||
123 | if(i < 2) | ||
124 | x[starNr] = -x[starNr]; | ||
125 | if(i == 0 || i == 2) | ||
126 | y[starNr] = -y[starNr]; | ||
127 | } | ||
128 | } | ||
129 | |||
130 | void StarField :: move( ) | ||
131 | { | ||
132 | if ( !sideways ) | ||
133 | { | ||
134 | int amountToMove = 16; | ||
135 | for(int i = 0; i < nrStars; i++) | ||
136 | { | ||
137 | // Rotate star | ||
138 | z[i] = z[i] - amountToMove; | ||
139 | if(z[i] < minZ) | ||
140 | newStar(i); | ||
141 | } | ||
142 | } | ||
143 | else | ||
144 | { | ||
145 | for(int i = 0; i < nrStars ; i++) | ||
146 | { | ||
147 | //Check speed limits x | ||
148 | if (vel_x[i] > top_star_speed) | ||
149 | vel_x[i] = top_star_speed; | ||
150 | else if (vel_x[i] < -top_star_speed) | ||
151 | vel_x[i] = -top_star_speed; | ||
152 | |||
153 | //Check speed limits y | ||
154 | if (vel_y[i] > top_star_speed) | ||
155 | vel_y[i] = top_star_speed; | ||
156 | else if (vel_y[i] < -top_star_speed) | ||
157 | vel_y[i] = -top_star_speed; | ||
158 | |||
159 | |||
160 | |||
161 | //Move Star | ||
162 | pos_x[i] += vel_x[i]; | ||
163 | pos_y[i] += vel_y[i]; | ||
164 | |||
165 | if (pos_x[i] < 0) | ||
166 | pos_x[i] = pos_x[i] + 240; | ||
167 | |||
168 | if (pos_x[i] > 240) | ||
169 | pos_x[i] = pos_x[i] - 240; | ||
170 | if (pos_y[i] < 0) | ||
171 | pos_y[i] = pos_y[i] + 320; | ||
172 | |||
173 | if (pos_y[i] > 320) | ||
174 | pos_y[i] = pos_y[i] - 320; | ||
175 | } | ||
176 | } | ||
177 | } | ||
178 | |||
179 | void StarField :: draw( SDL_Surface *screen, int w, int h ) | ||
180 | { | ||
181 | if ( !sideways ) | ||
182 | { | ||
183 | int scrW = w / 2; | ||
184 | int scrH = h / 2; | ||
185 | for(int i = 0; i < nrStars; i++) | ||
186 | { | ||
187 | int sx = (x[i] * 256) / z[i] + scrW; | ||
188 | int sy = (y[i] * 256) / z[i] + scrH; | ||
189 | if(sx < 0 || sx > w || sy < 0 || sy > h) | ||
190 | { | ||
191 | newStar(i); | ||
192 | } | ||
193 | else | ||
194 | { | ||
195 | int size = (z[i] * 3) / maxZ; | ||
196 | |||
197 | SDL_Rect r; | ||
198 | r.x = sx; | ||
199 | r.y = sy; | ||
200 | r.w = 3 - size; | ||
201 | r.h = 3 - size; | ||
202 | |||
203 | SDL_FillRect( screen, &r, SDL_MapRGB( screen->format, 255, 255, 255 ) ); | ||
204 | } | ||
205 | } | ||
206 | } | ||
207 | else | ||
208 | { | ||
209 | SDL_LockSurface( screen ); | ||
210 | for(int i = 0; i < nrStars ; i++) | ||
211 | { | ||
212 | |||
213 | Uint32 c = getpixel( screen, pos_x[i], pos_y[i] ); | ||
214 | |||
215 | |||
216 | if ( c == 0 ) | ||
217 | lineRGBA( screen, pos_x[i], pos_y[i], pos_x [i]+ vel_x[i], pos_y[i] + vel_y[i], star_color[i], star_color[i], star_color[i], 255 ); | ||
218 | |||
219 | //*** NOTE : if the velocity of the stars never changes then the values such as 'pos_x[i] + vel_x[i]' could be precalculated for each star *** | ||
220 | } | ||
221 | SDL_UnlockSurface( screen ); | ||
222 | } | ||
223 | } | ||
diff --git a/noncore/games/sfcave-sdl/starfield.h b/noncore/games/sfcave-sdl/starfield.h new file mode 100644 index 0000000..ae9bd34 --- a/dev/null +++ b/noncore/games/sfcave-sdl/starfield.h | |||
@@ -0,0 +1,41 @@ | |||
1 | #ifndef __STARFIELD_H | ||
2 | #define __STARFIELD_H | ||
3 | |||
4 | class StarField | ||
5 | { | ||
6 | public: | ||
7 | StarField( bool side = false, int nrStars = 100, int mx = 240, int my = 320, int minz = 32, int maxz = 725 ); | ||
8 | ~StarField(); | ||
9 | |||
10 | void init(); | ||
11 | void move( ); | ||
12 | void draw( SDL_Surface *screen, int w = 240, int h = 320 ); | ||
13 | |||
14 | private: | ||
15 | // 3d effect | ||
16 | int *x; | ||
17 | int *y; | ||
18 | int *z; | ||
19 | |||
20 | int maxX; | ||
21 | int maxY; | ||
22 | int minZ; | ||
23 | int maxZ; | ||
24 | |||
25 | // Sideways | ||
26 | int *star_color; | ||
27 | int *vel_x; | ||
28 | int *vel_y; | ||
29 | int *pos_x; | ||
30 | int *pos_y; | ||
31 | int min_brightness; | ||
32 | int top_star_speed; | ||
33 | |||
34 | bool sideways; | ||
35 | int nrStars; | ||
36 | |||
37 | void newStar( int i ); | ||
38 | }; | ||
39 | |||
40 | |||
41 | #endif | ||
diff --git a/noncore/games/sfcave-sdl/stringtokenizer.h b/noncore/games/sfcave-sdl/stringtokenizer.h new file mode 100644 index 0000000..3f299a6 --- a/dev/null +++ b/noncore/games/sfcave-sdl/stringtokenizer.h | |||
@@ -0,0 +1,23 @@ | |||
1 | #ifndef __STRINGTOKENIZER_H | ||
2 | #define __STRINGTOKENIZER_H | ||
3 | |||
4 | #include <vector> | ||
5 | using namespace std; | ||
6 | |||
7 | class StringTokenizer : public vector<string> | ||
8 | { | ||
9 | public: | ||
10 | StringTokenizer(const string &rStr, const string &rDelimiters = " ,\n") | ||
11 | { | ||
12 | string::size_type lastPos(rStr.find_first_not_of(rDelimiters, 0)); | ||
13 | string::size_type pos(rStr.find_first_of(rDelimiters, lastPos)); | ||
14 | while (string::npos != pos || string::npos != lastPos) | ||
15 | { | ||
16 | push_back(rStr.substr(lastPos, pos - lastPos)); | ||
17 | lastPos = rStr.find_first_not_of(rDelimiters, pos); | ||
18 | pos = rStr.find_first_of(rDelimiters, lastPos); | ||
19 | } | ||
20 | } | ||
21 | }; | ||
22 | |||
23 | #endif | ||
diff --git a/noncore/games/sfcave-sdl/terrain.cpp b/noncore/games/sfcave-sdl/terrain.cpp new file mode 100644 index 0000000..c001a56 --- a/dev/null +++ b/noncore/games/sfcave-sdl/terrain.cpp | |||
@@ -0,0 +1,313 @@ | |||
1 | #include "SDL.h" | ||
2 | #include "SDL_rotozoom.h" | ||
3 | #include "SDL_gfxPrimitives.h" | ||
4 | |||
5 | #include "constants.h" | ||
6 | #include "terrain.h" | ||
7 | #include "random.h" | ||
8 | #include "util.h" | ||
9 | #include "starfield.h" | ||
10 | |||
11 | Terrain :: Terrain( int w, int h, bool drawTop, bool drawBottom ) | ||
12 | { | ||
13 | sWidth = w; | ||
14 | sHeight = h; | ||
15 | speed = 1; | ||
16 | segSize = sWidth/(MAPSIZE-2)+1; | ||
17 | this->drawTop = drawTop; | ||
18 | this->drawBottom = drawBottom; | ||
19 | |||
20 | stars = new StarField( true ); | ||
21 | |||
22 | SDL_Surface *tmp = SDL_CreateRGBSurface(SDL_SWSURFACE, sWidth + 20, sHeight, 32, | ||
23 | 0x000000ff,0x0000ff00, 0x00ff0000, 0xff000000); | ||
24 | terrainSurface = SDL_DisplayFormat( tmp ); | ||
25 | SDL_FreeSurface( tmp ); | ||
26 | |||
27 | initTerrain(); | ||
28 | |||
29 | } | ||
30 | |||
31 | Terrain :: ~Terrain() | ||
32 | { | ||
33 | SDL_FreeSurface( terrainSurface ); | ||
34 | delete stars; | ||
35 | } | ||
36 | |||
37 | void Terrain :: initTerrain() | ||
38 | { | ||
39 | dir = 1; | ||
40 | offset = 0; | ||
41 | |||
42 | maxHeight = 50; | ||
43 | |||
44 | mapTop[0] = (int)(nextInt(50)) + 5; | ||
45 | mapBottom[0] = sHeight - (maxHeight - mapTop[0]); | ||
46 | for ( int i = 1 ; i < MAPSIZE ; ++i ) | ||
47 | setPoint( i ); | ||
48 | |||
49 | SDL_FillRect( terrainSurface, 0, 0 ); | ||
50 | // Draw Terrain into surface | ||
51 | Sint16 px[5]; | ||
52 | Sint16 py[5]; | ||
53 | |||
54 | for ( int i = 0 ; i < MAPSIZE ; ++i ) | ||
55 | { | ||
56 | int left = (i*segSize); | ||
57 | int right = ((i+1)*segSize); | ||
58 | px[0] = left; | ||
59 | py[0] = mapTop[i]; | ||
60 | px[1] = right; | ||
61 | py[1] = mapTop[i+1]; | ||
62 | px[2] = right; | ||
63 | py[2] = 0; | ||
64 | px[3] = left; | ||
65 | py[3] = 0; | ||
66 | |||
67 | if ( drawTop ) | ||
68 | { | ||
69 | // Only display top landscape if not running FLY_GAME | ||
70 | filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 ); | ||
71 | } | ||
72 | |||
73 | if ( drawBottom ) | ||
74 | { | ||
75 | py[0] = mapBottom[i]; | ||
76 | py[1] = mapBottom[i+1]; | ||
77 | py[2] = sHeight; | ||
78 | py[3] = sHeight; | ||
79 | filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 ); | ||
80 | } | ||
81 | |||
82 | } | ||
83 | |||
84 | |||
85 | } | ||
86 | |||
87 | void Terrain :: moveTerrain( int amountToMove ) | ||
88 | { | ||
89 | stars->move(); | ||
90 | |||
91 | offset += amountToMove; | ||
92 | speed = offset/segSize; | ||
93 | |||
94 | //printf( "offset - %d, speed - %d\n", offset, speed ); | ||
95 | if ( offset >= segSize ) | ||
96 | { | ||
97 | for ( int i = 0 ; i < (MAPSIZE)-speed ; ++i ) | ||
98 | { | ||
99 | mapTop[i] = mapTop[i+speed]; | ||
100 | mapBottom[i] = mapBottom[i+speed]; | ||
101 | } | ||
102 | |||
103 | for ( int i = (MAPSIZE)-speed ; i < MAPSIZE ; ++i ) | ||
104 | { | ||
105 | setPoint( i ); | ||
106 | } | ||
107 | |||
108 | SDL_Rect dst; | ||
109 | dst.x = offset; | ||
110 | dst.y = 0; | ||
111 | dst.w = sWidth; | ||
112 | dst.h = sHeight; | ||
113 | |||
114 | SDL_Rect dst2; | ||
115 | dst2.x = 0; | ||
116 | dst2.y = 0; | ||
117 | |||
118 | SDL_BlitSurface(terrainSurface, &dst, terrainSurface, &dst2 ); | ||
119 | |||
120 | dst.x = sWidth-5; | ||
121 | dst.y = 0; | ||
122 | dst.w = offset; | ||
123 | dst.h = sHeight; | ||
124 | SDL_FillRect( terrainSurface, &dst, 0 ); | ||
125 | for ( int i = (MAPSIZE-1) - speed -1; i < MAPSIZE-1 ; ++i ) | ||
126 | { | ||
127 | Sint16 px[4]; | ||
128 | Sint16 py[5]; | ||
129 | int left = ((i-1)*segSize); | ||
130 | int right = ((i)*segSize); | ||
131 | // printf( "left = %d, right = %d\n", left, right ); | ||
132 | |||
133 | px[0] = left; | ||
134 | py[0] = mapTop[i]; | ||
135 | px[1] = right; | ||
136 | py[1] = mapTop[i+1]; | ||
137 | px[2] = right; | ||
138 | py[2] = 0; | ||
139 | px[3] = left; | ||
140 | py[3] = 0; | ||
141 | |||
142 | if ( drawTop ) | ||
143 | { | ||
144 | // Only display top landscape if not running FLY_GAME | ||
145 | filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 ); | ||
146 | } | ||
147 | |||
148 | if ( drawBottom ) | ||
149 | { | ||
150 | py[0] = mapBottom[i]; | ||
151 | py[1] = mapBottom[i+1]; | ||
152 | py[2] = sHeight; | ||
153 | py[3] = sHeight; | ||
154 | filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 ); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | offset -= speed*segSize; | ||
159 | |||
160 | } | ||
161 | |||
162 | } | ||
163 | |||
164 | void Terrain :: setPoint( int point ) | ||
165 | { | ||
166 | if ( nextInt( 100 ) >= 80 ) | ||
167 | dir *= -1; | ||
168 | |||
169 | mapTop[point] = mapTop[point-1] + (dir * nextInt( 5 )); | ||
170 | if ( mapTop[point] < 0 ) | ||
171 | { | ||
172 | mapTop[point] = 0; | ||
173 | dir *= -1; | ||
174 | } | ||
175 | else if ( mapTop[point] >= maxHeight ) | ||
176 | { | ||
177 | mapTop[point] = maxHeight; | ||
178 | dir *= -1; | ||
179 | } | ||
180 | |||
181 | mapBottom[point] = sHeight - (maxHeight - mapTop[point]); | ||
182 | } | ||
183 | |||
184 | void Terrain :: increaseMaxHeight( int amount ) | ||
185 | { | ||
186 | maxHeight += amount; | ||
187 | } | ||
188 | |||
189 | void Terrain :: drawTerrain( SDL_Surface *screen ) | ||
190 | { | ||
191 | // Blit terrain surface onto screen | ||
192 | |||
193 | SDL_Rect dst; | ||
194 | dst.x = offset; | ||
195 | dst.y = 0; | ||
196 | dst.w = sWidth; | ||
197 | dst.h = sHeight; | ||
198 | //dst.h = maxHeight; | ||
199 | |||
200 | SDL_Rect dst2; | ||
201 | dst2.x = 0; | ||
202 | dst2.y = 0; | ||
203 | |||
204 | SDL_BlitSurface(terrainSurface, &dst, screen, &dst2 ); | ||
205 | |||
206 | stars->draw( screen ); | ||
207 | |||
208 | //dst.y = sHeight - maxHeight; | ||
209 | //dst2.y = sHeight - maxHeight; | ||
210 | //SDL_BlitSurface(terrainSurface, &dst, screen, &dst2 ); | ||
211 | |||
212 | /* | ||
213 | for ( int i = 0 ; i < MAPSIZE ; ++i ) | ||
214 | { | ||
215 | int x1 = (i*segSize) - (offset*speed); | ||
216 | int x2 = ((i+1)*segSize)-(offset*speed); | ||
217 | if ( x2 >= sWidth ) | ||
218 | x2 = sWidth-1; | ||
219 | aalineRGBA( screen, x1, mapTop[i], x2, mapTop[i+1], 0, 220, 0, 255 ); | ||
220 | aalineRGBA( screen, x1, mapBottom[i], x2, mapBottom[i+1], 0, 220, 0, 255 ); | ||
221 | } | ||
222 | */ | ||
223 | } | ||
224 | |||
225 | bool Terrain :: checkCollision( int x, int y, int h ) | ||
226 | { | ||
227 | if ( y < 0 || y > sHeight ) | ||
228 | return true; | ||
229 | // First get segment that matches x | ||
230 | SDL_LockSurface( terrainSurface ); | ||
231 | |||
232 | Uint32 c = getpixel( terrainSurface, x, y ); | ||
233 | |||
234 | SDL_UnlockSurface( terrainSurface ); | ||
235 | |||
236 | if ( c == 0 ) | ||
237 | return false; | ||
238 | else | ||
239 | return true; | ||
240 | } | ||
241 | |||
242 | |||
243 | // Test | ||
244 | #ifdef DEBUG_TERRAIN | ||
245 | SDL_Surface *screen; | ||
246 | Terrain *terrain; | ||
247 | |||
248 | void go() | ||
249 | { | ||
250 | /* Initialize SDL */ | ||
251 | if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) | ||
252 | { | ||
253 | fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); | ||
254 | exit(1); | ||
255 | } | ||
256 | atexit(SDL_Quit); | ||
257 | |||
258 | int videoflags = SDL_SWSURFACE ; | ||
259 | |||
260 | if ( (screen=SDL_SetVideoMode(280, 320,32,videoflags)) == NULL ) | ||
261 | { | ||
262 | fprintf(stderr, "Couldn't set %ix%i video mode: %s\n",WIDTH,HEIGHT,SDL_GetError()); | ||
263 | exit(2); | ||
264 | } | ||
265 | |||
266 | terrain = new Terrain( 240, 320 ); | ||
267 | |||
268 | bool done = false; | ||
269 | while ( !done ) | ||
270 | { | ||
271 | SDL_FillRect( screen, 0, 0 ); | ||
272 | terrain->drawTerrain( screen ); | ||
273 | terrain->moveTerrain( 5 ); | ||
274 | |||
275 | SDL_Flip( screen ); | ||
276 | |||
277 | SDL_Delay( 5 ); | ||
278 | |||
279 | SDL_Event event; | ||
280 | while ( SDL_PollEvent(&event) ) | ||
281 | { | ||
282 | switch (event.type) | ||
283 | { | ||
284 | case SDL_KEYDOWN: | ||
285 | // Escape keypress quits the app | ||
286 | if ( event.key.keysym.sym != SDLK_ESCAPE ) | ||
287 | { | ||
288 | terrain->moveTerrain( 5 ); | ||
289 | break; | ||
290 | } | ||
291 | case SDL_QUIT: | ||
292 | done = 1; | ||
293 | break; | ||
294 | default: | ||
295 | break; | ||
296 | } | ||
297 | } | ||
298 | } | ||
299 | } | ||
300 | |||
301 | |||
302 | |||
303 | |||
304 | #ifdef __cplusplus | ||
305 | extern "C" | ||
306 | #endif | ||
307 | int main( int argc, char *argv[] ) | ||
308 | { | ||
309 | go(); | ||
310 | } | ||
311 | |||
312 | #endif | ||
313 | |||
diff --git a/noncore/games/sfcave-sdl/terrain.h b/noncore/games/sfcave-sdl/terrain.h new file mode 100644 index 0000000..4070318 --- a/dev/null +++ b/noncore/games/sfcave-sdl/terrain.h | |||
@@ -0,0 +1,50 @@ | |||
1 | #ifndef __TERRAIN_H | ||
2 | #define __TERRAIN_H | ||
3 | |||
4 | #include <SDL.h> | ||
5 | |||
6 | class StarField; | ||
7 | class Terrain | ||
8 | { | ||
9 | public: | ||
10 | Terrain( int w, int h, bool drawTop = true, bool drawBottom = true ); | ||
11 | virtual ~Terrain(); | ||
12 | |||
13 | virtual void initTerrain(); | ||
14 | virtual void moveTerrain( int amountToMove ); | ||
15 | virtual bool checkCollision( int x, int y, int h ); | ||
16 | virtual void drawTerrain( SDL_Surface *screen ); | ||
17 | |||
18 | int getMapTop( int pos ) { return mapTop[pos]; } | ||
19 | int getMapBottom( int pos ) { return mapBottom[pos]; } | ||
20 | int getMaxHeight() { return maxHeight; } | ||
21 | void increaseMaxHeight( int amount ); | ||
22 | |||
23 | int offset; | ||
24 | protected: | ||
25 | |||
26 | int sWidth; | ||
27 | int sHeight; | ||
28 | |||
29 | int drawTop; | ||
30 | int drawBottom; | ||
31 | |||
32 | int mapTop[MAPSIZE]; | ||
33 | int mapBottom[MAPSIZE]; | ||
34 | int maxTop; | ||
35 | int maxBottom; | ||
36 | |||
37 | int maxHeight; | ||
38 | int dir; | ||
39 | int speed; | ||
40 | int segSize; | ||
41 | |||
42 | SDL_Surface *terrainSurface; | ||
43 | StarField *stars; | ||
44 | |||
45 | void setPoint( int point ); | ||
46 | }; | ||
47 | |||
48 | |||
49 | #endif | ||
50 | |||
diff --git a/noncore/games/sfcave-sdl/util.cpp b/noncore/games/sfcave-sdl/util.cpp new file mode 100644 index 0000000..86738ad --- a/dev/null +++ b/noncore/games/sfcave-sdl/util.cpp | |||
@@ -0,0 +1,64 @@ | |||
1 | #include "SDL.h" | ||
2 | |||
3 | #include <dirent.h> | ||
4 | |||
5 | #include <vector> | ||
6 | using namespace std; | ||
7 | |||
8 | #include "util.h" | ||
9 | #include "random.h" | ||
10 | |||
11 | Uint32 getpixel(SDL_Surface *surface, int x, int y) | ||
12 | { | ||
13 | int bpp = surface->format->BytesPerPixel; | ||
14 | /* Here p is the address to the pixel we want to retrieve */ | ||
15 | Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; | ||
16 | |||
17 | switch(bpp) { | ||
18 | case 1: | ||
19 | return *p; | ||
20 | |||
21 | case 2: | ||
22 | return *(Uint16 *)p; | ||
23 | |||
24 | case 3: | ||
25 | if(SDL_BYTEORDER == SDL_BIG_ENDIAN) | ||
26 | return p[0] << 16 | p[1] << 8 | p[2]; | ||
27 | else | ||
28 | return p[0] | p[1] << 8 | p[2] << 16; | ||
29 | |||
30 | case 4: | ||
31 | return *(Uint32 *)p; | ||
32 | |||
33 | default: | ||
34 | return 0; /* shouldn't happen, but avoids warnings */ | ||
35 | } | ||
36 | } | ||
37 | |||
38 | const char *chooseRandomFile( string path, string fileType ) | ||
39 | { | ||
40 | vector<string> files; | ||
41 | DIR *d = opendir( path.c_str() ); | ||
42 | if ( !d ) | ||
43 | return ""; | ||
44 | |||
45 | struct dirent *item = readdir( d ); | ||
46 | while ( item ) | ||
47 | { | ||
48 | string file = string( path ) + item->d_name; | ||
49 | |||
50 | // Rip extension from file | ||
51 | int pos = file.find( ".", 1 ) + 1; | ||
52 | string tmp = file.substr( pos ); | ||
53 | printf( "pos = %d, tmp =%s\n", pos, tmp.c_str() ); | ||
54 | if ( tmp.size() > 0 && fileType.find( tmp ) != -1 ) | ||
55 | { | ||
56 | printf( "Matching <%s> - %s with <%s>\n", file.substr( pos ).c_str(), file.c_str(), fileType.c_str() ); | ||
57 | files.push_back( file ); | ||
58 | } | ||
59 | item = readdir( d ); | ||
60 | } | ||
61 | |||
62 | closedir( d ); | ||
63 | return files[nextInt( files.size() )].c_str(); | ||
64 | } | ||
diff --git a/noncore/games/sfcave-sdl/util.h b/noncore/games/sfcave-sdl/util.h new file mode 100644 index 0000000..fe3e9c0 --- a/dev/null +++ b/noncore/games/sfcave-sdl/util.h | |||
@@ -0,0 +1,10 @@ | |||
1 | #ifndef __UTIL_H | ||
2 | #define __UTIL_H | ||
3 | |||
4 | #include <string> | ||
5 | using namespace std; | ||
6 | |||
7 | Uint32 getpixel(SDL_Surface *surface, int x, int y); | ||
8 | const char *chooseRandomFile( string path, string fileType ); | ||
9 | |||
10 | #endif | ||