Subversion Repositories Kolibri OS

Rev

Rev 1805 | Rev 5822 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include "kosSyst.h"
  2. #include "mcarray.h"
  3. #include "lang.h"
  4.  
  5.  
  6. // áèòìàï ïóñòîãî ìåñòà
  7. RGB bmEmpty[] = {
  8.         0x201010, 0x101020, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010,
  9.         0x101010, 0x102010, 0x201010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010,
  10.         0x101010, 0x101010, 0x101020, 0x102010, 0x101010, 0x101010, 0x101010, 0x101010,
  11.         0x101010, 0x101010, 0x101010, 0x201010, 0x101020, 0x101010, 0x101010, 0x101010,
  12.         0x101010, 0x101010, 0x101010, 0x101010, 0x102010, 0x201010, 0x101010, 0x101010,
  13.         0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101020, 0x102010, 0x101010,
  14.         0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x201010, 0x101020,
  15.         0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x102010
  16. };
  17.  
  18.  
  19. // áèòìàï èãðîêà
  20. RGB bmHero[] = {
  21.         0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020C0,
  22.         0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020C0, 0x2020A0,
  23.         0x2020E0, 0x2020E0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020A0, 0x2020A0,
  24.         0x2020E0, 0x2020E0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020A0, 0x2020A0,
  25.         0x2020E0, 0x2020E0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020A0, 0x2020A0,
  26.         0x2020E0, 0x2020E0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020A0, 0x2020A0,
  27.         0x2020E0, 0x2020C0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0,
  28.         0x2020C0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0
  29. };
  30.  
  31.  
  32. // áèòìàï èãðîêà
  33. RGB bmSuperHero[] = {
  34.         0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720B0,
  35.         0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720B0, 0x572090,
  36.         0x5720D0, 0x5720D0, 0x5720B0, 0x5720B0, 0x5720B0, 0x5720B0, 0x572090, 0x572090,
  37.         0x5720D0, 0x5720D0, 0x5720B0, 0x5720B0, 0x5720B0, 0x5720B0, 0x572090, 0x572090,
  38.         0x5720D0, 0x5720D0, 0x5720B0, 0x5720B0, 0x5720B0, 0x5720B0, 0x572090, 0x572090,
  39.         0x5720D0, 0x5720D0, 0x5720B0, 0x5720B0, 0x5720B0, 0x5720B0, 0x572090, 0x572090,
  40.         0x5720D0, 0x5720B0, 0x572090, 0x572090, 0x572090, 0x572090, 0x572090, 0x572090,
  41.         0x5720B0, 0x572090, 0x572090, 0x572090, 0x572090, 0x572090, 0x572090, 0x572090
  42. };
  43.  
  44.  
  45. // áèòìàï ãàäà, áåãàþùåãî ïî çàïîëíåííîé ìåñòíîñòè
  46. RGB bmEnemy1[] = {
  47.         0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xC02020,
  48.         0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xC02020, 0xA02020,
  49.         0xE02020, 0xE02020, 0xC02020, 0xC02020, 0xC02020, 0xC02020, 0xA02020, 0xA02020,
  50.         0xE02020, 0xE02020, 0xC02020, 0xC02020, 0xC02020, 0xC02020, 0xA02020, 0xA02020,
  51.         0xE02020, 0xE02020, 0xC02020, 0xC02020, 0xC02020, 0xC02020, 0xA02020, 0xA02020,
  52.         0xE02020, 0xE02020, 0xC02020, 0xC02020, 0xC02020, 0xC02020, 0xA02020, 0xA02020,
  53.         0xE02020, 0xC02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020,
  54.         0xC02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020
  55. };
  56.  
  57.  
  58. // áèòìàï ãàäà, áåãàþùåãî ïî ïóñòîìó ìåñòó
  59. RGB bmEnemy2[] = {
  60.         0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xC08020,
  61.         0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xC08020, 0xA08020,
  62.         0xE08020, 0xE08020, 0xC08020, 0xC08020, 0xC08020, 0xC08020, 0xA08020, 0xA08020,
  63.         0xE08020, 0xE08020, 0xC08020, 0xC08020, 0xC08020, 0xC08020, 0xA08020, 0xA08020,
  64.         0xE08020, 0xE08020, 0xC08020, 0xC08020, 0xC08020, 0xC08020, 0xA08020, 0xA08020,
  65.         0xE08020, 0xE08020, 0xC08020, 0xC08020, 0xC08020, 0xC08020, 0xA08020, 0xA08020,
  66.         0xE08020, 0xC08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020,
  67.         0xC08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020
  68. };
  69.  
  70.  
  71. // áèòìàï çàïîëíåíèÿ
  72. RGB bmWall[] = {
  73.         0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xCCCCCC,
  74.         0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA,
  75.         0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA,
  76.         0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA,
  77.         0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA,
  78.         0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA,
  79.         0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA,
  80.         0xCCCCCC, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA
  81. };
  82.  
  83.  
  84. // ñëåä èãðîêà
  85. RGB bmTrack[] = {
  86.         0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010,
  87.         0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010,
  88.         0x101010, 0x101010, 0x101010, 0x1010F0, 0x1010F0, 0x101010, 0x101010, 0x101010,
  89.         0x101010, 0x101010, 0x1010F0, 0x1010F0, 0x1010F0, 0x1010F0, 0x101010, 0x101010,
  90.         0x101010, 0x101010, 0x1010F0, 0x1010F0, 0x1010F0, 0x1010F0, 0x101010, 0x101010,
  91.         0x101010, 0x101010, 0x101010, 0x1010F0, 0x1010F0, 0x101010, 0x101010, 0x101010,
  92.         0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010,
  93.         0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010
  94. };
  95.  
  96.  
  97. // ñëåä èãðîêà
  98. RGB bmSuperTrack[] = {
  99.         0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010,
  100.         0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010,
  101.         0x101010, 0x101010, 0x101010, 0x5310D0, 0x5310D0, 0x101010, 0x101010, 0x101010,
  102.         0x101010, 0x101010, 0x5310D0, 0x5310D0, 0x5310D0, 0x5310D0, 0x101010, 0x101010,
  103.         0x101010, 0x101010, 0x5310D0, 0x5310D0, 0x5310D0, 0x5310D0, 0x101010, 0x101010,
  104.         0x101010, 0x101010, 0x101010, 0x5310D0, 0x5310D0, 0x101010, 0x101010, 0x101010,
  105.         0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010,
  106.         0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010
  107. };
  108.  
  109.  
  110. // çàïîëíåíèå ýêðàíà äëÿ ñìåíû óðîâíÿ
  111. RGB bmFlip[] = {
  112.         0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0,
  113.         0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010,
  114.         0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0,
  115.         0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010,
  116.         0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0,
  117.         0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010,
  118.         0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0,
  119.         0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010
  120. };
  121.  
  122.  
  123. // áîíóñ íåóÿçâèìîñòè
  124. RGB bmBonus1[] = {
  125.         0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xCCCCCC,
  126.         0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0x44AC44, 0x44AC44, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA,
  127.         0xFFFFFF, 0xCCCCCC, 0x44AC44, 0x44AC44, 0x44AC44, 0x44AC44, 0xCCCCCC, 0xAAAAAA,
  128.         0xFFFFFF, 0x44AC44, 0x44AC44, 0x0C8C0C, 0x0C8C0C, 0x44AC44, 0x44AC44, 0xAAAAAA,
  129.         0xFFFFFF, 0x44AC44, 0x44AC44, 0x0C8C0C, 0x0C8C0C, 0x44AC44, 0x44AC44, 0xAAAAAA,
  130.         0xFFFFFF, 0xCCCCCC, 0x44AC44, 0x44AC44, 0x44AC44, 0x44AC44, 0xCCCCCC, 0xAAAAAA,
  131.         0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0x44AC44, 0x44AC44, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA,
  132.         0xCCCCCC, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA
  133. };
  134.  
  135.  
  136. // áîíóñ æèçíè
  137. RGB bmBonus2[] = {
  138.         0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xCCCCCC,
  139.         0xFFFFFF, 0xCCCCCC, 0xD41414, 0xCCCCCC, 0xCCCCCC, 0xD41414, 0xCCCCCC, 0xAAAAAA,
  140.         0xFFFFFF, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xAAAAAA,
  141.         0xFFFFFF, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xAAAAAA,
  142.         0xFFFFFF, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xAAAAAA,
  143.         0xFFFFFF, 0xCCCCCC, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xCCCCCC, 0xAAAAAA,
  144.         0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xD41414, 0xD41414, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA,
  145.         0xCCCCCC, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA
  146. };
  147.  
  148.  
  149. //
  150. RGB bmPMButton[] = {
  151.         0xCCCCCC, 0xCCCCCC, 0x000000, 0x000000, 0xCCCCCC, 0xCCCCCC,
  152.         0xCCCCCC, 0xCCCCCC, 0x000000, 0x000000, 0xCCCCCC, 0xCCCCCC,
  153.         0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
  154.         0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
  155.         0xCCCCCC, 0xCCCCCC, 0x000000, 0x000000, 0xCCCCCC, 0xCCCCCC,
  156.         0xCCCCCC, 0xCCCCCC, 0x000000, 0x000000, 0xCCCCCC, 0xCCCCCC,
  157. };
  158.  
  159.  
  160. //
  161. void DrawAppWindow();
  162. //
  163. void DrawTop10Window();
  164. //
  165. void initWorldMap();
  166. //
  167. void drawWorldMap();
  168. //
  169. void clearWorldMap();
  170. //
  171. void drawWorldMapForFlip();
  172. //
  173. void drawWndTitleGo();
  174. //
  175. void ApplyMapDiffs( bool drawTitle = true );
  176. //
  177. int GetCompletePercents();
  178.  
  179.  
  180. #define EAT_ENEMY_BONUS         100
  181.  
  182. #define BEFORE_START_LEVEL      100
  183. #define BONUS1_LIFETIME         250
  184. #define BONUS1_IND_HSIZE        6
  185.  
  186. #define MIN_LOOP_DELAY          1
  187. #define MAX_LOOP_DELAY          20
  188. #define DEFAULT_LOOP_DELAY      12
  189.  
  190. #define blockSize                       8
  191.  
  192. #define ENTRY_WND_SIZE_X        400
  193. #define ENTRY_WND_SIZE_Y        144
  194.  
  195. #define TOP10_WND_SIZE_X        176
  196. #define TOP10_WND_SIZE_Y        144
  197.  
  198. #define MAX_X_SIZE                      96
  199. #define MIN_X_SIZE                      48
  200. #define MAX_Y_SIZE                      56
  201. #define MIN_Y_SIZE                      28
  202.  
  203. #define flipMapSize                     ((mapSizeX * mapSizeY) / 4)
  204. #define wndXOffet                       1
  205. #define wndYOffset                      22
  206. #define freeSpaceCount          ((mapSizeX - 4) * (mapSizeY - 4))
  207. //
  208. #define gmEmpty                         0
  209. #define gmHero                          1
  210. #define gmEnemy1                        2
  211. #define gmEnemy2                        3
  212. #define gmWall                          4
  213. #define gmTrack                         5
  214. #define gmFlip                          6
  215. #define gmBonus1                        7
  216. #define gmBonus2                        8
  217. #define gmSuperHero                     9
  218. #define gmSuperTrack            10
  219. #define gmProbe                         11
  220.  
  221. #define appStateEntry           0
  222. #define appStateGo                      1
  223. #define appStateHideMap         2
  224. #define appStateShowMap         3
  225. #define appStatePause           4
  226. #define appStateAfterDeath      5
  227. #define appStateTop10           6
  228.  
  229. #define spacePerEnemy           30
  230.  
  231.  
  232. #define BT_SIZE_X_PLUS          2
  233. #define BT_SIZE_X_MINUS         3
  234. #define BT_LOOP_PLUS            4
  235. #define BT_LOOP_MINUS           5
  236. #define BT_SIZE_Y_PLUS          6
  237. #define BT_SIZE_Y_MINUS         7
  238.  
  239. #define TOP_TBL_SIZE            10
  240.  
  241.  
  242. //
  243. struct hiScoreHero
  244. {
  245.         char name[12];
  246.         Dword score;
  247.         //
  248.         hiScoreHero()
  249.         {
  250.                 //
  251.                 this->ClearName();
  252.                 this->score = 0;
  253.         };
  254.         //
  255.         void ClearName()
  256.         {
  257.                 memset( (Byte *)(this->name), '.', sizeof(this->name) );
  258.         };
  259. };
  260.  
  261. //
  262. char top10FilePath[MAX_PATH];
  263. hiScoreHero heroTbl[TOP_TBL_SIZE];
  264.  
  265. //
  266. struct hiScoreFile
  267. {
  268.         Byte block[512];
  269.         kosFileInfo fi;
  270.         //
  271.         hiScoreFile()
  272.         {
  273.                 int i;
  274.  
  275.                 //
  276.                 this->fi.offsetLow = this->fi.offsetHigh = 0;
  277.                 this->fi.dataCount = 0;
  278.                 this->fi.bufferPtr = this->block;
  279.                 this->fi.rwMode = 0;
  280.                 memcpy( this->fi.fileURL, top10FilePath, sizeof( top10FilePath ) );
  281.                 //
  282.                 for ( i = 0; i < ( sizeof( this->block ) / sizeof( Dword ) ); i++ )
  283.                 {
  284.                         //
  285.                         ((Dword *)(this->block))[i] = rtlRand();
  286.                 }
  287.         };
  288.         //
  289.         virtual ~hiScoreFile()
  290.         {}
  291.         //
  292.         bool LoadFromDisk()
  293.         {
  294.                 bool result;
  295.                 int i;
  296.                 Dword j, k;
  297.                 Byte *bPtr;
  298.  
  299.                 //
  300.                 this->fi.rwMode = FO_READ;
  301.                 this->fi.dataCount = 512;
  302.                 result = kos_FileSystemAccess( &(this->fi) ) == 0;
  303.                 //
  304.                 if ( result )
  305.                 {
  306.                         // äåêîäèðóåì
  307.                         rtlSrand( ((Dword *)(this->block))[(sizeof(this->block) / sizeof(Dword)) - 1] );
  308.                         //
  309.                         for ( i = 0; i < (sizeof( heroTbl ) * 5); i++ )
  310.                         {
  311.                                 // íå òðîãàåì ïîñëåäíèé Dword
  312.                                 j = rtlRand() % (sizeof(this->block) - 7);
  313.                                 k = ( rtlRand() % 31 ) + 1;
  314.                                 //
  315.                                 bPtr = this->block + j;
  316.                                 //
  317.                                 __asm{
  318.                                         mov edx, bPtr
  319.                                         mov ecx, k
  320.                                         mov eax, [edx]
  321.                                         bswap eax
  322.                                         ror eax, cl
  323.                                         mov [edx], eax
  324.                                 }
  325.                         }
  326.                         //
  327.                         rtlSrand( kos_GetSystemClock() );
  328.                 }
  329.                 //
  330.                 return result;
  331.         };
  332.         //
  333.         bool SaveToDisk()
  334.         {
  335.                 int i;
  336.                 Dword *rndList;
  337.                 Byte *bPtr;
  338.                 Dword k, keyLock;
  339.  
  340.                 //
  341.                 rndList = new Dword[(sizeof( heroTbl ) * 5) * 2];
  342.                 //
  343.                 keyLock = rtlRand();
  344.                 //
  345.                 for ( i = 0; i < (sizeof( heroTbl ) * 5); i++ )
  346.                 {
  347.                         //
  348.                         rndList[i * 2] = rtlRand() % (sizeof(this->block) - 7);
  349.                         rndList[(i * 2) + 1] = ( rtlRand() % 31 ) + 1;
  350.                 }
  351.                 //
  352.                 for ( i = (sizeof( heroTbl ) * 5) - 1; i >= 0; i-- )
  353.                 {
  354.                         //
  355.                         bPtr = this->block + rndList[i * 2];
  356.                         k = rndList[(i * 2) + 1];
  357.                         //
  358.                         __asm{
  359.                                 mov edx, bPtr
  360.                                 mov ecx, k
  361.                                 mov eax, [edx]
  362.                                 rol eax, cl
  363.                                 bswap eax
  364.                                 mov [edx], eax
  365.                         }
  366.                 }
  367.                 //
  368.                 delete rndList;
  369.                 //
  370.                 ((Dword *)(this->block))[(sizeof(this->block) / sizeof(Dword)) - 1] = keyLock;
  371.                 //
  372.                 this->fi.rwMode = FO_WRITE;
  373.                 this->fi.dataCount = 512;
  374.                 return kos_FileSystemAccess( &( this->fi) ) == 0;
  375.         };
  376. };
  377.  
  378. ///
  379. hiScoreFile *top10Heroes = NULL;
  380.  
  381.  
  382. // çàãîëîâîê ãëàâíîãî îêíà
  383. char MainWindowTitle[] = "XONIX (C) MMVI by Rabid Rabbit";
  384. #if LANG == RUS
  385. char goWndTitle[] = "“஢¥­ì %U, § ¢¥à襭® %U%%, ¦¨§­¥©: %U, áçñâ: %U";
  386. char menuStr1[] = "1.  ç âì ¨£àã";
  387. char menuStr2[] = "2. ‚ë室";
  388. char menuStr3[] = "“¯à ¢«¥­¨¥: ‘’…‹Šˆ - ­ ¯à ¢«¥­¨¥ ¤¢¨¦¥­¨ï.";
  389. char menuStr4[] = "SPACE - ¯ ã§ , ESC - ¢ë室 ¢ ¬¥­î.";
  390. char thatsAllStr[] = "ˆ£à  ®ª®­ç¥­ .";
  391. char worldSizeStr[] = " §¬¥à ¯®«ï %U x %U í«¥¬¥­â®¢.";
  392. char mainLoopDelayStr[] = "‘ª®à®áâì %U";
  393. char top10str1[] = "ENTER - ¨¬ï Ok.";
  394. char top10str2[] = "ESC - ¢ë室 ¢ ¬¥­î";
  395. #else
  396. char goWndTitle[] = "Level %U, completed %U%%, lives: %U, scores: %U";
  397. char menuStr1[] = "1. Start game";
  398. char menuStr2[] = "2. Exit";
  399. char menuStr3[] = "Control: ARROWS - direction of movement.";
  400. char menuStr4[] = "SPACE - pause, ESC - leave to menu.";
  401. char thatsAllStr[] = "Game finished.";
  402. char worldSizeStr[] = "Field size %U x %U cells.";
  403. char mainLoopDelayStr[] = "Speed %U";
  404. char top10str1[] = "Enter - name Ok.";
  405. char top10str2[] = "ESC - leave to menu";
  406. #endif
  407. //
  408. Byte beep1[] = { 0x90, 0x33, 0 };
  409. //
  410. Byte *heroPtr = NULL;
  411. int heroDX = 0, heroDY = 0, lastMoveDirection = 0;
  412. //
  413. Byte * worldMap = NULL;
  414. //
  415. int     wndSizeX = ENTRY_WND_SIZE_X;
  416. int     wndSizeY = ENTRY_WND_SIZE_Y;
  417. int mapSizeX = 64;
  418. int mapSizeY = 32;
  419. int loopDelay = DEFAULT_LOOP_DELAY;
  420. int currentLevel = 1;
  421. int appState = appStateEntry;
  422. int levelFillEdge = 0;
  423. int levelFillCount = 0;
  424. int lifeCount = 0;
  425. int flipMapCount = 0;
  426. bool noBonus = false;
  427. bool goToNextLevel = false;
  428. bool bonus1Set = false;
  429. bool bonus2Set = false;
  430. int bonus1Count = 0;
  431. int currentHero = gmHero;
  432. int currentTrack = gmTrack;
  433. Dword scoreCount = 0;
  434. int enterName = -1;
  435. int enterCharNdx = 0;
  436. //
  437. MCArray<Byte*> fillList;
  438.  
  439. //
  440. struct flipMapEl
  441. {
  442.         Word x, y;
  443. };
  444.  
  445. //
  446. flipMapEl *flipMapPtr = NULL;
  447.  
  448.  
  449. //
  450. RGB *mapColours[] = {
  451.         bmEmpty,
  452.         bmHero,
  453.         bmEnemy1,
  454.         bmEnemy2,
  455.         bmWall,
  456.         bmTrack,
  457.         bmFlip,
  458.         bmBonus1,
  459.         bmBonus2,
  460.         bmSuperHero,
  461.         bmSuperTrack,
  462.         NULL
  463. };
  464.  
  465.  
  466. //
  467. struct sMapDiff
  468. {
  469.         Byte *elPtr;
  470.         Byte mapEl;
  471.         //
  472.         sMapDiff() {};
  473.         //
  474.         sMapDiff( Byte *sElPtr, Byte sMapEl )
  475.         {
  476.                 this->elPtr = sElPtr;
  477.                 this->mapEl = sMapEl;
  478.         };
  479. };
  480.  
  481.  
  482. //
  483. class CMapDiff : public MCArray<sMapDiff>
  484. {
  485. public:
  486.         virtual int Add( const sMapDiff &element )
  487.         {
  488.                 element.elPtr[0] = element.mapEl;
  489.                 return MCArray<sMapDiff>::Add( element );
  490.         }
  491. };
  492.  
  493.  
  494. //
  495. CMapDiff mapDiffList;
  496. MCArray<Byte*> sTrackList;
  497.  
  498.  
  499. //
  500. class CGenericEnemy
  501. {
  502. public:
  503.         //
  504.         Byte *ePtr;
  505.         int dx, dy;
  506.         //
  507.         virtual bool Move(void) = 0;
  508. };
  509.  
  510. class CWallEnemy : public CGenericEnemy
  511. {
  512. public:
  513.         virtual bool Move(void);
  514. };
  515.  
  516. class CSpaceEnemy : public CGenericEnemy
  517. {
  518. public:
  519.         virtual bool Move(void);
  520. };
  521.  
  522.  
  523.  
  524. //
  525. bool CWallEnemy::Move()
  526. {
  527.         int ddx;
  528.         Byte *nextPtr;
  529.         Byte mapEl, dirMap;
  530.         bool result, border;
  531.  
  532.         //
  533.         result = false;
  534.         border = false;
  535.         //
  536.         ddx = ( this->ePtr - worldMap ) % mapSizeX;
  537.         //
  538.         if ( ddx == 0 && this->dx < 0 )
  539.         {
  540.                 border = true;
  541.                 this->dx = 0 - this->dx;
  542.         }
  543.         //
  544.         if ( ddx == (mapSizeX - 1) && this->dx > 0 )
  545.         {
  546.                 border = true;
  547.                 this->dx = 0 - this->dx;
  548.         }
  549.         //
  550.         ddx = ( this->ePtr - worldMap ) / mapSizeX;
  551.         //
  552.         if ( ddx == 0 && this->dy < 0 )
  553.         {
  554.                 border = true;
  555.                 this->dy = 0 - this->dy;
  556.         }
  557.         //
  558.         if ( ddx == (mapSizeY - 1) && this->dy > 0 )
  559.         {
  560.                 border = true;
  561.                 this->dy = 0 - this->dy;
  562.         }
  563.         // ïîëó÷èì êîîðäèíàòû ìåñòà, â êîòîðîå ïîïàäàåò îáúåêò
  564.         nextPtr = this->ePtr + ( this->dx + this->dy );
  565.         // ïîëó÷èì ýëåìåíò ñ êàðòû
  566.         mapEl = nextPtr[0];
  567.         //
  568.         // â çàâèñèìîñòè îò ýëåìåíòà
  569.         switch ( mapEl )
  570.         {
  571.         // íàïîðîëèñü íà èãðîêà
  572.         case gmHero:
  573.                 if ( sTrackList.GetCount() <= 0 )
  574.                 {
  575.                         result = true;
  576.                         break;
  577.                 }
  578.  
  579.         // ïóñòîå ìåñòî, ñëåä èãðîêà èëè ãàäû íà ïîëå - íàäî îòñêàêèâàòü
  580.         case gmSuperHero:
  581.         case gmSuperTrack:
  582.         case gmTrack:
  583.         case gmEnemy2:
  584.         case gmEmpty:
  585.                 //
  586.                 dirMap = 0;
  587.                 // -dx +dy
  588.                 mapEl = this->ePtr[this->dy - this->dx];
  589.                 if ( mapEl == gmEmpty
  590.                         || mapEl == gmTrack
  591.                         || mapEl == gmEnemy2
  592.                         || mapEl == gmSuperHero
  593.                         || mapEl == gmSuperTrack
  594.                         ) dirMap |= 1;
  595.                 // +dy
  596.                 mapEl = this->ePtr[this->dy];
  597.                 if ( mapEl == gmEmpty
  598.                         || mapEl == gmTrack
  599.                         || mapEl == gmEnemy2
  600.                         || mapEl == gmSuperHero
  601.                         || mapEl == gmSuperTrack
  602.                         ) dirMap |= 2;
  603.                 // +dx
  604.                 mapEl = this->ePtr[this->dx];
  605.                 if ( mapEl == gmEmpty
  606.                         || mapEl == gmTrack
  607.                         || mapEl == gmEnemy2
  608.                         || mapEl == gmSuperHero
  609.                         || mapEl == gmSuperTrack
  610.                         ) dirMap |= 4;
  611.                 // +dx -dy
  612.                 mapEl = this->ePtr[this->dx - this->dy];
  613.                 if ( mapEl == gmEmpty
  614.                         || mapEl == gmTrack
  615.                         || mapEl == gmEnemy2
  616.                         || mapEl == gmSuperHero
  617.                         || mapEl == gmSuperTrack
  618.                         ) dirMap |= 8;
  619.                 //
  620.                 switch ( dirMap )
  621.                 {
  622.                 case 2:
  623.                 case 3:
  624.                         this->dy = 0 - this->dy;
  625.                         break;
  626.  
  627.                 case 4:
  628.                 case 12:
  629.                         this->dx = 0 - this->dx;
  630.                         break;
  631.  
  632.                 default:
  633.                         this->dx = 0 - this->dx;
  634.                         this->dy = 0 - this->dy;
  635.                         break;
  636.                 }
  637.                 //
  638.                 nextPtr = this->ePtr + ( this->dx + this->dy );
  639.                 // ïîëó÷èì ýëåìåíò ñ êàðòû
  640.                 mapEl = nextPtr[0];
  641.                 //
  642.                 switch ( mapEl )
  643.                 {
  644.                 //
  645.                 case gmHero:
  646.                         if ( sTrackList.GetCount() <= 0 )
  647.                         {
  648.                                 result = true;
  649.                         }
  650.  
  651.                 //
  652.                 case gmSuperHero:
  653.                 case gmSuperTrack:
  654.                 case gmTrack:
  655.                 case gmEmpty:
  656.                 case gmEnemy2:
  657.                         break;
  658.  
  659.                 //
  660.                 default:
  661.                         // ñòèðàåì îáúåêò
  662.                         mapDiffList.Add( sMapDiff( this->ePtr, gmWall ) );
  663.                         // ïåðåìåñòèì îáúåêò
  664.                         this->ePtr = nextPtr;
  665.                         // ðèñóåì îáúåêò ïî íîâûì êîîðäèíàòàì
  666.                         mapDiffList.Add( sMapDiff( this->ePtr, gmEnemy1 ) );
  667.                         break;
  668.                 }
  669.                 //
  670.                 break;
  671.  
  672.         // ëåòèì
  673.         default:
  674.                 // ñòèðàåì îáúåêò
  675.                 mapDiffList.Add( sMapDiff( this->ePtr, gmWall ) );
  676.                 // ïåðåìåñòèì îáúåêò
  677.                 this->ePtr = nextPtr;
  678.                 // ðèñóåì îáúåêò ïî íîâûì êîîðäèíàòàì
  679.                 mapDiffList.Add( sMapDiff( this->ePtr, gmEnemy1 ) );
  680.                 //
  681.                 break;
  682.  
  683.         }
  684.         //
  685.         return result;
  686. }
  687.  
  688. //
  689. bool CSpaceEnemy::Move()
  690. {
  691.         Byte *nextPtr;
  692.         Byte mapEl, dirMap;
  693.         bool result, heroTrack;
  694.  
  695.         //
  696.         result = false;
  697.         //
  698.         heroTrack = ( sTrackList.GetCount() > 0 );
  699.         // ïîëó÷èì êîîðäèíàòû ìåñòà, â êîòîðîå ïîïàäàåò îáúåêò
  700.         nextPtr = this->ePtr + ( this->dx + this->dy );
  701.         // ïîëó÷èì ýëåìåíò ñ êàðòû
  702.         mapEl = nextPtr[0];
  703.         // â çàâèñèìîñòè îò ýëåìåíòà
  704.         switch ( mapEl )
  705.         {
  706.         // íàïîðîëèñü íà èãðîêà èëè åãî ñëåä
  707.         case gmTrack:
  708.                 result = true;
  709.                 break;
  710.  
  711.         //
  712.         case gmHero:
  713.                 if ( heroTrack )
  714.                 {
  715.                         result = true;
  716.                         break;
  717.                 }
  718.  
  719.         // íàäî îòñêàêèâàòü
  720.         case gmSuperHero:
  721.         case gmSuperTrack:
  722.         case gmBonus1:
  723.         case gmBonus2:
  724.         case gmEnemy1:
  725.         case gmWall:
  726.                 //
  727.                 dirMap = 0;
  728.                 // -dx +dy
  729.                 mapEl = this->ePtr[this->dy - this->dx];
  730.                 if ( mapEl == gmWall ||
  731.                         mapEl == gmEnemy1 ||
  732.                         mapEl == gmBonus1 ||
  733.                         mapEl == gmBonus2 ||
  734.                         mapEl == gmSuperHero ||
  735.                         mapEl == gmSuperTrack ||
  736.                         ( mapEl == gmHero && !heroTrack )
  737.                         ) dirMap |= 1;
  738.                 // +dy
  739.                 mapEl = this->ePtr[this->dy];
  740.                 if ( mapEl == gmWall ||
  741.                         mapEl == gmEnemy1 ||
  742.                         mapEl == gmBonus1 ||
  743.                         mapEl == gmBonus2 ||
  744.                         mapEl == gmSuperHero ||
  745.                         mapEl == gmSuperTrack ||
  746.                         ( mapEl == gmHero && !heroTrack )
  747.                         ) dirMap |= 2;
  748.                 // +dx
  749.                 mapEl = this->ePtr[this->dx];
  750.                 if ( mapEl == gmWall ||
  751.                         mapEl == gmEnemy1 ||
  752.                         mapEl == gmBonus1 ||
  753.                         mapEl == gmBonus2 ||
  754.                         mapEl == gmSuperHero ||
  755.                         mapEl == gmSuperTrack ||
  756.                         ( mapEl == gmHero && !heroTrack )
  757.                         ) dirMap |= 4;
  758.                 // +dx -dy
  759.                 mapEl = this->ePtr[this->dx - this->dy];
  760.                 if ( mapEl == gmWall ||
  761.                         mapEl == gmEnemy1 ||
  762.                         mapEl == gmBonus1 ||
  763.                         mapEl == gmBonus2 ||
  764.                         mapEl == gmSuperHero ||
  765.                         mapEl == gmSuperTrack ||
  766.                         ( mapEl == gmHero && !heroTrack )
  767.                         ) dirMap |= 8;
  768.                 //
  769.                 switch ( dirMap )
  770.                 {
  771.                 case 2:
  772.                 case 3:
  773.                         this->dy = 0 - this->dy;
  774.                         break;
  775.  
  776.                 case 4:
  777.                 case 12:
  778.                         this->dx = 0 - this->dx;
  779.                         break;
  780.  
  781.                 default:
  782.                         this->dx = 0 - this->dx;
  783.                         this->dy = 0 - this->dy;
  784.                         break;
  785.                 }
  786.                 //
  787.                 nextPtr = this->ePtr + ( this->dx + this->dy );
  788.                 // ïîëó÷èì ýëåìåíò ñ êàðòû
  789.                 mapEl = nextPtr[0];
  790.                 //
  791.                 switch ( mapEl )
  792.                 {
  793.                 //
  794.                 case gmTrack:
  795.                         result = true;
  796.                         break;
  797.  
  798.                 //
  799.                 case gmHero:
  800.                         if ( heroTrack )
  801.                         {
  802.                                 result = true;
  803.                                 break;
  804.                         }
  805.  
  806.                 //
  807.                 case gmSuperHero:
  808.                 case gmSuperTrack:
  809.                 case gmBonus1:
  810.                 case gmBonus2:
  811.                 case gmWall:
  812.                 case gmEnemy1:
  813.                         break;
  814.  
  815.                 //
  816.                 default:
  817.                         // ñòèðàåì îáúåêò
  818.                         mapDiffList.Add( sMapDiff( this->ePtr, gmEmpty ) );
  819.                         // ïåðåìåñòèì îáúåêò
  820.                         this->ePtr = nextPtr;
  821.                         // ðèñóåì îáúåêò ïî íîâûì êîîðäèíàòàì
  822.                         mapDiffList.Add( sMapDiff( this->ePtr, gmEnemy2 ) );
  823.                         break;
  824.                 }
  825.                 //
  826.                 break;
  827.  
  828.         // ëåòèì
  829.         default:
  830.                 // ñòèðàåì îáúåêò
  831.                 mapDiffList.Add( sMapDiff( this->ePtr, gmEmpty ) );
  832.                 // ïåðåìåñòèì îáúåêò
  833.                 this->ePtr = nextPtr;
  834.                 // ðèñóåì îáúåêò ïî íîâûì êîîðäèíàòàì
  835.                 mapDiffList.Add( sMapDiff( this->ePtr, gmEnemy2 ) );
  836.                 //
  837.                 break;
  838.  
  839.         }
  840.         //
  841.  
  842.         //
  843.         return result;
  844. }
  845.  
  846.  
  847. //
  848. MCArray<CGenericEnemy *> mapEnemies;
  849.  
  850.  
  851. //
  852. void xonixFree(void)
  853. {
  854.         clearWorldMap();
  855.         if ( flipMapPtr != NULL )
  856.         {
  857.                 delete flipMapPtr;
  858.                 flipMapPtr = NULL;
  859.         }
  860. }
  861.  
  862.  
  863. //
  864. void checkAndSetBonus2()
  865. {
  866.         Dword i;
  867.  
  868.         //
  869.         if ( (!bonus2Set)
  870.                 && rtlRand() < 0x40000000
  871.                 && lifeCount < 3
  872.                 && GetCompletePercents() > 50 )
  873.         {
  874.                 //
  875.                 bonus2Set = true;
  876.                 //
  877.                 for ( i = rtlRand() % (mapSizeX * mapSizeY); worldMap[i] != gmWall; i = rtlRand() % (mapSizeX * mapSizeY) );
  878.                 //
  879.                 mapDiffList.Add( sMapDiff( worldMap + i, gmBonus2 ) );
  880.         }
  881. }
  882.  
  883.  
  884. //
  885. void ChangeHero()
  886. {
  887.         if ( bonus1Count < 1 )
  888.         {
  889.                 currentHero = gmHero;
  890.                 currentTrack = gmTrack;
  891.         }
  892.         else
  893.         {
  894.                 currentHero = gmSuperHero;
  895.                 currentTrack = gmSuperTrack;
  896.         }
  897. }
  898.  
  899.  
  900. //
  901. void checkAndSetBonus1()
  902. {
  903.         Dword i;
  904.  
  905.         //
  906.         if ( (!bonus1Set)
  907.                 && rtlRand() > 0x80000000
  908.                 && lifeCount < 2
  909.                 && GetCompletePercents() > 75 )
  910.         {
  911.                 //
  912.                 bonus1Set = true;
  913.                 //
  914.                 for ( i = rtlRand() % (mapSizeX * mapSizeY); worldMap[i] != gmWall; i = rtlRand() % (mapSizeX * mapSizeY) );
  915.                 //
  916.                 mapDiffList.Add( sMapDiff( worldMap + i, gmBonus1 ) );
  917.         }
  918. }
  919.  
  920.  
  921. //
  922. void CreateFlipMap(void)
  923. {
  924.         Word i, j;
  925.         int ndx, ndx2, k;
  926.         flipMapEl el;
  927.         static int lastMapSizeX = 0, lastMapSizeY = 0;
  928.  
  929.         //
  930.         if ( lastMapSizeX != mapSizeX || lastMapSizeY != mapSizeY )
  931.         {
  932.                 //
  933.                 lastMapSizeX = mapSizeX;
  934.                 lastMapSizeY = mapSizeY;
  935.                 //
  936.                 if ( flipMapPtr != NULL )
  937.                 {
  938.                         delete flipMapPtr;
  939.                         flipMapPtr = NULL;
  940.                 }
  941.         }
  942.         //
  943.         if ( flipMapPtr == NULL )
  944.         {
  945.                 flipMapPtr = new flipMapEl[flipMapSize];
  946.                 //
  947.                 ndx = 0;
  948.                 //
  949.                 for ( i = 0; i < mapSizeY; i += 2 )
  950.                 {
  951.                         for ( j = 0; j < mapSizeX; j += 2 )
  952.                         {
  953.                                 //
  954.                                 flipMapPtr[ndx].x = j;
  955.                                 flipMapPtr[ndx].y = i;
  956.                                 //
  957.                                 ndx++;
  958.                         }
  959.                 }
  960.         }
  961.         //
  962.         for ( k = 0; k < flipMapSize; k++ )
  963.         {
  964.                 //
  965.                 ndx = rtlRand() % flipMapSize;
  966.                 ndx2 = rtlRand() % flipMapSize;
  967.                 //
  968.                 el = flipMapPtr[ndx];
  969.                 flipMapPtr[ndx] = flipMapPtr[ndx2];
  970.                 flipMapPtr[ndx2] = el;
  971.         }
  972. }
  973.  
  974.  
  975. //
  976. bool ProcessEndTrack()
  977. {
  978.         int i, j, k, m;
  979.         bool noFill;
  980.         Byte *mPtr, *findPtr;
  981.  
  982.         //
  983.         j = sTrackList.GetCount();
  984.         //
  985.         scoreCount += j;
  986.         //
  987.         for ( i = 0; i < j; i++ )
  988.         {
  989.                 //
  990.                 mapDiffList.Add( sMapDiff( sTrackList[i], gmWall ) );
  991.         }
  992.         //
  993.         levelFillCount -= j;
  994.         //
  995.         sTrackList.Clear();
  996.         //
  997.         heroPtr += heroDX + heroDY;
  998.         mapDiffList.Add( sMapDiff( heroPtr, currentHero ) );
  999.         //
  1000.         heroDX = 0;
  1001.         heroDY = 0;
  1002.         lastMoveDirection = 0;
  1003.         // çàëèâêà
  1004.         mPtr = worldMap;
  1005.         //
  1006.         for ( i = 0; i < mapSizeY; i++ )
  1007.         {
  1008.                 for ( j = 0; j < mapSizeX; j++ )
  1009.                 {
  1010.                         //
  1011.                         if ( mPtr[0] == gmEmpty )
  1012.                         {
  1013.                                 //
  1014.                                 fillList.Clear();
  1015.                                 //
  1016.                                 noFill = false;
  1017.                                 //
  1018.                                 fillList.Add( mPtr );
  1019.                                 //
  1020.                                 mPtr[0] = gmProbe;
  1021.                                 //
  1022.                                 for ( k = 0; k < fillList.GetCount(); k++ )
  1023.                                 {
  1024.                                         // ñïðàâà
  1025.                                         findPtr = fillList[k] + 1;
  1026.                                         //
  1027.                                         switch ( findPtr[0] )
  1028.                                         {
  1029.                                         case gmEmpty:
  1030.                                                 fillList.Add( findPtr );
  1031.                                                 findPtr[0] = gmProbe;
  1032.                                                 break;
  1033.                                         case gmEnemy2:
  1034.                                                 noFill = true;
  1035.                                                 break;
  1036.                                         default:
  1037.                                                 break;
  1038.                                         }
  1039.                                         // ñëåâà
  1040.                                         findPtr = fillList[k] - 1;
  1041.                                         //
  1042.                                         switch ( findPtr[0] )
  1043.                                         {
  1044.                                         case gmEmpty:
  1045.                                                 fillList.Add( findPtr );
  1046.                                                 findPtr[0] = gmProbe;
  1047.                                                 break;
  1048.                                         case gmEnemy2:
  1049.                                                 noFill = true;
  1050.                                                 break;
  1051.                                         default:
  1052.                                                 break;
  1053.                                         }
  1054.                                         // ñâåðõó
  1055.                                         findPtr = fillList[k] - mapSizeX;
  1056.                                         //
  1057.                                         switch ( findPtr[0] )
  1058.                                         {
  1059.                                         case gmEmpty:
  1060.                                                 fillList.Add( findPtr );
  1061.                                                 findPtr[0] = gmProbe;
  1062.                                                 break;
  1063.                                         case gmEnemy2:
  1064.                                                 noFill = true;
  1065.                                                 break;
  1066.                                         default:
  1067.                                                 break;
  1068.                                         }
  1069.                                         // ñíèçó
  1070.                                         findPtr = fillList[k] + mapSizeX;
  1071.                                         //
  1072.                                         switch ( findPtr[0] )
  1073.                                         {
  1074.                                         case gmEmpty:
  1075.                                                 fillList.Add( findPtr );
  1076.                                                 findPtr[0] = gmProbe;
  1077.                                                 break;
  1078.                                         case gmEnemy2:
  1079.                                                 noFill = true;
  1080.                                                 break;
  1081.                                         default:
  1082.                                                 break;
  1083.                                         }
  1084.                                 }
  1085.                                 //
  1086.                                 if ( noFill )
  1087.                                 {
  1088.                                         //
  1089.                                         fillList.Clear();
  1090.                                 }
  1091.                                 else
  1092.                                 {
  1093.                                         //
  1094.                                         m = fillList.GetCount();
  1095.                                         //
  1096.                                         scoreCount += m;
  1097.                                         //
  1098.                                         for ( k = 0; k < m; k++ )
  1099.                                         {
  1100.                                                 //
  1101.                                                 mapDiffList.Add( sMapDiff( fillList[k], gmWall ) );
  1102.                                         }
  1103.                                         //
  1104.                                         levelFillCount -= m;
  1105.                                 }
  1106.                         }
  1107.                         else
  1108.                         {
  1109.                                 mPtr++;
  1110.                         }
  1111.                 }
  1112.         }
  1113.         //
  1114.         mPtr = worldMap;
  1115.         //
  1116.         for ( i = 0; i < mapSizeY; i++ )
  1117.         {
  1118.                 for ( j = 0; j < mapSizeX; j++ )
  1119.                 {
  1120.                         //
  1121.                         if ( mPtr[0] == gmProbe ) mPtr[0] = gmEmpty;
  1122.                         //
  1123.                         mPtr++;
  1124.                 }
  1125.         }
  1126.         //
  1127.         checkAndSetBonus1();
  1128.         checkAndSetBonus2();
  1129.         //
  1130.         ApplyMapDiffs();
  1131.         //
  1132.         return levelFillCount <= levelFillEdge;
  1133. }      
  1134.  
  1135.  
  1136. //
  1137. void EatEnemy( Byte *enemyPos )
  1138. {
  1139.         bool Eat = true;
  1140.         int i, j;
  1141.  
  1142.         //
  1143.         while ( Eat )
  1144.         {
  1145.                 //
  1146.                 Eat = false;
  1147.                 //
  1148.                 j = mapEnemies.GetCount();
  1149.                 //
  1150.                 for ( i = 0; i < j; i++ )
  1151.                 {
  1152.                         //
  1153.                         if ( mapEnemies[i]->ePtr == enemyPos )
  1154.                         {
  1155.                                 //
  1156.                                 delete mapEnemies[i];
  1157.                                 //
  1158.                                 mapEnemies.RemoveAt( i );
  1159.                                 //
  1160.                                 Eat = true;
  1161.                                 //
  1162.                                 scoreCount += EAT_ENEMY_BONUS;
  1163.                                 //
  1164.                                 break;
  1165.                         }
  1166.                 }
  1167.         }
  1168. }
  1169.  
  1170.  
  1171. //
  1172. bool MoveHero()
  1173. {
  1174.         int ddx;
  1175.         Byte *nextPtr;
  1176.         Byte mapEl;
  1177.         bool result;
  1178.  
  1179.         //
  1180.         if ( heroDX == 0 && heroDY == 0 ) return false;
  1181.         //
  1182.         result = false;
  1183.         //
  1184.         nextPtr = heroPtr + ( heroDX + heroDY );
  1185.         //
  1186.         ddx = ( ( heroPtr - worldMap ) % mapSizeX ) - ( ( nextPtr - worldMap ) % mapSizeX );
  1187.         //
  1188.         if ( ddx < -1 || ddx > 1 || nextPtr < worldMap || nextPtr >= ( worldMap + ( mapSizeX * mapSizeY ) ) )
  1189.         {
  1190.                 heroDX = 0;
  1191.                 heroDY = 0;
  1192.                 return false;
  1193.         }
  1194.  
  1195.  
  1196.         //
  1197.         mapEl = nextPtr[0];
  1198.         //
  1199.         if ( sTrackList.GetCount() > 0 )
  1200.         {
  1201.                 //
  1202.                 switch ( mapEl )
  1203.                 {
  1204.                 //
  1205.                 case gmEmpty:
  1206.                         sTrackList.Add( nextPtr );
  1207.                         break;
  1208.                 //
  1209.                 case gmBonus1:
  1210.                         bonus1Count = BONUS1_LIFETIME;
  1211.                         ChangeHero();
  1212.                         goToNextLevel = ProcessEndTrack();
  1213.                         return false;
  1214.                         break;
  1215.                 //
  1216.                 case gmBonus2:
  1217.                         lifeCount++;
  1218.                         goToNextLevel = ProcessEndTrack();
  1219.                         return false;
  1220.                         break;
  1221.                 //
  1222.                 case gmWall:
  1223.                         goToNextLevel = ProcessEndTrack();
  1224.                         return false;
  1225.                         break;
  1226.                 //
  1227.                 case gmEnemy1:
  1228.                         if ( bonus1Count > 0 )
  1229.                         {
  1230.                                 //
  1231.                                 EatEnemy( nextPtr );
  1232.                                 //
  1233.                                 goToNextLevel = ProcessEndTrack();
  1234.                                 //
  1235.                                 return false;
  1236.                                 break;
  1237.                         }
  1238.                         else
  1239.                         {
  1240.                                 //
  1241.                                 return true;
  1242.                         }
  1243.                         break;
  1244.                 //
  1245.                 case gmEnemy2:
  1246.                         if ( bonus1Count > 0 )
  1247.                         {
  1248.                                 //
  1249.                                 EatEnemy( nextPtr );
  1250.                                 sTrackList.Add( nextPtr );
  1251.                                 break;
  1252.                         }
  1253.                         else
  1254.                         {
  1255.                                 //
  1256.                                 return true;
  1257.                         }
  1258.                         break;
  1259.                 //
  1260.                 default:
  1261.                         return true;
  1262.                         break;
  1263.                 }
  1264.         }
  1265.         else
  1266.         {
  1267.                 //
  1268.                 switch ( mapEl )
  1269.                 {
  1270.                 //
  1271.                 case gmEmpty:
  1272.                         sTrackList.Add( nextPtr );
  1273.                         break;
  1274.                 //
  1275.                 case gmBonus1:
  1276.                         bonus1Count = BONUS1_LIFETIME;
  1277.                         break;
  1278.                 //
  1279.                 case gmBonus2:
  1280.                         lifeCount++;
  1281.                         break;
  1282.                 //
  1283.                 case gmWall:
  1284.                         break;
  1285.                 //
  1286.                 case gmEnemy1:
  1287.                         if ( bonus1Count > 0 )
  1288.                         {
  1289.                                 EatEnemy( nextPtr );
  1290.                         }
  1291.                         else
  1292.                         {
  1293.                                 result = true;
  1294.                         }
  1295.                         break;
  1296.                 //
  1297.                 case gmEnemy2:
  1298.                         if ( bonus1Count > 0 )
  1299.                         {
  1300.                                 EatEnemy( nextPtr );
  1301.                                 sTrackList.Add( nextPtr );
  1302.                         }
  1303.                         else
  1304.                         {
  1305.                                 result = true;
  1306.                         }
  1307.                         break;
  1308.                 //
  1309.                 default:
  1310.                         result = true;
  1311.                         break;
  1312.                 }
  1313.         }
  1314.  
  1315.         //
  1316.         mapDiffList.Add( sMapDiff( heroPtr, sTrackList.GetCount() <= 1 ? gmWall : currentTrack ) );
  1317.         heroPtr = nextPtr;
  1318.         mapDiffList.Add( sMapDiff( heroPtr, currentHero ) );
  1319.  
  1320.         return result;
  1321. }
  1322.  
  1323.  
  1324. //
  1325. bool MoveEnemies()
  1326. {
  1327.         bool result;
  1328.         int i, j, ir;
  1329.  
  1330.         //
  1331.         result = false;
  1332.         ir = 0;
  1333.         //
  1334.         j = mapEnemies.GetCount();
  1335.         //
  1336.         for ( i = 0; i < j; i++ )
  1337.         {
  1338.                 ir += ( mapEnemies[i]->Move() ? 1 : 0 );
  1339.         }
  1340.         //
  1341.         result = ( ir != 0 );
  1342.         //
  1343.         return result;
  1344. }
  1345.  
  1346.  
  1347. //
  1348. void ApplyMapDiffs( bool drawTitle )
  1349. {
  1350.         int i, j;
  1351.  
  1352.         //
  1353.         kos_WindowRedrawStatus( 1 );
  1354.         //
  1355.         if ( drawTitle ) drawWndTitleGo();
  1356.         //
  1357.         j = mapDiffList.GetCount();
  1358.         //
  1359.         for ( i = 0; i < j; i++ )
  1360.         {
  1361.                 ////
  1362.                 //kos_DrawBar(
  1363.                 //      wndXOffet + ( ( ( mapDiffList[i].elPtr - worldMap ) % mapSizeX ) * blockSize ),
  1364.                 //      wndYOffset + ( ( ( mapDiffList[i].elPtr - worldMap ) / mapSizeX ) * blockSize ),
  1365.                 //      blockSize, blockSize,
  1366.                 //      mapColours[mapDiffList[i].mapEl]
  1367.                 //);
  1368.                 //
  1369.                 kos_PutImage(
  1370.                         mapColours[mapDiffList[i].mapEl],
  1371.                         blockSize,
  1372.                         blockSize,
  1373.                         wndXOffet + ( ( ( mapDiffList[i].elPtr - worldMap ) % mapSizeX ) * blockSize ),
  1374.                         wndYOffset + ( ( ( mapDiffList[i].elPtr - worldMap ) / mapSizeX ) * blockSize )
  1375.                         );
  1376.         }
  1377.         //
  1378.         kos_WindowRedrawStatus( 2 );
  1379.         //
  1380.         mapDiffList.Clear();
  1381. }
  1382.  
  1383.  
  1384. //
  1385. void DeadHeroProcess()
  1386. {
  1387.         int i, j;
  1388.         Byte *mPtr = beep1;
  1389.  
  1390.         // beep
  1391.         __asm{
  1392.                 mov eax, 55
  1393.                 mov ebx, eax
  1394.                 mov esi, mPtr
  1395.                 push eax
  1396.                 int 0x40
  1397.                 pop eax
  1398.         }
  1399.         //
  1400.         j = sTrackList.GetCount();
  1401.         //
  1402.         for ( i = 0; i < j; i++ )
  1403.         {
  1404.                 //
  1405.                 mapDiffList.Add( sMapDiff( sTrackList[i], gmEmpty ) );
  1406.         }
  1407.         //
  1408.         mapDiffList.Add( sMapDiff( heroPtr, sTrackList.GetCount() > 0 ? gmEmpty : gmWall ) );
  1409.         //
  1410.         sTrackList.Clear();
  1411.         //
  1412.         heroPtr = worldMap;
  1413.         //
  1414.         while ( heroPtr[0] != gmWall ) heroPtr++;
  1415.         //
  1416.         mapDiffList.Add( sMapDiff( heroPtr, gmHero ) );
  1417.         //
  1418.         noBonus = true;
  1419.         //
  1420.         lifeCount--;
  1421.         //
  1422.         heroDX = 0;
  1423.         heroDY = 0;
  1424.         lastMoveDirection = 0;
  1425. }
  1426.  
  1427.  
  1428. //
  1429. bool CheckForNextLevel()
  1430. {
  1431.         //
  1432.         if ( goToNextLevel )
  1433.         {
  1434.                 //
  1435.                 CreateFlipMap();
  1436.                 goToNextLevel = false;
  1437.                 currentLevel++;
  1438.                 appState = appStateHideMap;
  1439.                 flipMapCount = 0;
  1440.                 return true;
  1441.         }
  1442.  
  1443.         //
  1444.         return false;
  1445. }
  1446.  
  1447.  
  1448. //
  1449. void SetGameVars()
  1450. {
  1451.         //
  1452.         currentLevel = 1;
  1453.         lifeCount = 3;
  1454.         noBonus = true;
  1455.         bonus1Set = false;
  1456.         bonus2Set = false;
  1457.         bonus1Count = 0;
  1458.         goToNextLevel = false;
  1459.         currentHero = gmHero;
  1460.         currentTrack = gmTrack;
  1461.         scoreCount = 0;
  1462.         enterName = -1;
  1463.         //
  1464.         wndSizeX = ((mapSizeX*blockSize)+2);
  1465.         wndSizeY = ((mapSizeY*blockSize)+23);
  1466.         //
  1467.         kos_ChangeWindow( -1, -1, wndSizeX, wndSizeY );
  1468. }
  1469.  
  1470. //
  1471. void SetEntryVars()
  1472. {
  1473.         //
  1474.         wndSizeX = ENTRY_WND_SIZE_X;
  1475.         wndSizeY = ENTRY_WND_SIZE_Y;
  1476.         //
  1477.         kos_ChangeWindow( -1, -1, wndSizeX, wndSizeY );
  1478.         kos_SetKeyboardDataMode( KM_SCANS );
  1479. }
  1480.  
  1481.  
  1482. //
  1483. void __cdecl ReleaseTop10()
  1484. {
  1485.         //
  1486.         if ( top10Heroes != NULL )
  1487.         {
  1488.                 //
  1489.                 memcpy( top10Heroes->block, heroTbl, sizeof(heroTbl) );
  1490.                 //
  1491.                 top10Heroes->SaveToDisk();
  1492.                 //
  1493.                 delete top10Heroes;
  1494.         }
  1495. }
  1496.  
  1497.  
  1498. //
  1499. void PrepareTop10()
  1500. {
  1501.         //
  1502.         top10Heroes = new hiScoreFile;
  1503.         //
  1504.         atexit( ReleaseTop10 );
  1505.         //
  1506.         if ( top10Heroes->LoadFromDisk() )
  1507.         {
  1508.                 //
  1509.                 memcpy( heroTbl, top10Heroes->block, sizeof(heroTbl) );
  1510.         }
  1511. }
  1512.  
  1513.  
  1514. //
  1515. void SetUpTop10()
  1516. {
  1517.         int i, j;
  1518.         Byte keyCode;
  1519.  
  1520.         //
  1521.         while ( kos_CheckForEvent() == 2 ) kos_GetKey( keyCode );
  1522.         //
  1523.         kos_SetKeyboardDataMode( KM_CHARS );
  1524.         //
  1525.         kos_ChangeWindow( -1, -1, TOP10_WND_SIZE_X, TOP10_WND_SIZE_Y );
  1526.         //
  1527.         for ( i = 0; i < TOP_TBL_SIZE; i++ )
  1528.         {
  1529.                 //
  1530.                 if ( heroTbl[i].score < scoreCount )
  1531.                 {
  1532.                         //
  1533.                         for ( j = TOP_TBL_SIZE - 1; j > i; j-- )
  1534.                         {
  1535.                                 //
  1536.                                 heroTbl[j] = heroTbl[j-1];
  1537.                         }
  1538.                         //
  1539.                         heroTbl[i].ClearName();
  1540.                         heroTbl[i].score = scoreCount;
  1541.                         //
  1542.                         enterName = i;
  1543.                         enterCharNdx = 0;
  1544.                         //
  1545.                         break;
  1546.                 }
  1547.         }
  1548. }
  1549.  
  1550.  
  1551. //
  1552. // òî÷êà âõîäà è ôóíêöèÿ îáðàáîòêè ñîîáùåíèé
  1553. //
  1554. void kos_Main()
  1555. {
  1556.         Dword buttonID;
  1557.         Byte keyCode;
  1558.         Byte *bPtr;
  1559.         bool workOn = true;
  1560.         char *cPtr;
  1561.  
  1562.         // îòäåëÿåì èìÿ ìîäóëÿ îò ïóòè
  1563.         cPtr = strrchr( kosExePath, '/' );
  1564.         // ïðîâåðêà ;)
  1565.         if ( cPtr == NULL )
  1566.         {
  1567.                 //
  1568.                 rtlDebugOutString( "Invalid path to executable." );
  1569.                 //
  1570.                 return;
  1571.         }
  1572.         //
  1573.         cPtr[1] = 0;
  1574.         //
  1575.         strcpy( top10FilePath, kosExePath );
  1576.         //
  1577.         strcpy( top10FilePath + ((cPtr - kosExePath) + 1), "xonix.t10" );
  1578.  
  1579.         // âûïîëíåíèå ôóíêöèé èíèöèàëèçàöèè
  1580.         kos_SetKeyboardDataMode( KM_SCANS );
  1581.         //
  1582.         PrepareTop10();
  1583.  
  1584.         //
  1585.         while( workOn )
  1586.         {
  1587.                 switch ( appState )
  1588.                 {
  1589.                 //
  1590.                 case appStateEntry:
  1591.                         switch ( kos_WaitForEvent() )
  1592.                         {
  1593.                         // ïåðåðèñîâêà îêíà
  1594.                         case 1:
  1595.                                 DrawAppWindow();
  1596.                                 break;
  1597.  
  1598.                         //
  1599.                         case 2:
  1600.                                 kos_GetKey( keyCode );
  1601.                                 switch ( keyCode )
  1602.                                 {
  1603.                                 //
  1604.                                 case 2:
  1605.                                         //
  1606.                                         appState = appStateGo;
  1607.                                         SetGameVars();
  1608.                                         initWorldMap();
  1609.                                         DrawAppWindow();
  1610.                                         break;
  1611.  
  1612.                                 //
  1613.                                 case 3:
  1614.                                         xonixFree();
  1615.                                         workOn = false;
  1616.                                         break;
  1617.                                 }
  1618.                                 break;
  1619.                         //
  1620.                         case 3:
  1621.                                 //
  1622.                                 if ( ! kos_GetButtonID( buttonID ) ) break;
  1623.                                 //
  1624.                                 switch ( buttonID )
  1625.                                 {
  1626.                                 //
  1627.                                 case BT_SIZE_X_PLUS:
  1628.                                         mapSizeX += 2;
  1629.                                         if ( mapSizeX > MAX_X_SIZE ) mapSizeX = MAX_X_SIZE;
  1630.                                         break;
  1631.                                 //
  1632.                                 case BT_SIZE_X_MINUS:
  1633.                                         mapSizeX -= 2;
  1634.                                         if ( mapSizeX < MIN_X_SIZE ) mapSizeX = MIN_X_SIZE;
  1635.                                         break;
  1636.                                 //
  1637.                                 case BT_SIZE_Y_PLUS:
  1638.                                         mapSizeY += 2;
  1639.                                         if ( mapSizeY > MAX_Y_SIZE ) mapSizeY = MAX_Y_SIZE;
  1640.                                         break;
  1641.                                 //
  1642.                                 case BT_SIZE_Y_MINUS:
  1643.                                         mapSizeY -= 2;
  1644.                                         if ( mapSizeY < MIN_Y_SIZE ) mapSizeY = MIN_Y_SIZE;
  1645.                                         break;
  1646.                                 //
  1647.                                 case BT_LOOP_MINUS:
  1648.                                         loopDelay++;;
  1649.                                         if ( loopDelay > MAX_LOOP_DELAY ) loopDelay = MAX_LOOP_DELAY;
  1650.                                         break;
  1651.                                 //
  1652.                                 case BT_LOOP_PLUS:
  1653.                                         loopDelay--;;
  1654.                                         if ( loopDelay < MIN_LOOP_DELAY ) loopDelay = MIN_LOOP_DELAY;
  1655.                                         break;
  1656.                                 //
  1657.                                 default:
  1658.                                         break;
  1659.                                 }
  1660.                                 DrawAppWindow();
  1661.                                 break;
  1662.                         //
  1663.                         default:
  1664.                                 break;
  1665.                         }
  1666.                         break;
  1667.                 //
  1668.                 case appStateGo:
  1669.                         //
  1670.                         kos_Pause( loopDelay );
  1671.                         //
  1672.                         if ( bonus1Count > 0 ) bonus1Count--;
  1673.                         //
  1674.                         ChangeHero();
  1675.                         //
  1676.                         switch( kos_WaitForEvent( 1 ) )
  1677.                         {
  1678.                         //
  1679.                         case 0:
  1680.                                 if ( MoveHero() )
  1681.                                 {
  1682.                                         //
  1683.                                         DeadHeroProcess();
  1684.                                 }
  1685.                                 else
  1686.                                 {
  1687.                                         //
  1688.                                         if ( CheckForNextLevel() )
  1689.                                         {
  1690.                                                 break;
  1691.                                         }
  1692.                                 }
  1693.                                 if ( MoveEnemies() )
  1694.                                 {
  1695.                                         // ñîæðàëè èãðîêà
  1696.                                         DeadHeroProcess();
  1697.                                 }
  1698.                                 ApplyMapDiffs();
  1699.                                 break;
  1700.                         //
  1701.                         case 1:
  1702.                                 DrawAppWindow();
  1703.                                 break;
  1704.  
  1705.                         //
  1706.                         case 2:
  1707.                                 do kos_GetKey( keyCode ); while ( keyCode & 0x80 );
  1708.                                 switch ( keyCode )
  1709.                                 {
  1710.                                 //
  1711.                                 case 0x1:
  1712.                                         SetEntryVars();
  1713.                                         appState = appStateEntry;
  1714.                                         clearWorldMap();
  1715.                                         DrawAppWindow();
  1716.                                         continue;
  1717.  
  1718.                                 //
  1719.                                 case 0x39:
  1720.                                         appState = appStatePause;
  1721.                                         break;
  1722.  
  1723.                                 //
  1724.                                 case 0x48:
  1725.                                         heroDX = 0;
  1726.                                         if ( lastMoveDirection == 0x50 )
  1727.                                         {
  1728.                                                 heroDY = 0;
  1729.                                                 lastMoveDirection = 0;
  1730.                                         }
  1731.                                         else
  1732.                                         {
  1733.                                                 heroDY = -mapSizeX;
  1734.                                                 lastMoveDirection = 0x48;
  1735.                                         }
  1736.                                         break;
  1737.  
  1738.                                 //
  1739.                                 case 0x50:
  1740.                                         heroDX = 0;
  1741.                                         if ( lastMoveDirection == 0x48 )
  1742.                                         {
  1743.                                                 heroDY = 0;
  1744.                                                 lastMoveDirection = 0;
  1745.                                         }
  1746.                                         else
  1747.                                         {
  1748.                                                 heroDY = mapSizeX;
  1749.                                                 lastMoveDirection = 0x50;
  1750.                                         }
  1751.                                         break;
  1752.  
  1753.                                 //
  1754.                                 case 0x4B:
  1755.                                         heroDY = 0;
  1756.                                         if ( lastMoveDirection == 0x4D )
  1757.                                         {
  1758.                                                 heroDX = 0;
  1759.                                                 lastMoveDirection = 0;
  1760.                                         }
  1761.                                         else
  1762.                                         {
  1763.                                                 heroDX = -1;
  1764.                                                 lastMoveDirection = 0x4B;
  1765.                                         }
  1766.                                         break;
  1767.  
  1768.                                 //
  1769.                                 case 0x4D:
  1770.                                         heroDY = 0;
  1771.                                         if ( lastMoveDirection == 0x4B )
  1772.                                         {
  1773.                                                 heroDX = 0;
  1774.                                                 lastMoveDirection = 0;
  1775.                                         }
  1776.                                         else
  1777.                                         {
  1778.                                                 heroDX = 1;
  1779.                                                 lastMoveDirection = 0x4D;
  1780.                                         }
  1781.                                         break;
  1782.                                 }
  1783.                                 //
  1784.                                 if ( MoveHero() )
  1785.                                 {
  1786.                                         //
  1787.                                         DeadHeroProcess();
  1788.                                 }
  1789.                                 else
  1790.                                 {
  1791.                                         //
  1792.                                         if ( CheckForNextLevel() )
  1793.                                         {
  1794.                                                 break;
  1795.                                         }
  1796.                                 }
  1797.                                 if ( MoveEnemies() )
  1798.                                 {
  1799.                                         // ñîæðàëè èãðîêà
  1800.                                         DeadHeroProcess();
  1801.                                 }
  1802.                                 ApplyMapDiffs();
  1803.                                 break;
  1804.  
  1805.                         //
  1806.                         default:
  1807.                                 //
  1808.                                 if ( MoveHero() )
  1809.                                 {
  1810.                                         //
  1811.                                         DeadHeroProcess();
  1812.                                 }
  1813.                                 if ( MoveEnemies() )
  1814.                                 {
  1815.                                         // ñîæðàëè èãðîêà
  1816.                                         DeadHeroProcess();
  1817.                                 }
  1818.                                 ApplyMapDiffs();
  1819.                                 break;
  1820.                         }
  1821.                         //
  1822.                         if ( lifeCount <= 0 )
  1823.                         {
  1824.                                 appState = appStateAfterDeath;
  1825.                                 DrawAppWindow();
  1826.                         }
  1827.                         //
  1828.                         break;
  1829.  
  1830.                 //
  1831.                 case appStateAfterDeath:
  1832.                         switch ( kos_WaitForEvent() )
  1833.                         {
  1834.                         //
  1835.                         case 1:
  1836.                                 DrawAppWindow();
  1837.                                 break;
  1838.                         //
  1839.                         case 2:
  1840.                                 do kos_GetKey( keyCode ); while ( keyCode & 0x80 );
  1841.                                 if ( keyCode != 0 )
  1842.                                 {
  1843.                                         //
  1844.                                         appState = appStateTop10;
  1845.                                         SetUpTop10();
  1846.                                         DrawAppWindow();
  1847.                                 }
  1848.                                 break;
  1849.                         //
  1850.                         case 3:
  1851.                                 if ( kos_GetButtonID( buttonID ) )
  1852.                                 {
  1853.                                         //
  1854.                                         if ( buttonID == 1 )
  1855.                                         {
  1856.                                                 //
  1857.                                                 appState = appStateTop10;
  1858.                                                 SetUpTop10();
  1859.                                                 DrawAppWindow();
  1860.                                         }
  1861.                                 }
  1862.                         //
  1863.                         default:
  1864.                                 break;
  1865.                         }
  1866.                         break;
  1867.  
  1868.                 //
  1869.                 case appStateTop10:
  1870.                         switch ( kos_WaitForEvent() )
  1871.                         {
  1872.                         //
  1873.                         case 1:
  1874.                                 DrawAppWindow();
  1875.                                 break;
  1876.                         //
  1877.                         case 2:
  1878.                                 //
  1879.                                 kos_GetKey( keyCode );
  1880.                                 //
  1881.                                 if ( enterName < 0 )
  1882.                                 {
  1883.                                         //
  1884.                                         if ( keyCode == 0x1b )
  1885.                                         {
  1886.                                                 //
  1887.                                                 SetEntryVars();
  1888.                                                 clearWorldMap();
  1889.                                                 appState = appStateEntry;
  1890.                                                 DrawAppWindow();
  1891.                                         }
  1892.                                 }
  1893.                                 else
  1894.                                 {
  1895.                                         //
  1896.                                         switch ( keyCode )
  1897.                                         {
  1898.                                         //
  1899.                                         case 13:
  1900.                                                 //
  1901.                                                 enterName = -1;
  1902.                                                 break;
  1903.                                         //
  1904.                                         case 8:
  1905.                                                 //
  1906.                                                 if ( enterCharNdx > 0 )
  1907.                                                 {
  1908.                                                         //
  1909.                                                         heroTbl[enterName].name[--enterCharNdx] = '.';
  1910.                                                 }
  1911.                                                 break;
  1912.                                         //
  1913.                                         default:
  1914.                                                 if ( keyCode >= 0x20 )
  1915.                                                 {
  1916.                                                         //
  1917.                                                         heroTbl[enterName].name[enterCharNdx++] = keyCode;
  1918.                                                         //
  1919.                                                         if ( enterCharNdx >= sizeof(heroTbl[0].name) )
  1920.                                                         {
  1921.                                                                 //
  1922.                                                                 enterName = -1;
  1923.                                                         }
  1924.                                                 }
  1925.                                                 break;
  1926.                                         }
  1927.                                         //
  1928.                                         DrawAppWindow();
  1929.                                 }
  1930.                                 //
  1931.                                 break;
  1932.                         //
  1933.                         default:
  1934.                                 break;
  1935.                         }
  1936.                         break;
  1937.  
  1938.                 //
  1939.                 case appStatePause:
  1940.                         switch ( kos_WaitForEvent() )
  1941.                         {
  1942.                         case 1:
  1943.                                 DrawAppWindow();
  1944.                                 break;
  1945.  
  1946.                         case 2:
  1947.                                 do kos_GetKey( keyCode ); while ( keyCode & 0x80 );
  1948.                                 if ( keyCode != 0 )
  1949.                                 {
  1950.                                         //
  1951.                                         appState = appStateGo;
  1952.                                 }
  1953.                                 break;
  1954.  
  1955.                         default:
  1956.                                 break;
  1957.                         }
  1958.                         break;
  1959.  
  1960.                 //
  1961.                 case appStateHideMap:
  1962.                         //
  1963.                         switch ( kos_WaitForEvent( 1 ) )
  1964.                         {
  1965.                         case 1:
  1966.                                 DrawAppWindow();
  1967.                                 break;
  1968.                         case 2:
  1969.                                 while ( kos_GetKey( keyCode ) );
  1970.                                 break;
  1971.                         default:
  1972.                                 bPtr = worldMap + (flipMapPtr[flipMapCount].x + (flipMapPtr[flipMapCount].y * mapSizeX));
  1973.                                 mapDiffList.Add( sMapDiff( bPtr, gmFlip ) );
  1974.                                 mapDiffList.Add( sMapDiff( bPtr + 1, gmFlip ) );
  1975.                                 mapDiffList.Add( sMapDiff( bPtr + mapSizeX, gmFlip ) );
  1976.                                 mapDiffList.Add( sMapDiff( bPtr + (mapSizeX + 1), gmFlip ) );
  1977.                                 ApplyMapDiffs( false );
  1978.                                 break;
  1979.                         }
  1980.                         //
  1981.                         flipMapCount++;
  1982.                         //
  1983.                         if ( flipMapCount >= flipMapSize )
  1984.                         {
  1985.                                 flipMapCount = 0;
  1986.                                 appState = appStateShowMap;
  1987.                                 DrawAppWindow();
  1988.                         }
  1989.                         break;
  1990.                 //
  1991.                 case appStateShowMap:
  1992.                         //
  1993.                         switch ( kos_WaitForEvent( 1 ) )
  1994.                         {
  1995.                         case 1:
  1996.                                 DrawAppWindow();
  1997.                                 break;
  1998.                         default:
  1999.                                 break;
  2000.                         }
  2001.                         //
  2002.                         flipMapCount++;
  2003.                         //
  2004.                         if ( flipMapCount >= BEFORE_START_LEVEL )
  2005.                         {
  2006.                                 clearWorldMap();
  2007.                                 flipMapCount = 0;
  2008.                                 initWorldMap();
  2009.                                 appState = appStateGo;
  2010.                                 DrawAppWindow();
  2011.                         }
  2012.                         //
  2013.                         break;
  2014.                 }
  2015.         }
  2016. }
  2017.  
  2018.  
  2019. //
  2020. void DrawEntryScreen()
  2021. {
  2022.         PRINTK pr;
  2023.         char line[64];
  2024.  
  2025.         //
  2026.         kos_DefineAndDrawWindow(
  2027.                 100, 100,
  2028.                 wndSizeX, wndSizeY,
  2029.                 0, 0,
  2030.                 0, 0x2040A0,
  2031.                 0x2040A0
  2032.                 );
  2033.         //
  2034.         kos_WriteTextToWindow(
  2035.                 4, 4,
  2036.                 0x10, 0x42D2E2,
  2037.                 MainWindowTitle,
  2038.                 sizeof( MainWindowTitle ) - 1
  2039.                 );
  2040.         //
  2041.         kos_WriteTextToWindow(
  2042.                 8, 32,
  2043.                 0x10, 0x12FF12,
  2044.                 menuStr1,
  2045.                 sizeof( menuStr1 ) - 1
  2046.                 );
  2047.         //
  2048.         kos_WriteTextToWindow(
  2049.                 8, 48,
  2050.                 0x10, 0x12FF12,
  2051.                 menuStr2,
  2052.                 sizeof( menuStr2 ) - 1
  2053.                 );
  2054.         //
  2055.         kos_WriteTextToWindow(
  2056.                 8, 80,
  2057.                 0x10, 0xD0FF12,
  2058.                 menuStr3,
  2059.                 sizeof( menuStr3 ) - 1
  2060.                 );
  2061.         //
  2062.         kos_WriteTextToWindow(
  2063.                 8, 96,
  2064.                 0x10, 0xD0FF12,
  2065.                 menuStr4,
  2066.                 sizeof( menuStr4 ) - 1
  2067.                 );
  2068.         // ðàçìåð ïîëÿ
  2069.         pr.fmtline = worldSizeStr;
  2070.         pr.args[0] = mapSizeX;
  2071.         pr.args[1] = mapSizeY;
  2072.         sprintk( line, &pr );
  2073.         //
  2074.         kos_WriteTextToWindow(
  2075.                 8, 112,
  2076.                 0x10, 0x12C0D0,
  2077.                 line,
  2078.                 strlen( line )
  2079.                 );
  2080.         // êíîïêè X
  2081.         kos_DefineButton(
  2082.                 ENTRY_WND_SIZE_X - 58, 112,
  2083.                 12, 12,
  2084.                 BT_SIZE_X_MINUS,
  2085.                 0xCCCCCC
  2086.                 );
  2087.         //
  2088.         kos_PutImage( bmPMButton + 12, 6, 2, ENTRY_WND_SIZE_X - 58 + 3, 117 );
  2089.         //
  2090.         kos_DefineButton(
  2091.                 ENTRY_WND_SIZE_X - 45, 112,
  2092.                 12, 12,
  2093.                 BT_SIZE_X_PLUS,
  2094.                 0xCCCCCC
  2095.                 );
  2096.         //
  2097.         kos_PutImage( bmPMButton, 6, 6, ENTRY_WND_SIZE_X - 45 + 3, 115 );
  2098.         // êíîïêè Y
  2099.         kos_DefineButton(
  2100.                 ENTRY_WND_SIZE_X - 29, 112,
  2101.                 12, 12,
  2102.                 BT_SIZE_Y_MINUS,
  2103.                 0xCCCCCC
  2104.                 );
  2105.         //
  2106.         kos_PutImage( bmPMButton + 12, 6, 2, ENTRY_WND_SIZE_X - 29 + 3, 117 );
  2107.         //
  2108.         kos_DefineButton(
  2109.                 ENTRY_WND_SIZE_X - 16, 112,
  2110.                 12, 12,
  2111.                 BT_SIZE_Y_PLUS,
  2112.                 0xCCCCCC
  2113.                 );
  2114.         //
  2115.         kos_PutImage( bmPMButton, 6, 6, ENTRY_WND_SIZE_X - 16 + 3, 115 );
  2116.         //
  2117.         //çàäåðæêà â öèêëå âûáîðêè ñîîáùåíèé
  2118.         pr.fmtline = mainLoopDelayStr;
  2119.         pr.args[0] = MAX_LOOP_DELAY + MIN_LOOP_DELAY - loopDelay;
  2120.         sprintk( line, &pr );
  2121.         //
  2122.         kos_WriteTextToWindow(
  2123.                 8, 128,
  2124.                 0x10, 0x12C0D0,
  2125.                 line,
  2126.                 strlen( line )
  2127.                 );
  2128.         //
  2129.         kos_DefineButton(
  2130.                 ENTRY_WND_SIZE_X - 29, 128,
  2131.                 12, 12,
  2132.                 BT_LOOP_MINUS,
  2133.                 0xCCCCCC
  2134.                 );
  2135.         //
  2136.         kos_PutImage( bmPMButton + 12, 6, 2, ENTRY_WND_SIZE_X - 29 + 3, 133 );
  2137.         //
  2138.         kos_DefineButton(
  2139.                 ENTRY_WND_SIZE_X - 16, 128,
  2140.                 12, 12,
  2141.                 BT_LOOP_PLUS,
  2142.                 0xCCCCCC
  2143.                 );
  2144.         //
  2145.         kos_PutImage( bmPMButton, 6, 6, ENTRY_WND_SIZE_X - 16 + 3, 131 );
  2146. }
  2147.  
  2148.  
  2149. //
  2150. void DrawAppWindow()
  2151. {
  2152.         //
  2153.         kos_WindowRedrawStatus( 1 );
  2154.  
  2155.         switch ( appState )
  2156.         {
  2157.         //
  2158.         case appStateTop10:
  2159.                 DrawTop10Window();
  2160.                 break;
  2161.         //
  2162.         case appStateEntry:
  2163.                 //
  2164.                 DrawEntryScreen();
  2165.                 break;
  2166.         //
  2167.         case appStateGo:
  2168.         case appStateShowMap:
  2169.         case appStatePause:
  2170.                 drawWorldMap();
  2171.                 break;
  2172.         //
  2173.         case appStateAfterDeath:
  2174.                 //
  2175.                 drawWorldMap();
  2176.                 //
  2177.                 kos_DefineButton(
  2178.                         ( wndSizeX / 2 ) - 64,
  2179.                         ( wndSizeY / 2 ) - 16,
  2180.                         128, 32,
  2181.                         1,
  2182.                         0x136793
  2183.                         );
  2184.                 //
  2185.                 kos_WriteTextToWindow(
  2186.                         ( wndSizeX / 2 ) - ( sizeof( thatsAllStr ) * 4 ),
  2187.                         ( wndSizeY / 2 ) - 4,
  2188.                         0x10, 0xFFFFFF,
  2189.                         thatsAllStr,
  2190.                         sizeof ( thatsAllStr ) - 1
  2191.                         );
  2192.  
  2193.                 //
  2194.                 break;
  2195.         //
  2196.         case appStateHideMap:
  2197.                 drawWorldMapForFlip();
  2198.                 break;
  2199.         }
  2200.         //
  2201.         kos_WindowRedrawStatus( 2 );
  2202. }
  2203.  
  2204.  
  2205. //
  2206. void initWorldMap()
  2207. {
  2208.         int i, j, m, allocSize;
  2209.         CWallEnemy *we;
  2210.         CSpaceEnemy *se;
  2211.  
  2212.         //
  2213.         allocSize = mapSizeX * mapSizeY;
  2214.         worldMap = new Byte[allocSize];
  2215.         //
  2216.         __asm{
  2217.                 mov edi, worldMap
  2218.                 mov ecx, allocSize
  2219.                 mov al, gmEmpty
  2220.                 rep stosb
  2221.         }
  2222.  
  2223.  
  2224.         //
  2225.         levelFillEdge = ( ( currentLevel + 1 ) * spacePerEnemy ) + currentLevel;
  2226.         levelFillCount = freeSpaceCount;
  2227.         //
  2228.         if ( ! noBonus )
  2229.         {
  2230.                 lifeCount++;
  2231.         }
  2232.         //
  2233.         noBonus = false;
  2234.         bonus1Set = false;
  2235.         bonus2Set = false;
  2236.         bonus1Count = 0;
  2237.         goToNextLevel = false;
  2238.         currentHero = gmHero;
  2239.         currentTrack = gmTrack;
  2240.  
  2241.         //
  2242.         for ( i = 0; i < mapSizeX; i++ )
  2243.         {
  2244.                 //
  2245.                 worldMap[i] = gmWall;
  2246.                 worldMap[mapSizeX + i] = gmWall;
  2247.                 //
  2248.                 worldMap[((mapSizeY-2)*mapSizeX) + i] = gmWall;
  2249.                 worldMap[((mapSizeY-1)*mapSizeX) + i] = gmWall;
  2250.         }
  2251.         //
  2252.         for ( i = 2; i < (mapSizeY-2); i++ )
  2253.         {
  2254.                 //
  2255.                 worldMap[(i*mapSizeX)] = gmWall;
  2256.                 worldMap[(i*mapSizeX) + 1] = gmWall;
  2257.                 worldMap[(i*mapSizeX) + mapSizeX - 2] = gmWall;
  2258.                 worldMap[(i*mapSizeX) + mapSizeX - 1] = gmWall;
  2259.         }
  2260.         //
  2261.         heroPtr = worldMap + ( mapSizeX / 2 );
  2262.         heroPtr[0] = gmHero;
  2263.         heroDX = 0;
  2264.         heroDY = 0;
  2265.         //
  2266.         for ( i = 0; i < currentLevel; i++ )
  2267.         {
  2268.                 //
  2269.                 for (
  2270.                         j = ( rtlRand() % (mapSizeX * (mapSizeY - 2)) ) + (mapSizeX * 2);
  2271.                         worldMap[j] != gmWall;
  2272.                         j = rtlRand() % (mapSizeX * mapSizeY)
  2273.                         );
  2274.                 //
  2275.                 we = new CWallEnemy();
  2276.                 //
  2277.                 we->ePtr = worldMap + j;
  2278.                 we->dx = rtlRand() & 1 ? 1 : -1;
  2279.                 we->dy = rtlRand() & 1 ? mapSizeX : -mapSizeX;
  2280.                 //
  2281.                 mapEnemies.Add( we );
  2282.                 //
  2283.                 worldMap[j] = gmEnemy1;
  2284.         }
  2285.         //
  2286.         m = currentLevel + 1;
  2287.         //
  2288.         for ( i = 0; i < m; i++ )
  2289.         {
  2290.                 //
  2291.                 for (
  2292.                         j = rtlRand() % (mapSizeX * mapSizeY);
  2293.                         worldMap[j] != gmEmpty;
  2294.                         j = rtlRand() % (mapSizeX * mapSizeY)
  2295.                         );
  2296.                 //
  2297.                 se = new CSpaceEnemy();
  2298.                 //
  2299.                 se->ePtr = worldMap + j;
  2300.                 se->dx = rtlRand() & 1 ? 1 : -1;
  2301.                 se->dy = rtlRand() & 1 ? mapSizeX : -mapSizeX;
  2302.                 //
  2303.                 mapEnemies.Add( se );
  2304.                 //
  2305.                 worldMap[j] = gmEnemy2;
  2306.         }
  2307. }
  2308.  
  2309.  
  2310. //
  2311. void drawWorldMap()
  2312. {
  2313.         //
  2314.         kos_DefineAndDrawWindow(
  2315.                 100, 100,
  2316.                 wndSizeX, wndSizeY,
  2317.                 0, 0,
  2318.                 0, 0x2040A0,
  2319.                 0x2040A0
  2320.                 );
  2321.         //
  2322.         drawWndTitleGo();
  2323.         //
  2324.         drawWorldMapForFlip();
  2325. }
  2326.  
  2327.  
  2328. //
  2329. int GetCompletePercents()
  2330. {
  2331.         int n1, n2;
  2332.  
  2333.         //
  2334.         n1 = freeSpaceCount - levelFillCount;
  2335.         n2 = freeSpaceCount - levelFillEdge;
  2336.         //
  2337.         return ( n1 >= n2 ) ? 100 : ( n1 * 100 ) / n2;
  2338. }
  2339.  
  2340.  
  2341. //
  2342. void drawWndTitleGo()
  2343. {
  2344.         PRINTK pr;
  2345.         char line[64];
  2346.  
  2347.         //
  2348.         kos_DrawBar(
  2349.                 1, 1,
  2350.                 wndSizeX - 2, 18,
  2351.                 0x2040A0
  2352.                 );
  2353.  
  2354.         //
  2355.         pr.fmtline = goWndTitle;
  2356.         pr.args[0] = currentLevel;
  2357.         pr.args[1] = GetCompletePercents();
  2358.         pr.args[2] = lifeCount;
  2359.         pr.args[3] = scoreCount;
  2360.         sprintk( line, &pr );
  2361.         //
  2362.         kos_WriteTextToWindow(
  2363.                 4, 4,
  2364.                 0x10, 0x42D2E2,
  2365.                 line,
  2366.                 strlen( line )
  2367.                 );
  2368.         //
  2369.         if ( bonus1Count > 0 )
  2370.         {
  2371.                 //
  2372.                 kos_DrawBar(
  2373.                         2, 22 - BONUS1_IND_HSIZE - 1,
  2374.                         wndSizeX - 4, BONUS1_IND_HSIZE,
  2375.                         0x2040A0
  2376.                         );
  2377.                 //
  2378.                 kos_DrawBar(
  2379.                         2, 22 - BONUS1_IND_HSIZE - 1,
  2380.                         ( bonus1Count * ( wndSizeX - 4 ) ) / BONUS1_LIFETIME, BONUS1_IND_HSIZE,
  2381.                         0x5720B0
  2382.                         );
  2383.         }
  2384. }
  2385.  
  2386. //
  2387. void drawWorldMapForFlip()
  2388. {
  2389.         int i, j;
  2390.         Byte *mPtr = worldMap;
  2391.  
  2392.         //
  2393.         for ( i = 0; i < mapSizeY; i++ )
  2394.         {
  2395.                 //
  2396.                 for ( j = 0; j < mapSizeX; j++ )
  2397.                 {
  2398.                         ////
  2399.                         //kos_DrawBar(
  2400.                         //      wndXOffet + ( j * blockSize ),
  2401.                         //      wndYOffset + ( i * blockSize ),
  2402.                         //      blockSize, blockSize,
  2403.                         //      mapColours[*mPtr]
  2404.                         //);
  2405.                         //
  2406.                         kos_PutImage(
  2407.                                 mapColours[*mPtr],
  2408.                                 blockSize,
  2409.                                 blockSize,
  2410.                                 wndXOffet + ( j * blockSize ),
  2411.                                 wndYOffset + ( i * blockSize )
  2412.                                 );
  2413.                         //
  2414.                         mPtr++;
  2415.                 }
  2416.         }
  2417. }
  2418.  
  2419.  
  2420. //
  2421. void clearWorldMap()
  2422. {
  2423.         int i, j;
  2424.  
  2425.         //
  2426.         sTrackList.Clear();
  2427.         fillList.Clear();
  2428.         mapDiffList.Clear();
  2429.         //
  2430.         j = mapEnemies.GetCount();
  2431.         //
  2432.         for ( i = 0; i < j; i++ )
  2433.         {
  2434.                 //
  2435.                 delete mapEnemies[i];
  2436.         }
  2437.         //
  2438.         mapEnemies.Clear();
  2439.         //
  2440.         if ( worldMap != NULL )
  2441.         {
  2442.                 delete worldMap;
  2443.                 worldMap = NULL;
  2444.         }
  2445. }
  2446.  
  2447.  
  2448. //
  2449. char Top10WndTitle[] = "Top 10";
  2450.  
  2451. //
  2452. void DrawTop10Window()
  2453. {
  2454.         int i;
  2455.  
  2456.         //
  2457.         kos_DefineAndDrawWindow(
  2458.                 100, 100,
  2459.                 TOP10_WND_SIZE_X, TOP10_WND_SIZE_Y,
  2460.                 0, 0,
  2461.                 0, 0x2040A0,
  2462.                 0x2040A0
  2463.                 );
  2464.         //
  2465.         kos_WriteTextToWindow(
  2466.                 4, 4,
  2467.                 0x0, 0x42D2E2,
  2468.                 Top10WndTitle,
  2469.                 sizeof( Top10WndTitle ) - 1
  2470.                 );
  2471.         //
  2472.         for ( i = 0; i < TOP_TBL_SIZE; i++ )
  2473.         {
  2474.                 //
  2475.                 kos_WriteTextToWindow(
  2476.                         6, wndYOffset + 2 + (i * 10),
  2477.                         0x0, enterName != i ? 0xFFFFFF : 0x00FF00,
  2478.                         heroTbl[i].name,
  2479.                         sizeof( heroTbl[0].name )
  2480.                         );
  2481.                 //
  2482.                 kos_DisplayNumberToWindow(
  2483.                         heroTbl[i].score,
  2484.                         8,
  2485.                         112, wndYOffset + 2 + (i * 10),
  2486.                         0xFFFF55,
  2487.                         nbDecimal,
  2488.                         false
  2489.                         );
  2490.         }
  2491.         //
  2492.         kos_WriteTextToWindow(
  2493.                 6, wndYOffset + 6 + (i * 10),
  2494.                 0x10, 0x1060D0,
  2495.                 enterName >= 0 ? top10str1 : top10str2,
  2496.                 enterName >= 0 ? sizeof(top10str1) - 1 : sizeof(top10str2) - 1
  2497.                 );
  2498. }
  2499.  
  2500.  
  2501.