kolibrios/programs/games/xonix/trunk/main.cpp
Ivan Baravy e7b30b9ca0 fix r5822
git-svn-id: svn://kolibrios.org@5823 a494cfbc-eb01-0410-851d-a64ba20cac60
2015-09-08 20:38:41 +00:00

2574 lines
48 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "kosSyst.h"
#include "mcarray.h"
#include "lang.h"
// áèòìàï ïóñòîãî ìåñòà
RGB bmEmpty[] = {
0x201010, 0x101020, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010,
0x101010, 0x102010, 0x201010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010,
0x101010, 0x101010, 0x101020, 0x102010, 0x101010, 0x101010, 0x101010, 0x101010,
0x101010, 0x101010, 0x101010, 0x201010, 0x101020, 0x101010, 0x101010, 0x101010,
0x101010, 0x101010, 0x101010, 0x101010, 0x102010, 0x201010, 0x101010, 0x101010,
0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101020, 0x102010, 0x101010,
0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x201010, 0x101020,
0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x102010
};
// áèòìàï èãðîêà
RGB bmHero[] = {
0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020C0,
0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020C0, 0x2020A0,
0x2020E0, 0x2020E0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020A0, 0x2020A0,
0x2020E0, 0x2020E0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020A0, 0x2020A0,
0x2020E0, 0x2020E0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020A0, 0x2020A0,
0x2020E0, 0x2020E0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020A0, 0x2020A0,
0x2020E0, 0x2020C0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0,
0x2020C0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0
};
// áèòìàï èãðîêà
RGB bmSuperHero[] = {
0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720B0,
0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720B0, 0x572090,
0x5720D0, 0x5720D0, 0x5720B0, 0x5720B0, 0x5720B0, 0x5720B0, 0x572090, 0x572090,
0x5720D0, 0x5720D0, 0x5720B0, 0x5720B0, 0x5720B0, 0x5720B0, 0x572090, 0x572090,
0x5720D0, 0x5720D0, 0x5720B0, 0x5720B0, 0x5720B0, 0x5720B0, 0x572090, 0x572090,
0x5720D0, 0x5720D0, 0x5720B0, 0x5720B0, 0x5720B0, 0x5720B0, 0x572090, 0x572090,
0x5720D0, 0x5720B0, 0x572090, 0x572090, 0x572090, 0x572090, 0x572090, 0x572090,
0x5720B0, 0x572090, 0x572090, 0x572090, 0x572090, 0x572090, 0x572090, 0x572090
};
// áèòìàï ãàäà, áåãàþùåãî ïî çàïîëíåííîé ìåñòíîñòè
RGB bmEnemy1[] = {
0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xC02020,
0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xC02020, 0xA02020,
0xE02020, 0xE02020, 0xC02020, 0xC02020, 0xC02020, 0xC02020, 0xA02020, 0xA02020,
0xE02020, 0xE02020, 0xC02020, 0xC02020, 0xC02020, 0xC02020, 0xA02020, 0xA02020,
0xE02020, 0xE02020, 0xC02020, 0xC02020, 0xC02020, 0xC02020, 0xA02020, 0xA02020,
0xE02020, 0xE02020, 0xC02020, 0xC02020, 0xC02020, 0xC02020, 0xA02020, 0xA02020,
0xE02020, 0xC02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020,
0xC02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020
};
// áèòìàï ãàäà, áåãàþùåãî ïî ïóñòîìó ìåñòó
RGB bmEnemy2[] = {
0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xC08020,
0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xC08020, 0xA08020,
0xE08020, 0xE08020, 0xC08020, 0xC08020, 0xC08020, 0xC08020, 0xA08020, 0xA08020,
0xE08020, 0xE08020, 0xC08020, 0xC08020, 0xC08020, 0xC08020, 0xA08020, 0xA08020,
0xE08020, 0xE08020, 0xC08020, 0xC08020, 0xC08020, 0xC08020, 0xA08020, 0xA08020,
0xE08020, 0xE08020, 0xC08020, 0xC08020, 0xC08020, 0xC08020, 0xA08020, 0xA08020,
0xE08020, 0xC08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020,
0xC08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020
};
// áèòìàï çàïîëíåíèÿ
RGB bmWall[] = {
0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xCCCCCC,
0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA,
0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA,
0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA,
0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA,
0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA,
0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA,
0xCCCCCC, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA
};
// ñëåä èãðîêà
RGB bmTrack[] = {
0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010,
0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010,
0x101010, 0x101010, 0x101010, 0x1010F0, 0x1010F0, 0x101010, 0x101010, 0x101010,
0x101010, 0x101010, 0x1010F0, 0x1010F0, 0x1010F0, 0x1010F0, 0x101010, 0x101010,
0x101010, 0x101010, 0x1010F0, 0x1010F0, 0x1010F0, 0x1010F0, 0x101010, 0x101010,
0x101010, 0x101010, 0x101010, 0x1010F0, 0x1010F0, 0x101010, 0x101010, 0x101010,
0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010,
0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010
};
// ñëåä èãðîêà
RGB bmSuperTrack[] = {
0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010,
0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010,
0x101010, 0x101010, 0x101010, 0x5310D0, 0x5310D0, 0x101010, 0x101010, 0x101010,
0x101010, 0x101010, 0x5310D0, 0x5310D0, 0x5310D0, 0x5310D0, 0x101010, 0x101010,
0x101010, 0x101010, 0x5310D0, 0x5310D0, 0x5310D0, 0x5310D0, 0x101010, 0x101010,
0x101010, 0x101010, 0x101010, 0x5310D0, 0x5310D0, 0x101010, 0x101010, 0x101010,
0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010,
0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010
};
// çàïîëíåíèå ýêðàíà äëÿ ñìåíû óðîâíÿ
RGB bmFlip[] = {
0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0,
0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010,
0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0,
0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010,
0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0,
0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010,
0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0,
0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010
};
// áîíóñ íåóÿçâèìîñòè
RGB bmBonus1[] = {
0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xCCCCCC,
0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0x44AC44, 0x44AC44, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA,
0xFFFFFF, 0xCCCCCC, 0x44AC44, 0x44AC44, 0x44AC44, 0x44AC44, 0xCCCCCC, 0xAAAAAA,
0xFFFFFF, 0x44AC44, 0x44AC44, 0x0C8C0C, 0x0C8C0C, 0x44AC44, 0x44AC44, 0xAAAAAA,
0xFFFFFF, 0x44AC44, 0x44AC44, 0x0C8C0C, 0x0C8C0C, 0x44AC44, 0x44AC44, 0xAAAAAA,
0xFFFFFF, 0xCCCCCC, 0x44AC44, 0x44AC44, 0x44AC44, 0x44AC44, 0xCCCCCC, 0xAAAAAA,
0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0x44AC44, 0x44AC44, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA,
0xCCCCCC, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA
};
// áîíóñ æèçíè
RGB bmBonus2[] = {
0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xCCCCCC,
0xFFFFFF, 0xCCCCCC, 0xD41414, 0xCCCCCC, 0xCCCCCC, 0xD41414, 0xCCCCCC, 0xAAAAAA,
0xFFFFFF, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xAAAAAA,
0xFFFFFF, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xAAAAAA,
0xFFFFFF, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xAAAAAA,
0xFFFFFF, 0xCCCCCC, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xCCCCCC, 0xAAAAAA,
0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xD41414, 0xD41414, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA,
0xCCCCCC, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA
};
//
RGB bmPMButton[] = {
0xCCCCCC, 0xCCCCCC, 0x000000, 0x000000, 0xCCCCCC, 0xCCCCCC,
0xCCCCCC, 0xCCCCCC, 0x000000, 0x000000, 0xCCCCCC, 0xCCCCCC,
0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
0xCCCCCC, 0xCCCCCC, 0x000000, 0x000000, 0xCCCCCC, 0xCCCCCC,
0xCCCCCC, 0xCCCCCC, 0x000000, 0x000000, 0xCCCCCC, 0xCCCCCC,
};
//
void DrawAppWindow();
//
void DrawTop10Window();
//
void initWorldMap();
//
void drawWorldMap();
//
void clearWorldMap();
//
void drawWorldMapForFlip();
//
void drawWndTitleGo();
//
void ApplyMapDiffs( bool drawTitle = true );
//
int GetCompletePercents();
#define EAT_ENEMY_BONUS 100
#define BEFORE_START_LEVEL 100
#define BONUS1_LIFETIME 250
#define BONUS1_IND_HSIZE 6
#define MIN_LOOP_DELAY 1
#define MAX_LOOP_DELAY 20
#define DEFAULT_LOOP_DELAY 12
#define blockSize 8
#define ENTRY_CLIENT_SIZE_X (400 - 2)
#define ENTRY_CLIENT_SIZE_Y (144 - 2 - 20)
#define TOP10_CLIENT_SIZE_X (176 - 2)
#define TOP10_CLIENT_SIZE_Y (144 - 2 - 20)
#define MAX_X_SIZE 96
#define MIN_X_SIZE 48
#define MAX_Y_SIZE 56
#define MIN_Y_SIZE 28
#define flipMapSize ((mapSizeX * mapSizeY) / 4)
#define freeSpaceCount ((mapSizeX - 4) * (mapSizeY - 4))
//
#define gmEmpty 0
#define gmHero 1
#define gmEnemy1 2
#define gmEnemy2 3
#define gmWall 4
#define gmTrack 5
#define gmFlip 6
#define gmBonus1 7
#define gmBonus2 8
#define gmSuperHero 9
#define gmSuperTrack 10
#define gmProbe 11
#define appStateEntry 0
#define appStateGo 1
#define appStateHideMap 2
#define appStateShowMap 3
#define appStatePause 4
#define appStateAfterDeath 5
#define appStateTop10 6
#define spacePerEnemy 30
#define BT_SIZE_X_PLUS 2
#define BT_SIZE_X_MINUS 3
#define BT_LOOP_PLUS 4
#define BT_LOOP_MINUS 5
#define BT_SIZE_Y_PLUS 6
#define BT_SIZE_Y_MINUS 7
#define TOP_TBL_SIZE 10
//
struct hiScoreHero
{
char name[12];
Dword score;
//
hiScoreHero()
{
//
this->ClearName();
this->score = 0;
};
//
void ClearName()
{
memset( (Byte *)(this->name), '.', sizeof(this->name) );
};
};
//
char top10FilePath[MAX_PATH];
hiScoreHero heroTbl[TOP_TBL_SIZE];
//
struct hiScoreFile
{
Byte block[512];
kosFileInfo fi;
//
hiScoreFile()
{
int i;
//
this->fi.offsetLow = this->fi.offsetHigh = 0;
this->fi.dataCount = 0;
this->fi.bufferPtr = this->block;
this->fi.rwMode = 0;
memcpy( this->fi.fileURL, top10FilePath, sizeof( top10FilePath ) );
//
for ( i = 0; i < ( sizeof( this->block ) / sizeof( Dword ) ); i++ )
{
//
((Dword *)(this->block))[i] = rtlRand();
}
};
//
virtual ~hiScoreFile()
{}
//
bool LoadFromDisk()
{
bool result;
int i;
Dword j, k;
Byte *bPtr;
//
this->fi.rwMode = FO_READ;
this->fi.dataCount = 512;
result = kos_FileSystemAccess( &(this->fi) ) == 0;
//
if ( result )
{
// äåêîäèðóåì
rtlSrand( ((Dword *)(this->block))[(sizeof(this->block) / sizeof(Dword)) - 1] );
//
for ( i = 0; i < (sizeof( heroTbl ) * 5); i++ )
{
// íå òðîãàåì ïîñëåäíèé Dword
j = rtlRand() % (sizeof(this->block) - 7);
k = ( rtlRand() % 31 ) + 1;
//
bPtr = this->block + j;
//
__asm{
mov edx, bPtr
mov ecx, k
mov eax, [edx]
bswap eax
ror eax, cl
mov [edx], eax
}
}
//
rtlSrand( kos_GetSystemClock() );
}
//
return result;
};
//
bool SaveToDisk()
{
int i;
Dword *rndList;
Byte *bPtr;
Dword k, keyLock;
//
rndList = new Dword[(sizeof( heroTbl ) * 5) * 2];
//
keyLock = rtlRand();
//
for ( i = 0; i < (sizeof( heroTbl ) * 5); i++ )
{
//
rndList[i * 2] = rtlRand() % (sizeof(this->block) - 7);
rndList[(i * 2) + 1] = ( rtlRand() % 31 ) + 1;
}
//
for ( i = (sizeof( heroTbl ) * 5) - 1; i >= 0; i-- )
{
//
bPtr = this->block + rndList[i * 2];
k = rndList[(i * 2) + 1];
//
__asm{
mov edx, bPtr
mov ecx, k
mov eax, [edx]
rol eax, cl
bswap eax
mov [edx], eax
}
}
//
delete rndList;
//
((Dword *)(this->block))[(sizeof(this->block) / sizeof(Dword)) - 1] = keyLock;
//
this->fi.rwMode = FO_WRITE;
this->fi.dataCount = 512;
return kos_FileSystemAccess( &( this->fi) ) == 0;
};
};
///
hiScoreFile *top10Heroes = NULL;
sProcessInfo process_info;
// çàãîëîâîê ãëàâíîãî îêíà
char MainWindowTitle[] = "XONIX (C) MMVI by Rabid Rabbit";
char WindowTitle[128];
char Top10WndTitle[] = "Top 10";
#if LANG == RUS
char goWndTitle[] = "“஢¥­ì %U, § ¢¥à襭® %U%%, ¦¨§­¥©: %U, áçñâ: %U";
char goWndTitleSuperHero[] = "“஢¥­ì %U, § ¢¥à襭® %U%%, ¦¨§­¥©: %U, áçñâ: %U, á㯥ࣥன: %U%%";
char menuStr1[] = "1. <20> ç âì ¨£àã";
char menuStr2[] = "2. ‚ë室";
char menuStr3[] = "“¯à ¢«¥­¨¥: <E28098>Šˆ - ­ ¯à ¢«¥­¨¥ ¤¢¨¦¥­¨ï.";
char menuStr4[] = "SPACE - ¯ ã§ , ESC - ¢ë室 ¢ ¬¥­î.";
char thatsAllStr[] = "ˆ£à  ®ª®­ç¥­ .";
char worldSizeStr[] = "<EFBFBD> §¬¥à ¯®«ï %U x %U í«¥¬¥­â®¢.";
char mainLoopDelayStr[] = "‘ª®à®áâì %U";
char top10str1[] = "ENTER - ¨¬ï Ok.";
char top10str2[] = "ESC - ¢ë室 ¢ ¬¥­î";
#else
char goWndTitle[] = "Level %U, completed %U%%, lives: %U, scores: %U";
char goWndTitleSuperHero[] = "Level %U, completed %U%%, lives: %U, scores: %U, superhero: %U%%";
char menuStr1[] = "1. Start game";
char menuStr2[] = "2. Exit";
char menuStr3[] = "Control: ARROWS - direction of movement.";
char menuStr4[] = "SPACE - pause, ESC - leave to menu.";
char thatsAllStr[] = "Game finished.";
char worldSizeStr[] = "Field size %U x %U cells.";
char mainLoopDelayStr[] = "Speed %U";
char top10str1[] = "Enter - name Ok.";
char top10str2[] = "ESC - leave to menu";
#endif
//
Byte beep1[] = { 0x90, 0x33, 0 };
//
Byte *heroPtr = NULL;
int heroDX = 0, heroDY = 0, lastMoveDirection = 0;
//
Byte * worldMap = NULL;
//
int wndSizeX = 0;
int wndSizeY = 0;
int mapSizeX = 64;
int mapSizeY = 32;
int loopDelay = DEFAULT_LOOP_DELAY;
int currentLevel = 1;
int appState = appStateEntry;
int levelFillEdge = 0;
int levelFillCount = 0;
int lifeCount = 0;
int flipMapCount = 0;
bool noBonus = false;
bool goToNextLevel = false;
bool bonus1Set = false;
bool bonus2Set = false;
int bonus1Count = 0;
int currentHero = gmHero;
int currentTrack = gmTrack;
Dword scoreCount = 0;
int enterName = -1;
int enterCharNdx = 0;
//
MCArray<Byte*> fillList;
//
struct flipMapEl
{
Word x, y;
};
//
flipMapEl *flipMapPtr = NULL;
//
RGB *mapColours[] = {
bmEmpty,
bmHero,
bmEnemy1,
bmEnemy2,
bmWall,
bmTrack,
bmFlip,
bmBonus1,
bmBonus2,
bmSuperHero,
bmSuperTrack,
NULL
};
//
struct sMapDiff
{
Byte *elPtr;
Byte mapEl;
//
sMapDiff() {};
//
sMapDiff( Byte *sElPtr, Byte sMapEl )
{
this->elPtr = sElPtr;
this->mapEl = sMapEl;
};
};
//
class CMapDiff : public MCArray<sMapDiff>
{
public:
virtual int Add( const sMapDiff &element )
{
element.elPtr[0] = element.mapEl;
return MCArray<sMapDiff>::Add( element );
}
};
//
CMapDiff mapDiffList;
MCArray<Byte*> sTrackList;
//
class CGenericEnemy
{
public:
//
Byte *ePtr;
int dx, dy;
//
virtual bool Move(void) = 0;
};
class CWallEnemy : public CGenericEnemy
{
public:
virtual bool Move(void);
};
class CSpaceEnemy : public CGenericEnemy
{
public:
virtual bool Move(void);
};
//
bool CWallEnemy::Move()
{
int ddx;
Byte *nextPtr;
Byte mapEl, dirMap;
bool result, border;
//
result = false;
border = false;
//
ddx = ( this->ePtr - worldMap ) % mapSizeX;
//
if ( ddx == 0 && this->dx < 0 )
{
border = true;
this->dx = 0 - this->dx;
}
//
if ( ddx == (mapSizeX - 1) && this->dx > 0 )
{
border = true;
this->dx = 0 - this->dx;
}
//
ddx = ( this->ePtr - worldMap ) / mapSizeX;
//
if ( ddx == 0 && this->dy < 0 )
{
border = true;
this->dy = 0 - this->dy;
}
//
if ( ddx == (mapSizeY - 1) && this->dy > 0 )
{
border = true;
this->dy = 0 - this->dy;
}
// ïîëó÷èì êîîðäèíàòû ìåñòà, â êîòîðîå ïîïàäàåò îáúåêò
nextPtr = this->ePtr + ( this->dx + this->dy );
// ïîëó÷èì ýëåìåíò ñ êàðòû
mapEl = nextPtr[0];
//
// â çàâèñèìîñòè îò ýëåìåíòà
switch ( mapEl )
{
// íàïîðîëèñü íà èãðîêà
case gmHero:
if ( sTrackList.GetCount() <= 0 )
{
result = true;
break;
}
// ïóñòîå ìåñòî, ñëåä èãðîêà èëè ãàäû íà ïîëå - íàäî îòñêàêèâàòü
case gmSuperHero:
case gmSuperTrack:
case gmTrack:
case gmEnemy2:
case gmEmpty:
//
dirMap = 0;
// -dx +dy
mapEl = this->ePtr[this->dy - this->dx];
if ( mapEl == gmEmpty
|| mapEl == gmTrack
|| mapEl == gmEnemy2
|| mapEl == gmSuperHero
|| mapEl == gmSuperTrack
) dirMap |= 1;
// +dy
mapEl = this->ePtr[this->dy];
if ( mapEl == gmEmpty
|| mapEl == gmTrack
|| mapEl == gmEnemy2
|| mapEl == gmSuperHero
|| mapEl == gmSuperTrack
) dirMap |= 2;
// +dx
mapEl = this->ePtr[this->dx];
if ( mapEl == gmEmpty
|| mapEl == gmTrack
|| mapEl == gmEnemy2
|| mapEl == gmSuperHero
|| mapEl == gmSuperTrack
) dirMap |= 4;
// +dx -dy
mapEl = this->ePtr[this->dx - this->dy];
if ( mapEl == gmEmpty
|| mapEl == gmTrack
|| mapEl == gmEnemy2
|| mapEl == gmSuperHero
|| mapEl == gmSuperTrack
) dirMap |= 8;
//
switch ( dirMap )
{
case 2:
case 3:
this->dy = 0 - this->dy;
break;
case 4:
case 12:
this->dx = 0 - this->dx;
break;
default:
this->dx = 0 - this->dx;
this->dy = 0 - this->dy;
break;
}
//
nextPtr = this->ePtr + ( this->dx + this->dy );
// ïîëó÷èì ýëåìåíò ñ êàðòû
mapEl = nextPtr[0];
//
switch ( mapEl )
{
//
case gmHero:
if ( sTrackList.GetCount() <= 0 )
{
result = true;
}
//
case gmSuperHero:
case gmSuperTrack:
case gmTrack:
case gmEmpty:
case gmEnemy2:
break;
//
default:
// ñòèðàåì îáúåêò
mapDiffList.Add( sMapDiff( this->ePtr, gmWall ) );
// ïåðåìåñòèì îáúåêò
this->ePtr = nextPtr;
// ðèñóåì îáúåêò ïî íîâûì êîîðäèíàòàì
mapDiffList.Add( sMapDiff( this->ePtr, gmEnemy1 ) );
break;
}
//
break;
// ëåòèì
default:
// ñòèðàåì îáúåêò
mapDiffList.Add( sMapDiff( this->ePtr, gmWall ) );
// ïåðåìåñòèì îáúåêò
this->ePtr = nextPtr;
// ðèñóåì îáúåêò ïî íîâûì êîîðäèíàòàì
mapDiffList.Add( sMapDiff( this->ePtr, gmEnemy1 ) );
//
break;
}
//
return result;
}
//
bool CSpaceEnemy::Move()
{
Byte *nextPtr;
Byte mapEl, dirMap;
bool result, heroTrack;
//
result = false;
//
heroTrack = ( sTrackList.GetCount() > 0 );
// ïîëó÷èì êîîðäèíàòû ìåñòà, â êîòîðîå ïîïàäàåò îáúåêò
nextPtr = this->ePtr + ( this->dx + this->dy );
// ïîëó÷èì ýëåìåíò ñ êàðòû
mapEl = nextPtr[0];
// â çàâèñèìîñòè îò ýëåìåíòà
switch ( mapEl )
{
// íàïîðîëèñü íà èãðîêà èëè åãî ñëåä
case gmTrack:
result = true;
break;
//
case gmHero:
if ( heroTrack )
{
result = true;
break;
}
// íàäî îòñêàêèâàòü
case gmSuperHero:
case gmSuperTrack:
case gmBonus1:
case gmBonus2:
case gmEnemy1:
case gmWall:
//
dirMap = 0;
// -dx +dy
mapEl = this->ePtr[this->dy - this->dx];
if ( mapEl == gmWall ||
mapEl == gmEnemy1 ||
mapEl == gmBonus1 ||
mapEl == gmBonus2 ||
mapEl == gmSuperHero ||
mapEl == gmSuperTrack ||
( mapEl == gmHero && !heroTrack )
) dirMap |= 1;
// +dy
mapEl = this->ePtr[this->dy];
if ( mapEl == gmWall ||
mapEl == gmEnemy1 ||
mapEl == gmBonus1 ||
mapEl == gmBonus2 ||
mapEl == gmSuperHero ||
mapEl == gmSuperTrack ||
( mapEl == gmHero && !heroTrack )
) dirMap |= 2;
// +dx
mapEl = this->ePtr[this->dx];
if ( mapEl == gmWall ||
mapEl == gmEnemy1 ||
mapEl == gmBonus1 ||
mapEl == gmBonus2 ||
mapEl == gmSuperHero ||
mapEl == gmSuperTrack ||
( mapEl == gmHero && !heroTrack )
) dirMap |= 4;
// +dx -dy
mapEl = this->ePtr[this->dx - this->dy];
if ( mapEl == gmWall ||
mapEl == gmEnemy1 ||
mapEl == gmBonus1 ||
mapEl == gmBonus2 ||
mapEl == gmSuperHero ||
mapEl == gmSuperTrack ||
( mapEl == gmHero && !heroTrack )
) dirMap |= 8;
//
switch ( dirMap )
{
case 2:
case 3:
this->dy = 0 - this->dy;
break;
case 4:
case 12:
this->dx = 0 - this->dx;
break;
default:
this->dx = 0 - this->dx;
this->dy = 0 - this->dy;
break;
}
//
nextPtr = this->ePtr + ( this->dx + this->dy );
// ïîëó÷èì ýëåìåíò ñ êàðòû
mapEl = nextPtr[0];
//
switch ( mapEl )
{
//
case gmTrack:
result = true;
break;
//
case gmHero:
if ( heroTrack )
{
result = true;
break;
}
//
case gmSuperHero:
case gmSuperTrack:
case gmBonus1:
case gmBonus2:
case gmWall:
case gmEnemy1:
break;
//
default:
// ñòèðàåì îáúåêò
mapDiffList.Add( sMapDiff( this->ePtr, gmEmpty ) );
// ïåðåìåñòèì îáúåêò
this->ePtr = nextPtr;
// ðèñóåì îáúåêò ïî íîâûì êîîðäèíàòàì
mapDiffList.Add( sMapDiff( this->ePtr, gmEnemy2 ) );
break;
}
//
break;
// ëåòèì
default:
// ñòèðàåì îáúåêò
mapDiffList.Add( sMapDiff( this->ePtr, gmEmpty ) );
// ïåðåìåñòèì îáúåêò
this->ePtr = nextPtr;
// ðèñóåì îáúåêò ïî íîâûì êîîðäèíàòàì
mapDiffList.Add( sMapDiff( this->ePtr, gmEnemy2 ) );
//
break;
}
//
//
return result;
}
//
MCArray<CGenericEnemy *> mapEnemies;
//
void xonixFree(void)
{
clearWorldMap();
if ( flipMapPtr != NULL )
{
delete flipMapPtr;
flipMapPtr = NULL;
}
}
//
void checkAndSetBonus2()
{
Dword i;
//
if ( (!bonus2Set)
&& rtlRand() < 0x40000000
&& lifeCount < 3
&& GetCompletePercents() > 50 )
{
//
bonus2Set = true;
//
for ( i = rtlRand() % (mapSizeX * mapSizeY); worldMap[i] != gmWall; i = rtlRand() % (mapSizeX * mapSizeY) );
//
mapDiffList.Add( sMapDiff( worldMap + i, gmBonus2 ) );
}
}
//
void ChangeHero()
{
if ( bonus1Count < 1 )
{
currentHero = gmHero;
currentTrack = gmTrack;
}
else
{
currentHero = gmSuperHero;
currentTrack = gmSuperTrack;
}
}
//
void checkAndSetBonus1()
{
Dword i;
//
if ((!bonus1Set)
&& rtlRand() > 0x80000000
&& lifeCount < 2
&& GetCompletePercents() > 75 )
{
//
bonus1Set = true;
//
for ( i = rtlRand() % (mapSizeX * mapSizeY); worldMap[i] != gmWall; i = rtlRand() % (mapSizeX * mapSizeY) );
//
mapDiffList.Add( sMapDiff( worldMap + i, gmBonus1 ) );
}
}
//
void CreateFlipMap(void)
{
Word i, j;
int ndx, ndx2, k;
flipMapEl el;
static int lastMapSizeX = 0, lastMapSizeY = 0;
//
if ( lastMapSizeX != mapSizeX || lastMapSizeY != mapSizeY )
{
//
lastMapSizeX = mapSizeX;
lastMapSizeY = mapSizeY;
//
if ( flipMapPtr != NULL )
{
delete flipMapPtr;
flipMapPtr = NULL;
}
}
//
if ( flipMapPtr == NULL )
{
flipMapPtr = new flipMapEl[flipMapSize];
//
ndx = 0;
//
for ( i = 0; i < mapSizeY; i += 2 )
{
for ( j = 0; j < mapSizeX; j += 2 )
{
//
flipMapPtr[ndx].x = j;
flipMapPtr[ndx].y = i;
//
ndx++;
}
}
}
//
for ( k = 0; k < flipMapSize; k++ )
{
//
ndx = rtlRand() % flipMapSize;
ndx2 = rtlRand() % flipMapSize;
//
el = flipMapPtr[ndx];
flipMapPtr[ndx] = flipMapPtr[ndx2];
flipMapPtr[ndx2] = el;
}
}
//
bool ProcessEndTrack()
{
int i, j, k, m;
bool noFill;
Byte *mPtr, *findPtr;
//
j = sTrackList.GetCount();
//
scoreCount += j;
//
for ( i = 0; i < j; i++ )
{
//
mapDiffList.Add( sMapDiff( sTrackList[i], gmWall ) );
}
//
levelFillCount -= j;
//
sTrackList.Clear();
//
heroPtr += heroDX + heroDY;
mapDiffList.Add( sMapDiff( heroPtr, currentHero ) );
//
heroDX = 0;
heroDY = 0;
lastMoveDirection = 0;
// çàëèâêà
mPtr = worldMap;
//
for ( i = 0; i < mapSizeY; i++ )
{
for ( j = 0; j < mapSizeX; j++ )
{
//
if ( mPtr[0] == gmEmpty )
{
//
fillList.Clear();
//
noFill = false;
//
fillList.Add( mPtr );
//
mPtr[0] = gmProbe;
//
for ( k = 0; k < fillList.GetCount(); k++ )
{
// ñïðàâà
findPtr = fillList[k] + 1;
//
switch ( findPtr[0] )
{
case gmEmpty:
fillList.Add( findPtr );
findPtr[0] = gmProbe;
break;
case gmEnemy2:
noFill = true;
break;
default:
break;
}
// ñëåâà
findPtr = fillList[k] - 1;
//
switch ( findPtr[0] )
{
case gmEmpty:
fillList.Add( findPtr );
findPtr[0] = gmProbe;
break;
case gmEnemy2:
noFill = true;
break;
default:
break;
}
// ñâåðõó
findPtr = fillList[k] - mapSizeX;
//
switch ( findPtr[0] )
{
case gmEmpty:
fillList.Add( findPtr );
findPtr[0] = gmProbe;
break;
case gmEnemy2:
noFill = true;
break;
default:
break;
}
// ñíèçó
findPtr = fillList[k] + mapSizeX;
//
switch ( findPtr[0] )
{
case gmEmpty:
fillList.Add( findPtr );
findPtr[0] = gmProbe;
break;
case gmEnemy2:
noFill = true;
break;
default:
break;
}
}
//
if ( noFill )
{
//
fillList.Clear();
}
else
{
//
m = fillList.GetCount();
//
scoreCount += m;
//
for ( k = 0; k < m; k++ )
{
//
mapDiffList.Add( sMapDiff( fillList[k], gmWall ) );
}
//
levelFillCount -= m;
}
}
else
{
mPtr++;
}
}
}
//
mPtr = worldMap;
//
for ( i = 0; i < mapSizeY; i++ )
{
for ( j = 0; j < mapSizeX; j++ )
{
//
if ( mPtr[0] == gmProbe ) mPtr[0] = gmEmpty;
//
mPtr++;
}
}
//
checkAndSetBonus1();
checkAndSetBonus2();
//
ApplyMapDiffs();
//
return levelFillCount <= levelFillEdge;
}
//
void EatEnemy( Byte *enemyPos )
{
bool Eat = true;
int i, j;
//
while ( Eat )
{
//
Eat = false;
//
j = mapEnemies.GetCount();
//
for ( i = 0; i < j; i++ )
{
//
if ( mapEnemies[i]->ePtr == enemyPos )
{
//
delete mapEnemies[i];
//
mapEnemies.RemoveAt( i );
//
Eat = true;
//
scoreCount += EAT_ENEMY_BONUS;
//
break;
}
}
}
}
//
bool MoveHero()
{
int ddx;
Byte *nextPtr;
Byte mapEl;
bool result;
//
if ( heroDX == 0 && heroDY == 0 ) return false;
//
result = false;
//
nextPtr = heroPtr + ( heroDX + heroDY );
//
ddx = ( ( heroPtr - worldMap ) % mapSizeX ) - ( ( nextPtr - worldMap ) % mapSizeX );
//
if ( ddx < -1 || ddx > 1 || nextPtr < worldMap || nextPtr >= ( worldMap + ( mapSizeX * mapSizeY ) ) )
{
heroDX = 0;
heroDY = 0;
return false;
}
//
mapEl = nextPtr[0];
//
if ( sTrackList.GetCount() > 0 )
{
//
switch ( mapEl )
{
//
case gmEmpty:
sTrackList.Add( nextPtr );
break;
//
case gmBonus1:
bonus1Count = BONUS1_LIFETIME;
ChangeHero();
goToNextLevel = ProcessEndTrack();
return false;
break;
//
case gmBonus2:
lifeCount++;
goToNextLevel = ProcessEndTrack();
return false;
break;
//
case gmWall:
goToNextLevel = ProcessEndTrack();
return false;
break;
//
case gmEnemy1:
if ( bonus1Count > 0 )
{
//
EatEnemy( nextPtr );
//
goToNextLevel = ProcessEndTrack();
//
return false;
break;
}
else
{
//
return true;
}
break;
//
case gmEnemy2:
if ( bonus1Count > 0 )
{
//
EatEnemy( nextPtr );
sTrackList.Add( nextPtr );
break;
}
else
{
//
return true;
}
break;
//
default:
return true;
break;
}
}
else
{
//
switch ( mapEl )
{
//
case gmEmpty:
sTrackList.Add( nextPtr );
break;
//
case gmBonus1:
bonus1Count = BONUS1_LIFETIME;
break;
//
case gmBonus2:
lifeCount++;
break;
//
case gmWall:
break;
//
case gmEnemy1:
if ( bonus1Count > 0 )
{
EatEnemy( nextPtr );
}
else
{
result = true;
}
break;
//
case gmEnemy2:
if ( bonus1Count > 0 )
{
EatEnemy( nextPtr );
sTrackList.Add( nextPtr );
}
else
{
result = true;
}
break;
//
default:
result = true;
break;
}
}
//
mapDiffList.Add( sMapDiff( heroPtr, sTrackList.GetCount() <= 1 ? gmWall : currentTrack ) );
heroPtr = nextPtr;
mapDiffList.Add( sMapDiff( heroPtr, currentHero ) );
return result;
}
//
bool MoveEnemies()
{
bool result;
int i, j, ir;
//
result = false;
ir = 0;
//
j = mapEnemies.GetCount();
//
for ( i = 0; i < j; i++ )
{
ir += ( mapEnemies[i]->Move() ? 1 : 0 );
}
//
result = ( ir != 0 );
//
return result;
}
//
void ApplyMapDiffs( bool drawTitle )
{
int i, j;
//
// kos_WindowRedrawStatus( 1 );
//
if ( drawTitle ) drawWndTitleGo();
//
j = mapDiffList.GetCount();
//
for ( i = 0; i < j; i++ )
{
kos_PutImage(
mapColours[mapDiffList[i].mapEl],
blockSize,
blockSize,
( ( mapDiffList[i].elPtr - worldMap ) % mapSizeX ) * blockSize,
( ( mapDiffList[i].elPtr - worldMap ) / mapSizeX ) * blockSize
);
}
//
// kos_WindowRedrawStatus( 2 );
//
mapDiffList.Clear();
}
//
void DeadHeroProcess()
{
int i, j;
Byte *mPtr = beep1;
// beep
__asm{
mov eax, 55
mov ebx, eax
mov esi, mPtr
push eax
int 0x40
pop eax
}
//
j = sTrackList.GetCount();
//
for ( i = 0; i < j; i++ )
{
//
mapDiffList.Add( sMapDiff( sTrackList[i], gmEmpty ) );
}
//
mapDiffList.Add( sMapDiff( heroPtr, sTrackList.GetCount() > 0 ? gmEmpty : gmWall ) );
//
sTrackList.Clear();
//
heroPtr = worldMap;
//
while ( heroPtr[0] != gmWall ) heroPtr++;
//
mapDiffList.Add( sMapDiff( heroPtr, gmHero ) );
//
noBonus = true;
//
lifeCount--;
//
heroDX = 0;
heroDY = 0;
lastMoveDirection = 0;
}
//
bool CheckForNextLevel()
{
//
if ( goToNextLevel )
{
//
CreateFlipMap();
goToNextLevel = false;
currentLevel++;
appState = appStateHideMap;
flipMapCount = 0;
return true;
}
//
return false;
}
//
void SetGameVars()
{
//
currentLevel = 1;
lifeCount = 3;
noBonus = true;
bonus1Set = false;
bonus2Set = false;
bonus1Count = 0;
goToNextLevel = false;
currentHero = gmHero;
currentTrack = gmTrack;
scoreCount = 0;
enterName = -1;
//
wndSizeX = ((mapSizeX*blockSize) + 5*2);
wndSizeY = ((mapSizeY*blockSize) + kos_GetSkinHeight() + 5);
//
kos_ChangeWindow( -1, -1, wndSizeX-1, wndSizeY-1 );
}
//
void SetEntryVars()
{
//
wndSizeX = ENTRY_CLIENT_SIZE_X + 5*2;
wndSizeY = ENTRY_CLIENT_SIZE_Y + kos_GetSkinHeight() + 5;
//
kos_SetWindowCaption(MainWindowTitle);
kos_ChangeWindow( -1, -1, wndSizeX-1, wndSizeY-1 );
kos_SetKeyboardDataMode( KM_SCANS );
}
//
void __cdecl ReleaseTop10()
{
//
if ( top10Heroes != NULL )
{
//
memcpy( top10Heroes->block, heroTbl, sizeof(heroTbl) );
//
top10Heroes->SaveToDisk();
//
delete top10Heroes;
}
}
//
void PrepareTop10()
{
//
top10Heroes = new hiScoreFile;
//
atexit( ReleaseTop10 );
//
if ( top10Heroes->LoadFromDisk() )
{
//
memcpy( heroTbl, top10Heroes->block, sizeof(heroTbl) );
}
}
//
void SetUpTop10()
{
int i, j;
Byte keyCode;
//
while ( kos_CheckForEvent() == 2 ) kos_GetKey( keyCode );
//
kos_SetKeyboardDataMode( KM_CHARS );
kos_SetWindowCaption(Top10WndTitle);
//
kos_ChangeWindow(-1, -1, TOP10_CLIENT_SIZE_X + 5 * 2 - 1, TOP10_CLIENT_SIZE_Y + kos_GetSkinHeight() + 5 - 1);
//
for ( i = 0; i < TOP_TBL_SIZE; i++ )
{
//
if ( heroTbl[i].score < scoreCount )
{
//
for ( j = TOP_TBL_SIZE - 1; j > i; j-- )
{
//
heroTbl[j] = heroTbl[j-1];
}
//
heroTbl[i].ClearName();
heroTbl[i].score = scoreCount;
//
enterName = i;
enterCharNdx = 0;
//
break;
}
}
}
//
// òî÷êà âõîäà è ôóíêöèÿ îáðàáîòêè ñîîáùåíèé
//
void kos_Main()
{
Dword buttonID;
Byte keyCode;
Byte *bPtr;
bool workOn = true;
char *cPtr;
wndSizeX = ENTRY_CLIENT_SIZE_X + 5 * 2;
wndSizeY = ENTRY_CLIENT_SIZE_Y + kos_GetSkinHeight() + 5;
// îòäåëÿåì èìÿ ìîäóëÿ îò ïóòè
cPtr = strrchr( kosExePath, '/' );
// ïðîâåðêà ;)
if ( cPtr == NULL )
{
//
rtlDebugOutString( "xonix: Invalid path to executable." );
//
return;
}
//
cPtr[1] = 0;
//
strcpy( top10FilePath, kosExePath );
//
strcpy( top10FilePath + ((cPtr - kosExePath) + 1), "xonix.t10" );
// âûïîëíåíèå ôóíêöèé èíèöèàëèçàöèè
kos_SetKeyboardDataMode( KM_SCANS );
//
PrepareTop10();
//
while( workOn )
{
switch ( appState )
{
//
case appStateEntry:
switch ( kos_WaitForEvent() )
{
// ïåðåðèñîâêà îêíà
case 1:
DrawAppWindow();
break;
//
case 2:
kos_GetKey( keyCode );
switch ( keyCode )
{
//
case 2:
//
appState = appStateGo;
SetGameVars();
initWorldMap();
// DrawAppWindow();
break;
//
case 3:
xonixFree();
workOn = false;
break;
}
break;
//
case 3:
//
if ( ! kos_GetButtonID( buttonID ) ) break;
//
switch ( buttonID )
{
//
case BT_SIZE_X_PLUS:
mapSizeX += 2;
if ( mapSizeX > MAX_X_SIZE ) mapSizeX = MAX_X_SIZE;
break;
//
case BT_SIZE_X_MINUS:
mapSizeX -= 2;
if ( mapSizeX < MIN_X_SIZE ) mapSizeX = MIN_X_SIZE;
break;
//
case BT_SIZE_Y_PLUS:
mapSizeY += 2;
if ( mapSizeY > MAX_Y_SIZE ) mapSizeY = MAX_Y_SIZE;
break;
//
case BT_SIZE_Y_MINUS:
mapSizeY -= 2;
if ( mapSizeY < MIN_Y_SIZE ) mapSizeY = MIN_Y_SIZE;
break;
//
case BT_LOOP_MINUS:
loopDelay++;
if ( loopDelay > MAX_LOOP_DELAY ) loopDelay = MAX_LOOP_DELAY;
break;
//
case BT_LOOP_PLUS:
loopDelay--;
if ( loopDelay < MIN_LOOP_DELAY ) loopDelay = MIN_LOOP_DELAY;
break;
case 1:
xonixFree();
workOn = false;
break;
//
default:
break;
}
DrawAppWindow();
break;
//
default:
break;
}
break;
//
case appStateGo:
//
kos_Pause( loopDelay );
//
if ( bonus1Count > 0 ) bonus1Count--;
//
ChangeHero();
//
switch( kos_WaitForEvent( 1 ) )
{
//
case 0:
if ( MoveHero() )
{
//
DeadHeroProcess();
}
else
{
//
if ( CheckForNextLevel() )
{
break;
}
}
if ( MoveEnemies() )
{
// ñîæðàëè èãðîêà
DeadHeroProcess();
}
ApplyMapDiffs();
break;
//
case 1:
DrawAppWindow();
break;
//
case 2:
do kos_GetKey( keyCode ); while ( keyCode & 0x80 );
switch ( keyCode )
{
//
case 0x1:
SetEntryVars();
appState = appStateEntry;
clearWorldMap();
DrawAppWindow();
continue;
//
case 0x39:
appState = appStatePause;
break;
//
case 0x48:
heroDX = 0;
if ( lastMoveDirection == 0x50 )
{
heroDY = 0;
lastMoveDirection = 0;
}
else
{
heroDY = -mapSizeX;
lastMoveDirection = 0x48;
}
break;
//
case 0x50:
heroDX = 0;
if ( lastMoveDirection == 0x48 )
{
heroDY = 0;
lastMoveDirection = 0;
}
else
{
heroDY = mapSizeX;
lastMoveDirection = 0x50;
}
break;
//
case 0x4B:
heroDY = 0;
if ( lastMoveDirection == 0x4D )
{
heroDX = 0;
lastMoveDirection = 0;
}
else
{
heroDX = -1;
lastMoveDirection = 0x4B;
}
break;
//
case 0x4D:
heroDY = 0;
if ( lastMoveDirection == 0x4B )
{
heroDX = 0;
lastMoveDirection = 0;
}
else
{
heroDX = 1;
lastMoveDirection = 0x4D;
}
break;
}
//
if ( MoveHero() )
{
//
DeadHeroProcess();
}
else
{
//
if ( CheckForNextLevel() )
{
break;
}
}
if ( MoveEnemies() )
{
// ñîæðàëè èãðîêà
DeadHeroProcess();
}
ApplyMapDiffs();
break;
//
case 3:
kos_GetButtonID(buttonID);
if (buttonID == 1)
{
xonixFree();
workOn = false;
}
break;
default:
//
if ( MoveHero() )
{
//
DeadHeroProcess();
}
if ( MoveEnemies() )
{
// ñîæðàëè èãðîêà
DeadHeroProcess();
}
ApplyMapDiffs();
break;
}
//
if ( lifeCount <= 0 )
{
appState = appStateAfterDeath;
DrawAppWindow();
}
//
break;
//
case appStateAfterDeath:
switch ( kos_WaitForEvent() )
{
//
case 1:
DrawAppWindow();
break;
//
case 2:
do kos_GetKey( keyCode ); while ( keyCode & 0x80 );
if ( keyCode != 0 )
{
//
appState = appStateTop10;
SetUpTop10();
DrawAppWindow();
}
break;
//
case 3:
kos_GetButtonID(buttonID);
if ( buttonID == 1 )
{
//
appState = appStateTop10;
SetUpTop10();
DrawAppWindow();
}
//
default:
break;
}
break;
//
case appStateTop10:
switch ( kos_WaitForEvent() )
{
//
case 1:
DrawAppWindow();
break;
//
case 2:
//
kos_GetKey( keyCode );
//
if ( enterName < 0 )
{
//
if ( keyCode == 0x1b )
{
//
SetEntryVars();
clearWorldMap();
appState = appStateEntry;
DrawAppWindow();
}
}
else
{
//
switch ( keyCode )
{
//
case 13:
//
enterName = -1;
break;
//
case 8:
//
if ( enterCharNdx > 0 )
{
//
heroTbl[enterName].name[--enterCharNdx] = '.';
}
break;
//
default:
if ( keyCode >= 0x20 )
{
//
heroTbl[enterName].name[enterCharNdx++] = keyCode;
//
if ( enterCharNdx >= sizeof(heroTbl[0].name) )
{
//
enterName = -1;
}
}
break;
}
//
DrawAppWindow();
}
//
break;
//
case 3:
kos_GetButtonID(buttonID);
if (buttonID == 1)
{
xonixFree();
workOn = false;
}
break;
default:
break;
}
break;
//
case appStatePause:
switch ( kos_WaitForEvent() )
{
case 1:
DrawAppWindow();
break;
case 2:
do kos_GetKey( keyCode ); while ( keyCode & 0x80 );
if ( keyCode != 0 )
{
//
appState = appStateGo;
}
break;
case 3:
kos_GetButtonID(buttonID);
if (buttonID == 1)
{
xonixFree();
workOn = false;
}
break;
default:
break;
}
break;
//
case appStateHideMap:
//
switch ( kos_WaitForEvent( 1 ) )
{
case 1:
DrawAppWindow();
break;
case 2:
while ( kos_GetKey( keyCode ) );
break;
default:
bPtr = worldMap + (flipMapPtr[flipMapCount].x + (flipMapPtr[flipMapCount].y * mapSizeX));
mapDiffList.Add( sMapDiff( bPtr, gmFlip ) );
mapDiffList.Add( sMapDiff( bPtr + 1, gmFlip ) );
mapDiffList.Add( sMapDiff( bPtr + mapSizeX, gmFlip ) );
mapDiffList.Add( sMapDiff( bPtr + (mapSizeX + 1), gmFlip ) );
ApplyMapDiffs( false );
break;
}
//
flipMapCount++;
//
if ( flipMapCount >= flipMapSize )
{
flipMapCount = 0;
appState = appStateShowMap;
DrawAppWindow();
}
break;
//
case appStateShowMap:
//
switch ( kos_WaitForEvent( 1 ) )
{
case 1:
DrawAppWindow();
break;
default:
break;
}
//
flipMapCount++;
//
if ( flipMapCount >= BEFORE_START_LEVEL )
{
clearWorldMap();
flipMapCount = 0;
initWorldMap();
appState = appStateGo;
DrawAppWindow();
}
//
break;
}
}
}
//
void DrawEntryScreen()
{
PRINTK pr;
char line[64];
//
kos_DefineAndDrawWindow(
100, 100,
wndSizeX-1, wndSizeY-1,
0x34, 0,
0, 0,
MainWindowTitle
);
//
if (process_info.processInfo.window_state & 0x06)
return;
/*
kos_WriteTextToWindow(
4, 4,
0x10, 0x42D2E2,
MainWindowTitle,
sizeof( MainWindowTitle ) - 1
);
*/
//
kos_WriteTextToWindow(
8-1, 32-21,
0x10, 0x12FF12,
menuStr1,
sizeof( menuStr1 ) - 1
);
//
kos_WriteTextToWindow(
8-1, 48-21,
0x10, 0x12FF12,
menuStr2,
sizeof( menuStr2 ) - 1
);
//
kos_WriteTextToWindow(
8-1, 80-21,
0x10, 0xD0FF12,
menuStr3,
sizeof( menuStr3 ) - 1
);
//
kos_WriteTextToWindow(
8-1, 96-21,
0x10, 0xD0FF12,
menuStr4,
sizeof( menuStr4 ) - 1
);
// ðàçìåð ïîëÿ
pr.fmtline = worldSizeStr;
pr.args[0] = mapSizeX;
pr.args[1] = mapSizeY;
sprintk( line, &pr );
//
kos_WriteTextToWindow(
8-1, 112-21,
0x10, 0x12C0D0,
line,
strlen( line )
);
// êíîïêè X
// xo oo
// oo
kos_DefineButton(
ENTRY_CLIENT_SIZE_X - 62, 112-24,
13, 13,
BT_SIZE_X_MINUS,
0xCCCCCC
);
//
kos_PutImage( bmPMButton + 12, 6, 2, ENTRY_CLIENT_SIZE_X - (62-1) + 3, 117-23 );
//
// ox oo
// oo
kos_DefineButton(
ENTRY_CLIENT_SIZE_X - 48, 112-24,
13, 13,
BT_SIZE_X_PLUS,
0xCCCCCC
);
//
kos_PutImage( bmPMButton, 6, 6, ENTRY_CLIENT_SIZE_X - (48-1) + 3, 115-23 );
// êíîïêè Y
// oo xo
// oo
kos_DefineButton(
ENTRY_CLIENT_SIZE_X - 31, 112-24,
13, 13,
BT_SIZE_Y_MINUS,
0xCCCCCC
);
//
kos_PutImage( bmPMButton + 12, 6, 2, ENTRY_CLIENT_SIZE_X - (31-1) + 3, 117-23 );
//
// oo ox
// oo
kos_DefineButton(
ENTRY_CLIENT_SIZE_X - 17, 112-24,
13, 13,
BT_SIZE_Y_PLUS,
0xCCCCCC
);
//
kos_PutImage( bmPMButton, 6, 6, ENTRY_CLIENT_SIZE_X - (17-1) + 3, 115-23 );
//
//çàäåðæêà â öèêëå âûáîðêè ñîîáùåíèé
pr.fmtline = mainLoopDelayStr;
pr.args[0] = MAX_LOOP_DELAY + MIN_LOOP_DELAY - loopDelay;
sprintk( line, &pr );
//
kos_WriteTextToWindow(
8-1, 128-21,
0x10, 0x12C0D0,
line,
strlen( line )
);
//
kos_DefineButton(
ENTRY_CLIENT_SIZE_X - 31, 128-23,
13, 13,
BT_LOOP_MINUS,
0xCCCCCC
);
//
kos_PutImage( bmPMButton + 12, 6, 2, ENTRY_CLIENT_SIZE_X - (31-1) + 3, 133-22 );
//
kos_DefineButton(
ENTRY_CLIENT_SIZE_X - 17, 128-23,
13, 13,
BT_LOOP_PLUS,
0xCCCCCC
);
//
kos_PutImage( bmPMButton, 6, 6, ENTRY_CLIENT_SIZE_X - (17-1) + 3, 131-22 );
}
//
void DrawAppWindow()
{
kos_WindowRedrawStatus( 1 );
kos_ProcessInfo(&process_info, -1);
switch (appState)
{
//
case appStateTop10:
DrawTop10Window();
break;
//
case appStateEntry:
//
DrawEntryScreen();
break;
//
case appStateGo:
case appStateShowMap:
case appStatePause:
if (process_info.processInfo.window_state & 0x06)
{
appState = appStatePause;
}
drawWorldMap();
break;
//
case appStateAfterDeath:
//
drawWorldMap();
//
kos_DefineButton(
((wndSizeX - 10) / 2) - 64,
((wndSizeY - kos_GetSkinHeight() - 5) / 2) - 16,
128, 32,
1,
0x136793
);
//
kos_WriteTextToWindow(
((wndSizeX - 10) / 2) - (sizeof(thatsAllStr)* 4),
((wndSizeY - kos_GetSkinHeight() - 5) / 2) - 4,
0x10, 0xFFFFFF,
thatsAllStr,
sizeof (thatsAllStr)-1
);
//
break;
//
case appStateHideMap:
drawWorldMapForFlip();
break;
}
//
kos_WindowRedrawStatus( 2 );
}
//
void initWorldMap()
{
int i, j, m, allocSize;
CWallEnemy *we;
CSpaceEnemy *se;
//
allocSize = mapSizeX * mapSizeY;
worldMap = new Byte[allocSize];
//
__asm{
mov edi, worldMap
mov ecx, allocSize
mov al, gmEmpty
rep stosb
}
//
levelFillEdge = ( ( currentLevel + 1 ) * spacePerEnemy ) + currentLevel;
levelFillCount = freeSpaceCount;
//
if ( ! noBonus )
{
lifeCount++;
}
//
noBonus = false;
bonus1Set = false;
bonus2Set = false;
bonus1Count = 0;
goToNextLevel = false;
currentHero = gmHero;
currentTrack = gmTrack;
//
for ( i = 0; i < mapSizeX; i++ )
{
//
worldMap[i] = gmWall;
worldMap[mapSizeX + i] = gmWall;
//
worldMap[((mapSizeY-2)*mapSizeX) + i] = gmWall;
worldMap[((mapSizeY-1)*mapSizeX) + i] = gmWall;
}
//
for ( i = 2; i < (mapSizeY-2); i++ )
{
//
worldMap[(i*mapSizeX)] = gmWall;
worldMap[(i*mapSizeX) + 1] = gmWall;
worldMap[(i*mapSizeX) + mapSizeX - 2] = gmWall;
worldMap[(i*mapSizeX) + mapSizeX - 1] = gmWall;
}
//
heroPtr = worldMap + ( mapSizeX / 2 );
heroPtr[0] = gmHero;
heroDX = 0;
heroDY = 0;
//
for ( i = 0; i < currentLevel; i++ )
{
//
for (
j = ( rtlRand() % (mapSizeX * (mapSizeY - 2)) ) + (mapSizeX * 2);
worldMap[j] != gmWall;
j = rtlRand() % (mapSizeX * mapSizeY)
);
//
we = new CWallEnemy();
//
we->ePtr = worldMap + j;
we->dx = rtlRand() & 1 ? 1 : -1;
we->dy = rtlRand() & 1 ? mapSizeX : -mapSizeX;
//
mapEnemies.Add( we );
//
worldMap[j] = gmEnemy1;
}
//
m = currentLevel + 1;
//
for ( i = 0; i < m; i++ )
{
//
for (
j = rtlRand() % (mapSizeX * mapSizeY);
worldMap[j] != gmEmpty;
j = rtlRand() % (mapSizeX * mapSizeY)
);
//
se = new CSpaceEnemy();
//
se->ePtr = worldMap + j;
se->dx = rtlRand() & 1 ? 1 : -1;
se->dy = rtlRand() & 1 ? mapSizeX : -mapSizeX;
//
mapEnemies.Add( se );
//
worldMap[j] = gmEnemy2;
}
}
//
void drawWorldMap()
{
//
kos_DefineAndDrawWindow(
100, 100,
wndSizeX-1, wndSizeY-1,
0x74, 0,
0, 0,
MainWindowTitle
);
//
drawWndTitleGo();
//
drawWorldMapForFlip();
}
//
int GetCompletePercents()
{
int n1, n2;
//
n1 = freeSpaceCount - levelFillCount;
n2 = freeSpaceCount - levelFillEdge;
//
return ( n1 >= n2 ) ? 100 : ( n1 * 100 ) / n2;
}
//
void drawWndTitleGo()
{
PRINTK pr;
static char prev_title[64] = {'\0'};
//
/*
kos_DrawBar(
1, 1,
wndSizeX - 2, 18,
0x2040A0
);
*/
//
//pr.fmtline = goWndTitle;
pr.args[0] = currentLevel;
pr.args[1] = GetCompletePercents();
pr.args[2] = lifeCount;
pr.args[3] = scoreCount;
if (bonus1Count > 0)
{
pr.args[4] = 100*bonus1Count/BONUS1_LIFETIME;
pr.fmtline = goWndTitleSuperHero;
}
else
{
pr.fmtline = goWndTitle;
}
sprintk(WindowTitle, &pr);
//
bool same = true;
for (int i = 0; i < 64; i++)
{
if (WindowTitle[i] != prev_title[i])
{
same = false;
break;
}
if ((WindowTitle[i] == '\0') || (prev_title[i] == '\0'))
{
break;
}
}
if (!same)
{
kos_SetWindowCaption(WindowTitle);
strcpy(prev_title, WindowTitle);
}
/*
kos_WriteTextToWindow(
4, 4,
0x10, 0x42D2E2,
line,
strlen( line )
);
*/
//
/*
if ( bonus1Count > 0 )
{
//
kos_DrawBar(
2, 22 - BONUS1_IND_HSIZE - 1,
wndSizeX - 4, BONUS1_IND_HSIZE,
0x2040A0
);
//
kos_DrawBar(
2, 22 - BONUS1_IND_HSIZE - 1,
( bonus1Count * ( wndSizeX - 4 ) ) / BONUS1_LIFETIME, BONUS1_IND_HSIZE,
0x5720B0
);
}*/
}
//
void drawWorldMapForFlip()
{
int i, j;
Byte *mPtr = worldMap;
if (process_info.processInfo.window_state & 0x06)
return;
//
for ( i = 0; i < mapSizeY; i++ )
{
//
for ( j = 0; j < mapSizeX; j++ )
{
kos_PutImage(
mapColours[*mPtr],
blockSize,
blockSize,
j * blockSize,
i * blockSize
);
//
mPtr++;
}
}
}
//
void clearWorldMap()
{
int i, j;
//
sTrackList.Clear();
fillList.Clear();
mapDiffList.Clear();
//
j = mapEnemies.GetCount();
//
for ( i = 0; i < j; i++ )
{
//
delete mapEnemies[i];
}
//
mapEnemies.Clear();
//
if ( worldMap != NULL )
{
delete worldMap;
worldMap = NULL;
}
}
//
void DrawTop10Window()
{
int i;
//
kos_DefineAndDrawWindow(
100, 100,
0, 0,
0x34, 0,
0, 0,
Top10WndTitle
);
//
if (process_info.processInfo.window_state & 0x06)
return;
/*
kos_WriteTextToWindow(
4, 4,
0x0, 0x42D2E2,
Top10WndTitle,
sizeof( Top10WndTitle ) - 1
);
*/
//
for ( i = 0; i < TOP_TBL_SIZE; i++ )
{
//
kos_WriteTextToWindow(
6-1, 2 + (i * 10),
0x0, enterName != i ? 0xFFFFFF : 0x00FF00,
heroTbl[i].name,
sizeof( heroTbl[0].name )
);
//
kos_DisplayNumberToWindow(
heroTbl[i].score,
8,
112-1, 2 + (i * 10),
0xFFFF55,
nbDecimal,
false
);
}
//
kos_WriteTextToWindow(
6-1, 6 + (i * 10),
0x10, 0x1060D0,
enterName >= 0 ? top10str1 : top10str2,
enterName >= 0 ? sizeof(top10str1) - 1 : sizeof(top10str2) - 1
);
}