?login_element?

Subversion Repositories NedoOS

Rev

Rev 945 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include <evo.h>
  2. #include "resources.h"
  3.  
  4.  
  5. #define MAP_WDT 38
  6. #define MAP_HGT 22
  7.  
  8. static u8 map[MAP_WDT*MAP_HGT];
  9. static u8 updmap[MAP_WDT*MAP_HGT];
  10. static u8 fillmap[MAP_WDT*MAP_HGT];
  11.  
  12.  
  13.  
  14. struct {
  15.         u8 x,y;
  16.         u8 prevx,prevy;
  17.         u8 sx,sy;
  18.         u8 dir;
  19.         u8 prevdir;
  20.         u8 off;
  21.         u16 draw;
  22.         u8 fill;
  23.         u8 startx,starty;
  24. } player;
  25.  
  26.  
  27.  
  28. #define OBJ_MAX 10
  29.  
  30. static struct objStruct {
  31.         i16 x,y;
  32.         i16 dx,dy;
  33.         u8 hit;
  34. } objList[OBJ_MAX];
  35.  
  36. static u8 objCount;
  37.  
  38. static u16 gameScore;
  39. static u8 gameDone;
  40. static u8 gameLevel;
  41. static i8 gamePower;
  42. static u8 gameClearTarget;
  43. static u16 gameAreaClear;
  44. static u8 gameStartDelay;
  45. static u8 gameRestartDelay;
  46. static u8 gameHitCnt;
  47. static u8 gameImageID;
  48.  
  49. static u8 explodeX;
  50. static u8 explodeY;
  51. static u8 explodeCnt;
  52.  
  53. static u8 keys[40];
  54.  
  55. #define FP      6
  56.  
  57. #define MARK_SIDE(off,side) if(!map[(off)]) fillmap[(off)]=(side)
  58. #define TEST_MAP(x,y) (map[((y)>>3)*MAP_WDT+((x)>>3)])
  59.  
  60. #define LEVELS_ALL      10
  61.  
  62. //юяшёрэшх єЁютэ 
  63. //ърЁЄшэър, ярышЄЁр, ьєч√ър, ёъюы№ъю яЁюЎхэЄют эрфю эрсЁрЄ№
  64. //юс·хъЄ√ яю 4 срщЄр - ъююЁфшэрЄ√ т чэръюьхёЄрї, эрўры№э√х фхы№Є√ т яшъёхы ї
  65. //255 т ъюэЎх ёяшёър юс·хъЄют
  66.  
  67. const u8 levelData1[]={
  68. IMG_PIC1,PAL_PIC1,MUS_LOOP1,85,
  69.  9,10,(u8)-16,16,
  70. 28,10, 16,16,
  71. 255
  72. };
  73.  
  74. const u8 levelData2[]={
  75. IMG_PIC2,PAL_PIC2,MUS_LOOP1,85,
  76.  9, 8,(u8)-16,16,
  77. 19,12, 16,16,
  78. 28, 8,(u8)-16,16,
  79. 255
  80. };
  81.  
  82. const u8 levelData3[]={
  83. IMG_PIC3,PAL_PIC3,MUS_LOOP1,85,
  84.  9, 6, 16, 16,
  85. 28, 6,(u8)-16, 16,
  86.  9,15, 16,(u8)-16,
  87. 28,15,(u8)-16,(u8)-16,
  88. 255
  89. };
  90.  
  91. const u8 levelData4[]={
  92. IMG_PIC4,PAL_PIC4,MUS_LOOP1,80,
  93.  9, 6, 16, 16,
  94. 28, 6,(u8)-20, 20,
  95.  9,15, 20,(u8)-20,
  96. 28,15,(u8)-16,(u8)-16,
  97. 255
  98. };
  99.  
  100. const u8 levelData5[]={
  101. IMG_PIC5,PAL_PIC5,MUS_LOOP1,80,
  102.  9, 6, 16, 16,
  103. 28, 6,(u8)-20, 20,
  104. 19,10, 18,(u8)-18,
  105.  9,15, 20,(u8)-20,
  106. 28,15,(u8)-16,(u8)-16,
  107. 255
  108. };
  109.  
  110. const u8 levelData6[]={
  111. IMG_PIC6,PAL_PIC6,MUS_LOOP1,80,
  112.  7,10,(u8)-20,(u8)-20,
  113. 14, 6,(u8)-18,(u8)-18,
  114. 14,15,(u8)-18, 18,
  115. 24, 6, 18,(u8)-18,
  116. 24,15, 18, 18,
  117. 31,10, 20, 20,
  118. 255
  119. };
  120.  
  121. const u8 levelData7[]={
  122. IMG_PIC7,PAL_PIC7,MUS_LOOP1,75,
  123.  7, 6,(u8)-18,(u8)-18,
  124.  7,15,(u8)-18, 18,
  125. 14,10, 10,(u8)-10,
  126. 19,10, 20,(u8)-20,
  127. 24,10,(u8)-10, 10,
  128. 31, 6, 18,(u8)-18,
  129. 31,15, 18, 18,
  130. 255
  131. };
  132.  
  133. const u8 levelData8[]={
  134. IMG_PIC8,PAL_PIC8,MUS_LOOP1,75,
  135. 10, 4,(u8)-16, 16,
  136. 28, 4,(u8)-18, 18,
  137. 16, 8, 20, 20,
  138. 22, 8,(u8)-20, 20,
  139. 16,14, 20,(u8)-20,
  140. 22,14,(u8)-20,(u8)-20,
  141. 10,18, 18, 18,
  142. 28,18, 16, 16,
  143. 255
  144. };
  145.  
  146. const u8 levelData9[]={
  147. IMG_PIC9,PAL_PIC9,MUS_LOOP1,70,
  148. 13, 4, 18, 18,
  149. 10, 7, 18, 18,
  150.  7,10, 18, 18,
  151.  4,13, 18, 18,
  152. 20,11, 26, 26,
  153. 25,18,(u8)-18,(u8)-18,
  154. 28,15,(u8)-18,(u8)-18,
  155. 31,12,(u8)-18,(u8)-18,
  156. 34, 9,(u8)-18,(u8)-18,
  157. 255
  158. };
  159.  
  160. const u8 levelData10[]={
  161. IMG_PIC10,PAL_PIC10,MUS_LOOP1,70,
  162. 10,10,(u8)-22,(u8)-22,
  163. 12,10,(u8)-21, 21,
  164. 14,10, 20,(u8)-20,
  165. 16,10, 19, 19,
  166. 18,10,(u8)-18,(u8)-18,
  167. 20,10,(u8)-19, 19,
  168. 22,10, 20,(u8)-20,
  169. 24,10, 21, 21,
  170. 26,10,(u8)-22,(u8)-22,
  171. 255
  172. };
  173.  
  174. const u8* const levelsData[LEVELS_ALL]={
  175. levelData1,
  176. levelData2,
  177. levelData3,
  178. levelData4,
  179. levelData5,
  180. levelData6,
  181. levelData7,
  182. levelData8,
  183. levelData9,
  184. levelData10
  185. };
  186.  
  187.  
  188.  
  189. void put_char(u8 x,u8 y,u8 n)
  190. {
  191.         n=n-32;
  192.         n=(n&15)+((n>>4)<<5);
  193.  
  194.         select_image(IMG_FONT816);
  195.         draw_tile(x,y  ,n   );
  196.         draw_tile(x,y+1,n+16);
  197. }
  198.  
  199.  
  200.  
  201. void put_str(u8 x,u8 y,u8* str)
  202. {
  203.         static u8 i;
  204.  
  205.         while(1)
  206.         {
  207.                 i=*str++;
  208.                 if(!i) return;
  209.                 put_char(x,y,i);
  210.                 ++x;
  211.         }
  212. }
  213.  
  214.  
  215.  
  216. void put_num(u8 x,u8 y,u16 num,u8 figs)
  217. {
  218.         x+=figs;
  219.  
  220.         while(figs)
  221.         {
  222.                 put_char(x,y,'0'+(num%10));
  223.                 num/=10;
  224.                 --x;
  225.                 --figs;
  226.         }
  227. }
  228.  
  229.  
  230.  
  231. void put_char_buf(u16* buf,u8 wdt,u8 n)
  232. {
  233.         n=n-32;
  234.         n=(n&15)+((n>>4)<<5);
  235.  
  236.         buf[0  ]=n;
  237.         buf[wdt]=n+16;
  238. }
  239.  
  240.  
  241.  
  242. void put_str_buf(u16* buf,u8 wdt,u8* str)
  243. {
  244.         static u8 i;
  245.  
  246.         while(1)
  247.         {
  248.                 i=*str++;
  249.                 if(!i) return;
  250.                 put_char_buf(buf,wdt,i);
  251.                 *buf++;
  252.         }
  253. }
  254.  
  255.  
  256.  
  257. void put_num_buf(u16* buf,u8 wdt,u16 num,u8 figs)
  258. {
  259.         while(figs)
  260.         {
  261.                 put_char_buf(buf+figs,wdt,'0'+(num%10));
  262.                 num/=10;
  263.                 --figs;
  264.         }
  265. }
  266.  
  267.  
  268.  
  269. void put_large_str_buf(u16* buf,u8 wdt,const u8* str)
  270. {
  271.         static u8 i;
  272.         static u16 off,soff,doff;
  273.  
  274.         off=0;
  275.  
  276.         while(1)
  277.         {
  278.                 i=*str++;
  279.  
  280.                 if(!i) break;
  281.  
  282.                 if(i<'0'||i>'_')
  283.                 {
  284.                         off+=2;
  285.                         continue;
  286.                 }
  287.  
  288.                 i-='0';
  289.                 soff=((i&15)*3)+((i>>4)*192);
  290.                 doff=off;
  291.  
  292.                 for(i=0;i<4;++i)
  293.                 {
  294.                         buf[doff+0]=soff+0;
  295.                         buf[doff+1]=soff+1;
  296.                         buf[doff+2]=soff+2;
  297.                         soff+=48;
  298.                         doff+=wdt;
  299.                 }
  300.  
  301.                 off+=3;
  302.         }
  303. }
  304.  
  305.  
  306.  
  307. void put_large_str(const u8* str)
  308. {
  309.         static u8 i,j;
  310.         static u16 off;
  311.         static u16 buf[26*4];
  312.  
  313.         memset(buf,0xff,sizeof(buf));
  314.         put_large_str_buf(buf,26,str);
  315.  
  316.         off=0;
  317.  
  318.         for(i=0;i<4;++i)
  319.         {
  320.                 for(j=0;j<26;++j)
  321.                 {
  322.                         if(buf[off]!=0xffff)
  323.                         {
  324.                                 select_image(IMG_TEXTBACK1);
  325.                                 draw_tile(7+j,9+i,(i<<2)+(j&3));
  326.                                 select_image(IMG_FONT2432);
  327.                                 draw_tile_key(7+j,9+i,buf[off]);
  328.                         }
  329.  
  330.                         ++off;
  331.                 }
  332.         }
  333. }
  334.  
  335.  
  336.  
  337. void fade_to_black(void)
  338. {
  339.         static u8 i,j;
  340.  
  341.         for(i=1;i<3;++i)
  342.         {
  343.                 pal_bright(BRIGHT_MID-i);
  344.                 delay(5);
  345.         }
  346. }
  347.  
  348.  
  349.  
  350. void player_init(u8 x,u8 y)
  351. {
  352.         player.x=x;
  353.         player.y=y;
  354.         player.prevx=x;
  355.         player.prevy=y;
  356.         player.startx=x;
  357.         player.starty=y;
  358.         player.dir=0;
  359.         player.prevdir=0;
  360.         player.off=0;
  361.         player.draw=0;
  362.         player.fill=0;
  363.  
  364.         gameRestartDelay=100;
  365.  
  366.         memset(fillmap,0,sizeof(fillmap));
  367. }
  368.  
  369.  
  370.  
  371. void draw_map_part(u8 x,u8 y,u8 w,u8 h,u8 light)
  372. {
  373.         static u8 i,j,mask;
  374.         static u16 off,soff1,soff2;
  375.  
  376.         soff1=y*MAP_WDT+x;
  377.         soff2=soff1;
  378.  
  379.         select_image(gameImageID);
  380.  
  381.         ++x;
  382.         y+=2;
  383.         w+=x;
  384.         h+=y;
  385.  
  386.         for(i=y;i<h;++i)
  387.         {
  388.                 off=soff1;
  389.                 soff1+=MAP_WDT;
  390.  
  391.                 for(j=x;j<w;++j)
  392.                 {
  393.                         if(updmap[off])
  394.                         {
  395.                                 if(map[off]) draw_tile(j,i,off);
  396.                         }
  397.  
  398.                         ++off;
  399.                 }
  400.         }
  401.  
  402.         select_image(IMG_BGMASK);
  403.  
  404.         for(i=y;i<h;++i)
  405.         {
  406.                 off=soff2;
  407.                 soff2+=MAP_WDT;
  408.  
  409.                 for(j=x;j<w;++j)
  410.                 {
  411.                         if(updmap[off])
  412.                         {
  413.                                 updmap[off]=0;
  414.  
  415.                                 if(!map[off])
  416.                                 {
  417.                                         draw_tile(j,i,257);
  418.                                 }
  419.                                 else
  420.                                 {
  421.                                         mask=0;
  422.  
  423.                                         if(i>2)
  424.                                         {
  425.                                                 if(!map[off-MAP_WDT  ]) mask|=1;
  426.                                                 if(!map[off-MAP_WDT-1]) mask|=16;
  427.                                                 if(!map[off-MAP_WDT+1]) mask|=32;
  428.                                         }
  429.                                         if(i<1+MAP_HGT-1)
  430.                                         {
  431.                                                 if(!map[off+MAP_WDT  ]) mask|=2;
  432.                                                 if(!map[off+MAP_WDT-1]) mask|=64;
  433.                                                 if(!map[off+MAP_WDT+1]) mask|=128;
  434.                                         }
  435.                                         if(j>1)
  436.                                         {
  437.                                                 if(!map[off-1]) mask|=4;
  438.                                         }
  439.                                         if(j<MAP_WDT-1)
  440.                                         {
  441.                                                 if(!map[off+1]) mask|=8;
  442.                                         }
  443.  
  444.                                         if(light) draw_tile_key(j,i,256);
  445.                                         draw_tile_key(j,i,mask);
  446.                                 }
  447.                         }
  448.  
  449.                         ++off;
  450.                 }
  451.         }
  452. }
  453.  
  454.  
  455.  
  456. void draw_map(void)
  457. {
  458.         draw_map_part(0,0,MAP_WDT,MAP_HGT,FALSE);
  459. }
  460.  
  461.  
  462.  
  463. void draw_map_tile(u8 x,u8 y,u8 light)
  464. {
  465.         static u16 off;
  466.  
  467.         off=y*MAP_WDT+x;
  468.         updmap[off]=1;
  469.  
  470.         draw_map_part(x,y,1,1,light);
  471. }
  472.  
  473.  
  474.  
  475. void update_stats_score(void)
  476. {
  477.         put_num(6,0,gameScore,5);
  478. }
  479.  
  480.  
  481.  
  482. void update_stats_done(void)
  483. {
  484.         static u32 done;
  485.  
  486.         done=(u32)gameAreaClear*100/((MAP_HGT-2)*(MAP_WDT-2));
  487.         gameDone=(u8)done;
  488.  
  489.         put_num(26,0,gameDone,3);
  490. }
  491.  
  492.  
  493.  
  494. void update_stats_power(void)
  495. {
  496.         put_num(35,0,gamePower,3);
  497. }
  498.  
  499.  
  500.  
  501. void update_stats_all(void)
  502. {
  503.         put_str(1,0,"SCORE:      LEVEL:   DONE:   % POW:");
  504.         update_stats_score();
  505.         put_num(18,0,gameLevel+1,2);
  506.         update_stats_done();
  507.         update_stats_power();
  508. }
  509.  
  510.  
  511.  
  512. void player_screen_coords(void)
  513. {
  514.         u8 x,y;
  515.  
  516.         x=4-2+(player.x<<2);
  517.         y=(player.y<<3)+8+4;
  518.  
  519.         switch(player.dir)
  520.         {
  521.         case JOY_LEFT:  x+=(player.off>>1); break;
  522.         case JOY_RIGHT: x-=(player.off>>1); break;
  523.         case JOY_UP:    y+= player.off;     break;
  524.         case JOY_DOWN:  y-= player.off;     break;
  525.         }
  526.  
  527.         player.sx=x;
  528.         player.sy=y;
  529. }
  530.  
  531.  
  532.  
  533. void player_hit(i8 objid)
  534. {
  535.         static u16 off;
  536.  
  537.         if(objid>=0) objList[objid].hit=25;
  538.  
  539.         player_screen_coords();
  540.  
  541.         explodeX=player.sx;
  542.         explodeY=player.sy;
  543.         explodeCnt=8<<2;
  544.  
  545.         gameHitCnt=10;
  546.  
  547.         for(off=MAP_WDT+1;off<MAP_WDT*MAP_HGT-MAP_WDT;++off)
  548.         {
  549.                 if(map[off]==2)
  550.                 {
  551.                         map[off]=0;
  552.                         updmap[off]=1;
  553.                 }
  554.         }
  555.  
  556.         draw_map();
  557.  
  558.         gamePower-=10;
  559.  
  560.         if(gamePower<=0)
  561.         {
  562.                 gameDone=255;
  563.                 gameStartDelay=100;
  564.                 gameRestartDelay=100;
  565.                 gamePower=0;
  566.         }
  567.         else
  568.         {
  569.                 player_init(player.startx,player.starty);
  570.         }
  571.  
  572.         update_stats_power();
  573.         sfx_play(SFX_EXPLODE,8);
  574. }
  575.  
  576.  
  577.  
  578. u8 player_set_move(u8 dir)
  579. {
  580.         static u16 off;
  581.         static u8 x,y;
  582.  
  583.         if(!player.draw)
  584.         {
  585.                 player.startx=player.x;
  586.                 player.starty=player.y;
  587.         }
  588.         else
  589.         {
  590.                 if(player.prevdir==JOY_LEFT &&dir==JOY_RIGHT) return 0;
  591.                 if(player.prevdir==JOY_RIGHT&&dir==JOY_LEFT ) return 0;
  592.                 if(player.prevdir==JOY_UP   &&dir==JOY_DOWN ) return 0;
  593.                 if(player.prevdir==JOY_DOWN &&dir==JOY_UP   ) return 0;
  594.         }
  595.  
  596.         switch(dir)
  597.         {
  598.         case JOY_LEFT:  --player.x; break;
  599.         case JOY_RIGHT: ++player.x; break;
  600.         case JOY_UP:    --player.y; break;
  601.         case JOY_DOWN:  ++player.y; break;
  602.         }
  603.  
  604.         off=player.y*MAP_WDT+player.x;
  605.  
  606.         if(!map[off])
  607.         {
  608.                 ++player.draw;
  609.                 sfx_play(SFX_CUT,0);
  610.         }
  611.  
  612.         if(player.draw)
  613.         {
  614.                 if(map[off]==1)//чрыштър яю юъюэўрэшш фтшцхэш 
  615.                 {
  616.                         player.draw=0;
  617.                         player.fill=TRUE;
  618.                 }
  619.                 else
  620.                 {
  621.                         if(map[off]==2)//ёрьюышътшфрЎш 
  622.                         {
  623.                                 player_hit(-1);
  624.                                 return 0;
  625.                         }
  626.                         else
  627.                         {
  628.                                 switch(dir)//яюьхўрхь ёЄюЁюэ√ ышэшш фы  чрыштъш
  629.                                 {
  630.                                 case JOY_LEFT:
  631.                                         MARK_SIDE(off-MAP_WDT  ,2);
  632.                                         MARK_SIDE(off-MAP_WDT+1,2);
  633.                                         MARK_SIDE(off+MAP_WDT  ,1);
  634.                                         MARK_SIDE(off+MAP_WDT+1,1);
  635.                                         break;
  636.  
  637.                                 case JOY_RIGHT:
  638.                                         MARK_SIDE(off-MAP_WDT  ,1);
  639.                                         MARK_SIDE(off-MAP_WDT-1,1);
  640.                                         MARK_SIDE(off+MAP_WDT  ,2);
  641.                                         MARK_SIDE(off+MAP_WDT-1,2);
  642.                                         break;
  643.  
  644.                                 case JOY_UP:
  645.                                         MARK_SIDE(off-1        ,1);
  646.                                         MARK_SIDE(off-1+MAP_WDT,1);
  647.                                         MARK_SIDE(off+1        ,2);
  648.                                         MARK_SIDE(off+1+MAP_WDT,2);
  649.                                         break;
  650.  
  651.                                 case JOY_DOWN:
  652.                                         MARK_SIDE(off-1        ,2);
  653.                                         MARK_SIDE(off-1-MAP_WDT,2);
  654.                                         MARK_SIDE(off+1        ,1);
  655.                                         MARK_SIDE(off+1-MAP_WDT,1);
  656.                                         break;
  657.                                 }
  658.  
  659.                                 map    [off]=2;//Ёшёєхьр  ышэш 
  660.                                 fillmap[off]=0;//эх яЁютхЁ Є№ ¤Єш ъююЁфшэрЄ√ яЁш чрыштъх
  661.                                 updmap [off]=1;//юсэютшЄ№ Єрщы
  662.                         }
  663.                 }
  664.         }
  665.  
  666.         player.dir=dir;
  667.         player.off=8;
  668.  
  669.         return 0;
  670. }
  671.  
  672.  
  673.  
  674. u16 area_fill(u16 off,u8 area)
  675. {
  676.         static u16 icnt,tcnt,len,max;
  677.         static u16 front1[128],front2[128];
  678.         static u16 *src,*dst;
  679.  
  680.         map[off]=area;
  681.         front1[0]=off;
  682.         src=front1;
  683.         dst=front2;
  684.         tcnt=0;
  685.         len=1;
  686.  
  687.         while(1)
  688.         {
  689.                 icnt=0;
  690.  
  691.                 while(len)
  692.                 {
  693.                         off=*src++-1;
  694.                         --len;
  695.  
  696.                         if(!map[off]) { map[off]=area; dst[icnt++]=off; }
  697.                         off+=2;
  698.                         if(!map[off]) { map[off]=area; dst[icnt++]=off; }
  699.                         off-=MAP_WDT+1;
  700.                         if(!map[off]) { map[off]=area; dst[icnt++]=off; }
  701.                         off+=MAP_WDT*2;
  702.                         if(!map[off]) { map[off]=area; dst[icnt++]=off; }
  703.                 }
  704.  
  705.                 if(!icnt) break;
  706.  
  707.                 len=icnt;
  708.                 tcnt+=icnt;
  709.  
  710.                 if(dst==front2)
  711.                 {
  712.                         src=front2;
  713.                         dst=front1;
  714.                 }
  715.                 else
  716.                 {
  717.                         src=front1;
  718.                         dst=front2;
  719.                 }
  720.         }
  721.  
  722.         return tcnt;
  723. }
  724.  
  725.  
  726.  
  727. u16 map_fill(void)
  728. {
  729.         static u16 off,size,x,y,area_size[2];
  730.         static u8 i,side,t1,t2,t3,t4;
  731.  
  732.         //чрыштрхь юсырёЄш фы  ърцфющ шч ёЄюЁюэ ышэшш ш ёўшЄрхь шї яыю∙рф№
  733.  
  734.         area_size[0]=0;
  735.         area_size[1]=0;
  736.  
  737.         for(off=MAP_WDT+1;off<MAP_WDT*MAP_HGT-MAP_WDT;++off)
  738.         {
  739.                 if(fillmap[off])
  740.                 {
  741.                         side=fillmap[off];
  742.                         fillmap[off]=0;
  743.                         area_size[side-1]+=area_fill(off,side+2);
  744.                 }
  745.         }
  746.  
  747.         //яЁютхЁ хь яюярфрэшх юс·хъЄют т юсырёЄш ш ёсЁрё√трхь ЁрчьхЁ хёыш яюярыш
  748.  
  749.         for(i=0;i<objCount;++i)
  750.         {
  751.                 x=objList[i].x>>FP;
  752.                 y=objList[i].y>>FP;
  753.  
  754.                 t1=TEST_MAP(x+4,y-4);
  755.                 t2=TEST_MAP(x-4,y-4);
  756.                 t3=TEST_MAP(x+4,y+4);
  757.                 t4=TEST_MAP(x-4,y+4);
  758.  
  759.                 if(t1==3||t2==3||t3==3||t4==3) area_size[1]=0;
  760.                 if(t1==4||t2==4||t3==4||t4==4) area_size[0]=0;
  761.         }
  762.  
  763.         //т√сшЁрхь эршьхэ№°є■ юсырёЄ№
  764.         //эю хёыш юсх юсырёЄш чрэ Є√, Єю ёсЁрё√трхь чрыштъє
  765.  
  766.         side=area_size[0]<area_size[1]?3:4;
  767.         if(!area_size[0]&&!area_size[1]) side=5;
  768.  
  769.         //чрьхэ хь чрышЄє■ юсырёЄ№ яєёЄюЄющ хёыш эх чрышЄр
  770.         //чрюфэю ёўшЄрхь ЁрчьхЁ ышэшш
  771.  
  772.         size=0;
  773.  
  774.         for(off=MAP_WDT+1;off<MAP_WDT*MAP_HGT-MAP_WDT;++off)
  775.         {
  776.                 i=map[off];
  777.  
  778.                 if(i<2) continue;
  779.  
  780.                 if(i==2||i==side)
  781.                 {
  782.                         ++size;
  783.                         updmap[off]=1;
  784.                         map[off]=1;
  785.                 }
  786.                 else
  787.                 {
  788.                         map[off]=0;
  789.                 }
  790.         }
  791.  
  792.         if(size) sfx_play(SFX_SCORE,0);
  793.  
  794.         return size;
  795. }
  796.  
  797.  
  798.  
  799. void level_screen(void)
  800. {
  801.         static u8 str[]="LEVEL   ";
  802.         static u16 buf[40*7];
  803.         static u8 i,j,x,y,spr;
  804.         static i16 xoff,off;
  805.         const i16 delay=240;
  806.  
  807.         pal_bright(0);
  808.         pal_select(PAL_TEXTBACK1);
  809.  
  810.         clear_screen(0);
  811.         swap_screen();
  812.  
  813.         memset(buf,0xff,sizeof(buf));
  814.  
  815.         i=gameLevel+1;
  816.  
  817.         if(i>=10)
  818.         {
  819.                 str[6]='0'+i/10;
  820.                 str[7]='0'+i%10;
  821.                 off=9;
  822.         }
  823.         else
  824.         {
  825.                 str[6]='0'+i%10;
  826.                 str[7]=' ';
  827.                 off=11;
  828.         }
  829.  
  830.         put_large_str_buf(buf+off,40,str);
  831.  
  832.         put_str_buf(buf+5*40+15,40,"TARGET    %");
  833.         put_num_buf(buf+5*40+21,40,gameClearTarget,3);
  834.  
  835.         pal_bright(BRIGHT_MID);
  836.  
  837.         xoff=0;
  838.  
  839.         sprites_start();
  840.  
  841.         music_play(MUS_LEVEL);
  842.  
  843.         while(xoff<380)
  844.         {
  845.                 off=xoff>>2;
  846.  
  847.                 if(!(xoff&3)&&off<40)
  848.                 {
  849.                         x=off;
  850.                         y=10;
  851.  
  852.                         for(i=0;i<7;++i)
  853.                         {
  854.                                 if(i!=4&&buf[off]!=0xffff)
  855.                                 {
  856.                                         select_image(IMG_TEXTBACK1);
  857.                                         draw_tile(x,y,(i<<2)+(off&3));
  858.                                         select_image(i<5?IMG_FONT2432:IMG_FONT816);
  859.                                         draw_tile_key(x,y,buf[off]);
  860.                                 }
  861.  
  862.                                 off+=40;
  863.                                 ++y;
  864.                         }
  865.                 }
  866.  
  867.                 off=(xoff-delay-28)>>2;
  868.  
  869.                 if(!(xoff&3)&&off>=0&&off<40)
  870.                 {
  871.                         y=10;
  872.  
  873.                         for(i=0;i<7;++i)
  874.                         {
  875.                                 if(i!=4) draw_tile(off,y,47);
  876.                                 ++y;
  877.                         }
  878.                 }
  879.  
  880.                 y=10*8;
  881.                 spr=0;
  882.  
  883.                 for(i=0;i<3;++i)
  884.                 {
  885.                         off=xoff-28;
  886.  
  887.                         for(j=0;j<4;++j)
  888.                         {
  889.                                 if(off>=0&&off<160-8)
  890.                                 {
  891.                                         set_sprite(spr,off,y,SPR_TITLEMASK+8+j);
  892.                                         ++spr;
  893.                                 }
  894.  
  895.                                 if((off-delay)>=0&&(off-delay)<160-8)
  896.                                 {
  897.                                         set_sprite(spr,off-delay,y,SPR_TITLEMASK+12+j);
  898.                                         ++spr;
  899.                                 }
  900.  
  901.                                 off+=8;
  902.                         }
  903.  
  904.                         y+=i<1?16:24;
  905.                 }
  906.  
  907.                 xoff+=2;
  908.  
  909.                 swap_screen();
  910.         }
  911.  
  912.         music_stop();
  913.         sprites_stop();
  914. }
  915.  
  916.  
  917.  
  918. u8 game_loop(void)
  919. {
  920.         static u8 i,j,pp,spr,fill,frame,done,bright,t1,t2,t3,t4,pause;
  921.         static u16 x,y,off,score;
  922.         static i16 dx,dy;
  923.         static u8* levelData;
  924.  
  925.         levelData=(u8*)levelsData[gameLevel];
  926.         gameClearTarget=levelData[3];
  927.         gameImageID=levelData[0];
  928.  
  929.         level_screen();
  930.  
  931.         pal_bright(0);
  932.         pal_select(levelData[1]);
  933.  
  934.         memset(map,0,sizeof(map));
  935.  
  936.         for(i=0;i<MAP_WDT;++i)
  937.         {
  938.                 map[i]=1;
  939.                 map[i+(MAP_HGT-1)*MAP_WDT]=1;
  940.         }
  941.  
  942.         off=MAP_WDT;
  943.  
  944.         for(i=0;i<MAP_HGT-2;++i)
  945.         {
  946.                 map[off]=1;
  947.                 map[off+MAP_WDT-1]=1;
  948.                 off+=MAP_WDT;
  949.         }
  950.  
  951.         memcpy(updmap,map,sizeof(updmap));
  952.  
  953.         player_init(MAP_WDT>>1,0);
  954.  
  955.         gameDone=0;
  956.         gameAreaClear=0;
  957.         gameHitCnt=0;
  958.         gameStartDelay=100;
  959.  
  960.         objCount=0;
  961.         pp=4;
  962.  
  963.         while(objCount<OBJ_MAX)
  964.         {
  965.                 if(levelData[pp]==255) break;
  966.  
  967.                 objList[objCount].x=levelData[pp+0]<<(FP+3);
  968.                 objList[objCount].y=levelData[pp+1]<<(FP+3);
  969.                 objList[objCount].dx=((i8)levelData[pp+2])<<(FP-4);
  970.                 objList[objCount].dy=((i8)levelData[pp+3])<<(FP-4);
  971.                 objList[objCount].hit=0;
  972.  
  973.                 ++objCount;
  974.                 pp+=4;
  975.         }
  976.  
  977.         clear_screen(0);
  978.         draw_map();
  979.         update_stats_all();
  980.         swap_screen();
  981.  
  982.         fill=FALSE;
  983.         bright=0;
  984.         frame=0;
  985.         pause=FALSE;
  986.         explodeCnt=0;
  987.  
  988.         sprites_start();
  989.  
  990.         music_play(levelData[2]);
  991.  
  992.         while(1)
  993.         {
  994.                 if(gameHitCnt)
  995.                 {
  996.                         pal_bright(gameHitCnt&2?BRIGHT_MID:BRIGHT_MAX);
  997.                 }
  998.                 else
  999.                 {
  1000.                         pal_bright(bright);
  1001.  
  1002.                         if(gameStartDelay)
  1003.                         {
  1004.                                 if(!(frame&3)) if(bright<BRIGHT_MID) ++bright;
  1005.                         }
  1006.                 }
  1007.  
  1008.                 ++frame;
  1009.  
  1010.                 keyboard(keys);
  1011.  
  1012.                 if(!gameStartDelay&&!gameRestartDelay&&(keys[KEY_H]&KEY_PRESS))
  1013.                 {
  1014.                         pause^=TRUE;
  1015.                         bright=pause?2:3;
  1016.                 }
  1017.  
  1018.                 if(pause) continue;
  1019.  
  1020.                 if(!gameStartDelay&&!gameRestartDelay&&gameDone<gameClearTarget)
  1021.                 {
  1022.                         i=joystick();
  1023.  
  1024.                         if(keys[KEY_Q]) i|=JOY_UP;
  1025.                         if(keys[KEY_A]) i|=JOY_DOWN;
  1026.                         if(keys[KEY_O]) i|=JOY_LEFT;
  1027.                         if(keys[KEY_P]) i|=JOY_RIGHT;
  1028.  
  1029.                         if(!player.off)
  1030.                         {
  1031.                                 if(i&JOY_LEFT &&player.x>0        ) i=player_set_move(JOY_LEFT);
  1032.                                 if(i&JOY_RIGHT&&player.x<MAP_WDT-1) i=player_set_move(JOY_RIGHT);
  1033.                                 if(i&JOY_UP   &&player.y>0        ) i=player_set_move(JOY_UP);
  1034.                                 if(i&JOY_DOWN &&player.y<MAP_HGT-1) i=player_set_move(JOY_DOWN);
  1035.  
  1036.                                 if(!i&&!player.off&&player.draw) player_set_move(player.prevdir);
  1037.                         }
  1038.                         else
  1039.                         {
  1040.                                 player.off-=2;
  1041.  
  1042.                                 if(!player.off)
  1043.                                 {
  1044.                                         if(player.fill)
  1045.                                         {
  1046.                                                 player.fill=FALSE;
  1047.                                                 player.draw=0;
  1048.                                                 fill=TRUE;
  1049.                                         }
  1050.  
  1051.                                         if(player.draw>1) draw_map_tile(player.prevx,player.prevy,TRUE);
  1052.                                         if(player.draw>0) draw_map_tile(player.x,player.y,TRUE);
  1053.  
  1054.                                         player.prevx=player.x;
  1055.                                         player.prevy=player.y;
  1056.                                         player.prevdir=player.dir;
  1057.                                         player.dir=0;
  1058.                                 }
  1059.                         }
  1060.                 }
  1061.  
  1062.                 spr=0;
  1063.  
  1064.                 for(i=0;i<objCount;++i)
  1065.                 {
  1066.                         j=SPR_SPIKEBALL+(((frame)>>2)&7);
  1067.  
  1068.                         if(objList[i].hit)
  1069.                         {
  1070.                                 if(objList[i].hit&1) j+=8;
  1071.                                 --objList[i].hit;
  1072.                         }
  1073.  
  1074.                         set_sprite(spr,4+(objList[i].x>>(FP+1))-4,16+(objList[i].y>>FP)-8,j);
  1075.  
  1076.                         if(gameDone==255)
  1077.                         {
  1078.                                 ++spr;
  1079.                                 continue;
  1080.                         }
  1081.  
  1082.                         x=(objList[i].x+objList[i].dx)>>FP;
  1083.                         y= objList[i].y>>FP;
  1084.  
  1085.                         t1=TEST_MAP(x-3,y-3);
  1086.                         t2=TEST_MAP(x+3,y-3);
  1087.                         t3=TEST_MAP(x-3,y+3);
  1088.                         t4=TEST_MAP(x+3,y+3);
  1089.  
  1090.                         if(t1||t2||t3||t4)
  1091.                         {
  1092.                                 objList[i].dx=-objList[i].dx;
  1093.                                 dx=0;
  1094.                         }
  1095.                         else
  1096.                         {
  1097.                                 dx=objList[i].dx;
  1098.                         }
  1099.  
  1100.                         if(t1==2||t2==2||t3==2||t4==2) player_hit(i);
  1101.  
  1102.                         x= objList[i].x>>FP;
  1103.                         y=(objList[i].y+objList[i].dy)>>FP;
  1104.  
  1105.                         t1=TEST_MAP(x-3,y-3);
  1106.                         t2=TEST_MAP(x+3,y-3);
  1107.                         t3=TEST_MAP(x-3,y+3);
  1108.                         t4=TEST_MAP(x+3,y+3);
  1109.  
  1110.                         if(t1||t2||t3||t4)
  1111.                         {
  1112.                                 objList[i].dy=-objList[i].dy;
  1113.                                 dy=0;
  1114.                         }
  1115.                         else
  1116.                         {
  1117.                                 dy=objList[i].dy;
  1118.                         }
  1119.  
  1120.                         if(t1==2||t2==2||t3==2||t4==2) player_hit(i);
  1121.  
  1122.                         if(!gameStartDelay&&!objList[i].hit)
  1123.                         {
  1124.                                 objList[i].x+=dx;
  1125.                                 objList[i].y+=dy;
  1126.                         }
  1127.  
  1128.                         ++spr;
  1129.                 }
  1130.  
  1131.                 player_screen_coords();
  1132.  
  1133.                 if(gameRestartDelay)
  1134.                 {
  1135.                         i=(gameRestartDelay&16?10:0);
  1136.                 }
  1137.                 else
  1138.                 {
  1139.                         i=!player.draw?0:((frame>>1)&1);
  1140.                 }
  1141.  
  1142.                 if(explodeCnt)
  1143.                 {
  1144.                         set_sprite(spr,explodeX,explodeY,9-(explodeCnt>>2));
  1145.                 }
  1146.                 else
  1147.                 {
  1148.                         set_sprite(spr,player.sx,player.sy,gameDone!=255?SPR_PLAYER+i:SPRITE_END);
  1149.                 }
  1150.  
  1151.                 if(!explodeCnt&&!gameRestartDelay&&gameDone>=gameClearTarget) break;
  1152.  
  1153.                 swap_screen();
  1154.  
  1155.                 if(fill)
  1156.                 {
  1157.                         fill=FALSE;
  1158.                         score=map_fill();
  1159.                         gameAreaClear+=score;
  1160.                         gameScore+=score;
  1161.                         gamePower+=score/10;
  1162.                         if(gamePower>100) gamePower=100;
  1163.                         update_stats_done();
  1164.                         update_stats_score();
  1165.                         update_stats_power();
  1166.                         draw_map();
  1167.                 }
  1168.  
  1169.                 if(gameStartDelay) --gameStartDelay;
  1170.                 if(gameRestartDelay) --gameRestartDelay;
  1171.                 if(gameHitCnt) --gameHitCnt;
  1172.                 if(explodeCnt) --explodeCnt;
  1173.         }
  1174.  
  1175.         swap_screen();
  1176.         sprites_stop();
  1177.         music_stop();
  1178.  
  1179.         if(gameDone<=100)
  1180.         {
  1181.                 memset(map,1,sizeof(map));
  1182.                 memset(updmap,1,sizeof(updmap));
  1183.  
  1184.                 draw_image(1,2,gameImageID);
  1185.  
  1186.                 for(i=0;i<15;++i)
  1187.                 {
  1188.                         swap_screen();
  1189.                         vsync();
  1190.                 }
  1191.  
  1192.                 sample_play(SMP_MEOW);
  1193.         }
  1194.  
  1195.         delay(50);
  1196.  
  1197.         fade_to_black();
  1198.  
  1199.         return gameDone<=100?TRUE:FALSE;
  1200. }
  1201.  
  1202.  
  1203.  
  1204. void title_screen(void)
  1205. {
  1206.         const u8 pressStartStr[]="PRESS SPACE TO START";
  1207.         static u8 i,j,spr,xoff,dx,done,frame;
  1208.         static u16 off,pp;
  1209.         static i16 x,y;
  1210.  
  1211.         pal_bright(BRIGHT_MIN);
  1212.         pal_select(PAL_TITLE);
  1213.         clear_screen(0);
  1214.         swap_screen();
  1215.         pal_bright(BRIGHT_MID);
  1216.  
  1217.         select_image(IMG_TITLE);
  1218.  
  1219.         off=0;
  1220.  
  1221.         sprites_start();
  1222.  
  1223.         music_play(MUS_INTRO);
  1224.  
  1225.         while(off<18*4)
  1226.         {
  1227.                 pp=17;
  1228.                 y=4;
  1229.                 xoff=off>>2;
  1230.  
  1231.                 if((off&3)==0)
  1232.                 {
  1233.                         for(i=0;i<10;++i)
  1234.                         {
  1235.                                 dx=i<5?i:9-i;
  1236.                                 x=19-xoff+dx;
  1237.                                 if(x>=3&&x<=19) draw_tile(x,y,pp-xoff+dx);
  1238.                                 pp+=36;
  1239.                                 ++y;
  1240.                         }
  1241.                 }
  1242.  
  1243.                 if((off&3)==2)
  1244.                 {
  1245.                         for(i=0;i<10;++i)
  1246.                         {
  1247.                                 dx=i<5?i:9-i;
  1248.                                 x=20+xoff-dx;
  1249.                                 if(x<37&&x>=20) draw_tile(x,y,pp+xoff-dx+1);
  1250.                                 pp+=36;
  1251.                                 ++y;
  1252.                         }
  1253.                 }
  1254.  
  1255.                 spr=0;
  1256.                 y=3*8;
  1257.  
  1258.                 for(i=0;i<3;++i)
  1259.                 {
  1260.                         dx=i<<3;
  1261.  
  1262.                         x=19*4-off+dx;
  1263.                         if(x<8) x=8;
  1264.  
  1265.                         set_sprite(spr+0,x  ,y,SPR_TITLEMASK+2+0);
  1266.                         set_sprite(spr+1,x-8,y,SPR_TITLEMASK+2+4);
  1267.  
  1268.                         x=19*4-2+off-dx;
  1269.                         if(x>36*4) x=36*4;
  1270.  
  1271.                         set_sprite(spr+2,x  ,y,SPR_TITLEMASK+2+1);
  1272.                         set_sprite(spr+3,x+8,y,SPR_TITLEMASK+2+5);
  1273.  
  1274.                         spr+=4;
  1275.                         y+=16;
  1276.                 }
  1277.  
  1278.                 for(i=3;i<6;++i)
  1279.                 {
  1280.                         dx=(5-i)<<3;
  1281.  
  1282.                         x=19*4-off+dx;
  1283.                         if(x<8) x=8;
  1284.  
  1285.                         set_sprite(spr+0,x  ,y,SPR_TITLEMASK+0);
  1286.                         set_sprite(spr+1,x-8,y,SPR_TITLEMASK+4);
  1287.  
  1288.                         x=19*4-2+off-dx;
  1289.                         if(x>36*4) x=36*4;
  1290.  
  1291.                         set_sprite(spr+2,x  ,y,SPR_TITLEMASK+1);
  1292.                         set_sprite(spr+3,x+8,y,SPR_TITLEMASK+5);
  1293.  
  1294.                         spr+=4;
  1295.                         y+=16;
  1296.                 }
  1297.  
  1298.                 ++off;
  1299.  
  1300.                 swap_screen();
  1301.         }
  1302.  
  1303.         sprites_stop();
  1304.  
  1305.         for(i=BRIGHT_MID;i<=BRIGHT_MAX;++i)
  1306.         {
  1307.                 pal_bright(i);
  1308.                 delay(3);
  1309.         }
  1310.  
  1311.         put_str(10,18,pressStartStr);
  1312.         put_str(14,22,"pd$o#$ shiru");
  1313.  
  1314.         swap_screen();
  1315.  
  1316.         for(i=BRIGHT_MAX;i>=BRIGHT_MID;--i)
  1317.         {
  1318.                 pal_bright(i);
  1319.                 delay(5);
  1320.         }
  1321.  
  1322.         sprites_start();
  1323.  
  1324.         frame=0;
  1325.         done=FALSE;
  1326.  
  1327.         while(!done)
  1328.         {
  1329.                 if(frame&16)
  1330.                 {
  1331.                         put_str(10,18,pressStartStr);
  1332.                 }
  1333.                 else
  1334.                 {
  1335.                         for(i=0;i<20;++i) put_char(10+i,18,' ');
  1336.                 }
  1337.  
  1338.                 swap_screen();
  1339.  
  1340.                 if(joystick()&JOY_FIRE) done=TRUE;
  1341.  
  1342.                 ++frame;
  1343.         }
  1344.  
  1345.         sprites_stop();
  1346.         put_str(10,18,pressStartStr);
  1347.         swap_screen();
  1348.  
  1349.         music_stop();
  1350.         sample_play(SMP_START);
  1351.  
  1352.         fade_to_black();
  1353. }
  1354.  
  1355.  
  1356.  
  1357. void gameover_screen(void)
  1358. {
  1359.         static u8 i;
  1360.  
  1361.         pal_bright(BRIGHT_MIN);
  1362.         pal_select(PAL_TEXTBACK2);
  1363.  
  1364.         clear_screen(0);
  1365.  
  1366.         put_large_str("GAME OVER");
  1367.         put_str(11,15,"TOTAL SCORE:");
  1368.         put_num(23,15,gameScore,5);
  1369.  
  1370.         swap_screen();
  1371.  
  1372.         music_play(MUS_GAMEOVER);
  1373.  
  1374.         for(i=BRIGHT_MIN;i<=BRIGHT_MID;++i)
  1375.         {
  1376.                 pal_bright(i);
  1377.                 delay(8);
  1378.         }
  1379.  
  1380.         while(1)
  1381.         {
  1382.                 vsync();
  1383.  
  1384.                 if(joystick()&JOY_FIRE) break;
  1385.         }
  1386.  
  1387.         music_stop();
  1388.         fade_to_black();
  1389. }
  1390.  
  1391.  
  1392.  
  1393. void welldone_screen(void)
  1394. {
  1395.         static u8 i;
  1396.  
  1397.         pal_bright(BRIGHT_MIN);
  1398.         pal_select(PAL_TEXTBACK3);
  1399.  
  1400.         clear_screen(0);
  1401.  
  1402.         put_large_str("WELL DONE");
  1403.         put_str(11,15,"ALL LEVELS CLEAR !");
  1404.         put_str(11,18,"TOTAL SCORE:");
  1405.         put_num(23,18,gameScore,5);
  1406.  
  1407.         swap_screen();
  1408.  
  1409.         music_play(MUS_WELLDONE);
  1410.  
  1411.         for(i=BRIGHT_MIN;i<=BRIGHT_MID;++i)
  1412.         {
  1413.                 pal_bright(i);
  1414.                 delay(8);
  1415.         }
  1416.  
  1417.         while(1)
  1418.         {
  1419.                 vsync();
  1420.  
  1421.                 if(joystick()&JOY_FIRE) break;
  1422.         }
  1423.  
  1424.         music_stop();
  1425.         fade_to_black();
  1426. }
  1427.  
  1428.  
  1429.  
  1430. void main(void)
  1431. {
  1432.         color_key(1);
  1433.  
  1434.         while(1)
  1435.         {
  1436.                 title_screen();
  1437.  
  1438.                 gameScore=0;
  1439.                 gameLevel=0;
  1440.                 gamePower=0;
  1441.  
  1442.                 while(1)
  1443.                 {
  1444.                         if(game_loop())
  1445.                         {
  1446.                                 ++gameLevel;
  1447.  
  1448.                                 if(gameLevel==LEVELS_ALL)
  1449.                                 {
  1450.                                         welldone_screen();
  1451.                                         break;
  1452.                                 }
  1453.                         }
  1454.                         else
  1455.                         {
  1456.                                 gameover_screen();
  1457.                                 break;
  1458.                         }
  1459.                 }
  1460.         }
  1461. }