summaryrefslogtreecommitdiff
path: root/noncore/games/sfcave-sdl/sfcave.cpp
Unidiff
Diffstat (limited to 'noncore/games/sfcave-sdl/sfcave.cpp') (more/less context) (show whitespace changes)
-rw-r--r--noncore/games/sfcave-sdl/sfcave.cpp546
1 files changed, 546 insertions, 0 deletions
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
27void start( int argc, char *argv[] )
28{
29 FontHandler::init();
30 SFCave app( argc, argv );
31 FontHandler::cleanUp();
32}
33
34#ifdef __cplusplus
35extern "C"
36#endif
37int main(int argc, char *argv[])
38{
39 start( argc, argv );
40 return 0;
41}
42
43
44SFCave :: 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
77SFCave :: ~SFCave()
78{
79 if ( currentGame )
80 delete currentGame;
81
82 if ( menu )
83 delete menu;
84
85 SDL_FreeSurface( screen );
86}
87
88
89void SFCave :: drawGameScreen( )
90{
91 //ClearScreen(screen, "Titletext");
92
93}
94
95void 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
152void 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
356void 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
386void 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
518void SFCave :: setMenuStatusText( string statusText )
519{
520 menu->setStatusText( statusText );
521}
522
523
524void SFCave :: saveSetting( string key, string val )
525{
526 Settings cfg( "sfcave-sdl" );
527 cfg.writeSetting( key, val );
528}
529
530void SFCave :: saveSetting( string key, int val )
531{
532 Settings cfg( "sfcave-sdl" );
533 cfg.writeSetting( key, val );
534}
535
536string 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}