summaryrefslogtreecommitdiff
authorandyq <andyq>2002-12-09 20:30:46 (UTC)
committer andyq <andyq>2002-12-09 20:30:46 (UTC)
commitb9a448e0687558c1cb79f801161966e15d589132 (patch) (unidiff)
tree4f485b85b8bc03546008dd2003c75bf60f7acd9b
parentaccc4e231dc34744e75d32af77eeb98f46006c27 (diff)
downloadopie-b9a448e0687558c1cb79f801161966e15d589132.zip
opie-b9a448e0687558c1cb79f801161966e15d589132.tar.gz
opie-b9a448e0687558c1cb79f801161966e15d589132.tar.bz2
Added replay function and included own random method for replay functionality
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/sfcave/random.cpp179
-rw-r--r--noncore/games/sfcave/random.h19
-rw-r--r--noncore/games/sfcave/sfcave.cpp79
-rw-r--r--noncore/games/sfcave/sfcave.h12
-rw-r--r--noncore/games/sfcave/sfcave.pro4
5 files changed, 274 insertions, 19 deletions
diff --git a/noncore/games/sfcave/random.cpp b/noncore/games/sfcave/random.cpp
new file mode 100644
index 0000000..c4c10bb
--- a/dev/null
+++ b/noncore/games/sfcave/random.cpp
@@ -0,0 +1,179 @@
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#include "random.h"
38
39#define MODULUS 2147483647 /* DON'T CHANGE THIS VALUE */
40#define MULTIPLIER 48271 /* DON'T CHANGE THIS VALUE */
41#define CHECK 399268537 /* DON'T CHANGE THIS VALUE */
42#define STREAMS 256 /* # of streams, DON'T CHANGE THIS VALUE */
43#define A256 22925 /* jump multiplier, DON'T CHANGE THIS VALUE */
44#define DEFAULT 123456789 /* initial seed, use 0 < DEFAULT < MODULUS */
45
46static long seed[STREAMS] = {DEFAULT}; /* current state of each stream */
47static int stream = 0; /* stream index, 0 is the default */
48static int initialized = 0; /* test for stream initialization */
49
50
51 double Random(void)
52/* ----------------------------------------------------------------
53 * Random returns a pseudo-random real number uniformly distributed
54 * between 0.0 and 1.0.
55 * ----------------------------------------------------------------
56 */
57{
58 const long Q = MODULUS / MULTIPLIER;
59 const long R = MODULUS % MULTIPLIER;
60 long t;
61
62 t = MULTIPLIER * (seed[stream] % Q) - R * (seed[stream] / Q);
63 if (t > 0)
64 seed[stream] = t;
65 else
66 seed[stream] = t + MODULUS;
67 return ((double) seed[stream] / MODULUS);
68}
69
70
71 void PlantSeeds(long x)
72/* ---------------------------------------------------------------------
73 * Use this function to set the state of all the random number generator
74 * streams by "planting" a sequence of states (seeds), one per stream,
75 * with all states dictated by the state of the default stream.
76 * The sequence of planted states is separated one from the next by
77 * 8,367,782 calls to Random().
78 * ---------------------------------------------------------------------
79 */
80{
81 const long Q = MODULUS / A256;
82 const long R = MODULUS % A256;
83 int j;
84 int s;
85
86 initialized = 1;
87 s = stream; /* remember the current stream */
88 SelectStream(0); /* change to stream 0 */
89 PutSeed(x); /* set seed[0] */
90 stream = s; /* reset the current stream */
91 for (j = 1; j < STREAMS; j++) {
92 x = A256 * (seed[j - 1] % Q) - R * (seed[j - 1] / Q);
93 if (x > 0)
94 seed[j] = x;
95 else
96 seed[j] = x + MODULUS;
97 }
98}
99
100
101 void PutSeed(long x)
102/* ---------------------------------------------------------------
103 * Use this function to set the state of the current random number
104 * generator stream according to the following conventions:
105 * if x > 0 then x is the state (unless too large)
106 * if x < 0 then the state is obtained from the system clock
107 * if x = 0 then the state is to be supplied interactively
108 * ---------------------------------------------------------------
109 */
110{
111 char ok = 0;
112
113 if (x > 0)
114 x = x % MODULUS; /* correct if x is too large */
115 if (x < 0)
116 x = ((unsigned long) time((time_t *) NULL)) % MODULUS;
117 if (x == 0)
118 while (!ok) {
119 printf("\nEnter a positive integer seed (9 digits or less) >> ");
120 scanf("%ld", &x);
121 ok = (0 < x) && (x < MODULUS);
122 if (!ok)
123 printf("\nInput out of range ... try again\n");
124 }
125 seed[stream] = x;
126}
127
128
129 void GetSeed(long *x)
130/* ---------------------------------------------------------------
131 * Use this function to get the state of the current random number
132 * generator stream.
133 * ---------------------------------------------------------------
134 */
135{
136 *x = seed[stream];
137}
138
139
140 void SelectStream(int index)
141/* ------------------------------------------------------------------
142 * Use this function to set the current random number generator
143 * stream -- that stream from which the next random number will come.
144 * ------------------------------------------------------------------
145 */
146{
147 stream = ((unsigned int) index) % STREAMS;
148 if ((initialized == 0) && (stream != 0)) /* protect against */
149 PlantSeeds(DEFAULT); /* un-initialized streams */
150}
151
152
153 void TestRandom(void)
154/* ------------------------------------------------------------------
155 * Use this (optional) function to test for a correct implementation.
156 * ------------------------------------------------------------------
157 */
158{
159 long i;
160 long x;
161 double u;
162 char ok = 0;
163
164 SelectStream(0); /* select the default stream */
165 PutSeed(1); /* and set the state to 1 */
166 for(i = 0; i < 10000; i++)
167 u = Random();
168 GetSeed(&x); /* get the new state value */
169 ok = (x == CHECK); /* and check for correctness */
170
171 SelectStream(1); /* select stream 1 */
172 PlantSeeds(1); /* set the state of all streams */
173 GetSeed(&x); /* get the state of stream 1 */
174 ok = ok && (x == A256); /* x should be the jump multiplier */
175 if (ok)
176 printf("\n The implementation of rngs.c is correct.\n\n");
177 else
178 printf("\n\a ERROR -- the implementation of rngs.c is not correct.\n\n");
179}
diff --git a/noncore/games/sfcave/random.h b/noncore/games/sfcave/random.h
new file mode 100644
index 0000000..4bc7c06
--- a/dev/null
+++ b/noncore/games/sfcave/random.h
@@ -0,0 +1,19 @@
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
12double Random(void);
13void PlantSeeds(long x);
14void GetSeed(long *x);
15void PutSeed(long x);
16void SelectStream(int index);
17void TestRandom(void);
18
19#endif
diff --git a/noncore/games/sfcave/sfcave.cpp b/noncore/games/sfcave/sfcave.cpp
index 788606f..b5bc736 100644
--- a/noncore/games/sfcave/sfcave.cpp
+++ b/noncore/games/sfcave/sfcave.cpp
@@ -1,52 +1,54 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <stdlib.h> 2#include <stdlib.h>
3#include <math.h> 3#include <math.h>
4#include <time.h>
4 5
5#ifdef QWS 6#ifdef QWS
6#include <qpe/qpeapplication.h> 7#include <qpe/qpeapplication.h>
7#include <qpe/config.h> 8#include <qpe/config.h>
8#else 9#else
9#include <qapplication.h> 10#include <qapplication.h>
10#endif 11#endif
11 12
12#include "helpwindow.h" 13#include "helpwindow.h"
13#include "sfcave.h" 14#include "sfcave.h"
14 15
15#define CAPTION "SFCave 1.8 by AndyQ" 16#define CAPTION "SFCave 1.8 by AndyQ"
16 17
17#define UP_THRUST 0.6 18#define UP_THRUST 0.6
18#define NO_THRUST 0.8 19#define NO_THRUST 0.8
19#define MAX_DOWN_THRUST 4.0 20#define MAX_DOWN_THRUST 4.0
20#define MAX_UP_THRUST -3.5 21#define MAX_UP_THRUST -3.5
21 22
22// States 23// States
23#define STATE_BOSS 0 24#define STATE_BOSS 0
24#define STATE_RUNNING 1 25#define STATE_RUNNING 1
25#define STATE_CRASHING 2 26#define STATE_CRASHING 2
26#define STATE_CRASHED 3 27#define STATE_CRASHED 3
27#define STATE_NEWGAME 4 28#define STATE_NEWGAME 4
28#define STATE_MENU 5 29#define STATE_MENU 5
30#define STATE_REPLAY 6
29 31
30// Menus 32// Menus
31#define MENU_MAIN_MENU 0 33#define MENU_MAIN_MENU 0
32#define MENU_OPTIONS_MENU 1 34#define MENU_OPTIONS_MENU 1
33 35
34// Main Menu Options 36// Main Menu Options
35#define MENU_START_GAME 0 37#define MENU_START_GAME 0
36#define MENU_OPTIONS 1 38#define MENU_OPTIONS 1
37#define MENU_HELP 2 39#define MENU_HELP 2
38#define MENU_QUIT 3 40#define MENU_QUIT 3
39 41
40// Option Menu Options 42// Option Menu Options
41#define MENU_GAME_TYPE 0 43#define MENU_GAME_TYPE 0
42#define MENU_GAME_DIFFICULTY 1 44#define MENU_GAME_DIFFICULTY 1
43#define MENU_CLEAR_HIGHSCORES 2 45#define MENU_CLEAR_HIGHSCORES 2
44#define MENU_BACK 3 46#define MENU_BACK 3
45 47
46 48
47#define NR_GAME_DIFFICULTIES 3 49#define NR_GAME_DIFFICULTIES 3
48#define NR_GAME_TYPES 3 50#define NR_GAME_TYPES 3
49 51
50#define DIFICULTY_EASY 0 52#define DIFICULTY_EASY 0
51#define DIFICULTY_NORMAL 1 53#define DIFICULTY_NORMAL 1
52#define DIFICULTY_HARD 2 54#define DIFICULTY_HARD 2
@@ -106,205 +108,241 @@ int main( int argc, char *argv[] )
106 QApplication a( argc, argv ); 108 QApplication a( argc, argv );
107#endif 109#endif
108 110
109 int speed = 3; 111 int speed = 3;
110 for ( int i = 0 ; i < argc ; ++i ) 112 for ( int i = 0 ; i < argc ; ++i )
111 { 113 {
112 if ( strcmp( argv[i], "-s" ) == 0 ) 114 if ( strcmp( argv[i], "-s" ) == 0 )
113 { 115 {
114 if ( i+1 < argc ) 116 if ( i+1 < argc )
115 speed = atoi( argv[i+1] ); 117 speed = atoi( argv[i+1] );
116 } 118 }
117 } 119 }
118 120
119 SFCave app( speed ); 121 SFCave app( speed );
120 a.setMainWidget( &app ); 122 a.setMainWidget( &app );
121 app.show(); 123 app.show();
122 app.start(); 124 app.start();
123 a.exec(); 125 a.exec();
124} 126}
125 127
126SFCave :: SFCave( int spd, QWidget *w, char *name ) 128SFCave :: SFCave( int spd, QWidget *w, char *name )
127 : QMainWindow( w, name ) 129 : QMainWindow( w, name )
128 130
129{ 131{
132 replayIt = 0;
130#ifdef QWS 133#ifdef QWS
131 showMaximized(); 134 showMaximized();
132#else 135#else
133 resize( 240, 284 ); 136 resize( 240, 284 );
134#endif 137#endif
135 138
136 sWidth = width(); 139 sWidth = width();
137 sHeight = height(); 140 sHeight = height();
138 segSize = sWidth/(MAPSIZE-1)+1; 141 segSize = sWidth/(MAPSIZE-1)+1;
139 142
140 currentMenuNr = 0; 143 currentMenuNr = 0;
141 currentGameType = 0; 144 currentGameType = 0;
142 currentGameDifficulty = 0; 145 currentGameDifficulty = 0;
143 146
144 setCaption( CAPTION ); 147 setCaption( CAPTION );
145 showScoreZones = false; 148 showScoreZones = false;
146 149
147#ifdef QWS 150#ifdef QWS
148 Config cfg( "sfcave" ); 151 Config cfg( "sfcave" );
149 cfg.setGroup( "settings" ); 152 cfg.setGroup( "settings" );
150 QString key = "highScore_"; 153 QString key = "highScore_";
151 154
152 for ( int i = 0 ; i < 3 ; ++i ) 155 for ( int i = 0 ; i < 3 ; ++i )
153 { 156 {
154 for ( int j = 0 ; j < 3 ; ++j ) 157 for ( int j = 0 ; j < 3 ; ++j )
155 highestScore[i][j] = cfg.readNumEntry( key + gameTypes[i] + "_" + dificultyOption[j], 0 ); 158 highestScore[i][j] = cfg.readNumEntry( key + gameTypes[i] + "_" + dificultyOption[j], 0 );
156 } 159 }
157 160
158 currentGameType = cfg.readNumEntry( "gameType", 0 ); 161 currentGameType = cfg.readNumEntry( "gameType", 0 );
159 currentGameDifficulty = cfg.readNumEntry( "difficulty", 0 ); 162 currentGameDifficulty = cfg.readNumEntry( "difficulty", 0 );
160#endif 163#endif
161 speed = spd; // Change to 2 for PC 164 speed = spd; // Change to 2 for PC
162 press = false; 165 press = false;
163 166
164 offscreen = new QPixmap( sWidth, sHeight ); 167 offscreen = new QPixmap( sWidth, sHeight );
165 offscreen->fill( Qt::black ); 168 offscreen->fill( Qt::black );
166 169
167 setUp(); 170// setUp();
168 crashLineLength = -1; 171 crashLineLength = -1;
172 state = STATE_MENU;
173 prevState = STATE_MENU;
169 174
170 gameTimer = new QTimer( this, "game timer" ); 175 gameTimer = new QTimer( this, "game timer" );
171 connect( gameTimer, SIGNAL( timeout() ), 176 connect( gameTimer, SIGNAL( timeout() ),
172 this, SLOT( run() ) ); 177 this, SLOT( run() ) );
173} 178}
174 179
175SFCave :: ~SFCave() 180SFCave :: ~SFCave()
176{ 181{
177} 182}
178 183
179void SFCave :: start() 184void SFCave :: start()
180{ 185{
181 gameTimer->start( 10 ); 186 gameTimer->start( 10 );
182 187
183} 188}
184 189
190void SFCave :: setSeed( int seed )
191{
192 if ( seed == -1 )
193 currentSeed = ((unsigned long) time((time_t *) NULL));
194 else
195 currentSeed = seed;
196 PutSeed( currentSeed );
197}
198
185int SFCave :: nextInt( int range ) 199int SFCave :: nextInt( int range )
186{ 200{
187 return rand() % range; 201 int val = (int)(Random( ) * range);
202
203 return val;
204
188} 205}
189 206
190void SFCave :: setUp() 207void SFCave :: setUp()
191{ 208{
192 state = STATE_MENU;
193 prevState = STATE_MENU;
194
195 score = 0; 209 score = 0;
196 offset = 0; 210 offset = 0;
197 nrFrames = 0; 211 nrFrames = 0;
198 dir = 1; 212 dir = 1;
199 thrust = 0; 213 thrust = 0;
200 214
201 if ( CURRENT_GAME_TYPE == SFCAVE_GAME ) 215 if ( CURRENT_GAME_TYPE == SFCAVE_GAME )
202 { 216 {
203 thrustUp = UpThrustVals[SFCAVE_GAME_TYPE][currentGameDifficulty];; 217 thrustUp = UpThrustVals[SFCAVE_GAME_TYPE][currentGameDifficulty];;
204 noThrust = DownThrustVals[SFCAVE_GAME_TYPE][currentGameDifficulty];; 218 noThrust = DownThrustVals[SFCAVE_GAME_TYPE][currentGameDifficulty];;
205 maxUpThrust = MaxUpThrustVals[SFCAVE_GAME_TYPE][currentGameDifficulty];; 219 maxUpThrust = MaxUpThrustVals[SFCAVE_GAME_TYPE][currentGameDifficulty];;
206 maxDownThrust = MaxDownThrustVals[SFCAVE_GAME_TYPE][currentGameDifficulty];; 220 maxDownThrust = MaxDownThrustVals[SFCAVE_GAME_TYPE][currentGameDifficulty];;
207 } 221 }
208 else if ( CURRENT_GAME_TYPE == GATES_GAME ) 222 else if ( CURRENT_GAME_TYPE == GATES_GAME )
209 { 223 {
210 thrustUp = UpThrustVals[GATES_GAME_TYPE][currentGameDifficulty];; 224 thrustUp = UpThrustVals[GATES_GAME_TYPE][currentGameDifficulty];;
211 noThrust = DownThrustVals[GATES_GAME_TYPE][currentGameDifficulty];; 225 noThrust = DownThrustVals[GATES_GAME_TYPE][currentGameDifficulty];;
212 maxUpThrust = MaxUpThrustVals[GATES_GAME_TYPE][currentGameDifficulty];; 226 maxUpThrust = MaxUpThrustVals[GATES_GAME_TYPE][currentGameDifficulty];;
213 maxDownThrust = MaxDownThrustVals[GATES_GAME_TYPE][currentGameDifficulty];; 227 maxDownThrust = MaxDownThrustVals[GATES_GAME_TYPE][currentGameDifficulty];;
214 } 228 }
215 else 229 else
216 { 230 {
217 thrustUp = UpThrustVals[FLY_GAME_TYPE][currentGameDifficulty]; 231 thrustUp = UpThrustVals[FLY_GAME_TYPE][currentGameDifficulty];
218 noThrust = DownThrustVals[FLY_GAME_TYPE][currentGameDifficulty]; 232 noThrust = DownThrustVals[FLY_GAME_TYPE][currentGameDifficulty];
219 maxUpThrust = MaxUpThrustVals[FLY_GAME_TYPE][currentGameDifficulty]; 233 maxUpThrust = MaxUpThrustVals[FLY_GAME_TYPE][currentGameDifficulty];
220 maxDownThrust = MaxDownThrustVals[FLY_GAME_TYPE][currentGameDifficulty]; 234 maxDownThrust = MaxDownThrustVals[FLY_GAME_TYPE][currentGameDifficulty];
221 } 235 }
222 236
223 crashLineLength = 0; 237 crashLineLength = 0;
238 lastGateBottomY = 0;
224 239
225 user.setRect( 50, sWidth/2, 4, 4 ); 240 user.setRect( 50, sWidth/2, 4, 4 );
226 241
227 blockWidth = 20; 242 blockWidth = 20;
228 blockHeight = 70; 243 blockHeight = 70;
229 gapHeight = initialGateGaps[currentGameDifficulty]; 244 gapHeight = initialGateGaps[currentGameDifficulty];
230 gateDistance = 75; 245 gateDistance = 75;
231 nextGate = nextInt( 50 ) + gateDistance; 246 nextGate = nextInt( 50 ) + gateDistance;
232 247
233 for ( int i = 0 ; i < TRAILSIZE ; ++i ) 248 for ( int i = 0 ; i < TRAILSIZE ; ++i )
234 { 249 {
235 trail[i].setX( -1 ); 250 trail[i].setX( -1 );
236 trail[i].setY( 0 ); 251 trail[i].setY( 0 );
237 } 252 }
238 253
239 if ( CURRENT_GAME_TYPE != FLY_GAME ) 254 if ( CURRENT_GAME_TYPE != FLY_GAME )
240 { 255 {
241 maxHeight = 50; 256 maxHeight = 50;
242 257
243 mapTop[0] = (int)(nextInt(50)) + 5; 258 mapTop[0] = (int)(nextInt(50)) + 5;
244 mapBottom[0] = (int)(nextInt(50)) + 5; 259 mapBottom[0] = (int)(nextInt(50)) + 5;
245 for ( int i = 1 ; i < MAPSIZE ; ++i ) 260 for ( int i = 1 ; i < MAPSIZE ; ++i )
246 setPoint( i ); 261 setPoint( i );
247 } 262 }
248 else 263 else
249 { 264 {
250 maxHeight = 100; 265 maxHeight = 100;
251 266
252 for ( int i = 0 ; i < MAPSIZE ; ++i ) 267 for ( int i = 0 ; i < MAPSIZE ; ++i )
253 mapBottom[i] = sHeight - 10; 268 mapBottom[i] = sHeight - 10;
254 } 269 }
255 for ( int i = 0 ; i < BLOCKSIZE ; ++i ) 270 for ( int i = 0 ; i < BLOCKSIZE ; ++i )
256 blocks[i].setY( -1 ); 271 blocks[i].setY( -1 );
272
257} 273}
258 274
259void SFCave :: run() 275void SFCave :: run()
260{ 276{
261 switch ( state ) 277 switch ( state )
262 { 278 {
263 case STATE_MENU: 279 case STATE_MENU:
264 displayMenu(); 280 displayMenu();
265 break; 281 break;
266 case STATE_NEWGAME: 282 case STATE_NEWGAME:
283 setSeed( -1 );
267 setUp(); 284 setUp();
268 draw(); 285 draw();
269 state = STATE_RUNNING; 286 state = STATE_RUNNING;
287 replay = false;
288 replayList.clear();
270 break; 289 break;
290 case STATE_REPLAY:
291 setSeed( currentSeed );
292 setUp();
293 draw();
294 state = STATE_RUNNING;
295 replay = true;
296 if ( replayIt )
297 delete replayIt;
298 replayIt = new QListIterator<int>( replayList );
271 case STATE_BOSS: 299 case STATE_BOSS:
272 drawBoss(); 300 drawBoss();
273 break; 301 break;
274 302
275 case STATE_CRASHING: 303 case STATE_CRASHING:
276 case STATE_CRASHED: 304 case STATE_CRASHED:
277 draw(); 305 draw();
278 break; 306 break;
279 307
280 case STATE_RUNNING: 308 case STATE_RUNNING:
281 { 309 {
282 if ( nrFrames % 2 == 0 ) 310 if ( nrFrames % 2 == 0 )
283 handleKeys(); 311 handleKeys();
284 312
285 // Apply Game rules 313 // Apply Game rules
286 nrFrames ++; 314 nrFrames ++;
315
316 if ( replay )
317 {
318 while( replayIt->current() && *(replayIt->current()) == nrFrames )
319 {
320 press = !press;
321 ++(*replayIt);
322 }
323 }
324
287 if ( CURRENT_GAME_TYPE == SFCAVE_GAME ) 325 if ( CURRENT_GAME_TYPE == SFCAVE_GAME )
288 handleGameSFCave(); 326 handleGameSFCave();
289 else if ( CURRENT_GAME_TYPE == GATES_GAME ) 327 else if ( CURRENT_GAME_TYPE == GATES_GAME )
290 handleGameGates(); 328 handleGameGates();
291 else if ( CURRENT_GAME_TYPE == FLY_GAME ) 329 else if ( CURRENT_GAME_TYPE == FLY_GAME )
292 handleGameFly(); 330 handleGameFly();
293 331
294 draw(); 332 draw();
295 break; 333 break;
296 } 334 }
297 } 335 }
298} 336}
299 337
300void SFCave :: handleGameSFCave() 338void SFCave :: handleGameSFCave()
301{ 339{
302 // Update score 340 // Update score
303 if ( nrFrames % 5 == 0 ) 341 if ( nrFrames % 5 == 0 )
304 score ++; 342 score ++;
305 343
306 if ( nrFrames % 500 == 0 ) 344 if ( nrFrames % 500 == 0 )
307 { 345 {
308 if ( maxHeight < sHeight - 100 ) 346 if ( maxHeight < sHeight - 100 )
309 { 347 {
310 maxHeight += 10; 348 maxHeight += 10;
@@ -502,54 +540,55 @@ void SFCave :: addBlock()
502 if ( blocks[i].y() == -1 ) 540 if ( blocks[i].y() == -1 )
503 { 541 {
504 int x = sWidth; 542 int x = sWidth;
505 543
506 int y = mapTop[50] + (int)(nextInt(mapBottom[50] - mapTop[50] - blockHeight)); 544 int y = mapTop[50] + (int)(nextInt(mapBottom[50] - mapTop[50] - blockHeight));
507 545
508 blocks[i].setRect( x, y, blockWidth, blockHeight ); 546 blocks[i].setRect( x, y, blockWidth, blockHeight );
509 547
510 break; 548 break;
511 } 549 }
512 } 550 }
513} 551}
514 552
515void SFCave :: addGate() 553void SFCave :: addGate()
516{ 554{
517 for ( int i = 0 ; i < BLOCKSIZE ; ++i ) 555 for ( int i = 0 ; i < BLOCKSIZE ; ++i )
518 { 556 {
519 if ( blocks[i].y() == -1 ) 557 if ( blocks[i].y() == -1 )
520 { 558 {
521 int x1 = sWidth; 559 int x1 = sWidth;
522 int y1 = mapTop[50]; 560 int y1 = mapTop[50];
523 int b1Height = nextInt(mapBottom[50] - mapTop[50] - gapHeight); 561 int b1Height = nextInt(mapBottom[50] - mapTop[50] - gapHeight);
524 562
525 // See if height between last gate and this one is too big 563 // See if height between last gate and this one is too big
526 if ( b1Height - 200 > lastGateBottomY ) 564 if ( b1Height - 100 > lastGateBottomY )
527 b1Height -= 25; 565 b1Height -= 25;
528 else if ( b1Height + 200 < lastGateBottomY ) 566 else if ( b1Height + 100 < lastGateBottomY )
529 b1Height += 25; 567 b1Height += 25;
530 lastGateBottomY = b1Height; 568 lastGateBottomY = b1Height;
531 569
570
532 int x2 = sWidth; 571 int x2 = sWidth;
533 int y2 = y1 + b1Height + gapHeight; 572 int y2 = y1 + b1Height + gapHeight;
534 int b2Height = mapBottom[50] - y2; 573 int b2Height = mapBottom[50] - y2;
535 574
536 575
537 blocks[i].setRect( x1, y1, blockWidth, b1Height ); 576 blocks[i].setRect( x1, y1, blockWidth, b1Height );
538 blocks[i+1].setRect( x2, y2, blockWidth, b2Height ); 577 blocks[i+1].setRect( x2, y2, blockWidth, b2Height );
539 578
540 break; 579 break;
541 } 580 }
542 } 581 }
543} 582}
544 583
545void SFCave :: setPoint( int point ) 584void SFCave :: setPoint( int point )
546{ 585{
547 if ( nextInt(100) >= 80 ) 586 if ( nextInt(100) >= 80 )
548 dir *= -1; 587 dir *= -1;
549 588
550 mapTop[point] = mapTop[point-1] + (dir * nextInt( 5 ) ); 589 mapTop[point] = mapTop[point-1] + (dir * nextInt( 5 ) );
551 if ( mapTop[point] < 0 ) 590 if ( mapTop[point] < 0 )
552 { 591 {
553 mapTop[point] = 0; 592 mapTop[point] = 0;
554 dir *= -1; 593 dir *= -1;
555 } 594 }
@@ -752,95 +791,103 @@ void SFCave :: keyPressEvent( QKeyEvent *e )
752 } 791 }
753 else if ( currentMenuOption[currentMenuNr] == MENU_GAME_DIFFICULTY ) 792 else if ( currentMenuOption[currentMenuNr] == MENU_GAME_DIFFICULTY )
754 { 793 {
755 currentGameDifficulty ++; 794 currentGameDifficulty ++;
756 if ( currentGameDifficulty == NR_GAME_DIFFICULTIES ) 795 if ( currentGameDifficulty == NR_GAME_DIFFICULTIES )
757 currentGameDifficulty = 0; 796 currentGameDifficulty = 0;
758 } 797 }
759 } 798 }
760 break; 799 break;
761 800
762 case Qt::Key_Space: 801 case Qt::Key_Space:
763 case Qt::Key_Return: 802 case Qt::Key_Return:
764 case Qt::Key_Enter: 803 case Qt::Key_Enter:
765 dealWithMenuSelection(); 804 dealWithMenuSelection();
766 break; 805 break;
767 } 806 }
768 } 807 }
769 else 808 else
770 { 809 {
771 switch( e->key() ) 810 switch( e->key() )
772 { 811 {
773 case Qt::Key_Up: 812 case Qt::Key_Up:
774 case Qt::Key_F9: 813 case Qt::Key_F9:
775 case Qt::Key_Space: 814 case Qt::Key_Space:
776 press = true; 815 if ( !press )
816 {
817 press = true;
818 replayList.append( new int( nrFrames ) );
819 }
777 break; 820 break;
778 case Qt::Key_M: 821 case Qt::Key_M:
779 case Qt::Key_Return: 822 case Qt::Key_Return:
780 case Qt::Key_Enter: 823 case Qt::Key_Enter:
781 if ( state == STATE_CRASHED ) 824 if ( state == STATE_CRASHED )
782 state = STATE_MENU; 825 state = STATE_MENU;
783 break; 826 break;
784 827
785 case Qt::Key_Z: 828 case Qt::Key_Z:
786 showScoreZones = !showScoreZones; 829 showScoreZones = !showScoreZones;
787 break; 830 break;
788 831
789 default: 832 default:
790 e->ignore(); 833 e->ignore();
791 break; 834 break;
792 } 835 }
793 } 836 }
794} 837}
795 838
796void SFCave :: keyReleaseEvent( QKeyEvent *e ) 839void SFCave :: keyReleaseEvent( QKeyEvent *e )
797{ 840{
798 if ( state == STATE_MENU ) 841 if ( state == STATE_MENU )
799 { 842 {
800 } 843 }
801 else 844 else
802 { 845 {
803 switch( e->key() ) 846 switch( e->key() )
804 { 847 {
805 case Qt::Key_F9: 848 case Qt::Key_F9:
806 case Qt::Key_Space: 849 case Qt::Key_Space:
807 press = false; 850 case Qt::Key_Up:
851 if ( press )
852 {
853 press = false;
854
855 replayList.append( new int( nrFrames ) );
856 }
808 break; 857 break;
809 858
810 case Qt::Key_Up:
811 press = false;
812
813 case Qt::Key_R: 859 case Qt::Key_R:
814 case Qt::Key_Down:
815 if ( state == STATE_CRASHED ) 860 if ( state == STATE_CRASHED )
816 { 861 {
817 state = STATE_NEWGAME; 862 state = STATE_REPLAY;
818 } 863 }
819 else
820 movel = true;
821 break; 864 break;
822 865
866 case Qt::Key_Down:
867 if ( state == STATE_CRASHED )
868 state = STATE_NEWGAME;
869 break;
823 default: 870 default:
824 e->ignore(); 871 e->ignore();
825 break; 872 break;
826 } 873 }
827 } 874 }
828 875
829} 876}
830 877
831void SFCave :: displayMenu() 878void SFCave :: displayMenu()
832{ 879{
833 offscreen->fill( Qt::black ); 880 offscreen->fill( Qt::black );
834 881
835 QPainter p( offscreen ); 882 QPainter p( offscreen );
836 p.setPen( Qt::white ); 883 p.setPen( Qt::white );
837 884
838 QFont f( "Helvetica", 16 ); 885 QFont f( "Helvetica", 16 );
839 p.setFont( f ); 886 p.setFont( f );
840 887
841 QFontMetrics fm = p.fontMetrics(); 888 QFontMetrics fm = p.fontMetrics();
842 889
843 QString text = "SFCave"; 890 QString text = "SFCave";
844 p.drawText( (sWidth/2) - (fm.width( text )/2), 60, text ); 891 p.drawText( (sWidth/2) - (fm.width( text )/2), 60, text );
845 892
846 text = "Written by Andy Qua"; 893 text = "Written by Andy Qua";
diff --git a/noncore/games/sfcave/sfcave.h b/noncore/games/sfcave/sfcave.h
index 69a0e13..0d9a626 100644
--- a/noncore/games/sfcave/sfcave.h
+++ b/noncore/games/sfcave/sfcave.h
@@ -1,46 +1,55 @@
1#include <qmainwindow.h> 1#include <qmainwindow.h>
2#include <qpainter.h> 2#include <qpainter.h>
3#include <qpixmap.h> 3#include <qpixmap.h>
4#include <qpoint.h> 4#include <qpoint.h>
5#include <qrect.h> 5#include <qrect.h>
6#include <qtimer.h> 6#include <qtimer.h>
7#include <qlist.h>
7 8
8 9#include "random.h"
9 10
10#define MAPSIZE 52 11#define MAPSIZE 52
11#define BLOCKSIZE 6 12#define BLOCKSIZE 6
12#define TRAILSIZE 30 13#define TRAILSIZE 30
13 14
15
16
14class SFCave : public QMainWindow 17class SFCave : public QMainWindow
15{ 18{
16Q_OBJECT 19Q_OBJECT
17 20
18public: 21public:
19 int sWidth; 22 int sWidth;
20 int sHeight; 23 int sHeight;
21 int segSize; 24 int segSize;
22 25
26 int currentSeed;
27
28 QList<int> replayList;
29 QListIterator<int> *replayIt;
30 bool replay;
31
23 int blockWidth; 32 int blockWidth;
24 int blockHeight; 33 int blockHeight;
25 int gapHeight; 34 int gapHeight;
26 int state; 35 int state;
27 int prevState; 36 int prevState;
28 int speed; 37 int speed;
29 int crashLineLength; 38 int crashLineLength;
30 39
31 static double UpThrustVals[3][3]; 40 static double UpThrustVals[3][3];
32 static double DownThrustVals[3][3]; 41 static double DownThrustVals[3][3];
33 static double MaxUpThrustVals[3][3]; 42 static double MaxUpThrustVals[3][3];
34 static double MaxDownThrustVals[3][3]; 43 static double MaxDownThrustVals[3][3];
35 static int initialGateGaps[]; 44 static int initialGateGaps[];
36 45
37 double thrustUp; 46 double thrustUp;
38 double noThrust; 47 double noThrust;
39 double maxUpThrust; 48 double maxUpThrust;
40 double maxDownThrust; 49 double maxDownThrust;
41 50
42 int gateDistance; 51 int gateDistance;
43 int nextGate; 52 int nextGate;
44 int lastGateBottomY; 53 int lastGateBottomY;
45 54
46 static QString menuOptions[2][5]; 55 static QString menuOptions[2][5];
@@ -58,48 +67,49 @@ public:
58 67
59 int score; 68 int score;
60 int highestScore[3][3]; 69 int highestScore[3][3];
61 70
62 int mapTop[MAPSIZE]; 71 int mapTop[MAPSIZE];
63 int mapBottom[MAPSIZE]; 72 int mapBottom[MAPSIZE];
64 QRect blocks[BLOCKSIZE]; 73 QRect blocks[BLOCKSIZE];
65 QRect user; 74 QRect user;
66 QPoint trail[TRAILSIZE]; 75 QPoint trail[TRAILSIZE];
67 76
68 int offset; 77 int offset;
69 int maxHeight; 78 int maxHeight;
70 int nrFrames; 79 int nrFrames;
71 int dir; 80 int dir;
72 81
73 bool showScoreZones; 82 bool showScoreZones;
74 83
75 bool press; 84 bool press;
76 double thrust; 85 double thrust;
77 bool running; 86 bool running;
78 87
79 SFCave( int speed = 3, QWidget *p = 0, char *name = 0 ); 88 SFCave( int speed = 3, QWidget *p = 0, char *name = 0 );
80 ~SFCave(); 89 ~SFCave();
81 void start(); 90 void start();
91 void setSeed( int seed );
82 int nextInt( int range ); 92 int nextInt( int range );
83 void setUp(); 93 void setUp();
84 void handleGameSFCave(); 94 void handleGameSFCave();
85 void handleGameGates(); 95 void handleGameGates();
86 void handleGameFly(); 96 void handleGameFly();
87 bool checkFlyGameCollision(); 97 bool checkFlyGameCollision();
88 void moveFlyGameLandscape(); 98 void moveFlyGameLandscape();
89 void setFlyPoint( int point ); 99 void setFlyPoint( int point );
90 bool checkCollision(); 100 bool checkCollision();
91 void moveLandscape(); 101 void moveLandscape();
92 void addBlock(); 102 void addBlock();
93 void addGate(); 103 void addGate();
94 void setPoint( int point ); 104 void setPoint( int point );
95 void drawBoss(); 105 void drawBoss();
96 void draw(); 106 void draw();
97 void handleKeys(); 107 void handleKeys();
98 108
99 void displayMenu(); 109 void displayMenu();
100 void dealWithMenuSelection(); 110 void dealWithMenuSelection();
101 111
102 void keyPressEvent( QKeyEvent *e ); 112 void keyPressEvent( QKeyEvent *e );
103 void keyReleaseEvent( QKeyEvent *e ); 113 void keyReleaseEvent( QKeyEvent *e );
104 void saveScore(); 114 void saveScore();
105 115
diff --git a/noncore/games/sfcave/sfcave.pro b/noncore/games/sfcave/sfcave.pro
index f4b9e5d..5f49330 100644
--- a/noncore/games/sfcave/sfcave.pro
+++ b/noncore/games/sfcave/sfcave.pro
@@ -1,9 +1,9 @@
1 TEMPLATE= app 1 TEMPLATE= app
2 CONFIG += qt warn_on release 2 CONFIG += qt warn_on release
3 DESTDIR = $(OPIEDIR)/bin 3 DESTDIR = $(OPIEDIR)/bin
4 SOURCES = sfcave.cpp helpwindow.cpp 4 SOURCES = sfcave.cpp helpwindow.cpp random.cpp
5 HEADERS = sfcave.h helpwindow.h 5 HEADERS = sfcave.h helpwindow.h random.h
6 TARGET = sfcave 6 TARGET = sfcave
7 INCLUDEPATH += $(OPIEDIR)/include 7 INCLUDEPATH += $(OPIEDIR)/include
8 DEPENDPATH+= $(OPIEDIR)/include 8 DEPENDPATH+= $(OPIEDIR)/include
9LIBS += -lqpe 9LIBS += -lqpe