summaryrefslogtreecommitdiff
path: root/apps/plugins/chopper.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/chopper.c')
-rw-r--r--apps/plugins/chopper.c308
1 files changed, 158 insertions, 150 deletions
diff --git a/apps/plugins/chopper.c b/apps/plugins/chopper.c
index 5c52c91466..90e217b923 100644
--- a/apps/plugins/chopper.c
+++ b/apps/plugins/chopper.c
@@ -6,10 +6,10 @@
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id: $ 8 * $Id: $
9 * 9 *
10 * Originally by Joshua Oreman, improved by Prashant Varanasi 10 * Originally by Joshua Oreman, improved by Prashant Varanasi
11 * Ported to Rockbox by Ben Basha (Paprica) 11 * Ported to Rockbox by Ben Basha (Paprica)
12 * 12 *
13 * All files in this archive are subject to the GNU General Public License. 13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement. 14 * See the file COPYING in the source tree root for full license agreement.
15 * 15 *
@@ -43,31 +43,38 @@ PLUGIN_HEADER
43 43
44#define QUIT BUTTON_MENU 44#define QUIT BUTTON_MENU
45#define ACTION BUTTON_SELECT 45#define ACTION BUTTON_SELECT
46#define ACTIONTEXT "SELECT"
46 47
47#elif CONFIG_KEYPAD == IAUDIO_X5_PAD /* grayscale at the moment */ 48#elif CONFIG_KEYPAD == IAUDIO_X5_PAD /* grayscale at the moment */
48 49
49#define QUIT BUTTON_POWER 50#define QUIT BUTTON_POWER
50#define ACTION BUTTON_SELECT 51#define ACTION BUTTON_SELECT
52#define ACTIONTEXT "SELECT"
51 53
52#elif CONFIG_KEYPAD == IRIVER_H10_PAD 54#elif CONFIG_KEYPAD == IRIVER_H10_PAD
53#define QUIT BUTTON_POWER 55#define QUIT BUTTON_POWER
54#define ACTION BUTTON_RIGHT 56#define ACTION BUTTON_RIGHT
57#define ACTIONTEXT "RIGHT"
55 58
56#elif CONFIG_KEYPAD == SANSA_E200_PAD 59#elif CONFIG_KEYPAD == SANSA_E200_PAD
57#define QUIT BUTTON_POWER 60#define QUIT BUTTON_POWER
58#define ACTION BUTTON_SELECT 61#define ACTION BUTTON_SELECT
62#define ACTIONTEXT "SELECT"
59 63
60#elif CONFIG_KEYPAD == GIGABEAT_PAD 64#elif CONFIG_KEYPAD == GIGABEAT_PAD
61#define QUIT BUTTON_MENU 65#define QUIT BUTTON_MENU
62#define ACTION BUTTON_SELECT 66#define ACTION BUTTON_SELECT
67#define ACTIONTEXT "SELECT"
63 68
64#elif CONFIG_KEYPAD == RECORDER_PAD 69#elif CONFIG_KEYPAD == RECORDER_PAD
65#define QUIT BUTTON_OFF 70#define QUIT BUTTON_OFF
66#define ACTION BUTTON_PLAY 71#define ACTION BUTTON_PLAY
72#define ACTIONTEXT "PLAY"
67 73
68#elif CONFIG_KEYPAD == ONDIO_PAD 74#elif CONFIG_KEYPAD == ONDIO_PAD
69#define QUIT BUTTON_MENU 75#define QUIT BUTTON_MENU
70#define ACTION BUTTON_RIGHT 76#define ACTION BUTTON_RIGHT
77#define ACTIONTEXT "RIGHT"
71 78
72#else 79#else
73#error Unsupported keypad 80#error Unsupported keypad
@@ -113,10 +120,10 @@ struct CBlock
113{ 120{
114 int iWorldX; 121 int iWorldX;
115 int iWorldY; 122 int iWorldY;
116 123
117 int iSizeX; 124 int iSizeX;
118 int iSizeY; 125 int iSizeY;
119 126
120 int bIsActive; 127 int bIsActive;
121}; 128};
122 129
@@ -124,10 +131,10 @@ struct CParticle
124{ 131{
125 int iWorldX; 132 int iWorldX;
126 int iWorldY; 133 int iWorldY;
127 134
128 int iSpeedX; 135 int iSpeedX;
129 int iSpeedY; 136 int iSpeedY;
130 137
131 int bIsActive; 138 int bIsActive;
132}; 139};
133 140
@@ -157,7 +164,6 @@ static void chopRenderTerrain(struct CTerrain *ter);
157void chopper_load(bool newgame); 164void chopper_load(bool newgame);
158void cleanup_chopper(void); 165void cleanup_chopper(void);
159 166
160
161static void chopDrawPlayer(int x,int y) /* These are SCREEN coords, not world! */ 167static void chopDrawPlayer(int x,int y) /* These are SCREEN coords, not world! */
162{ 168{
163 169
@@ -168,7 +174,7 @@ static void chopDrawPlayer(int x,int y) /* These are SCREEN coords, not world! *
168#endif 174#endif
169 rb->lcd_fillrect(x+6, y+2, 12, 9); 175 rb->lcd_fillrect(x+6, y+2, 12, 9);
170 rb->lcd_fillrect(x-3, y+6, 20, 3); 176 rb->lcd_fillrect(x-3, y+6, 20, 3);
171 177
172#if LCD_DEPTH > 2 178#if LCD_DEPTH > 2
173 rb->lcd_set_foreground(LCD_RGBPACK(50,50,50)); 179 rb->lcd_set_foreground(LCD_RGBPACK(50,50,50));
174#elif LCD_DEPTH == 2 180#elif LCD_DEPTH == 2
@@ -176,24 +182,22 @@ static void chopDrawPlayer(int x,int y) /* These are SCREEN coords, not world! *
176#endif 182#endif
177 rb->lcd_fillrect(x+10, y, 2, 3); 183 rb->lcd_fillrect(x+10, y, 2, 3);
178 rb->lcd_fillrect(x+10, y, 1, 3); 184 rb->lcd_fillrect(x+10, y, 1, 3);
179 185
180#if LCD_DEPTH > 2 186#if LCD_DEPTH > 2
181 rb->lcd_set_foreground(LCD_RGBPACK(30,30,30)); 187 rb->lcd_set_foreground(LCD_RGBPACK(40,40,100));
182#elif LCD_DEPTH == 2 188#elif LCD_DEPTH == 2
183 rb->lcd_set_foreground(LCD_BLACK); 189 rb->lcd_set_foreground(LCD_BLACK);
184#endif 190#endif
185 rb->lcd_drawline(x, y+iRotorOffset, x+20, y-iRotorOffset); 191 rb->lcd_drawline(x, y+iRotorOffset, x+20, y-iRotorOffset);
186 192
187#if LCD_DEPTH > 2 193#if LCD_DEPTH > 2
188 rb->lcd_set_foreground(LCD_RGBPACK(10,10,10)); 194 rb->lcd_set_foreground(LCD_RGBPACK(20,20,50));
189#elif LCD_DEPTH == 2 195#elif LCD_DEPTH == 2
190 rb->lcd_set_foreground(LCD_BLACK); 196 rb->lcd_set_foreground(LCD_BLACK);
191#endif 197#endif
192 rb->lcd_fillrect(x - 2, y + 5, 2, 5); 198 rb->lcd_fillrect(x - 2, y + 5, 2, 5);
193
194}
195
196 199
200}
197 201
198static void chopClearTerrain(struct CTerrain *ter) 202static void chopClearTerrain(struct CTerrain *ter)
199{ 203{
@@ -206,61 +210,58 @@ int iR(int low,int high)
206 return low+rb->rand()%(high-low+1); 210 return low+rb->rand()%(high-low+1);
207} 211}
208 212
209
210static void chopCopyTerrain(struct CTerrain *src, struct CTerrain *dest, 213static void chopCopyTerrain(struct CTerrain *src, struct CTerrain *dest,
211 int xOffset,int yOffset) 214 int xOffset,int yOffset)
212{ 215{
213 int i=0; 216 int i=0;
214 217
215 while(i < src->iNodesCount) 218 while(i < src->iNodesCount)
216 { 219 {
217 dest->mNodes[i].x = src->mNodes[i].x + xOffset; 220 dest->mNodes[i].x = src->mNodes[i].x + xOffset;
218 dest->mNodes[i].y = src->mNodes[i].y + yOffset; 221 dest->mNodes[i].y = src->mNodes[i].y + yOffset;
219 222
220 i++; 223 i++;
221 } 224 }
222 225
223 dest->iNodesCount = src->iNodesCount; 226 dest->iNodesCount = src->iNodesCount;
224 dest->iLastNodePlacedPosX = src->iLastNodePlacedPosX; 227 dest->iLastNodePlacedPosX = src->iLastNodePlacedPosX;
225 228
226} 229}
227
228 230
229static void chopAddTerrainNode(struct CTerrain *ter, int x, int y) 231static void chopAddTerrainNode(struct CTerrain *ter, int x, int y)
230{ 232{
231 int i=0; 233 int i=0;
232 234
233 if(ter->iNodesCount + 1 >= MAX_TERRAIN_NODES) 235 if(ter->iNodesCount + 1 >= MAX_TERRAIN_NODES)
234 { 236 {
235 /* DEBUGF("ERROR: Not enough nodes!\n"); */ 237 /* DEBUGF("ERROR: Not enough nodes!\n"); */
236 return; 238 return;
237 } 239 }
238 240
239 ter->iNodesCount++; 241 ter->iNodesCount++;
240 242
241 i = ter->iNodesCount - 1; 243 i = ter->iNodesCount - 1;
242 244
243 ter->mNodes[i].x = x; 245 ter->mNodes[i].x = x;
244 ter->mNodes[i].y= y; 246 ter->mNodes[i].y= y;
245 247
246 ter->iLastNodePlacedPosX = x; 248 ter->iLastNodePlacedPosX = x;
247
248}
249 249
250}
250 251
251static void chopTerrainNodeDeleteAndShift(struct CTerrain *ter,int nodeIndex) 252static void chopTerrainNodeDeleteAndShift(struct CTerrain *ter,int nodeIndex)
252{ 253{
253 int i=nodeIndex; 254 int i=nodeIndex;
254 255
255 while( i < ter->iNodesCount ) 256 while( i < ter->iNodesCount )
256 { 257 {
257 ter->mNodes[i - 1] = ter->mNodes[i]; 258 ter->mNodes[i - 1] = ter->mNodes[i];
258 i++; 259 i++;
259 } 260 }
260 261
261 ter->iNodesCount--; 262 ter->iNodesCount--;
262 263
263 264
264} 265}
265 266
266int chopUpdateTerrainRecycling(struct CTerrain *ter) 267int chopUpdateTerrainRecycling(struct CTerrain *ter)
@@ -270,28 +271,28 @@ int chopUpdateTerrainRecycling(struct CTerrain *ter)
270 int iNewNodePos,g,v; 271 int iNewNodePos,g,v;
271 while(i < ter->iNodesCount) 272 while(i < ter->iNodesCount)
272 { 273 {
273 274
274 if( iCameraPosX > ter->mNodes[i].x) 275 if( iCameraPosX > ter->mNodes[i].x)
275 { 276 {
276 277
277 chopTerrainNodeDeleteAndShift(ter,i); 278 chopTerrainNodeDeleteAndShift(ter,i);
278 279
279 iNewNodePos = ter->iLastNodePlacedPosX + 50; 280 iNewNodePos = ter->iLastNodePlacedPosX + 50;
280 g = iScreenY - 10; 281 g = iScreenY - 10;
281 282
282 v = 3*iPlayerSpeedX; 283 v = 3*iPlayerSpeedX;
283 if(v>50) 284 if(v>50)
284 v=50; 285 v=50;
285 if(iLevelMode == LEVEL_MODE_STEEP) 286 if(iLevelMode == LEVEL_MODE_STEEP)
286 v*=5; 287 v*=5;
287 288
288 chopAddTerrainNode(ter,iNewNodePos,g - iR(-v,v)); 289 chopAddTerrainNode(ter,iNewNodePos,g - iR(-v,v));
289 ret=1; 290 ret=1;
290 291
291 } 292 }
292 293
293 i++; 294 i++;
294 295
295 } 296 }
296 297
297 return 1; 298 return 1;
@@ -299,10 +300,10 @@ int chopUpdateTerrainRecycling(struct CTerrain *ter)
299 300
300int chopTerrainHeightAtPoint(struct CTerrain *ter, int pX) 301int chopTerrainHeightAtPoint(struct CTerrain *ter, int pX)
301{ 302{
302 303
303 int iNodeIndexOne=0,iNodeIndexTwo=0, h, terY1, terY2, terX1, terX2, a, b; 304 int iNodeIndexOne=0,iNodeIndexTwo=0, h, terY1, terY2, terX1, terX2, a, b;
304 float c,d; 305 float c,d;
305 306
306 int i=0; 307 int i=0;
307 for(i=1;i<MAX_TERRAIN_NODES;i++) 308 for(i=1;i<MAX_TERRAIN_NODES;i++)
308 { 309 {
@@ -311,18 +312,18 @@ int chopTerrainHeightAtPoint(struct CTerrain *ter, int pX)
311 iNodeIndexOne = i - 1; 312 iNodeIndexOne = i - 1;
312 break; 313 break;
313 } 314 }
314 315
315 } 316 }
316 317
317 iNodeIndexTwo = iNodeIndexOne + 1; 318 iNodeIndexTwo = iNodeIndexOne + 1;
318 terY1 = ter->mNodes[iNodeIndexOne].y; 319 terY1 = ter->mNodes[iNodeIndexOne].y;
319 terY2 = ter->mNodes[iNodeIndexTwo].y; 320 terY2 = ter->mNodes[iNodeIndexTwo].y;
320 321
321 terX1 = 0; 322 terX1 = 0;
322 terX2 = ter->mNodes[iNodeIndexTwo].x - ter->mNodes[iNodeIndexOne].x; 323 terX2 = ter->mNodes[iNodeIndexTwo].x - ter->mNodes[iNodeIndexOne].x;
323 324
324 pX-= ter->mNodes[iNodeIndexOne].x; 325 pX-= ter->mNodes[iNodeIndexOne].x;
325 326
326 a = terY2 - terY1; 327 a = terY2 - terY1;
327 b = terX2; 328 b = terX2;
328 c = pX; 329 c = pX;
@@ -334,26 +335,24 @@ int chopTerrainHeightAtPoint(struct CTerrain *ter, int pX)
334 335
335} 336}
336 337
337
338int chopPointInTerrain(struct CTerrain *ter, int pX, int pY, int iTestType) 338int chopPointInTerrain(struct CTerrain *ter, int pX, int pY, int iTestType)
339{ 339{
340 int h = chopTerrainHeightAtPoint(ter, pX); 340 int h = chopTerrainHeightAtPoint(ter, pX);
341 341
342 if(iTestType == 0) 342 if(iTestType == 0)
343 return (pY > h); 343 return (pY > h);
344 else 344 else
345 return (pY < h); 345 return (pY < h);
346} 346}
347 347
348
349static void chopAddBlock(int x,int y,int sx,int sy, int indexOverride) 348static void chopAddBlock(int x,int y,int sx,int sy, int indexOverride)
350{ 349{
351 int i=0; 350 int i=0;
352 351
353 if(indexOverride < 0) 352 if(indexOverride < 0)
354 { 353 {
355 while(mBlocks[i].bIsActive && i < NUMBER_OF_BLOCKS) 354 while(mBlocks[i].bIsActive && i < NUMBER_OF_BLOCKS)
356 i++; 355 i++;
357 if(i==NUMBER_OF_BLOCKS) 356 if(i==NUMBER_OF_BLOCKS)
358 { 357 {
359 DEBUGF("No blocks!\n"); 358 DEBUGF("No blocks!\n");
@@ -362,20 +361,20 @@ static void chopAddBlock(int x,int y,int sx,int sy, int indexOverride)
362 } 361 }
363 else 362 else
364 i = indexOverride; 363 i = indexOverride;
365 364
366 mBlocks[i].bIsActive = 1; 365 mBlocks[i].bIsActive = 1;
367 mBlocks[i].iWorldX = x; 366 mBlocks[i].iWorldX = x;
368 mBlocks[i].iWorldY = y; 367 mBlocks[i].iWorldY = y;
369 mBlocks[i].iSizeX = sx; 368 mBlocks[i].iSizeX = sx;
370 mBlocks[i].iSizeY = sy; 369 mBlocks[i].iSizeY = sy;
371 370
372 iLastBlockPlacedPosX = x; 371 iLastBlockPlacedPosX = x;
373} 372}
374 373
375static void chopAddParticle(int x,int y,int sx,int sy) 374static void chopAddParticle(int x,int y,int sx,int sy)
376{ 375{
377 int i=0; 376 int i=0;
378 377
379 while(mParticles[i].bIsActive && i < NUMBER_OF_PARTICLES) 378 while(mParticles[i].bIsActive && i < NUMBER_OF_PARTICLES)
380 i++; 379 i++;
381 380
@@ -387,7 +386,7 @@ static void chopAddParticle(int x,int y,int sx,int sy)
387 mParticles[i].iWorldY = y; 386 mParticles[i].iWorldY = y;
388 mParticles[i].iSpeedX = sx; 387 mParticles[i].iSpeedX = sx;
389 mParticles[i].iSpeedY = sy; 388 mParticles[i].iSpeedY = sy;
390 389
391} 390}
392 391
393static void chopGenerateBlockIfNeeded(void) 392static void chopGenerateBlockIfNeeded(void)
@@ -395,24 +394,24 @@ static void chopGenerateBlockIfNeeded(void)
395 int i=0; 394 int i=0;
396 int DistSpeedX = iPlayerSpeedX * 5; 395 int DistSpeedX = iPlayerSpeedX * 5;
397 if(DistSpeedX<200) DistSpeedX = 200; 396 if(DistSpeedX<200) DistSpeedX = 200;
398 397
399 while(i < NUMBER_OF_BLOCKS) 398 while(i < NUMBER_OF_BLOCKS)
400 { 399 {
401 if(!mBlocks[i].bIsActive) 400 if(!mBlocks[i].bIsActive)
402 { 401 {
403 int iX,iY,sX,sY; 402 int iX,iY,sX,sY;
404 403
405 iX = iLastBlockPlacedPosX + (350-DistSpeedX); 404 iX = iLastBlockPlacedPosX + (350-DistSpeedX);
406 sX = blockw; 405 sX = blockw;
407 406
408 iY = iR(0,iScreenY); 407 iY = iR(0,iScreenY);
409 sY = blockh + iR(1,blockh/3); 408 sY = blockh + iR(1,blockh/3);
410 409
411 chopAddBlock(iX,iY,sX,sY,i); 410 chopAddBlock(iX,iY,sX,sY,i);
412 } 411 }
413 412
414 i++; 413 i++;
415 } 414 }
416 415
417} 416}
418 417
@@ -420,13 +419,13 @@ static int chopBlockCollideWithPlayer(struct CBlock *mBlock)
420{ 419{
421 int px = iPlayerPosX; 420 int px = iPlayerPosX;
422 int py = iPlayerPosY; 421 int py = iPlayerPosY;
423 422
424 int x = mBlock->iWorldX-17; 423 int x = mBlock->iWorldX-17;
425 int y = mBlock->iWorldY-11; 424 int y = mBlock->iWorldY-11;
426 425
427 int x2 = x + mBlock->iSizeX+17; 426 int x2 = x + mBlock->iSizeX+17;
428 int y2 = y + mBlock->iSizeY+11; 427 int y2 = y + mBlock->iSizeY+11;
429 428
430 if(px>x && px<x2) 429 if(px>x && px<x2)
431 { 430 {
432 if(py>y && py<y2) 431 if(py>y && py<y2)
@@ -434,8 +433,8 @@ static int chopBlockCollideWithPlayer(struct CBlock *mBlock)
434 return 1; 433 return 1;
435 } 434 }
436 } 435 }
437 436
438 return 0; 437 return 0;
439} 438}
440 439
441static int chopBlockOffscreen(struct CBlock *mBlock) 440static int chopBlockOffscreen(struct CBlock *mBlock)
@@ -448,8 +447,8 @@ static int chopBlockOffscreen(struct CBlock *mBlock)
448 447
449static int chopParticleOffscreen(struct CParticle *mParticle) 448static int chopParticleOffscreen(struct CParticle *mParticle)
450{ 449{
451 if (mParticle->iWorldX < iCameraPosX || mParticle->iWorldY < 0 || 450 if (mParticle->iWorldX < iCameraPosX || mParticle->iWorldY < 0 ||
452 mParticle->iWorldY > iScreenY || mParticle->iWorldX > iCameraPosX + 451 mParticle->iWorldY > iScreenY || mParticle->iWorldX > iCameraPosX +
453 iScreenX) 452 iScreenX)
454 { 453 {
455 return 1; 454 return 1;
@@ -464,7 +463,7 @@ static void checkHighScore(void)
464 char scoretext[30]; 463 char scoretext[30];
465 int w; 464 int w;
466 highscore = score; 465 highscore = score;
467 rb->snprintf(scoretext, sizeof(scoretext), "New High Score: %d", 466 rb->snprintf(scoretext, sizeof(scoretext), "New High Score: %d",
468 highscore); 467 highscore);
469 rb->lcd_getstringsize(scoretext, &w, NULL); 468 rb->lcd_getstringsize(scoretext, &w, NULL);
470 rb->lcd_putsxy(LCD_WIDTH/2 - w/2 ,LCD_HEIGHT/2 + 20, scoretext); 469 rb->lcd_putsxy(LCD_WIDTH/2 - w/2 ,LCD_HEIGHT/2 + 20, scoretext);
@@ -476,30 +475,30 @@ static void chopKillPlayer(void)
476 int w, i, button; 475 int w, i, button;
477 for (i = 0; i < NUMBER_OF_PARTICLES; i++) { 476 for (i = 0; i < NUMBER_OF_PARTICLES; i++) {
478 mParticles[i].bIsActive = 0; 477 mParticles[i].bIsActive = 0;
479 chopAddParticle(iPlayerPosX + iR(0,20), iPlayerPosY + iR(0,20), 478 chopAddParticle(iPlayerPosX + iR(0,20), iPlayerPosY + iR(0,20),
480 iR(-2,2), iR(-2,2)); 479 iR(-2,2), iR(-2,2));
481 } 480 }
482 481
483 iPlayerAlive--; 482 iPlayerAlive--;
484 483
485 if (iPlayerAlive == 0) { 484 if (iPlayerAlive == 0) {
486 rb->lcd_set_drawmode(DRMODE_FG); 485 rb->lcd_set_drawmode(DRMODE_FG);
487#if LCD_DEPTH >= 2 486#if LCD_DEPTH >= 2
488 rb->lcd_set_foreground(LCD_BLACK); 487 rb->lcd_set_foreground(LCD_WHITE);
489#endif 488#endif
490 checkHighScore(); 489 checkHighScore();
491 490
492 rb->lcd_getstringsize("Game Over", &w, NULL); 491 rb->lcd_getstringsize("Game Over", &w, NULL);
493 rb->lcd_putsxy(LCD_WIDTH/2 - w/2 ,LCD_HEIGHT/2 - 20, "Game Over"); 492 rb->lcd_putsxy(LCD_WIDTH/2 - w/2 ,LCD_HEIGHT/2 - 20, "Game Over");
494 rb->lcd_getstringsize("Press action to continue", &w, NULL); 493 rb->lcd_getstringsize("Press " ACTIONTEXT " to continue", &w, NULL);
495 rb->lcd_putsxy(LCD_WIDTH/2 - w/2 ,LCD_HEIGHT/2, 494 rb->lcd_putsxy(LCD_WIDTH/2 - w/2 ,LCD_HEIGHT/2,
496 "Press action to continue"); 495 "Press " ACTIONTEXT " to continue");
497 rb->lcd_update(); 496 rb->lcd_update();
498 497
499 rb->lcd_set_drawmode(DRMODE_SOLID); 498 rb->lcd_set_drawmode(DRMODE_SOLID);
500 499
501 rb->sleep(HZ * 0.5); 500 rb->sleep(HZ * 0.5);
502 501
503 while (true) { 502 while (true) {
504 button = rb->button_get(true); 503 button = rb->button_get(true);
505 if (button == ACTION 504 if (button == ACTION
@@ -520,17 +519,16 @@ static void chopKillPlayer(void)
520 } 519 }
521 } 520 }
522 } 521 }
523 522
524 } else 523 } else
525 chopper_load(false); 524 chopper_load(false);
526 525
527} 526}
528 527
529
530static void chopDrawTheWorld(void) 528static void chopDrawTheWorld(void)
531{ 529{
532 int i=0; 530 int i=0;
533 531
534 while(i < NUMBER_OF_BLOCKS) 532 while(i < NUMBER_OF_BLOCKS)
535 { 533 {
536 if(mBlocks[i].bIsActive) 534 if(mBlocks[i].bIsActive)
@@ -540,12 +538,12 @@ static void chopDrawTheWorld(void)
540 else 538 else
541 chopDrawBlock(&mBlocks[i]); 539 chopDrawBlock(&mBlocks[i]);
542 } 540 }
543 541
544 i++; 542 i++;
545 } 543 }
546 544
547 i=0; 545 i=0;
548 546
549 while(i < NUMBER_OF_PARTICLES) 547 while(i < NUMBER_OF_PARTICLES)
550 { 548 {
551 if(mParticles[i].bIsActive) 549 if(mParticles[i].bIsActive)
@@ -555,27 +553,26 @@ static void chopDrawTheWorld(void)
555 else 553 else
556 chopDrawParticle(&mParticles[i]); 554 chopDrawParticle(&mParticles[i]);
557 } 555 }
558 556
559 i++; 557 i++;
560 } 558 }
561 559
562 chopRenderTerrain(&mGround); 560 chopRenderTerrain(&mGround);
563 chopRenderTerrain(&mRoof); 561 chopRenderTerrain(&mRoof);
564 562
565} 563}
566 564
567
568static void chopDrawParticle(struct CParticle *mParticle) 565static void chopDrawParticle(struct CParticle *mParticle)
569{ 566{
570 567
571 int iPosX = (mParticle->iWorldX - iCameraPosX); 568 int iPosX = (mParticle->iWorldX - iCameraPosX);
572 int iPosY = (mParticle->iWorldY); 569 int iPosY = (mParticle->iWorldY);
573#if LCD_DEPTH > 2 570#if LCD_DEPTH > 2
574 rb->lcd_set_foreground(LCD_RGBPACK(150,150,150)); 571 rb->lcd_set_foreground(LCD_RGBPACK(192,192,192));
575#elif LCD_DEPTH == 2 572#elif LCD_DEPTH == 2
576 rb->lcd_set_foreground(LCD_LIGHTGRAY); 573 rb->lcd_set_foreground(LCD_LIGHTGRAY);
577#endif 574#endif
578 rb->lcd_fillrect(iPosX, iPosY, 3, 3); 575 rb->lcd_fillrect(iPosX, iPosY, 3, 3);
579 576
580} 577}
581 578
@@ -584,7 +581,7 @@ static void chopDrawScene(void)
584 char s[30]; 581 char s[30];
585 int w; 582 int w;
586#if LCD_DEPTH > 2 583#if LCD_DEPTH > 2
587 rb->lcd_set_background(LCD_RGBPACK(145,197,255)); 584 rb->lcd_set_background(LCD_BLACK);
588#elif LCD_DEPTH == 2 585#elif LCD_DEPTH == 2
589 rb->lcd_set_background(LCD_WHITE); 586 rb->lcd_set_background(LCD_WHITE);
590#endif 587#endif
@@ -592,11 +589,11 @@ static void chopDrawScene(void)
592 589
593 chopDrawTheWorld(); 590 chopDrawTheWorld();
594 chopDrawPlayer(iPlayerPosX - iCameraPosX, iPlayerPosY); 591 chopDrawPlayer(iPlayerPosX - iCameraPosX, iPlayerPosY);
595 592
596 score = -20 + iPlayerPosX/3; 593 score = -20 + iPlayerPosX/3;
597 rb->lcd_set_drawmode(DRMODE_FG); 594 rb->lcd_set_drawmode(DRMODE_FG);
598#if LCD_DEPTH > 2 595#if LCD_DEPTH > 2
599 rb->lcd_set_foreground(LCD_RGBPACK(20,20,20)); 596 rb->lcd_set_foreground(LCD_BLACK);
600#elif LCD_DEPTH == 2 597#elif LCD_DEPTH == 2
601 rb->lcd_set_foreground(LCD_WHITE); 598 rb->lcd_set_foreground(LCD_WHITE);
602#endif 599#endif
@@ -606,7 +603,7 @@ static void chopDrawScene(void)
606 rb->lcd_getstringsize(s, &w, NULL); 603 rb->lcd_getstringsize(s, &w, NULL);
607 rb->lcd_putsxy(LCD_WIDTH - 2 - w, 2, s); 604 rb->lcd_putsxy(LCD_WIDTH - 2 - w, 2, s);
608 rb->lcd_set_drawmode(DRMODE_SOLID); 605 rb->lcd_set_drawmode(DRMODE_SOLID);
609 606
610 rb->lcd_update(); 607 rb->lcd_update();
611} 608}
612 609
@@ -616,23 +613,29 @@ static int chopMenu(int menunum)
616 int result; 613 int result;
617 int res = 0; 614 int res = 0;
618 bool menu_quit = false; 615 bool menu_quit = false;
619 616
620 static const struct menu_item items[] = { 617 static const struct menu_item items[] = {
621 { "Start New Game", NULL }, 618 { "Start New Game", NULL },
622 { "Resume Game", NULL }, 619 { "Resume Game", NULL },
623 { "Level", NULL }, 620 { "Level", NULL },
624 { "Help", NULL },
625 { "Quit", NULL }, 621 { "Quit", NULL },
626 }; 622 };
627 623
628 static const struct opt_items levels[2] = { 624 static const struct opt_items levels[2] = {
629 { "Normal", -1 }, 625 { "Normal", -1 },
630 { "Steep", -1 }, 626 { "Steep", -1 },
631 }; 627 };
632 628
629#if HAVE_LCD_COLOR
630 rb->lcd_set_foreground(LCD_WHITE);
631 rb->lcd_set_background(LCD_BLACK);
632#endif
633
634 rb->lcd_clear_display();
635
633 m = rb->menu_init(items, sizeof(items) / sizeof(*items), 636 m = rb->menu_init(items, sizeof(items) / sizeof(*items),
634 NULL, NULL, NULL, NULL); 637 NULL, NULL, NULL, NULL);
635 638
636 while (!menu_quit) { 639 while (!menu_quit) {
637 result=rb->menu_show(m); 640 result=rb->menu_show(m);
638 switch (result) 641 switch (result)
@@ -654,9 +657,6 @@ static int chopMenu(int menunum)
654 rb->set_option("Level", &iLevelMode, INT, levels, 2, NULL); 657 rb->set_option("Level", &iLevelMode, INT, levels, 2, NULL);
655 break; 658 break;
656 case 3: 659 case 3:
657 rb->splash(HZ, true, "NOT AVAILABLE");
658 break;
659 case 4:
660 menu_quit=true; 660 menu_quit=true;
661 res = PLUGIN_OK; 661 res = PLUGIN_OK;
662 break; 662 break;
@@ -676,27 +676,27 @@ static int chopGameLoop(void)
676 int move_button, ret; 676 int move_button, ret;
677 bool exit=false; 677 bool exit=false;
678 int end, i=0, bdelay=0, last_button=BUTTON_NONE; 678 int end, i=0, bdelay=0, last_button=BUTTON_NONE;
679 679
680 if (chopUpdateTerrainRecycling(&mGround) == 1) 680 if (chopUpdateTerrainRecycling(&mGround) == 1)
681 /* mirror the sky if we've changed the ground */ 681 /* mirror the sky if we've changed the ground */
682 chopCopyTerrain(&mGround, &mRoof, 0, -( iScreenY * 0.75)); 682 chopCopyTerrain(&mGround, &mRoof, 0, -( iScreenY * 0.75));
683 683
684 ret = chopMenu(0); 684 ret = chopMenu(0);
685 if (ret != -1) 685 if (ret != -1)
686 return PLUGIN_OK; 686 return PLUGIN_OK;
687 687
688 chopDrawScene(); 688 chopDrawScene();
689 689
690 while (!exit) { 690 while (!exit) {
691 691
692 end = *rb->current_tick + (CYCLETIME * HZ) / 1000; 692 end = *rb->current_tick + (CYCLETIME * HZ) / 1000;
693 693
694 if(chopUpdateTerrainRecycling(&mGround) == 1) 694 if(chopUpdateTerrainRecycling(&mGround) == 1)
695 /* mirror the sky if we've changed the ground */ 695 /* mirror the sky if we've changed the ground */
696 chopCopyTerrain(&mGround, &mRoof, 0, -( iScreenY * 0.75)); 696 chopCopyTerrain(&mGround, &mRoof, 0, -( iScreenY * 0.75));
697 697
698 iRotorOffset = iR(-1,1); 698 iRotorOffset = iR(-1,1);
699 699
700 /* We need to have this here so particles move when we're dead */ 700 /* We need to have this here so particles move when we're dead */
701 701
702 for (i=0; i < NUMBER_OF_PARTICLES; i++) 702 for (i=0; i < NUMBER_OF_PARTICLES; i++)
@@ -707,21 +707,21 @@ static int chopGameLoop(void)
707 } 707 }
708 708
709 /* Redraw the main window: */ 709 /* Redraw the main window: */
710 chopDrawScene(); 710 chopDrawScene();
711
711 712
712
713 iGravityTimerCountdown--; 713 iGravityTimerCountdown--;
714 714
715 if(iGravityTimerCountdown <= 0) 715 if(iGravityTimerCountdown <= 0)
716 { 716 {
717 iGravityTimerCountdown = 3; 717 iGravityTimerCountdown = 3;
718 chopAddParticle(iPlayerPosX, iPlayerPosY+5, 0, 0); 718 chopAddParticle(iPlayerPosX, iPlayerPosY+5, 0, 0);
719 } 719 }
720 720
721 if(iLevelMode == LEVEL_MODE_NORMAL) 721 if(iLevelMode == LEVEL_MODE_NORMAL)
722 chopGenerateBlockIfNeeded(); 722 chopGenerateBlockIfNeeded();
723 723
724 724
725 move_button=rb->button_status(); 725 move_button=rb->button_status();
726 if (rb->button_get(false) == QUIT) { 726 if (rb->button_get(false) == QUIT) {
727 ret = chopMenu(1); 727 ret = chopMenu(1);
@@ -756,13 +756,13 @@ static int chopGameLoop(void)
756 bdelay = 3; 756 bdelay = 3;
757 if (bdelay == 0) 757 if (bdelay == 0)
758 iPlayerSpeedY = 4; 758 iPlayerSpeedY = 4;
759 759
760 if (rb->default_event_handler(move_button) == SYS_USB_CONNECTED) 760 if (rb->default_event_handler(move_button) == SYS_USB_CONNECTED)
761 return PLUGIN_USB_CONNECTED; 761 return PLUGIN_USB_CONNECTED;
762 break; 762 break;
763 } 763 }
764 last_button = move_button; 764 last_button = move_button;
765 765
766 if (bdelay < 0) { 766 if (bdelay < 0) {
767 iPlayerSpeedY = bdelay; 767 iPlayerSpeedY = bdelay;
768 bdelay++; 768 bdelay++;
@@ -770,11 +770,11 @@ static int chopGameLoop(void)
770 iPlayerSpeedY = bdelay; 770 iPlayerSpeedY = bdelay;
771 bdelay--; 771 bdelay--;
772 } 772 }
773 773
774 iCameraPosX = iPlayerPosX - 25; 774 iCameraPosX = iPlayerPosX - 25;
775 iPlayerPosX += iPlayerSpeedX; 775 iPlayerPosX += iPlayerSpeedX;
776 iPlayerPosY += iPlayerSpeedY; 776 iPlayerPosY += iPlayerSpeedY;
777 777
778 chopCounter++; 778 chopCounter++;
779 /* increase speed as we go along */ 779 /* increase speed as we go along */
780 if (chopCounter == 100){ 780 if (chopCounter == 100){
@@ -782,8 +782,8 @@ static int chopGameLoop(void)
782 chopCounter=0; 782 chopCounter=0;
783 } 783 }
784 784
785 if (iPlayerPosY > iScreenY-10 || iPlayerPosY < -5 || 785 if (iPlayerPosY > iScreenY-10 || iPlayerPosY < -5 ||
786 chopPointInTerrain(&mGround, iPlayerPosX, iPlayerPosY + 10, 0) || 786 chopPointInTerrain(&mGround, iPlayerPosX, iPlayerPosY + 10, 0) ||
787 chopPointInTerrain(&mRoof, iPlayerPosX ,iPlayerPosY, 1)) 787 chopPointInTerrain(&mRoof, iPlayerPosX ,iPlayerPosY, 1))
788 { 788 {
789 chopKillPlayer(); 789 chopKillPlayer();
@@ -792,7 +792,7 @@ static int chopGameLoop(void)
792 if (ret != -1) 792 if (ret != -1)
793 return ret; 793 return ret;
794 } 794 }
795 795
796 for (i=0; i < NUMBER_OF_BLOCKS; i++) 796 for (i=0; i < NUMBER_OF_BLOCKS; i++)
797 if(mBlocks[i].bIsActive == 1) 797 if(mBlocks[i].bIsActive == 1)
798 if(chopBlockCollideWithPlayer(&mBlocks[i])) { 798 if(chopBlockCollideWithPlayer(&mBlocks[i])) {
@@ -807,22 +807,22 @@ static int chopGameLoop(void)
807 rb->sleep(end-*rb->current_tick); 807 rb->sleep(end-*rb->current_tick);
808 else 808 else
809 rb->yield(); 809 rb->yield();
810 810
811 } 811 }
812 return PLUGIN_OK; 812 return PLUGIN_OK;
813} 813}
814 814
815static void chopDrawBlock(struct CBlock *mBlock) 815static void chopDrawBlock(struct CBlock *mBlock)
816{ 816{
817 int iPosX = (mBlock->iWorldX - iCameraPosX); 817 int iPosX = (mBlock->iWorldX - iCameraPosX);
818 int iPosY = (mBlock->iWorldY); 818 int iPosY = (mBlock->iWorldY);
819#if LCD_DEPTH > 2 819#if LCD_DEPTH > 2
820 rb->lcd_set_foreground(LCD_RGBPACK(30,30,30)); 820 rb->lcd_set_foreground(LCD_RGBPACK(100,255,100));
821#elif LCD_DEPTH == 2 821#elif LCD_DEPTH == 2
822 rb->lcd_set_foreground(LCD_BLACK); 822 rb->lcd_set_foreground(LCD_BLACK);
823#endif 823#endif
824 rb->lcd_fillrect(iPosX, iPosY, mBlock->iSizeX, 824 rb->lcd_fillrect(iPosX, iPosY, mBlock->iSizeX,
825 mBlock->iSizeY); 825 mBlock->iSizeY);
826} 826}
827 827
828 828
@@ -834,21 +834,21 @@ static void chopRenderTerrain(struct CTerrain *ter)
834 int oldx=0; 834 int oldx=0;
835 835
836 int ay=0; 836 int ay=0;
837 if(ter->mNodes[0].y < LCD_HEIGHT/2) 837 if(ter->mNodes[0].y < LCD_HEIGHT/2)
838 ay=0; 838 ay=0;
839 else 839 else
840 ay=LCD_HEIGHT; 840 ay=LCD_HEIGHT;
841 841
842 while(i < ter->iNodesCount && oldx < LCD_WIDTH) 842 while(i < ter->iNodesCount && oldx < LCD_WIDTH)
843 { 843 {
844 844
845 int x = ter->mNodes[i-1].x - iCameraPosX; 845 int x = ter->mNodes[i-1].x - iCameraPosX;
846 int y = ter->mNodes[i-1].y; 846 int y = ter->mNodes[i-1].y;
847 847
848 int x2 = ter->mNodes[i].x - iCameraPosX; 848 int x2 = ter->mNodes[i].x - iCameraPosX;
849 int y2 = ter->mNodes[i].y; 849 int y2 = ter->mNodes[i].y;
850#if LCD_DEPTH > 2 850#if LCD_DEPTH > 2
851 rb->lcd_set_foreground(LCD_RGBPACK(50,100,250)); 851 rb->lcd_set_foreground(LCD_RGBPACK(100,255,100));
852#elif LCD_DEPTH == 2 852#elif LCD_DEPTH == 2
853 rb->lcd_set_foreground(LCD_DARKGRAY); 853 rb->lcd_set_foreground(LCD_DARKGRAY);
854#endif 854#endif
@@ -860,20 +860,20 @@ static void chopRenderTerrain(struct CTerrain *ter)
860 xlcd_filltriangle(x, ay, x, y, x2, y2 / 2); 860 xlcd_filltriangle(x, ay, x, y, x2, y2 / 2);
861 else 861 else
862 xlcd_filltriangle(x, ay, x, y, x2, LCD_HEIGHT - (LCD_HEIGHT - y2) / 2); 862 xlcd_filltriangle(x, ay, x, y, x2, LCD_HEIGHT - (LCD_HEIGHT - y2) / 2);
863 863
864 oldx = x; 864 oldx = x;
865 i++; 865 i++;
866 866
867 } 867 }
868 868
869} 869}
870 870
871void chopper_load(bool newgame) 871void chopper_load(bool newgame)
872{ 872{
873 873
874 int i; 874 int i;
875 int g; 875 int g;
876 876
877 if (newgame) { 877 if (newgame) {
878 iScreenX = LCD_WIDTH; 878 iScreenX = LCD_WIDTH;
879 iScreenY = LCD_HEIGHT; 879 iScreenY = LCD_HEIGHT;
@@ -890,23 +890,23 @@ void chopper_load(bool newgame)
890 chopCounter = 0; 890 chopCounter = 0;
891 iPlayerSpeedX = 3; 891 iPlayerSpeedX = 3;
892 iPlayerSpeedY = 0; 892 iPlayerSpeedY = 0;
893 iCameraPosX = 30; 893 iCameraPosX = 30;
894 894
895 for (i=0; i < NUMBER_OF_PARTICLES; i++) 895 for (i=0; i < NUMBER_OF_PARTICLES; i++)
896 mParticles[i].bIsActive = 0; 896 mParticles[i].bIsActive = 0;
897 897
898 for (i=0; i < NUMBER_OF_BLOCKS; i++) 898 for (i=0; i < NUMBER_OF_BLOCKS; i++)
899 mBlocks[i].bIsActive = 0; 899 mBlocks[i].bIsActive = 0;
900 900
901 g = iScreenY - 10; 901 g = iScreenY - 10;
902 chopClearTerrain(&mGround); 902 chopClearTerrain(&mGround);
903 903
904 for (i=0; i < MAX_TERRAIN_NODES; i++) 904 for (i=0; i < MAX_TERRAIN_NODES; i++)
905 chopAddTerrainNode(&mGround,i * 30,g - iR(0,20)); 905 chopAddTerrainNode(&mGround,i * 30,g - iR(0,20));
906 906
907 if (chopUpdateTerrainRecycling(&mGround) == 1) 907 if (chopUpdateTerrainRecycling(&mGround) == 1)
908 /* mirror the sky if we've changed the ground */ 908 /* mirror the sky if we've changed the ground */
909 chopCopyTerrain(&mGround, &mRoof, 0, -( iScreenY * 0.75)); 909 chopCopyTerrain(&mGround, &mRoof, 0, -( iScreenY * 0.75));
910 910
911 iLevelMode = LEVEL_MODE_NORMAL; 911 iLevelMode = LEVEL_MODE_NORMAL;
912 if (iLevelMode == LEVEL_MODE_NORMAL) 912 if (iLevelMode == LEVEL_MODE_NORMAL)
@@ -922,6 +922,14 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
922 int ret; 922 int ret;
923 923
924 rb->lcd_setfont(FONT_SYSFIXED); 924 rb->lcd_setfont(FONT_SYSFIXED);
925#if LCD_DEPTH > 1
926 rb->lcd_set_backdrop(NULL);
927#endif
928#if HAVE_LCD_COLOR
929 rb->lcd_set_background(LCD_BLACK);
930 rb->lcd_set_foreground(LCD_WHITE);
931#endif
932
925 /* Permanently enable the backlight (unless the user has turned it off) */ 933 /* Permanently enable the backlight (unless the user has turned it off) */
926 if (rb->global_settings->backlight_timeout > 0) 934 if (rb->global_settings->backlight_timeout > 0)
927 rb->backlight_set_timeout(1); 935 rb->backlight_set_timeout(1);
@@ -931,12 +939,12 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
931 xlcd_init(rb); 939 xlcd_init(rb);
932 configfile_init(rb); 940 configfile_init(rb);
933 configfile_load(CFG_FILE, config, 1, 0); 941 configfile_load(CFG_FILE, config, 1, 0);
934 942
935 chopper_load(true); 943 chopper_load(true);
936 ret = chopGameLoop(); 944 ret = chopGameLoop();
937 945
938 configfile_save(CFG_FILE, config, 1, 0); 946 configfile_save(CFG_FILE, config, 1, 0);
939 947
940 /* Restore user's original backlight setting */ 948 /* Restore user's original backlight setting */
941 rb->lcd_setfont(FONT_UI); 949 rb->lcd_setfont(FONT_UI);
942 rb->backlight_set_timeout(rb->global_settings->backlight_timeout); 950 rb->backlight_set_timeout(rb->global_settings->backlight_timeout);