2019-08-26 03:59:14 +00:00
|
|
|
#include "menu.h"
|
2019-09-19 19:45:19 +00:00
|
|
|
|
|
|
|
#include "build.h"
|
|
|
|
#include "cd.h"
|
|
|
|
#include "cdaudio.h"
|
|
|
|
#include "compat.h"
|
2019-08-26 03:59:14 +00:00
|
|
|
#include "engine.h"
|
2019-09-19 19:45:19 +00:00
|
|
|
#include "exhumed.h"
|
|
|
|
#include "gun.h"
|
|
|
|
#include "init.h"
|
|
|
|
#include "input.h"
|
2019-08-26 03:59:14 +00:00
|
|
|
#include "keyboard.h"
|
2019-09-19 19:45:19 +00:00
|
|
|
#include "light.h"
|
|
|
|
#include "names.h"
|
|
|
|
#include "object.h"
|
|
|
|
#include "player.h"
|
2019-08-26 03:59:14 +00:00
|
|
|
#include "random.h"
|
2019-09-19 19:45:19 +00:00
|
|
|
#include "sequence.h"
|
2019-08-26 03:59:14 +00:00
|
|
|
#include "sound.h"
|
2019-09-19 19:45:19 +00:00
|
|
|
#include "status.h"
|
|
|
|
#include "typedefs.h"
|
2019-08-26 03:59:14 +00:00
|
|
|
#include "view.h"
|
|
|
|
|
|
|
|
#include <assert.h>
|
2019-09-19 19:45:19 +00:00
|
|
|
#include <string>
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
#ifdef __WATCOMC__
|
|
|
|
#include <stdlib.h>
|
|
|
|
#endif
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
#define kMaxSaveSlots 5
|
|
|
|
#define kMaxSaveSlotChars 25
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
GameStat GameStats;
|
|
|
|
|
|
|
|
short nCinemaSeen[30];
|
|
|
|
|
|
|
|
// this might be static within the DoPlasma function?
|
2019-08-31 07:47:15 +00:00
|
|
|
uint8_t plasmaBuffer[25600];
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
uint8_t energytile[4356] = { 0 };
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
uint8_t cinemapal[768];
|
2019-09-19 19:45:19 +00:00
|
|
|
short nLeft[50] = { 0 };
|
|
|
|
int line;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
short SavePosition = -1;
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
uint8_t *cur;
|
|
|
|
uint8_t *dest;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
unsigned int nSmokeBottom;
|
|
|
|
unsigned int nSmokeRight;
|
|
|
|
unsigned int nSmokeTop;
|
|
|
|
unsigned int nSmokeLeft;
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
unsigned int nRandom = 0x41C6167E;
|
|
|
|
int dword_9AB57 = 0x1F;
|
|
|
|
short word_9AB5B = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
int keytimer = 0;
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
int plasma_A[5] = { 0 };
|
|
|
|
int plasma_B[5] = { 0 };
|
|
|
|
int plasma_C[5] = { 0 };
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
short nMenuKeys[] = {
|
|
|
|
sc_N, sc_L, sc_M, sc_V, sc_Q, sc_None
|
|
|
|
}; // select a menu item using the keys. 'N' for New Gane, 'V' for voume etc. 'M' picks Training for some reason...
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
int zoomsize = 0;
|
|
|
|
|
|
|
|
void menu_ResetKeyTimer();
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
enum
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
kMenuNewGame = 0,
|
|
|
|
kMenuLoadGame,
|
|
|
|
kMenuTraining,
|
|
|
|
kMenuVolume,
|
|
|
|
kMenuQuitGame,
|
|
|
|
kMenuMaxItems
|
2019-08-26 03:59:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
void ClearCinemaSeen() { memset(nCinemaSeen, 0, sizeof(nCinemaSeen)); }
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
unsigned int menu_RandomBit2()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
unsigned int result = nRandom & 1;
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (--dword_9AB57 > 0)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
nRandom = (result << 31) | (nRandom >> 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dword_9AB57 = 31;
|
|
|
|
nRandom ^= nRandom >> 4;
|
|
|
|
}
|
|
|
|
return result;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int menu_RandomLong2()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
int randLong = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
for (int i = 0; i < 32; i++)
|
|
|
|
{
|
|
|
|
int val = menu_RandomBit2();
|
|
|
|
randLong *= 2;
|
|
|
|
randLong |= val;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
return randLong;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
void InitEnergyTile() { memset(energytile, 96, sizeof(energytile)); }
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
void DoEnergyTile()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
tileLoad(kEnergy1);
|
|
|
|
tileLoad(kEnergy2);
|
|
|
|
|
|
|
|
nButtonColor += nButtonColor < 0 ? 8 : 0;
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
uint8_t *ptr1 = (uint8_t *)(waloff[kEnergy1] + 1984);
|
|
|
|
uint8_t *ptr2 = (uint8_t *)(waloff[kEnergy1] + 2048);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
short nColor = nButtonColor + 161;
|
|
|
|
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
for (i = 0; i < 32; i++)
|
|
|
|
{
|
|
|
|
memset(ptr1, nColor, 64);
|
|
|
|
memset(ptr2, nColor, 64);
|
|
|
|
|
|
|
|
ptr1 -= 64;
|
|
|
|
ptr2 += 64;
|
|
|
|
|
|
|
|
nColor++;
|
2019-09-19 19:45:19 +00:00
|
|
|
|
|
|
|
if (nColor >= 168)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nColor = 160;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nSmokeSparks)
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
uint8_t *c = &energytile[67]; // TODO - checkme
|
|
|
|
uint8_t *ptrW = (uint8_t *)waloff[kEnergy2];
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
for (i = 0; i < 64; i++)
|
|
|
|
{
|
|
|
|
for (j = 0; j < 64; j++)
|
|
|
|
{
|
|
|
|
if (*c != 96)
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (*c <= 158)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
*ptrW = 96;
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
else
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
*ptrW = (*c) - 1;
|
|
|
|
}
|
|
|
|
//continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (menu_RandomBit2())
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
*ptrW = *c;
|
|
|
|
c++;
|
|
|
|
ptrW++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
char al = *(c + 1);
|
|
|
|
char ah = *(c - 1);
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (al <= ah)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
al = ah;
|
|
|
|
}
|
|
|
|
|
|
|
|
char cl = al;
|
2019-09-19 19:45:19 +00:00
|
|
|
al = *(c - 66);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (cl <= al)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
cl = al;
|
|
|
|
}
|
|
|
|
|
|
|
|
al = *(c + 66);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (cl <= al)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
cl = al;
|
|
|
|
}
|
|
|
|
|
|
|
|
al = *(c + 66);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (cl <= al)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
cl = al;
|
|
|
|
}
|
|
|
|
|
|
|
|
al = *(c + 66);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (cl <= al)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
cl = al;
|
|
|
|
}
|
|
|
|
|
|
|
|
al = *(c - 65);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (cl <= al)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
cl = al;
|
|
|
|
}
|
|
|
|
|
|
|
|
al = *(c - 67);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (cl > al)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
al = cl;
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (al <= 159)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
*ptrW = 96;
|
|
|
|
//continue;
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
else
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
if (!menu_RandomBit2())
|
|
|
|
{
|
|
|
|
cl--;
|
|
|
|
}
|
|
|
|
|
|
|
|
*ptrW = cl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
c++;
|
|
|
|
ptrW++;
|
|
|
|
}
|
|
|
|
|
|
|
|
c += 2;
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
c = &energytile[67]; // TODO - checkme
|
|
|
|
ptrW = (uint8_t *)waloff[kEnergy2];
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
for (i = 0; i < 64; i++)
|
|
|
|
{
|
|
|
|
memcpy(c, ptrW, 64);
|
|
|
|
c += 66;
|
|
|
|
ptrW += 64;
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
ptrW = (uint8_t *)waloff[kEnergy2];
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
for (i = 0; i < 4096; i++)
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (*ptrW == 96)
|
|
|
|
{
|
|
|
|
*ptrW = 255; // -1?
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
|
|
|
|
ptrW++;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
word_9AB5B--;
|
|
|
|
if (word_9AB5B <= 0)
|
|
|
|
{
|
|
|
|
int randSize = (RandomSize(5) & 0x1F) + 16;
|
|
|
|
int randSize2 = (RandomSize(5) & 0x1F) + 16;
|
|
|
|
|
|
|
|
int val = randSize << 5;
|
|
|
|
val += randSize;
|
|
|
|
val *= 2;
|
|
|
|
val += randSize2;
|
|
|
|
|
|
|
|
energytile[val] = 195;
|
2019-09-19 19:45:19 +00:00
|
|
|
word_9AB5B = 1;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//int TILE_4092 = kTile4092;
|
|
|
|
int nPlasmaTile = kTile4092;
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
#define kPlasmaWidth 320
|
|
|
|
#define kPlasmaHeight 80
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
void menu_DoPlasma()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
if (waloff[kTile4092] == 0)
|
|
|
|
{
|
|
|
|
tileCreate(kTile4092, kPlasmaWidth, kPlasmaHeight);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
memset((void *)waloff[kTile4092], 96, kPlasmaWidth * kPlasmaHeight);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
waloff[kTile4093] = (intptr_t)plasmaBuffer;
|
|
|
|
memset(plasmaBuffer, 96, sizeof(plasmaBuffer));
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
nSmokeLeft = 160 - tilesiz[kExhumedLogo].x / 2;
|
2019-08-31 07:47:15 +00:00
|
|
|
nSmokeRight = nSmokeLeft + tilesiz[kExhumedLogo].x;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
tilesiz[kTile4093].x = kPlasmaWidth;
|
|
|
|
tilesiz[kTile4093].y = kPlasmaHeight;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
nSmokeTop = 40 - tilesiz[kExhumedLogo].y / 2;
|
2019-08-31 11:44:02 +00:00
|
|
|
nSmokeBottom = nSmokeTop + tilesiz[kExhumedLogo].y - 1;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 09:08:38 +00:00
|
|
|
//uint32_t t = time(0) << 16;
|
|
|
|
//uint32_t t2 = time(0) | t;
|
2019-09-06 05:18:12 +00:00
|
|
|
nRandom = (int)totalclock;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
for (int i = 0; i < 5; i++)
|
|
|
|
{
|
|
|
|
int logoWidth = tilesiz[kExhumedLogo].x;
|
2019-08-26 03:59:14 +00:00
|
|
|
#if 1
|
2019-08-31 07:47:15 +00:00
|
|
|
plasma_C[i] = (nSmokeLeft + rand() % logoWidth) << 16;
|
|
|
|
plasma_B[i] = (menu_RandomLong2() % 327680) + 0x10000;
|
2019-08-26 03:59:14 +00:00
|
|
|
#else
|
2019-09-19 19:45:19 +00:00
|
|
|
int r = rand();
|
2019-08-31 07:47:15 +00:00
|
|
|
int rand2 = menu_RandomLong2();
|
|
|
|
|
|
|
|
__asm {
|
|
|
|
mov ebx, i
|
|
|
|
mov ecx, logoWidth
|
|
|
|
mov eax, r
|
|
|
|
mov edx, eax
|
|
|
|
sar edx, 31
|
|
|
|
idiv ecx
|
|
|
|
|
|
|
|
add edx, nSmokeLeft
|
|
|
|
shl edx, 16
|
|
|
|
mov ecx, 327680
|
|
|
|
mov plasma_C[ebx * 4], edx
|
|
|
|
xor edx, edx
|
|
|
|
mov eax, rand2
|
2019-09-19 19:45:19 +00:00
|
|
|
// call menu_RandomLong2
|
2019-08-31 07:47:15 +00:00
|
|
|
div ecx
|
|
|
|
add edx, 10000h
|
|
|
|
mov plasma_B[ebx * 4], edx
|
2019-09-19 19:45:19 +00:00
|
|
|
}
|
|
|
|
;
|
2019-08-26 03:59:14 +00:00
|
|
|
#endif
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (menu_RandomBit2())
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
plasma_B[i] = -plasma_B[i];
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
plasma_A[i] = menu_RandomBit2();
|
|
|
|
}
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
videoClearScreen(overscanindex);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
uint8_t *r_ebx = (uint8_t *)waloff[nPlasmaTile] + 81;
|
|
|
|
uint8_t *r_edx = (uint8_t *)waloff[nPlasmaTile ^ 1] + 81; // flip between value of 4092 and 4093 with xor
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
for (int x = 0; x < kPlasmaWidth - 2; x++)
|
2019-09-19 19:45:19 +00:00
|
|
|
// for (int x = 1; x < 318; x++)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
// for (int y = 1; y < 79; y++)
|
2019-08-31 07:47:15 +00:00
|
|
|
for (int y = 0; y < kPlasmaHeight - 2; y++)
|
|
|
|
{
|
|
|
|
uint8_t al = *r_edx;
|
|
|
|
|
|
|
|
if (al != 96)
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (al > 158)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
*r_ebx = al - 1;
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
else
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
*r_ebx = 96;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (menu_RandomBit2())
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
*r_ebx = *r_edx;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
uint8_t al = *(r_edx + 1);
|
|
|
|
uint8_t cl = *(r_edx - 1);
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (al <= cl)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
al = cl;
|
|
|
|
}
|
|
|
|
|
|
|
|
cl = al;
|
|
|
|
al = *(r_edx - 80);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (cl <= al)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
cl = al;
|
|
|
|
}
|
|
|
|
|
|
|
|
al = *(r_edx + 80);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (cl <= al)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
cl = al;
|
|
|
|
}
|
|
|
|
|
|
|
|
al = *(r_edx + 80);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (cl <= al)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
cl = al;
|
|
|
|
}
|
|
|
|
|
|
|
|
al = *(r_edx + 80);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (cl <= al)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
cl = al;
|
|
|
|
}
|
|
|
|
|
|
|
|
al = *(r_edx - 79);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (cl > al)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
al = cl;
|
|
|
|
}
|
|
|
|
|
|
|
|
cl = *(r_edx - 81);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (al <= cl)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
al = cl;
|
|
|
|
}
|
|
|
|
|
|
|
|
cl = al;
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (al <= 159)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
*r_ebx = 96;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (!menu_RandomBit2())
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
cl--;
|
|
|
|
}
|
|
|
|
|
|
|
|
*r_ebx = cl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// before restarting inner loop
|
|
|
|
r_edx++;
|
|
|
|
r_ebx++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// before restarting outer loop
|
|
|
|
r_edx += 2;
|
|
|
|
r_ebx += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
tileLoad(kExhumedLogo);
|
|
|
|
|
|
|
|
for (int j = 0; j < 5; j++)
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
int pB = plasma_B[j];
|
|
|
|
int pC = plasma_C[j];
|
|
|
|
int badOffset = (pC >> 16) < nSmokeLeft || (pC >> 16) >= nSmokeRight;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
uint8_t *ptr3 = (uint8_t *)(waloff[kExhumedLogo] + ((pC >> 16) - nSmokeLeft) * tilesiz[kExhumedLogo].y);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
plasma_C[j] += plasma_B[j];
|
|
|
|
|
2019-08-31 11:44:02 +00:00
|
|
|
if ((pB > 0 && (plasma_C[j] >> 16) >= nSmokeRight) || (pB < 0 && (plasma_C[j] >> 16) <= nSmokeLeft))
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
int esi = plasma_A[j];
|
2019-08-31 07:47:15 +00:00
|
|
|
plasma_B[j] = -plasma_B[j];
|
|
|
|
plasma_A[j] = esi == 0;
|
|
|
|
}
|
2019-08-31 15:04:06 +00:00
|
|
|
|
|
|
|
if (badOffset)
|
|
|
|
continue;
|
2019-09-19 19:45:19 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
unsigned int nSmokeOffset = 0;
|
|
|
|
|
|
|
|
if (plasma_A[j])
|
|
|
|
{
|
|
|
|
nSmokeOffset = nSmokeTop;
|
|
|
|
|
|
|
|
while (nSmokeOffset < nSmokeBottom)
|
|
|
|
{
|
|
|
|
uint8_t al = *ptr3;
|
2019-09-19 19:45:19 +00:00
|
|
|
if (al != 255 && al != 96)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
break;
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
nSmokeOffset++;
|
|
|
|
ptr3++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nSmokeOffset = nSmokeBottom;
|
|
|
|
|
|
|
|
ptr3 += tilesiz[kExhumedLogo].y - 1;
|
|
|
|
|
|
|
|
while (nSmokeOffset > nSmokeTop)
|
|
|
|
{
|
|
|
|
uint8_t al = *ptr3;
|
2019-09-19 19:45:19 +00:00
|
|
|
if (al != 255 && al != 96)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
nSmokeOffset--;
|
|
|
|
ptr3--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
uint8_t *v28 = (uint8_t *)(80 * (plasma_C[j] >> 16) + waloff[nPlasmaTile]);
|
2019-08-31 07:47:15 +00:00
|
|
|
v28[nSmokeOffset] = 175;
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
tileInvalidate(nPlasmaTile, -1, -1);
|
2019-08-31 15:04:06 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
overwritesprite(0, 0, nPlasmaTile, 0, 2, kPalNormal);
|
2019-08-31 07:47:15 +00:00
|
|
|
overwritesprite(160, 40, kExhumedLogo, 0, 3, kPalNormal);
|
2019-09-19 19:45:19 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
// flip between tile 4092 and 4093
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nPlasmaTile == kTile4092)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nPlasmaTile = kTile4093;
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
else if (nPlasmaTile == kTile4093)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nPlasmaTile = kTile4092;
|
|
|
|
}
|
|
|
|
|
|
|
|
// draw the fire urn/lamp thingies
|
2019-09-19 19:45:19 +00:00
|
|
|
int dword_9AB5F = ((int)totalclock / 16) & 3;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
overwritesprite(50, 150, kTile3512 + dword_9AB5F, 0, 3, kPalNormal);
|
2019-08-26 03:59:14 +00:00
|
|
|
overwritesprite(270, 150, kTile3512 + ((dword_9AB5F + 2) & 3), 0, 3, kPalNormal);
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
// TEMP
|
2019-09-06 05:18:12 +00:00
|
|
|
int time = (int)totalclock + 4;
|
2019-09-19 19:45:19 +00:00
|
|
|
while ((int)totalclock < time)
|
|
|
|
{
|
2019-08-31 15:04:06 +00:00
|
|
|
HandleAsync();
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
uint8_t MapDataArray_A[] = { 0, 50, 10, 20, 0, 45, 236, 20, 5, 0, 246, 10, 30, 236, 0, 20, 0, 0, 0, 0 };
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
struct TILEFRAMEDEF
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
short nTile;
|
|
|
|
short xOffs;
|
|
|
|
short yOffs;
|
2019-08-26 03:59:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// 22 bytes
|
|
|
|
struct MapNamePlaque
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
short xPos;
|
|
|
|
short yPos;
|
2019-08-31 07:47:15 +00:00
|
|
|
TILEFRAMEDEF tiles[2];
|
|
|
|
TILEFRAMEDEF text;
|
2019-08-26 03:59:14 +00:00
|
|
|
};
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
MapNamePlaque mapNamePlaques[]
|
|
|
|
= { { 100, 170, 3376, 0, 0, 3377, 0, 0, 3411, 18, 6 }, { 230, 10, 3378, 0, 0, 3379, 0, 0, 3414, 18, 6 }, // DENDUR (level 2)
|
|
|
|
{ 180, 125, 3380, 0, 0, 3381, 0, 0, 3417, 18, 6 }, // Kalabash
|
|
|
|
{ 10, 95, 3382, 0, 0, 3383, 0, 0, 3420, 18, 6 }, { 210, 160, 3384, 0, 0, 3385, 0, 0, 3423, 18, 6 },
|
|
|
|
{ 10, 110, 3371, 0, 0, 3386, 0, 0, 3426, 18, 6 }, { 10, 50, 3387, 0, 0, 3388, 0, 0, 3429, 18, 6 },
|
|
|
|
{ 140, 0, 3389, 0, 0, 3390, 0, 0, 3432, 18, 6 }, { 30, 20, 3391, 0, 0, 3392, 0, 0, 3435, 18, 6 },
|
|
|
|
{ 200, 150, 3409, 0, 0, 3410, 0, 0, 3418, 20, 4 }, { 145, 170, 3393, 0, 0, 3394, 0, 0, 3438, 18, 6 },
|
|
|
|
{ 80, 80, 3395, 0, 0, 3396, 0, 0, 3441, 18, 6 }, { 15, 0, 3397, 0, 0, 3398, 0, 0, 3444, 18, 5 },
|
|
|
|
{ 220, 35, 3399, 0, 0, 3400, 0, 0, 3447, 18, 6 }, { 190, 40, 3401, 0, 0, 3402, 0, 0, 3450, 18, 6 },
|
|
|
|
{ 20, 130, 3403, 0, 0, 3404, 0, 0, 3453, 19, 6 }, { 220, 160, 3405, 0, 0, 3406, 0, 0, 3456, 18, 6 },
|
|
|
|
{ 20, 10, 3407, 0, 0, 3408, 0, 0, 3459, 18, 6 }, { 200, 10, 3412, 0, 0, 3413, 0, 0, 3419, 18, 5 },
|
|
|
|
{ 20, 10, 3415, 0, 0, 3416, 0, 0, 3421, 19, 4 } };
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
// 3 different types of fire, each with 4 frames
|
2019-09-19 19:45:19 +00:00
|
|
|
TILEFRAMEDEF FireTiles[3][4] = { { { 3484, 0, 3 }, { 3485, 0, 0 }, { 3486, 0, 3 }, { 3487, 0, 0 } },
|
|
|
|
{ { 3488, 1, 0 }, { 3489, 1, 0 }, { 3490, 0, 1 }, { 3491, 1, 1 } },
|
|
|
|
{ { 3492, 1, 2 }, { 3493, 1, 0 }, { 3494, 1, 2 }, { 3495, 1, 0 } } };
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
struct Fire
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
short nFireType;
|
|
|
|
short xPos;
|
|
|
|
short yPos;
|
2019-08-26 03:59:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// 20 bytes
|
|
|
|
struct MapFire
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
short nFires;
|
2019-09-19 19:45:19 +00:00
|
|
|
Fire fires[3];
|
2019-08-26 03:59:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
level 1 - 3 fires
|
|
|
|
level 2 - 3 fires
|
|
|
|
level 3 - 1 fire
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
MapFire MapLevelFires[] = { 3, { { 0, 107, 95 }, { 1, 58, 140 }, { 2, 28, 38 } }, 3, { { 2, 240, 0 }, { 0, 237, 32 }, { 1, 200, 30 } },
|
|
|
|
2, { { 2, 250, 57 }, { 0, 250, 43 }, { 2, 200, 70 } }, 2, { { 1, 82, 59 }, { 2, 84, 16 }, { 0, 10, 95 } },
|
|
|
|
2, { { 2, 237, 50 }, { 1, 215, 42 }, { 1, 210, 50 } }, 3, { { 0, 40, 7 }, { 1, 75, 6 }, { 2, 100, 10 } },
|
|
|
|
3, { { 0, 58, 61 }, { 1, 85, 80 }, { 2, 111, 63 } }, 3, { { 0, 260, 65 }, { 1, 228, 0 }, { 2, 259, 15 } },
|
|
|
|
2, { { 0, 81, 38 }, { 2, 58, 38 }, { 2, 30, 20 } }, 3, { { 0, 259, 49 }, { 1, 248, 76 }, { 2, 290, 65 } },
|
|
|
|
3, { { 2, 227, 66 }, { 0, 224, 98 }, { 1, 277, 30 } }, 2, { { 0, 100, 10 }, { 2, 48, 76 }, { 2, 80, 80 } },
|
|
|
|
3, { { 0, 17, 2 }, { 1, 29, 49 }, { 2, 53, 28 } }, 3, { { 0, 266, 42 }, { 1, 283, 99 }, { 2, 243, 108 } },
|
|
|
|
2, { { 0, 238, 19 }, { 2, 240, 92 }, { 2, 190, 40 } }, 2, { { 0, 27, 0 }, { 1, 70, 40 }, { 0, 20, 130 } },
|
|
|
|
3, { { 0, 275, 65 }, { 1, 235, 8 }, { 2, 274, 6 } }, 3, { { 0, 75, 45 }, { 1, 152, 105 }, { 2, 24, 68 } },
|
|
|
|
3, { { 0, 290, 25 }, { 1, 225, 63 }, { 2, 260, 110 } }, 0, { { 1, 20, 10 }, { 1, 20, 10 }, { 1, 20, 10 } } };
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
int menu_DrawTheMap(int nLevel, int nLevelNew, int nLevelBest)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
int i;
|
2019-09-19 19:45:19 +00:00
|
|
|
int x = 0;
|
|
|
|
int var_2C = 0;
|
|
|
|
int var_38 = 0;
|
2019-08-31 07:47:15 +00:00
|
|
|
int bFadeDone = kFalse;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-06 05:18:12 +00:00
|
|
|
int startTime = (int)totalclock;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
ClearAllKeys();
|
|
|
|
UnMaskStatus();
|
|
|
|
videoSetViewableArea(0, 0, xdim - 1, ydim - 1);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
// 0-offset the level numbers
|
|
|
|
nLevel--;
|
|
|
|
nLevelNew--;
|
|
|
|
nLevelBest--;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nLevel > kMap20)
|
|
|
|
{ // max levels
|
2019-08-31 07:47:15 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nLevelNew > kMap20)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nLevel < 0)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nLevel = 0;
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nLevelNew < 0)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nLevelNew = nLevel;
|
|
|
|
}
|
|
|
|
|
|
|
|
int y1 = MapDataArray_A[nLevel] + (200 * (nLevel / 2));
|
|
|
|
int y2 = MapDataArray_A[nLevelNew] + (200 * (nLevelNew / 2));
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (y1 < y2)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
var_2C = 2;
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (y1 > y2)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
var_2C = -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (var_38 < 12)
|
|
|
|
{
|
2019-08-31 15:04:06 +00:00
|
|
|
HandleAsync();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-09-06 05:18:12 +00:00
|
|
|
if (((int)totalclock - startTime) / kTimerTicks)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
var_38++;
|
2019-09-06 05:18:12 +00:00
|
|
|
startTime = (int)totalclock;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
2019-09-06 05:18:12 +00:00
|
|
|
int var_3C = (int)totalclock;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
int tileY = y1;
|
|
|
|
|
|
|
|
// Draw the background screens
|
|
|
|
for (i = 0; i < 10; i++)
|
|
|
|
{
|
|
|
|
overwritesprite(x, tileY, kTile3353 + i, 0, 2, kPalNormal);
|
|
|
|
tileY -= 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
// for each level - drawing the 'level completed' on-fire smoke markers
|
|
|
|
for (i = 0; i < kMap20; i++)
|
|
|
|
{
|
|
|
|
int screenY = (i >> 1) * -200;
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nLevelBest >= i) // check if the player has finished this level
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
for (int j = 0; j < MapLevelFires[i].nFires; j++)
|
|
|
|
{
|
2019-09-06 05:18:12 +00:00
|
|
|
int nFireFrame = (((int)totalclock >> 4) & 3);
|
2019-08-31 07:47:15 +00:00
|
|
|
assert(nFireFrame >= 0 && nFireFrame < 4);
|
|
|
|
|
|
|
|
int nFireType = MapLevelFires[i].fires[j].nFireType;
|
|
|
|
assert(nFireType >= 0 && nFireType < 3);
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
int nTile = FireTiles[nFireType][nFireFrame].nTile;
|
2019-08-31 07:47:15 +00:00
|
|
|
int smokeX = MapLevelFires[i].fires[j].xPos + FireTiles[nFireType][nFireFrame].xOffs;
|
|
|
|
int smokeY = MapLevelFires[i].fires[j].yPos + FireTiles[nFireType][nFireFrame].yOffs + y1 + screenY;
|
|
|
|
|
|
|
|
overwritesprite(smokeX, smokeY, nTile, 0, 2, kPalNormal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-06 05:18:12 +00:00
|
|
|
int t = ((((int)totalclock & 16) >> 4));
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
int nTile = mapNamePlaques[i].tiles[t].nTile;
|
|
|
|
|
|
|
|
int nameX = mapNamePlaques[i].xPos + mapNamePlaques[i].tiles[t].xOffs;
|
|
|
|
int nameY = mapNamePlaques[i].yPos + mapNamePlaques[i].tiles[t].yOffs + y1 + screenY;
|
|
|
|
|
|
|
|
// Draw level name plaque
|
|
|
|
overwritesprite(nameX, nameY, nTile, 0, 2, kPalNormal);
|
|
|
|
|
|
|
|
int8_t shade = 96;
|
|
|
|
|
|
|
|
if (nLevelNew == i)
|
|
|
|
{
|
2019-09-06 05:18:12 +00:00
|
|
|
shade = (Sin(16 * (int)totalclock) + 31) >> 8;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
else if (nLevelBest >= i)
|
|
|
|
{
|
|
|
|
shade = 31;
|
|
|
|
}
|
|
|
|
|
|
|
|
int textY = mapNamePlaques[i].yPos + mapNamePlaques[i].text.yOffs + y1 + screenY;
|
|
|
|
int textX = mapNamePlaques[i].xPos + mapNamePlaques[i].text.xOffs;
|
2019-09-19 19:45:19 +00:00
|
|
|
nTile = mapNamePlaques[i].text.nTile;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
// draw the text, alternating between red and black
|
|
|
|
overwritesprite(textX, textY, nTile, shade, 2, kPalNormal);
|
|
|
|
}
|
|
|
|
|
|
|
|
videoNextPage();
|
|
|
|
if (!bFadeDone)
|
|
|
|
{
|
|
|
|
bFadeDone = kTrue;
|
|
|
|
FadeIn();
|
2019-09-06 05:18:12 +00:00
|
|
|
var_3C = (int)totalclock;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (y1 == y2)
|
|
|
|
{
|
|
|
|
if (KB_KeyDown[sc_UpArrow])
|
|
|
|
{
|
|
|
|
KB_KeyDown[sc_UpArrow] = 0;
|
|
|
|
|
|
|
|
if (nLevelNew <= nLevelBest)
|
|
|
|
{
|
|
|
|
nLevelNew++;
|
|
|
|
|
|
|
|
y2 = MapDataArray_A[nLevelNew] + (200 * (nLevelNew / 2));
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (y1 <= y2)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
var_2C = 2;
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
else
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
var_2C = -2;
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
var_38 = 0;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (KB_KeyDown[sc_DownArrow])
|
|
|
|
{
|
|
|
|
KB_KeyDown[sc_DownArrow] = 0;
|
|
|
|
|
|
|
|
if (nLevelNew > 0)
|
|
|
|
{
|
|
|
|
nLevelNew--;
|
|
|
|
|
|
|
|
y2 = MapDataArray_A[nLevelNew] + (200 * (nLevelNew / 2));
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (y1 <= y2)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
var_2C = 2;
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
else
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
var_2C = -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
var_38 = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (KB_KeyDown[sc_Escape] || KB_KeyDown[sc_Space] || KB_KeyDown[sc_Return])
|
|
|
|
{
|
|
|
|
KB_KeyDown[sc_Escape] = 0;
|
|
|
|
KB_KeyDown[sc_Return] = 0;
|
|
|
|
KB_KeyDown[sc_Space] = 0;
|
|
|
|
return nLevelNew + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-09-06 05:18:12 +00:00
|
|
|
y1 += var_2C * (((int)totalclock - var_3C) / 2);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
if (KB_KeyDown[sc_Escape] || KB_KeyDown[sc_Space] || KB_KeyDown[sc_Return])
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (var_2C < 8)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
var_2C *= 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
KB_KeyDown[sc_Escape] = 0;
|
|
|
|
KB_KeyDown[sc_Return] = 0;
|
|
|
|
KB_KeyDown[sc_Space] = 0;
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (y1 > y2 && var_2C > 0)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
y1 = y2;
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (y1 < y2 && var_2C < 0)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
y1 = y2;
|
|
|
|
}
|
|
|
|
|
|
|
|
var_38 = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MySetView(nViewLeft, nViewTop, nViewRight, nViewBottom);
|
|
|
|
return nLevelNew + 1;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void menu_AdjustVolume()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
int nOption = 1;
|
2019-09-19 19:45:19 +00:00
|
|
|
int var_8 = 0;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
2019-08-31 15:04:06 +00:00
|
|
|
HandleAsync();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
menu_DoPlasma();
|
|
|
|
|
2019-09-06 05:18:12 +00:00
|
|
|
overwritesprite(80, 50, kMenuMusicTile, (Sin((int)totalclock << 4) >> 9) * (nOption == 0), 2, kPalNormal);
|
2019-08-31 07:47:15 +00:00
|
|
|
overwritesprite(55, 75, kMenuBlankTitleTile, 0, 2, kPalNormal);
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
seq_DrawGunSequence(SeqOffsets[kSeqSlider], // eax
|
|
|
|
gMusicVolume % 3, // pick one of 3 frames?
|
|
|
|
(gMusicVolume >> 1) - 93, // ebx. must be x???
|
|
|
|
-22,
|
|
|
|
0,
|
|
|
|
0);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-09-06 05:18:12 +00:00
|
|
|
overwritesprite(80, 110, kMenuSoundFxTile, (Sin((int)totalclock << 4) >> 9) * (nOption == 1), 2, kPalNormal);
|
2019-08-31 07:47:15 +00:00
|
|
|
overwritesprite(55, 135, kMenuBlankTitleTile, 0, 2, kPalNormal);
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
seq_DrawGunSequence(SeqOffsets[kSeqSlider], gFXVolume % 3, (gFXVolume / 2) - 93, 38, 0, 0);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
int y = (60 * nOption) + 38;
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
overwritesprite(60, y, kMenuCursorTile, 0, 2, kPalNormal);
|
2019-08-31 07:47:15 +00:00
|
|
|
overwritesprite(206, y, kMenuCursorTile, 0, 10, kPalNormal);
|
|
|
|
|
|
|
|
videoNextPage();
|
|
|
|
|
|
|
|
if (KB_KeyDown[sc_Escape] || KB_KeyDown[sc_Return] || KB_KeyDown[sc_Space])
|
|
|
|
{
|
|
|
|
PlayLocalSound(StaticSound[kSound33], 0);
|
|
|
|
KB_KeyDown[sc_Escape] = 0;
|
|
|
|
KB_KeyDown[sc_Space] = 0;
|
|
|
|
KB_KeyDown[sc_Return] = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (KB_KeyDown[sc_UpArrow])
|
|
|
|
{
|
|
|
|
if (nOption > 0)
|
|
|
|
{
|
|
|
|
nOption--;
|
|
|
|
PlayLocalSound(StaticSound[kSound35], 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
KB_KeyDown[sc_UpArrow] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (KB_KeyDown[sc_DownArrow])
|
|
|
|
{
|
|
|
|
if (nOption < 1)
|
|
|
|
{
|
|
|
|
nOption++;
|
|
|
|
PlayLocalSound(StaticSound[kSound35], 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
KB_KeyDown[sc_DownArrow] = 0;
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if ((int)totalclock <= var_8)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-09-06 05:18:12 +00:00
|
|
|
var_8 = (int)totalclock + 5;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
if (KB_KeyDown[sc_LeftArrow])
|
|
|
|
{
|
|
|
|
switch (nOption)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (gMusicVolume > 3)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
gMusicVolume -= 4;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
// TODO SetMusicVolume();
|
|
|
|
// TODO setCDaudiovolume(gMusicVolume);
|
2019-08-31 07:47:15 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (gFXVolume > 3)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
gFXVolume -= 4;
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (LocalSoundPlaying())
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
UpdateLocalSound();
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
else
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
PlayLocalSound(StaticSound[kSound23], 0);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (KB_KeyDown[sc_RightArrow])
|
|
|
|
{
|
|
|
|
switch (nOption)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (gMusicVolume < 252)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
gMusicVolume += 4;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
// TODO SetMusicVolume();
|
|
|
|
// TODO setCDaudiovolume(gMusicVolume);
|
2019-08-31 07:47:15 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (gFXVolume < 252)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
gFXVolume += 4;
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (LocalSoundPlaying())
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
UpdateLocalSound();
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
else
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
PlayLocalSound(StaticSound[kSound23], 0);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (GetLocalSound() != 23)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
continue;
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
else
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
StopLocalSound();
|
|
|
|
}
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int menu_NewGameMenu()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
const char endMark = 0xF;
|
2019-09-19 19:45:19 +00:00
|
|
|
char nameList[5][25];
|
|
|
|
int nNameLen = sizeof(nameList);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
int nNameOffset = 0; // char index into slot name string
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-08-31 16:05:11 +00:00
|
|
|
//int nPages = numpages;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
int arg_3E = tilesiz[kMenuBlankTitleTile].x - 10;
|
|
|
|
|
|
|
|
int nSlot = 0;
|
|
|
|
|
|
|
|
FILE *fp = fopen("savgamea.sav", "rb");
|
|
|
|
if (fp == NULL)
|
|
|
|
{
|
|
|
|
memset(nameList, 0, nNameLen);
|
|
|
|
memset(&GameStats, 0, sizeof(GameStat));
|
|
|
|
|
|
|
|
fp = fopen("savgamea.sav", "wb+");
|
|
|
|
if (fp != NULL)
|
|
|
|
{
|
|
|
|
fwrite(nameList, nNameLen, 1, fp);
|
2019-09-19 19:45:19 +00:00
|
|
|
fwrite(&GameStats, 75, 1, fp); //fwrite(&GameStats, 75, 5, fp); // CHECKME! the size
|
2019-08-31 07:47:15 +00:00
|
|
|
fwrite(&endMark, sizeof(endMark), 1, fp);
|
|
|
|
|
|
|
|
fclose(fp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int nRead = fread(nameList, 1, nNameLen, fp);
|
|
|
|
if (nRead != nNameLen)
|
|
|
|
{
|
|
|
|
memset(nameList, 0, nNameLen);
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(fp);
|
|
|
|
}
|
|
|
|
|
|
|
|
// while (1)
|
|
|
|
{
|
|
|
|
ClearAllKeys();
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
2019-08-31 15:04:06 +00:00
|
|
|
HandleAsync();
|
2019-08-31 07:47:15 +00:00
|
|
|
menu_DoPlasma();
|
|
|
|
|
|
|
|
int y = (tilesiz[kMenuBlankTitleTile].y - (tilesiz[kMenuBlankTitleTile].y / 2) / 2) + 65;
|
|
|
|
rotatesprite(160 << 16, y << 16, 0x10000, 0, kMenuNewGameTile, 0, 0, 2, 0, 0, xdim, ydim);
|
|
|
|
|
|
|
|
int edi = 0;
|
|
|
|
|
|
|
|
int arg_4A = 90;
|
|
|
|
int arg_4E = 98;
|
|
|
|
|
|
|
|
// Loop #3
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
|
|
{
|
|
|
|
// CHECKME
|
2019-09-06 05:18:12 +00:00
|
|
|
int8_t shade = ((Sin((int)totalclock << 4) >> 9) * (i == nSlot)) + ((i != nSlot) * 31);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
overwritesprite(55, arg_4A, kMenuBlankTitleTile, shade, 2, kPalNormal);
|
|
|
|
myprintext(63, arg_4E, nameList[i], 0);
|
|
|
|
|
|
|
|
arg_4E += 22;
|
|
|
|
arg_4A += 22;
|
|
|
|
|
|
|
|
edi++;
|
|
|
|
}
|
|
|
|
|
|
|
|
edi = nSlot * 22;
|
|
|
|
|
|
|
|
// draw selection markers
|
|
|
|
overwritesprite(35, edi + 78, kMenuCursorTile, 0, 2, kPalNormal);
|
|
|
|
overwritesprite(233, edi + 78, kMenuCursorTile, 0, 10, kPalNormal);
|
|
|
|
videoNextPage();
|
|
|
|
|
2019-08-31 16:05:11 +00:00
|
|
|
//nPages--;
|
|
|
|
//if (nPages > 0) {
|
|
|
|
// continue;
|
|
|
|
//}
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
if (KB_KeyDown[sc_Escape])
|
|
|
|
{
|
|
|
|
PlayLocalSound(StaticSound[kSound33], 0);
|
|
|
|
KB_KeyDown[sc_Escape] = 0;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (KB_KeyDown[sc_UpArrow])
|
|
|
|
{
|
|
|
|
PlayLocalSound(StaticSound[kSound35], 0);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nSlot <= 0)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nSlot = 4;
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
else
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nSlot--;
|
|
|
|
}
|
|
|
|
|
|
|
|
KB_KeyDown[sc_UpArrow] = 0;
|
|
|
|
ClearAllKeys();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (KB_KeyDown[sc_DownArrow])
|
|
|
|
{
|
|
|
|
PlayLocalSound(StaticSound[kSound35], 0);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nSlot >= 4)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nSlot = 0;
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
else
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nSlot++;
|
|
|
|
}
|
|
|
|
|
|
|
|
KB_KeyDown[sc_DownArrow] = 0;
|
|
|
|
ClearAllKeys();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (KB_KeyDown[sc_Return] || KB_KeyWaiting())
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PlayLocalSound(StaticSound[kSound33], 0);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (KB_KeyDown[sc_Return])
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
ClearAllKeys();
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
char *pName = nameList[nSlot];
|
|
|
|
int nNameLength = strlen(pName);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
memset(pName, 0, nNameLength);
|
|
|
|
|
|
|
|
menu_DoPlasma();
|
|
|
|
overwritesprite(55, (nSlot * 22) + 90, kMenuBlankTitleTile, 0, 2, kPalNormal);
|
|
|
|
|
|
|
|
int arg_5A = 90;
|
|
|
|
int arg_52 = 98;
|
|
|
|
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
|
|
{
|
|
|
|
overwritesprite(55, arg_5A, kMenuBlankTitleTile, (i != nSlot) * 31, 2, kPalNormal);
|
|
|
|
myprintext(63, arg_52, nameList[i], 0);
|
|
|
|
|
|
|
|
arg_52 += 22;
|
|
|
|
arg_5A += 22;
|
|
|
|
}
|
|
|
|
|
|
|
|
int x = 35;
|
|
|
|
int y = (nSlot * 22) + 78;
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
2019-08-31 15:04:06 +00:00
|
|
|
HandleAsync();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
overwritesprite(x, y, kMenuCursorTile, 0, 2, kPalNormal);
|
|
|
|
overwritesprite(233, y, kMenuCursorTile, 0, 10, kPalNormal);
|
|
|
|
videoNextPage();
|
|
|
|
|
|
|
|
char ch = 0;
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
check_keys:
|
|
|
|
if (KB_KeyWaiting())
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2019-08-31 15:04:06 +00:00
|
|
|
HandleAsync();
|
2019-08-31 07:47:15 +00:00
|
|
|
ch = KB_GetCh();
|
2019-09-19 19:45:19 +00:00
|
|
|
if (!ch)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
KB_GetCh();
|
2019-09-19 19:45:19 +00:00
|
|
|
goto check_keys;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
// handle key input
|
|
|
|
if (ch == asc_Enter)
|
|
|
|
{
|
|
|
|
// loc_39ACA:
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
nameList[nSlot][nNameOffset] = 0;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
PlayLocalSound(StaticSound[kSound33], 0);
|
|
|
|
KB_KeyDown[sc_Return] = 0;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nameList[nSlot][0] == 0)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nNameLength) // does the save slot already exist?
|
|
|
|
{
|
|
|
|
menu_DoPlasma();
|
|
|
|
if (Query(2, 4, "Overwrite existing game?", "Y/N", 'Y', 13, 'N', 27) >= 2)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
FILE *fp = fopen("savgamea.sav", "rb+");
|
|
|
|
if (fp == NULL)
|
|
|
|
{
|
|
|
|
return -1;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
memset(&GameStats, 0, sizeof(GameStat));
|
|
|
|
GameStats.nWeapons = 1;
|
|
|
|
GameStats.nMap = 1;
|
|
|
|
|
|
|
|
fwrite(nameList, sizeof(nameList), 1, fp);
|
|
|
|
fseek(fp, sizeof(nameList), SEEK_SET);
|
|
|
|
fseek(fp, nSlot * sizeof(GameStat), SEEK_CUR);
|
|
|
|
fwrite(&GameStats, sizeof(GameStat), 1, fp);
|
|
|
|
fclose(fp);
|
|
|
|
return nSlot;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
else
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
// Enter wasn't pressed
|
|
|
|
PlayLocalSound(4, 0); // ??
|
|
|
|
|
|
|
|
if (ch == asc_BackSpace)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
nameList[nSlot][nNameOffset] = 0;
|
|
|
|
|
|
|
|
if (nNameOffset > 0)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
nNameOffset--;
|
|
|
|
}
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
nameList[nSlot][nNameOffset] = 0;
|
|
|
|
}
|
|
|
|
else if (ch == asc_Escape)
|
|
|
|
{
|
|
|
|
PlayLocalSound(StaticSound[kSound33], 0);
|
|
|
|
KB_ClearKeysDown();
|
|
|
|
KB_FlushKeyboardQueue();
|
|
|
|
KB_KeyDown[sc_Escape] = 0;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// check if a slot name is being typed
|
|
|
|
if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch == ' '))
|
|
|
|
{
|
|
|
|
ch = toupper(ch);
|
|
|
|
if (nNameOffset < 24) // n chars per slot name
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
nameList[nSlot][nNameOffset] = ch;
|
|
|
|
nNameOffset++;
|
|
|
|
nameList[nSlot][nNameOffset] = '\0'; // null terminate in the new offset
|
|
|
|
|
|
|
|
int nLen = MyGetStringWidth(nameList[nSlot]);
|
|
|
|
if (nLen > arg_3E)
|
|
|
|
{
|
|
|
|
nNameOffset--;
|
|
|
|
nameList[nSlot][nNameOffset] = '\0';
|
|
|
|
}
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
}
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
// loc_399FD:
|
|
|
|
menu_DoPlasma();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
int arg_5E = ((int)totalclock / 30) & 1;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
int y = 90;
|
|
|
|
int arg_42 = 98;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
for (int i = 0; i < 5; i++)
|
|
|
|
{
|
|
|
|
overwritesprite(55, y, kMenuBlankTitleTile, (i != nSlot) * 31, 2, kPalNormal);
|
|
|
|
int nTextWidth = myprintext(63, arg_42, nameList[i], 0);
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
// flash a full-stop to show the current typing position
|
|
|
|
if (arg_5E != 0 && nSlot == i)
|
|
|
|
{
|
|
|
|
myprintext(nTextWidth, arg_42, ".", 0);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
|
|
|
|
arg_42 += 22;
|
|
|
|
y += 22;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int menu_LoadGameMenu()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
char nameList[5][25];
|
|
|
|
|
|
|
|
int nSlot = 0;
|
|
|
|
|
|
|
|
FILE *fp = fopen("savgamea.sav", "rb");
|
|
|
|
if (fp == NULL)
|
|
|
|
{
|
|
|
|
memset(nameList, 0, sizeof(nameList));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fread(nameList, sizeof(nameList), 1, fp);
|
|
|
|
fclose(fp);
|
|
|
|
}
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
menu_DoPlasma();
|
|
|
|
|
2019-08-31 15:04:06 +00:00
|
|
|
HandleAsync();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
overwritesprite(80, 65, kMenuLoadGameTile, 0, 2, kPalNormal);
|
|
|
|
|
|
|
|
int spriteY = 90;
|
2019-09-19 19:45:19 +00:00
|
|
|
int textY = 98;
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
for (int i = 0; i < kMaxSaveSlots; i++)
|
|
|
|
{
|
|
|
|
// TODO - shade flashing
|
|
|
|
overwritesprite(55, spriteY, kMenuBlankTitleTile, 0, 2, kPalNormal);
|
|
|
|
|
|
|
|
myprintext(63, textY, nameList[i], 0);
|
|
|
|
textY += 22;
|
|
|
|
spriteY += 22;
|
|
|
|
}
|
|
|
|
|
|
|
|
int y = (nSlot * 22) + 78;
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
overwritesprite(35, y, kMenuCursorTile, 0, 2, kPalNormal);
|
2019-08-31 07:47:15 +00:00
|
|
|
overwritesprite(233, y, kMenuCursorTile, 0, 10, kPalNormal);
|
|
|
|
videoNextPage();
|
|
|
|
|
|
|
|
if (KB_KeyDown[sc_Escape])
|
|
|
|
{
|
|
|
|
PlayLocalSound(StaticSound[kSound33], 0);
|
|
|
|
KB_KeyDown[sc_Escape] = 0;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (KB_KeyDown[sc_UpArrow])
|
|
|
|
{
|
|
|
|
PlayLocalSound(StaticSound[kSound35], 0);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nSlot > 0)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nSlot--;
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
else
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nSlot = kMaxSaveSlots - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
KB_KeyDown[sc_UpArrow] = 0;
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (KB_KeyDown[sc_DownArrow]) // checkme - is 0x5b in disassembly
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
PlayLocalSound(StaticSound[kSound35], 0);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nSlot < kMaxSaveSlots - 1)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nSlot++;
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
else
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nSlot = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
KB_KeyDown[sc_DownArrow] = 0;
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (!KB_KeyDown[sc_Return])
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
PlayLocalSound(StaticSound[kSound33], 0);
|
|
|
|
KB_KeyDown[sc_Return] = 0;
|
|
|
|
KB_ClearKeysDown();
|
|
|
|
KB_FlushKeyboardQueue();
|
|
|
|
|
|
|
|
if (nameList[nSlot][0] != '\0')
|
|
|
|
{
|
|
|
|
PlayLocalSound(StaticSound[33], 0);
|
|
|
|
return nSlot;
|
|
|
|
}
|
|
|
|
|
|
|
|
PlayLocalSound(4, 0);
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
void menu_ResetKeyTimer() { keytimer = (int)totalclock + 2400; }
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
void menu_GameLoad2(FILE *fp)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
fread(&GameStats, sizeof(GameStats), 1, fp);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
nPlayerWeapons[nLocalPlayer] = GameStats.nWeapons;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
PlayerList[nLocalPlayer].nCurrentWeapon = GameStats.nCurrentWeapon;
|
2019-09-19 19:45:19 +00:00
|
|
|
nPlayerClip[nLocalPlayer] = GameStats.clip;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int nPistolBullets = PlayerList[nLocalPlayer].nAmmo[kWeaponPistol];
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nPistolBullets >= 6)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nPistolBullets = 6;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
nPistolClip[nLocalPlayer] = nPistolBullets;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
memcpy(&PlayerList[nLocalPlayer], &GameStats.player, sizeof(Player));
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
nPlayerItem[nLocalPlayer] = GameStats.items;
|
|
|
|
nPlayerLives[nLocalPlayer] = GameStats.nLives;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
SetPlayerItem(nLocalPlayer, nPlayerItem[nLocalPlayer]);
|
|
|
|
CheckClip(nLocalPlayer);
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
short menu_GameLoad(int nSlot)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
memset(&GameStats, 0, sizeof(GameStats));
|
2019-09-19 19:45:19 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
FILE *fp = fopen("savegamea.sav", "rb");
|
2019-09-19 19:45:19 +00:00
|
|
|
if (fp == NULL)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
fseek(fp, 125, SEEK_SET);
|
|
|
|
fseek(fp, nSlot * sizeof(GameStats), SEEK_CUR);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
menu_GameLoad2(fp);
|
|
|
|
fclose(fp);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
return GameStats.nMap;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void menu_GameSave2(FILE *fp)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
memset(&GameStats, 0, sizeof(GameStats));
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
GameStats.nMap = (uint8_t)levelnew;
|
|
|
|
GameStats.nWeapons = nPlayerWeapons[nLocalPlayer];
|
2019-08-31 07:47:15 +00:00
|
|
|
GameStats.nCurrentWeapon = PlayerList[nLocalPlayer].nCurrentWeapon;
|
2019-09-19 19:45:19 +00:00
|
|
|
GameStats.clip = nPlayerClip[nLocalPlayer];
|
|
|
|
GameStats.items = nPlayerItem[nLocalPlayer];
|
|
|
|
GameStats.nLives = nPlayerLives[nLocalPlayer];
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
memcpy(&GameStats.player, &PlayerList[nLocalPlayer], sizeof(GameStats.player));
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
fwrite(&GameStats, sizeof(GameStats), 1, fp);
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void menu_GameSave(int nSaveSlot)
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nSaveSlot < 0)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
FILE *fp = fopen("savgamea.sav", "rb+");
|
|
|
|
if (fp != NULL)
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
fseek(fp, 125, SEEK_SET); // skip save slot names
|
2019-08-31 07:47:15 +00:00
|
|
|
fseek(fp, sizeof(GameStat) * nSaveSlot, SEEK_CUR);
|
|
|
|
menu_GameSave2(fp);
|
|
|
|
fclose(fp);
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void menu_ResetZoom()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
zoomsize = 0;
|
|
|
|
PlayLocalSound(StaticSound[kSound62], 0);
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int menu_Menu(int nVal)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
GrabPalette();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int var_1C = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
videoSetViewableArea(0, 0, xdim - 1, ydim - 1);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
KB_KeyDown[sc_Escape] = 0;
|
|
|
|
|
|
|
|
StopAllSounds();
|
|
|
|
StopLocalSound();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
menu_ResetKeyTimer();
|
|
|
|
|
|
|
|
KB_FlushKeyboardQueue();
|
|
|
|
KB_ClearKeysDown();
|
|
|
|
|
|
|
|
menu_ResetZoom();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
short ptr[5];
|
|
|
|
memset(ptr, 1, sizeof(ptr));
|
|
|
|
|
|
|
|
// disable new game and load game if in multiplayer?
|
|
|
|
if (nNetPlayerCount)
|
|
|
|
{
|
|
|
|
ptr[1] = 0;
|
|
|
|
ptr[0] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// denote which menu item we've currently got selected
|
|
|
|
int nMenu = 0;
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
2019-08-31 15:04:06 +00:00
|
|
|
HandleAsync();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
// skip any disabled menu items so we're selecting the first active one
|
|
|
|
while (!ptr[nMenu])
|
|
|
|
{
|
|
|
|
nMenu++;
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nMenu == 5)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nMenu = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// handle the menu zoom-in
|
|
|
|
if (zoomsize < 0x10000)
|
|
|
|
{
|
|
|
|
zoomsize += 4096;
|
2019-09-19 19:45:19 +00:00
|
|
|
if (zoomsize >= 0x10000)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
zoomsize = 0x10000;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// menu idle timer
|
2019-09-19 19:45:19 +00:00
|
|
|
if (!nVal && (int)totalclock > keytimer)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
return 9;
|
|
|
|
}
|
|
|
|
|
|
|
|
// loc_39F54:
|
|
|
|
menu_DoPlasma();
|
|
|
|
|
|
|
|
int y = 65 - tilesiz[kMenuNewGameTile].y / 2;
|
|
|
|
|
|
|
|
// YELLOW loop - Draw the 5 menu options (NEW GAME, TRAINING etc)
|
|
|
|
for (int j = 0; j < 5; j++)
|
|
|
|
{
|
|
|
|
int8_t shade;
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nMenu == j)
|
|
|
|
{ // currently selected menu item
|
2019-09-06 05:18:12 +00:00
|
|
|
shade = Sin((int)totalclock << 4) >> 9;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
else if (ptr[j])
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
shade = 0;
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
else
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
shade = 25;
|
|
|
|
}
|
|
|
|
|
|
|
|
picanm[j + kMenuNewGameTile].xofs = 0;
|
|
|
|
picanm[j + kMenuNewGameTile].yofs = 0;
|
|
|
|
rotatesprite(160 << 16, (y + tilesiz[j + kMenuNewGameTile].y) << 16, zoomsize, 0, kMenuNewGameTile + j, shade, 0, 2, 0, 0, xdim, ydim);
|
|
|
|
|
|
|
|
y += 22;
|
|
|
|
}
|
|
|
|
|
|
|
|
// tilesizx is 51
|
|
|
|
// tilesizy is 33
|
|
|
|
|
|
|
|
int markerY = (22 * nMenu) + 53;
|
2019-09-19 19:45:19 +00:00
|
|
|
overwritesprite(62, markerY, kMenuCursorTile, 0, 2, kPalNormal);
|
2019-08-31 07:47:15 +00:00
|
|
|
overwritesprite(62 + 146, markerY, kMenuCursorTile, 0, 10, kPalNormal);
|
|
|
|
|
|
|
|
videoNextPage();
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
int l = 0; // edi
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
// ORANGE loop
|
2019-09-19 19:45:19 +00:00
|
|
|
for (l = 0;; l++)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
int nKey = nMenuKeys[l];
|
2019-09-19 19:45:19 +00:00
|
|
|
if (!nKey)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (KB_KeyDown[nKey])
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
goto LABEL_21; // TEMP
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// loc_3A0A7
|
|
|
|
while (KB_KeyDown[sc_Escape])
|
|
|
|
{
|
2019-08-31 15:04:06 +00:00
|
|
|
HandleAsync();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
PlayLocalSound(StaticSound[kSound33], 0);
|
|
|
|
KB_KeyDown[sc_Escape] = 0;
|
|
|
|
|
|
|
|
if (nVal)
|
|
|
|
{
|
|
|
|
StopAllSounds();
|
|
|
|
PlayLocalSound(StaticSound[kSound33], 0);
|
|
|
|
MySetView(nViewLeft, nViewTop, nViewRight, nViewBottom);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
l = 4;
|
2019-09-19 19:45:19 +00:00
|
|
|
LABEL_21:
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
menu_ResetKeyTimer();
|
|
|
|
|
|
|
|
if (l != nMenu)
|
|
|
|
{
|
|
|
|
PlayLocalSound(StaticSound[kSound35], 0);
|
|
|
|
KB_KeyDown[nMenuKeys[l]] = 0;
|
2019-09-19 19:45:19 +00:00
|
|
|
nMenu = l;
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (KB_KeyDown[sc_Space] || KB_KeyDown[sc_Return])
|
|
|
|
{
|
|
|
|
var_1C = 1;
|
|
|
|
}
|
|
|
|
else if (var_1C)
|
|
|
|
{
|
|
|
|
var_1C = 0;
|
|
|
|
|
|
|
|
PlayLocalSound(StaticSound[kSound33], 0);
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
switch (nMenu) // TODO - change var name?
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
case kMenuNewGame:
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nTotalPlayers > 1)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
menu_ResetZoom();
|
|
|
|
menu_ResetKeyTimer();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
SavePosition = menu_NewGameMenu();
|
2019-09-19 19:45:19 +00:00
|
|
|
if (SavePosition == -1)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
menu_ResetZoom();
|
|
|
|
menu_ResetKeyTimer();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
FadeOut(1);
|
|
|
|
StopAllSounds();
|
|
|
|
|
|
|
|
StopAllSounds();
|
|
|
|
PlayLocalSound(StaticSound[kSound33], 0);
|
|
|
|
MySetView(nViewLeft, nViewTop, nViewRight, nViewBottom);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
case kMenuLoadGame:
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nTotalPlayers > 1)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
menu_ResetZoom();
|
|
|
|
menu_ResetKeyTimer();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
SavePosition = menu_LoadGameMenu();
|
|
|
|
|
|
|
|
StopAllSounds();
|
|
|
|
|
|
|
|
StopAllSounds();
|
|
|
|
PlayLocalSound(StaticSound[kSound33], 0);
|
|
|
|
MySetView(nViewLeft, nViewTop, nViewRight, nViewBottom);
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
case kMenuTraining:
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nTotalPlayers > 1)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
menu_ResetZoom();
|
|
|
|
menu_ResetKeyTimer();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
StopAllSounds();
|
|
|
|
PlayLocalSound(StaticSound[kSound33], 0);
|
|
|
|
MySetView(nViewLeft, nViewTop, nViewRight, nViewBottom);
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
case kMenuVolume:
|
|
|
|
{
|
|
|
|
menu_AdjustVolume();
|
|
|
|
menu_ResetZoom();
|
|
|
|
menu_ResetKeyTimer();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case kMenuQuitGame:
|
|
|
|
{
|
|
|
|
StopAllSounds();
|
|
|
|
StopAllSounds();
|
|
|
|
PlayLocalSound(StaticSound[kSound33], 0);
|
|
|
|
MySetView(nViewLeft, nViewTop, nViewRight, nViewBottom);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
default:
|
2019-08-31 07:47:15 +00:00
|
|
|
menu_ResetZoom();
|
|
|
|
menu_ResetKeyTimer();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (KB_KeyDown[sc_UpArrow])
|
|
|
|
{
|
|
|
|
PlayLocalSound(StaticSound[kSound35], 0);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nMenu <= 0)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nMenu = 4;
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
else
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nMenu--;
|
|
|
|
}
|
|
|
|
|
|
|
|
KB_KeyDown[sc_UpArrow] = 0;
|
|
|
|
menu_ResetKeyTimer();
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (KB_KeyDown[sc_DownArrow]) // FIXME - is this down arrow? value is '5B' in disassembly
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
|
|
|
PlayLocalSound(StaticSound[kSound35], 0);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nMenu >= 4)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nMenu = 0;
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
else
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nMenu++;
|
|
|
|
}
|
|
|
|
|
|
|
|
KB_KeyDown[sc_DownArrow] = 0;
|
|
|
|
menu_ResetKeyTimer();
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO - change to #defines
|
2019-09-19 19:45:19 +00:00
|
|
|
if (KB_KeyDown[0x5c])
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
KB_KeyDown[0x5c] = 0;
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (KB_KeyDown[0x5d])
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
KB_KeyDown[0x5d] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
return 0; // todo
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
#define kMaxCinemaPals 16
|
|
|
|
const char *cinpalfname[kMaxCinemaPals] = { "3454.pal", "3452.pal", "3449.pal", "3445.pal", "set.pal", "3448.pal", "3446.pal", "hsc1.pal",
|
|
|
|
"2972.pal", "2973.pal", "2974.pal", "2975.pal", "2976.pal", "heli.pal", "2978.pal", "terror.pal" };
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
int linecount;
|
|
|
|
int nextclock;
|
2019-08-26 03:59:14 +00:00
|
|
|
short nHeight;
|
|
|
|
short nCrawlY;
|
|
|
|
short cinematile;
|
|
|
|
|
|
|
|
|
|
|
|
// TODO - moveme
|
|
|
|
int LoadCinemaPalette(int nPal)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
nPal--;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nPal < 0 || nPal >= kMaxCinemaPals)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
return -2;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
// original code strcpy'd into a buffer first...
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int hFile = kopen4load(cinpalfname[nPal], 1);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (hFile < 0)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
return -2;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
kread(hFile, cinemapal, sizeof(cinemapal));
|
|
|
|
kclose(hFile);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
return nPal;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int IncrementCinemaFadeIn()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
dest = cinemapal;
|
2019-09-19 19:45:19 +00:00
|
|
|
cur = curpal;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
int ebx = 0;
|
|
|
|
|
|
|
|
for (int i = 0; i < 768; i++)
|
|
|
|
{
|
|
|
|
ebx++;
|
|
|
|
|
|
|
|
if (*cur < *dest)
|
|
|
|
{
|
|
|
|
(*cur)++;
|
|
|
|
}
|
|
|
|
else if (*cur == *dest)
|
|
|
|
{
|
|
|
|
ebx--;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
(*cur)--;
|
|
|
|
}
|
|
|
|
|
|
|
|
cur++;
|
|
|
|
dest++;
|
|
|
|
}
|
|
|
|
|
|
|
|
MySetPalette(curpal);
|
|
|
|
return ebx;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CinemaFadeIn()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
BlackOut();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
int val = IncrementCinemaFadeIn();
|
|
|
|
WaitTicks(2);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (val <= 0)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ComputeCinemaText(int nLine)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
linecount = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
while (1)
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (!strcmp(gString[linecount + nLine], "END"))
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
break;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
int nWidth = MyGetStringWidth(gString[linecount + nLine]);
|
2019-08-31 07:47:15 +00:00
|
|
|
nLeft[linecount] = 160 - nWidth / 2;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
linecount++;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
nCrawlY = 199;
|
|
|
|
nHeight = linecount * 10;
|
2019-09-19 19:45:19 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
ClearAllKeys();
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2019-08-31 09:08:38 +00:00
|
|
|
void ReadyCinemaText(uint16_t nVal)
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
line = FindGString("CINEMAS");
|
2019-09-19 19:45:19 +00:00
|
|
|
if (line < 0)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (nVal)
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
while (strcmp(gString[line], "END"))
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
line++;
|
|
|
|
}
|
|
|
|
|
|
|
|
line++;
|
|
|
|
nVal--;
|
|
|
|
}
|
|
|
|
|
|
|
|
ComputeCinemaText(line);
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
uint8_t AdvanceCinemaText()
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
int var_1C = nCDTrackLength;
|
2019-09-19 19:45:19 +00:00
|
|
|
int tmp = nHeight + nCrawlY > 0;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-08-31 10:36:26 +00:00
|
|
|
if (tmp || nCDTrackLength && nCDTrackLength > 0)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2019-09-06 05:18:12 +00:00
|
|
|
nextclock = (int)totalclock + 14;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-08-31 10:36:26 +00:00
|
|
|
if (tmp > 0)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
short y = nCrawlY;
|
|
|
|
int edi = 0;
|
2019-08-31 07:47:15 +00:00
|
|
|
|
|
|
|
while (edi < linecount && y <= 199)
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (y >= -10)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
myprintext(nLeft[edi], y, gString[line + edi], 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
edi++;
|
|
|
|
y += 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
nCrawlY--;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
2019-08-31 15:04:06 +00:00
|
|
|
HandleAsync();
|
2019-08-31 07:47:15 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (KB_KeyDown[sc_Escape] || KB_KeyDown[sc_Return] || KB_KeyDown[sc_Space])
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (var_1C || nCDTrackLength)
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nextclock <= (int)totalclock)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
return kTrue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return kTrue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return kFalse;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DoCinemaText(short nVal)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
ReadyCinemaText(nVal);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
overwritesprite(0, 0, cinematile, 0, 2, kPalNormal);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
uint8_t bContinue = AdvanceCinemaText();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
WaitVBL();
|
|
|
|
videoNextPage();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (!bContinue)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void GoToTheCinema(int nVal)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
UnMaskStatus();
|
|
|
|
|
|
|
|
switch (nVal - 1)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
LoadCinemaPalette(1);
|
|
|
|
cinematile = 3454;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
LoadCinemaPalette(2);
|
|
|
|
cinematile = 3452;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
LoadCinemaPalette(3);
|
|
|
|
cinematile = 3449;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
LoadCinemaPalette(4);
|
|
|
|
cinematile = 3445;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
LoadCinemaPalette(5);
|
|
|
|
cinematile = 3451;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 5:
|
|
|
|
{
|
|
|
|
LoadCinemaPalette(6);
|
|
|
|
cinematile = 3448;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 6:
|
|
|
|
{
|
|
|
|
LoadCinemaPalette(7);
|
|
|
|
cinematile = 3446;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FadeOut(kFalse);
|
|
|
|
StopAllSounds();
|
|
|
|
NoClip();
|
|
|
|
|
|
|
|
overwritesprite(0, 0, 764, 100, 2, kPalNormal);
|
|
|
|
videoNextPage();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
// int386(16, (const union REGS *)&val, (union REGS *)&val)
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
overwritesprite(0, 0, cinematile, 0, 2, kPalNormal);
|
|
|
|
videoNextPage();
|
|
|
|
|
|
|
|
CinemaFadeIn();
|
|
|
|
ClearAllKeys();
|
|
|
|
|
|
|
|
int ebx = -1;
|
|
|
|
int edx = -1;
|
|
|
|
|
|
|
|
switch (nVal - 1)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
WaitAnyKey(10);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0:
|
|
|
|
ebx = 4;
|
|
|
|
edx = ebx;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
ebx = 0;
|
|
|
|
break;
|
2019-09-19 19:45:19 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
case 2:
|
|
|
|
ebx = 2;
|
|
|
|
edx = ebx;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
ebx = 7;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
ebx = 3;
|
|
|
|
edx = ebx;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 5:
|
|
|
|
ebx = 8;
|
|
|
|
edx = ebx;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 6:
|
|
|
|
ebx = 6;
|
|
|
|
edx = ebx;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ebx != -1)
|
|
|
|
{
|
|
|
|
if (edx != -1)
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (CDplaying())
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
fadecdaudio();
|
|
|
|
}
|
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
playCDtrack(edx + 2); // , 1);
|
2019-08-31 07:47:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DoCinemaText(ebx);
|
|
|
|
}
|
|
|
|
|
|
|
|
FadeOut(kTrue);
|
|
|
|
|
|
|
|
overwritesprite(0, 0, 764, 100, 2, kPalNormal);
|
|
|
|
videoNextPage();
|
|
|
|
|
|
|
|
MySetPalette(kenpal);
|
|
|
|
GrabPalette();
|
|
|
|
Clip();
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
short nBeforeScene[] = { 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
|
|
|
|
|
|
|
|
|
|
void CheckBeforeScene(int nLevel)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
if (nLevel == kMap20)
|
|
|
|
{
|
|
|
|
DoLastLevelCinema();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nBeforeScene[nLevel])
|
|
|
|
{
|
|
|
|
if (!nCinemaSeen[nLevel])
|
|
|
|
{
|
|
|
|
GoToTheCinema(nLevel);
|
|
|
|
nCinemaSeen[nLevel] = 1;
|
|
|
|
}
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int showmap(short nLevel, short nLevelNew, short nLevelBest)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
FadeOut(0);
|
|
|
|
EraseScreen(overscanindex);
|
|
|
|
GrabPalette();
|
|
|
|
BlackOut();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (nLevelNew != 11)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
CheckBeforeScene(nLevelNew);
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int selectedLevel = menu_DrawTheMap(nLevel, nLevelNew, nLevelBest);
|
2019-09-19 19:45:19 +00:00
|
|
|
if (selectedLevel == 11)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
CheckBeforeScene(selectedLevel);
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
return selectedLevel;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DoAfterCinemaScene(int nLevel)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
short word_9ABD5[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 7, 0, 0, 0, 0, 6 };
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (word_9ABD5[nLevel])
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
GoToTheCinema(word_9ABD5[nLevel]);
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DoFailedFinalScene()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
videoSetViewableArea(0, 0, xdim - 1, ydim - 1);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (CDplaying())
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
fadecdaudio();
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
playCDtrack(9);
|
|
|
|
FadeToWhite();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
// TODO GoToTheCinema(word_9ABFF);
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int FindGString(const char *str)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
int i = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
if (!strcmp(gString[i], str))
|
|
|
|
return i + 1;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
if (!strcmp(gString[i], "EOF"))
|
|
|
|
break;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
i++;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
return -1;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
uint8_t CheckForEscape()
|
2019-08-26 03:59:14 +00:00
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
if (!KB_KeyWaiting() || (KB_GetCh() != 27))
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
return kFalse;
|
|
|
|
}
|
2019-09-19 19:45:19 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
return kTrue;
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DoStatic(int a, int b)
|
|
|
|
{
|
2019-09-19 19:45:19 +00:00
|
|
|
RandomLong(); // nothing done with the result of this?
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
tileLoad(kTileLoboLaptop);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int v2 = 160 - a / 2;
|
2019-09-19 19:45:19 +00:00
|
|
|
int v4 = 81 - b / 2;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int var_18 = v2 + a;
|
2019-09-19 19:45:19 +00:00
|
|
|
int v5 = v4 + b;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
uint8_t *pTile = (uint8_t *)(waloff[kTileLoboLaptop] + (200 * v2)) + v4;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
while (v2 < var_18)
|
|
|
|
{
|
|
|
|
uint8_t *pStart = pTile;
|
|
|
|
pTile += 200;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int v7 = v4;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
while (v7 < v5)
|
|
|
|
{
|
|
|
|
*pStart = RandomBit() * 16;
|
2019-09-19 19:45:19 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
v7++;
|
|
|
|
pStart++;
|
|
|
|
}
|
|
|
|
v2++;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
overwritesprite(0, 0, kTileLoboLaptop, 0, 2, kPalNormal);
|
|
|
|
videoNextPage();
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DoLastLevelCinema()
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
FadeOut(0);
|
|
|
|
UnMaskStatus();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
videoSetViewableArea(0, 0, xdim - 1, ydim - 1);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
EraseScreen(-1);
|
|
|
|
RestorePalette();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int nString = FindGString("LASTLEVEL");
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
PlayLocalSound(StaticSound[kSound75], 0);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
tileLoad(kTileLoboLaptop);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
memcpy((void *)waloff[kTileLoboLaptop], (void *)waloff[kTileLoboLaptop], tilesiz[kTileLoboLaptop].x * tilesiz[kTileLoboLaptop].y);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int var_24 = 16;
|
|
|
|
int var_28 = 12;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-06 05:18:12 +00:00
|
|
|
int nEndTime = (int)totalclock + 240;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
while (KB_KeyWaiting())
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
KB_GetCh();
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-06 05:18:12 +00:00
|
|
|
while (nEndTime > (int)totalclock)
|
2019-08-31 07:47:15 +00:00
|
|
|
{
|
2019-08-31 15:04:06 +00:00
|
|
|
HandleAsync();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
if (var_24 >= 116)
|
|
|
|
{
|
|
|
|
if (var_28 < 192)
|
|
|
|
var_28 += 20;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
var_24 += 20;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
DoStatic(var_28, var_24);
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
// loadtilelockmode = 1;
|
2019-08-31 07:47:15 +00:00
|
|
|
tileLoad(kTileLoboLaptop);
|
2019-09-19 19:45:19 +00:00
|
|
|
// loadtilelockmode = 0;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
// loc_3AD75
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
do
|
|
|
|
{
|
2019-08-31 15:04:06 +00:00
|
|
|
HandleAsync();
|
2019-09-19 19:45:19 +00:00
|
|
|
LABEL_11:
|
2019-08-31 07:47:15 +00:00
|
|
|
if (strlen(gString[nString]) == 0)
|
|
|
|
break;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int esi = nString;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
tileLoad(kTileLoboLaptop);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
while (strlen(gString[esi]) != 0)
|
|
|
|
esi++;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int ebp = esi;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
ebp -= nString;
|
|
|
|
ebp = 81 - (ebp <<= 2);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int var_1C = esi - nString;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
// loc_3ADD7
|
|
|
|
while (1)
|
|
|
|
{
|
2019-08-31 15:04:06 +00:00
|
|
|
HandleAsync();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
if (strlen(gString[nString]) == 0)
|
|
|
|
break;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
int xPos = 70;
|
2019-09-19 19:45:19 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
const char *nChar = gString[nString];
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
nString++;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
while (*nChar)
|
|
|
|
{
|
2019-08-31 15:04:06 +00:00
|
|
|
HandleAsync();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (*nChar != ' ')
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
PlayLocalSound(StaticSound[kSound71], 0);
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
xPos += CopyCharToBitmap(*nChar, kTileLoboLaptop, xPos, ebp);
|
|
|
|
nChar++;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
overwritesprite(0, 0, kTileLoboLaptop, 0, 2, kPalNormal);
|
|
|
|
videoNextPage();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
WaitVBL();
|
|
|
|
if (CheckForEscape())
|
|
|
|
goto LABEL_28;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
ebp += 8;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
nString++;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
KB_FlushKeyboardQueue();
|
|
|
|
KB_ClearKeysDown();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-06 05:18:12 +00:00
|
|
|
int v11 = kTimerTicks * (var_1C + 2) + (int)totalclock;
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
do
|
|
|
|
{
|
2019-08-31 15:04:06 +00:00
|
|
|
HandleAsync();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-06 05:18:12 +00:00
|
|
|
if (v11 <= (int)totalclock)
|
2019-08-31 07:47:15 +00:00
|
|
|
goto LABEL_11;
|
|
|
|
} while (!KB_KeyWaiting());
|
2019-09-19 19:45:19 +00:00
|
|
|
} while (KB_GetCh() != 27);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
|
|
|
LABEL_28:
|
2019-08-31 07:47:15 +00:00
|
|
|
PlayLocalSound(StaticSound[kSound75], 0);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
while (1)
|
|
|
|
{
|
2019-08-31 15:04:06 +00:00
|
|
|
HandleAsync();
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
DoStatic(var_28, var_24);
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (var_28 > 20)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
var_28 -= 20;
|
|
|
|
continue;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-09-19 19:45:19 +00:00
|
|
|
if (var_24 > 20)
|
|
|
|
{
|
2019-08-31 07:47:15 +00:00
|
|
|
var_24 -= 20;
|
|
|
|
continue;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
break;
|
|
|
|
}
|
2019-08-26 03:59:14 +00:00
|
|
|
|
2019-08-31 07:47:15 +00:00
|
|
|
EraseScreen(-1);
|
|
|
|
tileLoad(kTileLoboLaptop);
|
|
|
|
FadeOut(0);
|
|
|
|
MySetView(nViewLeft, nViewTop, nViewRight, nViewBottom);
|
|
|
|
MaskStatus();
|
2019-08-26 03:59:14 +00:00
|
|
|
}
|