summaryrefslogtreecommitdiff
path: root/apps/plugins/brickmania.c
diff options
context:
space:
mode:
authorKarl Kurbjun <kkurbjun@gmail.com>2009-08-28 23:55:44 +0000
committerKarl Kurbjun <kkurbjun@gmail.com>2009-08-28 23:55:44 +0000
commitd646dbe08eeb8af2bb1240f95dbaae7384f9eec1 (patch)
tree3f68f6141a8413313560b664c47f623789580a95 /apps/plugins/brickmania.c
parentbd946c255d8891107824bb58599023b364b82790 (diff)
downloadrockbox-d646dbe08eeb8af2bb1240f95dbaae7384f9eec1.tar.gz
rockbox-d646dbe08eeb8af2bb1240f95dbaae7384f9eec1.zip
Brickmania: Try to clean up some of the paddle collision code and add comments. Gameplay should be the same.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22523 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/brickmania.c')
-rw-r--r--apps/plugins/brickmania.c235
1 files changed, 126 insertions, 109 deletions
diff --git a/apps/plugins/brickmania.c b/apps/plugins/brickmania.c
index d033cb19a0..bdeb3af6f0 100644
--- a/apps/plugins/brickmania.c
+++ b/apps/plugins/brickmania.c
@@ -576,7 +576,13 @@ enum difficulty_options {
576int pad_pos_x; 576int pad_pos_x;
577int life; 577int life;
578enum { ST_READY, ST_START, ST_PAUSE } game_state = ST_READY; 578enum { ST_READY, ST_START, ST_PAUSE } game_state = ST_READY;
579int pad_type; 579
580enum {
581 normal = 0,
582 sticky = 1,
583 shooter = 2
584} pad_type;
585
580int score=0,vscore=0; 586int score=0,vscore=0;
581bool flip_sides=false; 587bool flip_sides=false;
582int level=0; 588int level=0;
@@ -599,8 +605,10 @@ typedef struct cube {
599cube brick[80]; 605cube brick[80];
600 606
601typedef struct balls { 607typedef struct balls {
608 /* pos_x and y store the current position of the ball */
602 int pos_x; 609 int pos_x;
603 int pos_y; 610 int pos_y;
611 /* x and y store the current speed of the ball */
604 int y; 612 int y;
605 int tempy; 613 int tempy;
606 int x; 614 int x;
@@ -645,7 +653,7 @@ static void brickmania_init_game(int new_game)
645 653
646 used_balls=1; 654 used_balls=1;
647 game_state=ST_READY; 655 game_state=ST_READY;
648 pad_type=0; 656 pad_type = normal;
649 pad_width=PAD_WIDTH; 657 pad_width=PAD_WIDTH;
650 flip_sides=false; 658 flip_sides=false;
651 num_count=10; 659 num_count=10;
@@ -925,23 +933,6 @@ static int brickmania_menu(void)
925 } 933 }
926} 934}
927 935
928static int brickmania_pad_check(int ballxc, int mode, int pon ,int ballnum)
929{
930 /* pon: positive(1) or negative(0) */
931
932 if (mode==0) {
933 if (pon == 0)
934 return -ballxc;
935 else
936 return ballxc;
937 } else {
938 if (ball[ballnum].x > 0)
939 return ballxc;
940 else
941 return ballxc*-1;
942 }
943}
944
945static int brickmania_fire_space(void) 936static int brickmania_fire_space(void)
946{ 937{
947 int t; 938 int t;
@@ -1091,17 +1082,17 @@ static int brickmania_game_loop(void)
1091 break; 1082 break;
1092 case 2: 1083 case 2:
1093 score+=34; 1084 score+=34;
1094 pad_type=1; 1085 pad_type = sticky;
1095 break; 1086 break;
1096 case 3: 1087 case 3:
1097 score+=47; 1088 score+=47;
1098 pad_type=2; 1089 pad_type = shooter;
1099 for(k=0;k<used_balls;k++) 1090 for(k=0;k<used_balls;k++)
1100 ball[k].glue=false; 1091 ball[k].glue=false;
1101 break; 1092 break;
1102 case 4: 1093 case 4:
1103 score+=23; 1094 score+=23;
1104 pad_type=0; 1095 pad_type = normal;
1105 for(k=0;k<used_balls;k++) 1096 for(k=0;k<used_balls;k++)
1106 ball[k].glue=false; 1097 ball[k].glue=false;
1107 flip_sides=false; 1098 flip_sides=false;
@@ -1158,7 +1149,7 @@ static int brickmania_game_loop(void)
1158 1149
1159 brickx=LEFTMARGIN+j*BRICK_WIDTH; 1150 brickx=LEFTMARGIN+j*BRICK_WIDTH;
1160 bricky=TOPMARGIN+i*BRICK_HEIGHT; 1151 bricky=TOPMARGIN+i*BRICK_HEIGHT;
1161 if (pad_type==2) { 1152 if (pad_type == shooter) {
1162 for (k=0;k<30;k++) { 1153 for (k=0;k<30;k++) {
1163 if (fire[k].top+7>0) { 1154 if (fire[k].top+7>0) {
1164 if (brick[i*10+j].used==1 && 1155 if (brick[i*10+j].used==1 &&
@@ -1357,31 +1348,50 @@ static int brickmania_game_loop(void)
1357 0,pad_type*PAD_HEIGHT,pad_width, 1348 0,pad_type*PAD_HEIGHT,pad_width,
1358 pad_pos_x, PAD_POS_Y, pad_width, PAD_HEIGHT); 1349 pad_pos_x, PAD_POS_Y, pad_width, PAD_HEIGHT);
1359 1350
1360 if (game_state!=ST_PAUSE) { 1351 /* If the game is not paused continue */
1361 for(k=0;k<used_balls;k++) { 1352 if (game_state!=ST_PAUSE)
1362 1353 {
1363 if ((ball[k].pos_x >= pad_pos_x && 1354 /* Loop through all of the balls in play */
1364 ball[k].pos_x <= pad_pos_x+pad_width) && 1355 for(k=0;k<used_balls;k++)
1365 (PAD_POS_Y-4<ball[k].pos_y+BALL && 1356 {
1366 PAD_POS_Y>ball[k].pos_y+BALL) && (ball[k].y >0)) 1357 if ( (ball[k].pos_x >= pad_pos_x &&
1358 ball[k].pos_x <= pad_pos_x+pad_width) &&
1359 (PAD_POS_Y-4<ball[k].pos_y+BALL &&
1360 PAD_POS_Y>ball[k].pos_y+BALL) && (ball[k].y >0))
1361 {
1367 ball[k].tempy=PAD_POS_Y-ball[k].pos_y-BALL; 1362 ball[k].tempy=PAD_POS_Y-ball[k].pos_y-BALL;
1363 }
1368 else if ((4>ball[k].pos_y && 0<ball[k].pos_y) && 1364 else if ((4>ball[k].pos_y && 0<ball[k].pos_y) &&
1369 (ball[k].y <0)) 1365 (ball[k].y <0))
1366 {
1370 ball[k].tempy=-ball[k].pos_y; 1367 ball[k].tempy=-ball[k].pos_y;
1368 }
1371 if ((LCD_WIDTH-4<ball[k].pos_x+BALL && 1369 if ((LCD_WIDTH-4<ball[k].pos_x+BALL &&
1372 LCD_WIDTH>ball[k].pos_x+BALL) && (ball[k].x >0)) 1370 LCD_WIDTH>ball[k].pos_x+BALL) && (ball[k].x >0))
1371 {
1373 ball[k].tempx=LCD_WIDTH-ball[k].pos_x-BALL; 1372 ball[k].tempx=LCD_WIDTH-ball[k].pos_x-BALL;
1373 }
1374 else if ((4>ball[k].pos_x && 0<ball[k].pos_x) && 1374 else if ((4>ball[k].pos_x && 0<ball[k].pos_x) &&
1375 (ball[k].x <0)) 1375 (ball[k].x <0))
1376 {
1376 ball[k].tempx=-ball[k].pos_x; 1377 ball[k].tempx=-ball[k].pos_x;
1378 }
1377 1379
1378 /* top line */ 1380 /* Did the Ball hit the top of the screen? */
1379 if (ball[k].pos_y<= 0) 1381 if (ball[k].pos_y<= 0)
1382 {
1383 /* Reverse the direction */
1380 ball[k].y = ball[k].y*-1; 1384 ball[k].y = ball[k].y*-1;
1381 /* bottom line */ 1385 }
1382 else if (ball[k].pos_y+BALL >= GAMESCREEN_HEIGHT) { 1386 /* Player missed the ball and hit bottom of screen */
1383 if (used_balls>1) { 1387 else if (ball[k].pos_y+BALL >= GAMESCREEN_HEIGHT)
1388 {
1389 /* Player had balls to spare, so handle the removal */
1390 if (used_balls>1)
1391 {
1392 /* decrease number of balls in play */
1384 used_balls--; 1393 used_balls--;
1394 /* Replace removed ball with the last ball */
1385 ball[k].pos_x = ball[used_balls].pos_x; 1395 ball[k].pos_x = ball[used_balls].pos_x;
1386 ball[k].pos_y = ball[used_balls].pos_y; 1396 ball[k].pos_y = ball[used_balls].pos_y;
1387 ball[k].y = ball[used_balls].y; 1397 ball[k].y = ball[used_balls].y;
@@ -1390,6 +1400,7 @@ static int brickmania_game_loop(void)
1390 ball[k].tempx = ball[used_balls].tempx; 1400 ball[k].tempx = ball[used_balls].tempx;
1391 ball[k].glue = ball[used_balls].glue; 1401 ball[k].glue = ball[used_balls].glue;
1392 1402
1403 /* Reset the last ball that was removed */
1393 ball[used_balls].x=0; 1404 ball[used_balls].x=0;
1394 ball[used_balls].y=0; 1405 ball[used_balls].y=0;
1395 ball[used_balls].tempy=0; 1406 ball[used_balls].tempy=0;
@@ -1399,95 +1410,100 @@ static int brickmania_game_loop(void)
1399 1410
1400 k--; 1411 k--;
1401 continue; 1412 continue;
1402 } else { 1413 }
1414 else
1415 {
1416 /* Player lost a life */
1403 life--; 1417 life--;
1404 if (life>=0) { 1418 if (life>=0)
1419 {
1420 /* No lives left reset game */
1405 brickmania_init_game(0); 1421 brickmania_init_game(0);
1406 brickmania_sleep(2); 1422 brickmania_sleep(2);
1407 } 1423 }
1408 } 1424 }
1409 } 1425 }
1410 1426
1411 /* left line ,right line */ 1427 /* Check if the ball hit the left or right side */
1412 if ((ball[k].pos_x <= 0) || 1428 if ( (ball[k].pos_x <= 0) ||
1413 (ball[k].pos_x+BALL >= LCD_WIDTH)) { 1429 (ball[k].pos_x+BALL >= LCD_WIDTH))
1430 {
1431 /* Reverse direction */
1414 ball[k].x = ball[k].x*-1; 1432 ball[k].x = ball[k].x*-1;
1433 /* Re-position ball in gameboard */
1415 ball[k].pos_x = ball[k].pos_x <= 0 ? 0 : LCD_WIDTH-BALL; 1434 ball[k].pos_x = ball[k].pos_x <= 0 ? 0 : LCD_WIDTH-BALL;
1416 } 1435 }
1417 1436
1418 if ((ball[k].pos_y+BALL >= PAD_POS_Y && 1437 /* Did the ball hit the paddle? Depending on where the ball
1419 (ball[k].pos_x >= pad_pos_x && 1438 * Hit set the x/y speed appropriately.
1420 ball[k].pos_x <= pad_pos_x+pad_width)) && 1439 */
1421 game_state!=ST_READY && !ball[k].glue) { 1440 if( (ball[k].pos_y + BALL >= PAD_POS_Y &&
1422 1441 (ball[k].pos_x + HALFBALL >= pad_pos_x &&
1423 if ((ball[k].pos_x+HALFBALL >= pad_pos_x && 1442 ball[k].pos_x + HALFBALL <= pad_pos_x+pad_width)) &&
1424 ball[k].pos_x+HALFBALL <= 1443 game_state!=ST_READY && !ball[k].glue)
1425 pad_pos_x+(pad_width/2/4)) || 1444 {
1426 (ball[k].pos_x +HALFBALL>= 1445 /* Position the ball relative to the paddle width */
1427 pad_pos_x+(pad_width-(pad_width/2/4)) && 1446 int ball_repos=ball[k].pos_x + HALFBALL - pad_pos_x;
1428 ball[k].pos_x+HALFBALL <= pad_pos_x+pad_width)) { 1447 /* If the ball hits the right half of paddle, x speed
1429 1448 * should be positive, if it hits the left half it
1430 ball[k].y = -2; 1449 * should be negative.
1431 if (ball[k].pos_x != 0 && 1450 */
1432 ball[k].pos_x+BALL!=LCD_WIDTH) 1451 int x_direction = -1;
1433 ball[k].x = brickmania_pad_check(6,0, 1452
1434 ball[k].pos_x+2<=pad_pos_x+ 1453 /* Comparisons are done with respect to 1/2 pad_width */
1435 (pad_width/2)?0:1,k); 1454 if(ball_repos > pad_width/2)
1436 1455 {
1456 /* flip the relative position */
1457 ball_repos -= ((ball_repos - pad_width/2) << 1);
1458 /* Ball hit the right half so X speed calculations
1459 * should be positive.
1460 */
1461 x_direction = 1;
1437 } 1462 }
1438 else if ((ball[k].pos_x+HALFBALL >= 1463
1439 pad_pos_x+(pad_width/2/4) && 1464 /* Figure out where the ball hit relative to 1/2 pad
1440 ball[k].pos_x+HALFBALL <= 1465 * and in divisions of 4.
1441 pad_pos_x+2*(pad_width/2/4)) || 1466 */
1442 (ball[k].pos_x+HALFBALL >= 1467 ball_repos = ball_repos / (pad_width/2/4);
1443 pad_pos_x+(pad_width-2*(pad_width/2/4)) && 1468
1444 ball[k].pos_x+HALFBALL <= 1469 switch(ball_repos)
1445 pad_pos_x+(pad_width-(pad_width/2/4)) )) { 1470 {
1446 1471 /* Ball hit the outer edge of the paddle */
1472 case 0:
1473 ball[k].y = -2;
1474 ball[k].x = 6 * x_direction;
1475 break;
1476 /* Ball hit the next fourth of the paddle */
1477 case 1:
1447 ball[k].y = -3; 1478 ball[k].y = -3;
1448 if (ball[k].pos_x != 0 && 1479 ball[k].x = 4 * x_direction;
1449 ball[k].pos_x+BALL!=LCD_WIDTH) 1480 break;
1450 ball[k].x = brickmania_pad_check(4,0, 1481 /* Ball hit the third fourth of the paddle */
1451 ball[k].pos_x+2<=pad_pos_x+ 1482 case 2:
1452 (pad_width/2)?0:1,k);
1453
1454 }
1455 else if ((ball[k].pos_x+HALFBALL >=
1456 pad_pos_x+2*(pad_width/2/4) &&
1457 ball[k].pos_x+HALFBALL <=
1458 pad_pos_x+3*(pad_width/2/4)) ||
1459 (ball[k].pos_x+2 >=
1460 pad_pos_x+(pad_width-3*(pad_width/2/4)) &&
1461 ball[k].pos_x+2 <=
1462 pad_pos_x+ ((pad_width/2)-2*(pad_width/2/4)) )) {
1463
1464 ball[k].y = -4; 1483 ball[k].y = -4;
1465 if (ball[k].pos_x != 0 && 1484 ball[k].x = 3 * x_direction;
1466 ball[k].pos_x+BALL!=LCD_WIDTH) 1485 break;
1467 ball[k].x = brickmania_pad_check(3,0, 1486 /* Ball hit the fourth fourth of the paddle or dead
1468 ball[k].pos_x+2<=pad_pos_x+ 1487 * center.
1469 (pad_width/2)?0:1,k); 1488 */
1470 1489 case 3:
1471 } 1490 case 4:
1472 else if ((ball[k].pos_x+HALFBALL >=
1473 pad_pos_x+3*(pad_width/2/4) &&
1474 ball[k].pos_x+HALFBALL <=
1475 pad_pos_x+4*(pad_width/2/4)-2) ||
1476 (ball[k].pos_x+2 >= pad_pos_x+(pad_width/2+2) &&
1477 ball[k].pos_x+2 <=
1478 pad_pos_x+(pad_width-3*(pad_width/2/4)) )) {
1479
1480 ball[k].y = -4; 1491 ball[k].y = -4;
1481 if (ball[k].pos_x != 0 && 1492 /* Since this is the middle we don't want to
1482 ball[k].pos_x+BALL!=LCD_WIDTH) 1493 * force the ball in a different direction.
1483 ball[k].x = brickmania_pad_check(2,1,0,k); 1494 * Just keep it going in the same direction
1484 1495 * with a specific speed.
1485 } 1496 */
1486 else { 1497 ball[k].x = (ball[k].x > 0) ? 2: -2;
1498 break;
1499
1500 default:
1487 ball[k].y = -4; 1501 ball[k].y = -4;
1502 break;
1488 } 1503 }
1489 } 1504 }
1490 1505
1506 /* Update the ball position */
1491 if (!ball[k].glue) { 1507 if (!ball[k].glue) {
1492 ball[k].pos_x+=ball[k].tempx!=0?ball[k].tempx:ball[k].x; 1508 ball[k].pos_x+=ball[k].tempx!=0?ball[k].tempx:ball[k].x;
1493 ball[k].pos_y+=ball[k].tempy!=0?ball[k].tempy:ball[k].y; 1509 ball[k].pos_y+=ball[k].tempy!=0?ball[k].tempy:ball[k].y;
@@ -1495,9 +1511,10 @@ static int brickmania_game_loop(void)
1495 ball[k].tempy=0; 1511 ball[k].tempy=0;
1496 ball[k].tempx=0; 1512 ball[k].tempx=0;
1497 } 1513 }
1498 1514
1499 if (ball[k].pos_y+5 >= PAD_POS_Y && 1515 /* Handle the sticky situation */
1500 (pad_type==1 && !ball[k].glue) && 1516 if (ball[k].pos_y + BALL >= PAD_POS_Y &&
1517 (pad_type == sticky && !ball[k].glue) &&
1501 (ball[k].pos_x >= pad_pos_x && 1518 (ball[k].pos_x >= pad_pos_x &&
1502 ball[k].pos_x <= pad_pos_x+pad_width)) { 1519 ball[k].pos_x <= pad_pos_x+pad_width)) {
1503 ball[k].y=0; 1520 ball[k].y=0;
@@ -1632,13 +1649,13 @@ static int brickmania_game_loop(void)
1632 else if (game_state==ST_PAUSE) { 1649 else if (game_state==ST_PAUSE) {
1633 game_state=ST_START; 1650 game_state=ST_START;
1634 } 1651 }
1635 else if (pad_type==1) { 1652 else if (pad_type == sticky) {
1636 for(k=0;k<used_balls;k++) { 1653 for(k=0;k<used_balls;k++) {
1637 if (ball[k].glue) 1654 if (ball[k].glue)
1638 ball[k].glue=false; 1655 ball[k].glue=false;
1639 } 1656 }
1640 } 1657 }
1641 else if (pad_type==2) { 1658 else if (pad_type == shooter) {
1642 k=brickmania_fire_space(); 1659 k=brickmania_fire_space();
1643 fire[k].top=PAD_POS_Y-7; 1660 fire[k].top=PAD_POS_Y-7;
1644 fire[k].left=pad_pos_x+1; 1661 fire[k].left=pad_pos_x+1;