home *** CD-ROM | disk | FTP | other *** search
/ ring.yamanashi.ac.jp/pub/pc/freem/action/ / action.zip / spout11.zip / SDL / spout.c < prev    next >
C/C++ Source or Header  |  2002-10-12  |  16KB  |  820 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #include "piece.h"
  6.  
  7. #include "sintable.h"
  8.  
  9. #define FRAMERATE 50
  10. #define MAX_GRAIN 500
  11.  
  12. const unsigned char    MATSUMI[] = {
  13. //     80,  77,  66,  80, 180,   0,   0,   0,   1,   0, 128,   0,  10,   0, 223, 119,
  14. //    160,   0,   0,   0,
  15.       0,   0,   0,   0,   0,   0,   0,  34,  56,  68,  10,   4,
  16.      80, 129, 202,   0,   0,   0,   0,   0,   8,   0,   8,  34,  73, 255, 127, 223,
  17.     241, 241,  95,   0,   0,   0,   0,   0,   8,   0,   0,  71,  72, 254,  10,   5,
  18.      67,  17,  68,   0,   1,   2,  59, 187, 137,  75, 136,  66, 164,  16,  81,  31,
  19.      84, 225, 155,   0,   2,  25,  10, 168, 138,  74,  72, 135,  33, 255,  49,   5,
  20.      97, 177,  78,   0,   2,  33,  58, 171, 142,  74,  72, 134,  32,  16,  23, 215,
  21.      86,  77, 117,   0,   2,  33,  34, 170,   9,  74,  73,   2,  73, 255,  49,  21,
  22.     176,  33,  78,   0,   1,  26,  59, 187, 137,  50,  73,   2,  76,  40,  81,  28,
  23.       0, 193, 181,   0,   0,   0,   0,   0,   0,   0,   0,   2, 245, 199,  23, 211,
  24.     240,  33,  12,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  25.       0,   0,   0,   0
  26. };
  27.  
  28. typedef struct {
  29.     short x, y;
  30. } SVECTOR;
  31.  
  32. typedef struct {
  33.     long x, y;
  34. } VECTOR;
  35.  
  36. typedef struct tagGRAIN {
  37.     struct tagGRAIN    *next;
  38.     struct tagGRAIN    *prev;
  39.  
  40.     SVECTOR s, v;
  41.     short pos;
  42.     unsigned char color;
  43. } GRAIN;
  44.  
  45. GRAIN *grainUseLink, *grainFreeLink;
  46.  
  47. unsigned char vbuff[128 * 88];
  48. unsigned char vbuff2[128 * 128];
  49.  
  50. GRAIN grain[MAX_GRAIN];
  51. GRAIN *v2g[128 * 128];
  52.  
  53. SVECTOR box;
  54.  
  55. VECTOR mPos, mSpeed;
  56. int mR;
  57.  
  58. int nGrain;
  59.  
  60. int time = FRAMERATE * 60, score = 0, height = 0, dispscore = 0;
  61. int hiScore[2] = {0, 0};
  62. int dispPos, upperLine, rollCount;
  63.  
  64. void spout(int t, int x, int y);
  65. void sweep(unsigned char c1, unsigned char c2);
  66. void initGrain(void);
  67. GRAIN *allocGrain(void);
  68. GRAIN *freeGrain(GRAIN *current);
  69.  
  70. void pceAppInit(void)
  71. {
  72.     pceLCDDispStop();
  73.     pceLCDSetBuffer(vbuff);
  74.     pceAppSetProcPeriod(1000 / FRAMERATE);
  75.  
  76.     memset(vbuff, 0, 128 * 88);
  77.  
  78.     pceLCDDispStart();
  79.  
  80.     pceCPUSetSpeed(CPU_SPEED_NORMAL);
  81.  
  82.     {
  83.         FILEACC fa;
  84.         if(!pceFileOpen(&fa, "spout.sco", FOMD_RD)) {
  85.             pceFileReadSct(&fa, (void *)hiScore, 0, 8);
  86.             pceFileClose(&fa);
  87.         }
  88.     }
  89.  
  90.     pcePadSetTrigMode(PP_MODE_SINGLE);
  91.  
  92.     srand(pceTimerGetCount());
  93. }
  94.  
  95. void pceAppProc(int cnt)
  96. {
  97.     static int gamePhase = 0, gameover;
  98.  
  99.     int pad = pcePadGet();
  100.  
  101.     if(    (pad & (PAD_C | TRG_D)) == (PAD_C | TRG_D) ||
  102.         (pad & (TRG_C | PAD_D)) == (TRG_C | PAD_D)) {
  103.         if(gamePhase >= 2) {
  104.             gamePhase = 0;
  105.         } else {
  106.             pceAppReqExit(0);
  107.         }
  108.         pad = 0;
  109.     }
  110.  
  111.     if(gamePhase == 4) {
  112.         if(pad & (TRG_C)) {
  113.             gamePhase = 3;
  114.         }
  115.         return;
  116.     }
  117.  
  118.     if(!(gamePhase & 1)) {
  119.         if(gamePhase == 0) {
  120.             if(score > hiScore[0] || (score == hiScore[0] && height > hiScore[1])) {
  121.                 FILEACC fa;
  122.                 hiScore[0] = score;
  123.                 hiScore[1] = height;
  124.                 if(!pceFileOpen(&fa, "spout.sco", FOMD_WR)) {
  125.                     pceFileWriteSct(&fa, (void *)hiScore, 0, 8);
  126.                 } else if(!pceFileCreate("spout.sco", 8)) {
  127.                     if(!pceFileOpen(&fa, "spout.sco", FOMD_WR)) {
  128.                         pceFileWriteSct(&fa, (void *)hiScore, 0, 8);
  129.                     }
  130.                 }
  131.                 pceFileClose(&fa);
  132.             }
  133.         } else {
  134.             score = 0;
  135.             dispscore = 0;
  136.             height = - 58;
  137.             time = 60 * FRAMERATE;
  138.         }
  139.  
  140.         {
  141.             int i;
  142.             for(i = 0; i < 128 * 128; i ++) {
  143.                 v2g[i] = NULL;
  144.             }
  145.             initGrain();
  146.             nGrain = 0;
  147.         }
  148.  
  149.         if(gamePhase & 2) {
  150.             memset(vbuff2, 0xd2, 128 * 128);
  151.             memset(vbuff2 + 128 * 0, 0, 128 * 78);
  152.             memset(vbuff2 + 128 * (128 - 32), 0, 128 * 32);
  153.         } else {
  154.             memset(vbuff2, 0, 128 * 128);
  155.         }
  156.  
  157.         memset(vbuff, 0, 128 * 88);
  158.  
  159.         {
  160.             int i;
  161.             unsigned char *pC;
  162.  
  163.             pC = vbuff2;
  164.             for(i = 0; i < 128; i ++) {
  165.                 *pC++ = 0x0b;
  166.                 *pC++ = 0x0b;
  167.                 *pC++ = 0x0b;
  168.                 *pC++ = 0x0b;
  169.                 pC += 128 - 8;
  170.                 *pC++ = 0x0b;
  171.                 *pC++ = 0x0b;
  172.                 *pC++ = 0x0b;
  173.                 *pC++ = 0x0b;
  174.             }
  175.         }
  176.  
  177.         mPos.x = 40 * 256;
  178.         mPos.y = 0 * 256;
  179.         mSpeed.x = 0;
  180.         mSpeed.y = 0;
  181.         mR = 256 + (gamePhase & 2) * 224;
  182.  
  183.         dispPos = 0;
  184.         upperLine = 0;
  185.         gameover = 0;
  186.         rollCount = 0;
  187.         gamePhase ++;
  188.  
  189.         memset(vbuff + 128, 0x03, 128);
  190.         pceFontSetType(2 + 128);
  191.         pceFontSetPos(0, 82);
  192.         if(height > 0) {
  193.             pceFontPrintf("time:%2d height:%4d score:%6d", (time + FRAMERATE - 1) / FRAMERATE, height % 10000, score % 1000000);
  194.         } else {
  195.             pceFontPrintf("time:%2d height:   0 score:%6d", (time + FRAMERATE - 1) / FRAMERATE, score % 1000000);
  196.         }
  197.         pceFontSetType(0);
  198.     }
  199.  
  200.     if((pad & TRG_C) && gamePhase == 3 && gameover == 0) {
  201.         pceFontSetType(2 + 128);
  202.         pceFontSetPos(64 - 7 * 4 / 2, 33);
  203.         pceFontPrintf(" pause ");
  204.         pceFontSetType(0);
  205.  
  206.         gamePhase = 4;
  207.  
  208.         pceLCDTrans();
  209.         return;
  210.     }
  211.  
  212.     if(gamePhase & 2) {
  213.         if(gameover == 0) {    
  214.             if((pad & PAD_RI)) {
  215.                 mR = (mR - 16) & 1023;
  216.             } else if((pad & PAD_LF)) {
  217.                 mR = (mR + 16) & 1023;
  218.             }
  219.             if((pad & (PAD_A | PAD_B))) {
  220.                 mSpeed.x -= sintable[(256 + mR) & 1023] / 128;
  221.                 mSpeed.y += sintable[mR] / 128;
  222.             }
  223.             mSpeed.y += 8;
  224.  
  225.             if(mSpeed.x < -256 * 4) {
  226.                 mSpeed.x = -256 * 4;
  227.             } else if(mSpeed.x > 256 * 4) {
  228.                 mSpeed.x = 256 * 4;
  229.             }
  230.             if(mSpeed.y < -256 * 4) {
  231.                 mSpeed.y = -256 * 4;
  232.             } else if(mSpeed.y > 256 * 4) {
  233.                 mSpeed.y = 256 * 4;
  234.             }
  235.  
  236.             mPos.x += mSpeed.x / 16;
  237.             mPos.y += mSpeed.y / 16;
  238.  
  239.             if(mPos.x >= 125 * 256) {
  240.                 mPos.x = 124 * 256;
  241.                 gameover = 1;
  242.             } else if(mPos.x <= 2 * 256) {
  243.                 mPos.x = 3 * 256;
  244.                 gameover = 1;
  245.             }
  246.             if(mPos.y >= 78 * 256) {
  247.                 mPos.y = 77 * 256;
  248.                 gameover = 1;
  249.             }
  250.  
  251.             if(mPos.y < 40 * 256) {
  252.                 unsigned char *pC;
  253.                 int i, j, w, x1 , x2;
  254.                 mPos.y += 256;
  255.                 upperLine = (upperLine - 1) & 127;
  256.                 height ++;
  257.  
  258.                 if(height > 0) {
  259.                     score ++;
  260.                     if((height & 127) == 0) {
  261.                         score += (time + FRAMERATE - 1) / FRAMERATE * 10;
  262.                         time += 60 * FRAMERATE;
  263.                         if(time > 99 * FRAMERATE) {
  264.                             time = 99 * FRAMERATE;
  265.                         }
  266.                         pceFontSetType(2 + 128);
  267.                         pceFontSetPos(4 * 5, 82);
  268.                         pceFontPrintf("%2d", (time + FRAMERATE - 1) / FRAMERATE);
  269.                         pceFontSetType(0);
  270.                     }
  271.                     pceFontSetType(2 + 128);
  272.                     pceFontSetPos(4 * 15, 82);
  273.                     pceFontPrintf("%4d", height % 10000);
  274.                     pceFontSetType(0);
  275.                 }
  276.  
  277.                 if(upperLine == 111 && height > 0) {
  278.                     unsigned long *pL;
  279.                     pL = (unsigned long *)(vbuff2 + 128 * 108 + 4);
  280.                     while(pL < (unsigned long *)(vbuff2 + 128 * 109 - 4)) {
  281.                         *pL++ = 0;
  282.                     }
  283.                     pL += 2;
  284.                     while(pL < (unsigned long *)(vbuff2 + 128 * 110 - 4)) {
  285.                         *pL++ = 0xd3d3d3d3;
  286.                     }
  287.                     pL += 2;
  288.                     while(pL < (unsigned long *)(vbuff2 + 128 * 111 - 4)) {
  289.                         *pL++ = 0;
  290.                     }
  291.                 }
  292.  
  293.                 box.x = 20 - (height + 40) / 64;
  294.                 if(box.x < 4) {
  295.                     box.x = 4;
  296.                 }
  297.                 box.y = 20 - (height + 40) / 64;
  298.                 if(box.y < 4) {
  299.                     box.y = 4;
  300.                 }
  301.  
  302.                 for(j = 0; j < 1; j ++) {
  303.                     int x, y;
  304.                     x = 4 + (rand() % box.x);
  305.                     y = 4 + (rand() % box.y);
  306.                     pC = vbuff2 + ((upperLine - 20 - (rand() & 7)) & 127) * 128;
  307.                     x1 = 4 + (rand() % (120 - x));
  308.                     x2 = x;
  309.                     i = y;
  310.                     while(i > 0) {
  311.                         if(pC < vbuff2) {
  312.                             pC += 128 * 128;
  313.                         }
  314.                         pC += x1;
  315.                         w = x2;
  316.                         while(w > 0) {
  317.                             *pC++ = 0;
  318.                             w --;
  319.                         }
  320.                         pC -= x1 + x2 + 128;
  321.                         i --;
  322.                     }
  323.                 }
  324.  
  325.                 sweep(0x13, 0xd2);
  326.             }
  327.         }
  328.     } else {
  329.         mPos.x = 7 * 256;
  330.         mPos.y = 60 * 256;
  331.         mR = 0;
  332.  
  333.         if((rollCount & 7) == 0) {
  334.             int i, j;
  335.  
  336.             if((upperLine & 31) == 0) {
  337.                 unsigned long *pL;
  338.                 pceLCDSetBuffer(vbuff2 + ((upperLine - 24) & 127) * 128);
  339.                 pceFontSetBkColor(0);
  340.  
  341.                 switch(upperLine / 32) {
  342.                     case 0:
  343.                         pL = (unsigned long *)(vbuff2 + 12 + ((upperLine - 24) & 127) * 128);
  344.                         for(i = 0; i < 16; i ++) {
  345.                             for(j = 0; j < 26 / 2; j ++) {
  346.                                 *pL = 0x91919191;
  347.                                 pL += 2;
  348.                             }
  349.                             if((i & 7) == 3) {
  350.                                 pL += 7;
  351.                             } else if((i & 7) == 7) {
  352.                                 pL += 5;
  353.                             } else {
  354.                                 pL += 6;
  355.                             }
  356.                         }
  357.  
  358.                         pceFontSetTxColor(0x03);
  359.                         pceFontSetType(1 + 128);
  360.                         pceFontSetPos(64 - 4 * 5, 0);
  361.                         pceFontPrintf("spout");
  362.                         break;
  363.  
  364.                     case 2:
  365.                         pceFontSetTxColor(0xc3);
  366.                         pceFontSetType(2 + 128);
  367.                         pceFontSetPos(118 - 20 * 4, 0);
  368.                         pceFontPrintf("    height: %8d", hiScore[1] % 1000000);
  369.                         pceFontSetPos(118 - 20 * 4, 6);
  370.                         pceFontPrintf("high-score: %8d", hiScore[0] % 1000000);
  371.                         break;
  372.  
  373.                     case 1:
  374.                         {
  375.                             const unsigned char *pS = MATSUMI;
  376.                             unsigned char *pD = vbuff2 + ((upperLine - 16) & 127) * 128;
  377.                             for(i = 0; i < 128 / 8 * 10; i ++) {
  378.                                 unsigned char t = *pS++;
  379.                                 for(j = 0; j < 8; j ++) {
  380.                                     if(t & 0x80) {
  381.                                         *pD = 0xc3;
  382.                                     }
  383.                                     pD ++;
  384.                                     t <<= 1;
  385.                                 }
  386.                             }
  387.                         }
  388.                         break;
  389.                 }
  390.  
  391.                 pceFontSetType(0);
  392.                 pceFontSetTxColor(0x03);
  393.                 pceFontSetBkColor(0);
  394.  
  395.                 pceLCDSetBuffer(vbuff);
  396.             }
  397.             upperLine = (upperLine - 1) & 127;
  398.  
  399.             sweep(0x13, 0x00);
  400.         }
  401.     }
  402.  
  403.     rollCount ++;
  404.  
  405.     {
  406.         static int gx[] = {-2, 2, -1, 1, 0};
  407.         int r, t;
  408.  
  409.         r = rand() & 3;
  410.         t = gx[r]; gx[r] = gx[r + 1]; gx[r + 1] = t;
  411.         if(gamePhase & 2) {
  412.             if(gameover == 0 && (pad & (PAD_A | PAD_B))) {
  413.                 int i, t, x, y;
  414.                 for(i = 0; i < 5; i ++) {
  415.                     t = mPos.x / 256 + gx[i] + ((mPos.y / 256 - 1 + abs(gx[i]) + dispPos) & 127) * 128;
  416.                     x = mSpeed.x / 16 + sintable[(256 + mR) & 1023] / 8;
  417.                     y = mSpeed.y / 16 - sintable[mR] / 8;
  418.                     spout(t, x, y);
  419.                 }
  420.             }
  421.         } else {
  422.             int i, t;
  423.             for(i = -1; i <= 2; i ++) {
  424.                 t = 7 + i + ((60 - 1 + dispPos) & 127) * 128;
  425.                 spout(t, 512, -384);
  426.             }
  427.         }
  428.     }
  429.  
  430.     {
  431.         GRAIN *pG, *pG2;
  432.         SVECTOR svt;
  433.  
  434.         pG = grainUseLink;
  435.         while(pG) {
  436.             int f = 0;
  437.             unsigned char *c;
  438.  
  439.             pG->v.y += 8;
  440.  
  441.             pG->s.x += pG->v.x;
  442.             pG->s.y += pG->v.y;
  443.  
  444.             *(vbuff2 + pG->pos) = 0;
  445.             *(v2g + pG->pos) = NULL;
  446.  
  447.             if(pG->s.y >= 256) {
  448.                 do {
  449.                     pG->s.y -= 256;
  450.                     pG->pos = (pG->pos + 128) & 16383;
  451.                     c = (vbuff2 + pG->pos);
  452.  
  453.                     if(*c) {
  454.                         if(*c & 0x04) {
  455.                             int r;
  456.                             pG2 = *(v2g + pG->pos);
  457.                             r = 31 - (rand() & 63);
  458.                             svt = pG->v;
  459.                             pG->v = pG2->v;
  460.                             pG2->v = svt;
  461.                             pG->v.x += r;
  462.                             pG2->v.x -= r;
  463.                         } else {
  464.                             pG->v.y = -pG->v.y / 2;
  465.                             pG->v.x += 15 - (rand() & 31);
  466.                             if(*c & 0xc0) {
  467.                                 *c -= 0x40;
  468.                                 if(!(*c & 0xc0)) {
  469.                                     *c = 0;
  470.                                 }
  471.                             }
  472.                             if(pG->color & 0xc0) {
  473.                                 pG->color -= 0x40;
  474.                             } else {
  475.                                 pG->color = 0;
  476.                                 f = 1;
  477.                             }
  478.                         }
  479.                         pG->pos = (pG->pos - 128) & 16383;
  480.                         break;
  481.                     }
  482.                 } while(pG->s.y >= 256);
  483.             } else {
  484.                 while(pG->s.y <= -256) {
  485.                     pG->s.y += 256;
  486.                     pG->pos = (pG->pos - 128) & 16383;
  487.                     c = (vbuff2 + pG->pos);
  488.  
  489.                     if(*c) {
  490.                         if(*c & 4) {
  491.                             pG2 = *(v2g + pG->pos);
  492.                             svt = pG->v;
  493.                             pG->v = pG2->v;
  494.                             pG2->v = svt;
  495.                         } else {
  496.                             pG->v.y = -pG->v.y / 2;
  497.                             if(*c & 0xc0) {
  498.                                 *c -= 0x40;
  499.                                 if(!(*c & 0xc0)) {
  500.                                     *c = 0;
  501.                                 }
  502.                             }
  503.                             if(pG->color & 0xc0) {
  504.                                 pG->color -= 0x40;
  505.                             } else {
  506.                                 pG->color = 0;
  507.                                 f = 1;
  508.                             }
  509.                         }
  510.                         pG->pos = (pG->pos + 128) & 16383;
  511.                         break;
  512.                     }
  513.                 }
  514.             }
  515.  
  516.             if(pG->s.x >= 256) {
  517.                 do {
  518.                     pG->s.x -= 256;
  519.                     pG->pos = (pG->pos + 1) & 16383;
  520.                     c = (vbuff2 + pG->pos);
  521.  
  522.                     if(*c) {
  523.                         if(*c & 4) {
  524.                             pG2 = *(v2g + pG->pos);
  525.                             svt = pG->v;
  526.                             pG->v = pG2->v;
  527.                             pG2->v = svt;
  528.                         } else {
  529.                             pG->v.x = -pG->v.x / 2;
  530.                             if(*c & 0xc0) {
  531.                                 *c -= 0x40;
  532.                                 if(!(*c & 0xc0)) {
  533.                                     *c = 0;
  534.                                 }
  535.                             }
  536.                             if(pG->color & 0xc0) {
  537.                                 pG->color -= 0x40;
  538.                             } else {
  539.                                 pG->color = 0;
  540.                                 f = 1;
  541.                             }
  542.                         }
  543.                         pG->pos = (pG->pos - 1) & 16383;
  544.                         break;
  545.                     }
  546.                 } while(pG->s.x >= 256);
  547.             } else {
  548.                 while(pG->s.x <= -256) {
  549.                     pG->s.x += 256;
  550.                     pG->pos = (pG->pos - 1) & 16383;
  551.                     c = (vbuff2 + pG->pos);
  552.  
  553.                     if(*c) {
  554.                         if(*c & 4) {
  555.                             pG2 = *(v2g + pG->pos);
  556.                             svt = pG->v;
  557.                             pG->v = pG2->v;
  558.                             pG2->v = svt;
  559.                         } else {
  560.                             pG->v.x = -pG->v.x / 2;
  561.                             if(*c & 0xc0) {
  562.                                 *c -= 0x40;
  563.                                 if(!(*c & 0xc0)) {
  564.                                     *c = 0;
  565.                                 }
  566.                             }
  567.                             if(pG->color & 0xc0) {
  568.                                 pG->color -= 0x40;
  569.                             } else {
  570.                                 pG->color = 0;
  571.                                 f = 1;
  572.                             }
  573.                         }
  574.                         pG->pos = (pG->pos + 1) & 16383;
  575.                         break;
  576.                     }
  577.                 }
  578.             }
  579.  
  580.             if(f) {
  581.                 *(vbuff2 + pG->pos) = pG->color;
  582.                 nGrain --;
  583.                 *(v2g + pG->pos) = NULL;
  584.                 pG = freeGrain(pG);
  585.             } else {
  586.                 *(vbuff2 + pG->pos) = pG->color;
  587.                 *(v2g + pG->pos) = pG;
  588.                 pG = pG->next;
  589.             }
  590.         }
  591.     }
  592.  
  593.     dispPos = upperLine;
  594.  
  595.     {
  596.         unsigned long *pL, *pL2, *pLe;
  597.         pL = (unsigned long *)(vbuff + 2 * 128);
  598.         pL2 = (unsigned long *)(vbuff2 + dispPos * 128);
  599.  
  600.         pLe = pL2 + 128 * 78 / 4;
  601.         if(pLe > (unsigned long *)(vbuff2 + 128 * 128)) {
  602.             pLe = (unsigned long *)(vbuff2 + 128 * 128);
  603.         }
  604.  
  605.         while(pL2 < pLe) {
  606.             *pL = *pL2 & 0x03030303;
  607.             pL ++;
  608.             pL2 ++;
  609.         }
  610.  
  611.         pL2 = (unsigned long *)(vbuff2);
  612.         while(pL < (unsigned long *)(vbuff + 128 * (78 + 2))) {
  613.             *pL = *pL2 & 0x03030303;
  614.             pL ++;
  615.             pL2 ++;
  616.         }
  617.     }
  618.  
  619.     {
  620.         unsigned char *pC;
  621.         pC = vbuff2 + mPos.x / 256 + ((mPos.y / 256 + dispPos) & 127) * 128;
  622.         if(*pC != 0 && (*pC & 4) == 0) {
  623.             gameover = *pC;
  624.         }
  625.     }
  626.  
  627.     {
  628.         static int gPhase = 0;
  629.         unsigned char *pC;
  630.         int i, x, y;
  631.         if(gameover == 0 && (gamePhase & 2)) {
  632.             x = mPos.x + sintable[(256 + mR) & 1023] * gPhase / 64;
  633.             y = mPos.y - sintable[mR] * gPhase / 64;
  634.             for(i = 0; i < 3; i ++) {
  635.                 if(y >= 78 * 256) {
  636.                     break;
  637.                 }
  638.                 *(vbuff + x / 256 + (y / 256 + 2) * 128) = 3;
  639.                 x += sintable[(256 + mR) & 1023] / 16;
  640.                 y -= sintable[mR] / 16;
  641.  
  642.                 if(y >= 78 * 256) {
  643.                     break;
  644.                 }
  645.                 *(vbuff + x / 256 + (y / 256 + 2) * 128) = 3;
  646.                 x += sintable[(256 + mR) & 1023] / 16;
  647.                 y -= sintable[mR] / 16;
  648.  
  649.                 if(y >= 78 * 256) {
  650.                     break;
  651.                 }
  652.                 *(vbuff + x / 256 + (y / 256 + 2) * 128) = 3;
  653.                 x += sintable[(256 + mR) & 1023] * 2 / 16;
  654.                 y -= sintable[mR] * 2 / 16;
  655.             }
  656.             gPhase = (gPhase + 1) & 15;
  657.         }
  658.  
  659.         pC = vbuff + mPos.x / 256 + (mPos.y / 256 + 2) * 128;
  660.         *(pC - 129) = 0x03;
  661.         *(pC - 128) = 0x03;
  662.         *(pC - 127) = 0x03;
  663.         *(pC - 1) = 0x03;
  664.         *pC = 0x00;
  665.         *(pC + 1) = 0x03;
  666.         *(pC + 127) = 0x03;
  667.         *(pC + 128) = 0x03;
  668.         *(pC + 129) = 0x03;
  669.     }
  670.  
  671.     if(gamePhase == 1) {
  672.         if(pad & (TRG_A | TRG_B)) {
  673.             gamePhase = 2;
  674.         }
  675.     } else if(gameover) {
  676.         if(pad & (TRG_A | TRG_B)) {
  677.             gamePhase = 0;
  678.         }
  679.     }
  680.  
  681.     if((gamePhase & 2) && time && gameover == 0) {
  682.         time --;
  683.         if((time % FRAMERATE) == 0) {
  684.             pceFontSetType(2 + 128);
  685.             pceFontSetPos(4 * 5, 82);
  686.             pceFontPrintf("%2d", (time + FRAMERATE - 1) / FRAMERATE);
  687.             pceFontSetType(0);
  688.         }
  689.         if(time == 0) {
  690.             gameover = 1;
  691.         }
  692.     }
  693.  
  694.     if(dispscore < score) {
  695.         dispscore ++;
  696.         if(dispscore < score) {
  697.             dispscore ++;
  698.         }
  699.         pceFontSetType(2 + 128);
  700.         pceFontSetPos(4 * 26, 82);
  701.         pceFontPrintf("%6d", dispscore % 1000000);
  702.         pceFontSetType(0);
  703.     }
  704.  
  705.     if(gamePhase == 3 && gameover != 0) {
  706.         pceFontSetType(2 + 128);
  707.         pceFontSetPos(64 - 11 * 4 / 2, 33);
  708.         pceFontPrintf(" game over ");
  709.         pceFontSetType(0);
  710.     }
  711.  
  712.     pceLCDTrans();
  713. }
  714.  
  715.  
  716. void pceAppExit( void )
  717. {
  718.     pceCPUSetSpeed(CPU_SPEED_NORMAL);
  719. }
  720.  
  721. void spout(int t, int x, int y)
  722. {
  723.     if(*(vbuff2 + t) == 0) {
  724.         if(nGrain < MAX_GRAIN) {
  725.             GRAIN *pG = allocGrain();
  726.  
  727.             pG->v.x = x;
  728.             pG->v.y = y;
  729.             pG->s.x = 0;
  730.             pG->s.y = 0;
  731.  
  732.             pG->color = (2 + (rand() & 1)) + 4 + 64 * 3;
  733.  
  734.             pG->pos = t;
  735.             *(vbuff2 + t) = pG->color;
  736.             v2g[t] = pG;
  737.             nGrain ++;
  738.         }
  739.     }
  740. }
  741.  
  742. void sweep(unsigned char c1, unsigned char c2)
  743. {
  744.     int i;
  745.  
  746.     unsigned char *pC = vbuff2 + 4 + 128 * ((upperLine + 77) & 127);
  747.     for(i = 0; i < 120; i ++) {
  748.         if(*pC & 4) {
  749.             GRAIN **ppG;
  750.             ppG = v2g + (int)(pC - vbuff2);
  751.             freeGrain(*ppG);
  752.             *ppG = NULL;
  753.             nGrain --;
  754.         }
  755.         *pC++ = c1;
  756.     }
  757.  
  758.     pC += 8;
  759.     if(pC >= vbuff2 + 128 * 128) {
  760.         pC -= 128 * 128;
  761.     }
  762.  
  763.     for(i = 0; i < 120; i ++) {
  764.         *pC++ = c2;
  765.     }
  766. }
  767.  
  768. void initGrain(void)
  769. {
  770.     int i;
  771.  
  772.     for(i = 0; i < MAX_GRAIN - 1; i ++) {
  773.         grain[i].next = &grain[i + 1];
  774.     }
  775.     grain[i].next = NULL;
  776.  
  777.     grainFreeLink = grain;
  778.     grainUseLink = NULL;
  779.  
  780.     return;
  781. }
  782.  
  783. GRAIN *allocGrain(void)
  784. {
  785.     GRAIN *current = grainFreeLink;
  786.  
  787.     if(current) {
  788.         grainFreeLink = current->next;
  789.  
  790.         current->next = grainUseLink;
  791.         current->prev = NULL;
  792.         if(current->next) {
  793.             current->next->prev = current;
  794.         }
  795.         grainUseLink = current;
  796.     }
  797.  
  798.     return current;
  799. }
  800.  
  801. GRAIN *freeGrain(GRAIN *current)
  802. {
  803.     GRAIN *next = current->next;
  804.  
  805.     if(next) {
  806.         next->prev = current->prev;
  807.     }
  808.     if(current->prev) {
  809.         current->prev->next = next;
  810.     } else {
  811.         grainUseLink = next;
  812.     }
  813.  
  814.     current->next = grainFreeLink;
  815.     grainFreeLink = current;
  816.  
  817.     return next;
  818. }
  819.  
  820.