summaryrefslogtreecommitdiff
path: root/noncore/games/sfcave-sdl/game.cpp
Unidiff
Diffstat (limited to 'noncore/games/sfcave-sdl/game.cpp') (more/less context) (show whitespace changes)
-rw-r--r--noncore/games/sfcave-sdl/game.cpp332
1 files changed, 332 insertions, 0 deletions
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
21Game :: 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
34Game :: ~Game()
35{
36 if ( terrain )
37 delete terrain;
38
39 if ( player )
40 delete player;
41
42 replayList.clear();
43}
44
45void 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
70void 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
100QString 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
114void 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
124void 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
162void Game :: preDraw( SDL_Surface *screen )
163{
164}
165
166void 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
198void 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
217void 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
226void 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
267void 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
317Game *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}