1
0
Fork 0
forked from len0rd/rockbox
foxbox/apps/plugins/sdl/progs/wolf3d/wl_inter.c
Franklin Wei 3f59fc8b77 Wolfenstein 3-D!
This is a port of Wolf4SDL, which is derived from the original id
software source release. The port runs on top of the SDL plugin
runtime and is loaded as an overlay.

Licensing of the game code is not an issue, as discussed below
(essentially, the Debian project treats Wolf4SDL as GPLv2, with an
email from John Carmack backing it up):

  http://forums.rockbox.org/index.php?topic=52872

Included is a copy of MAME's Yamaha OPL sound chip emulator
(fmopl_gpl.c).  This file was not part of the original Wolf4SDL source
(which includes a non-GPL'd version), but was rather rebased from from
a later MAME source which had been relicensed to GPLv2.

Change-Id: I64c2ba035e0be7e2f49252f40640641416613439
2019-07-09 11:20:55 -04:00

1723 lines
39 KiB
C

// WL_INTER.C
#include "wl_def.h"
#pragma hdrstop
LRstruct LevelRatios[LRpack];
int32_t lastBreathTime = 0;
void Write (int x, int y, const char *string);
//==========================================================================
/*
==================
=
= CLearSplitVWB
=
==================
*/
void
ClearSplitVWB (void)
{
WindowX = 0;
WindowY = 0;
WindowW = 320;
WindowH = 160;
}
//==========================================================================
#ifdef SPEAR
#ifndef SPEARDEMO
////////////////////////////////////////////////////////
//
// End of Spear of Destiny
//
////////////////////////////////////////////////////////
void
EndScreen (int palette, int screen)
{
SDL_Color pal[256];
CA_CacheScreen (screen);
VW_UpdateScreen ();
CA_CacheGrChunk (palette);
VL_ConvertPalette(grsegs[palette], pal, 256);
VL_FadeIn (0, 255, pal, 30);
UNCACHEGRCHUNK (palette);
IN_ClearKeysDown ();
IN_Ack ();
VW_FadeOut ();
}
void
EndSpear (void)
{
SDL_Color pal[256];
EndScreen (END1PALETTE, ENDSCREEN11PIC);
CA_CacheScreen (ENDSCREEN3PIC);
VW_UpdateScreen ();
CA_CacheGrChunk (END3PALETTE);
VL_ConvertPalette(grsegs[END3PALETTE], pal, 256);
VL_FadeIn (0, 255, pal, 30);
UNCACHEGRCHUNK (END3PALETTE);
fontnumber = 0;
fontcolor = 0xd0;
WindowX = 0;
WindowW = 320;
PrintX = 0;
PrintY = 180;
US_CPrint (STR_ENDGAME1 "\n");
US_CPrint (STR_ENDGAME2);
VW_UpdateScreen ();
IN_UserInput(700);
PrintX = 0;
PrintY = 180;
VWB_Bar (0, 180, 320, 20, 0);
US_CPrint (STR_ENDGAME3 "\n");
US_CPrint (STR_ENDGAME4);
VW_UpdateScreen ();
IN_UserInput(700);
VW_FadeOut ();
EndScreen (END4PALETTE, ENDSCREEN4PIC);
EndScreen (END5PALETTE, ENDSCREEN5PIC);
EndScreen (END6PALETTE, ENDSCREEN6PIC);
EndScreen (END7PALETTE, ENDSCREEN7PIC);
EndScreen (END8PALETTE, ENDSCREEN8PIC);
EndScreen (END9PALETTE, ENDSCREEN9PIC);
EndScreen (END2PALETTE, ENDSCREEN12PIC);
MainMenu[savegame].active = 0;
}
#endif
#endif
//==========================================================================
/*
==================
=
= Victory
=
==================
*/
void
Victory (void)
{
#ifndef SPEARDEMO
int32_t sec;
int i, min, kr, sr, tr, x;
char tempstr[8];
#define RATIOX 6
#define RATIOY 14
#define TIMEX 14
#define TIMEY 8
#ifdef SPEAR
StartCPMusic (XTHEEND_MUS);
CA_CacheGrChunk (BJCOLLAPSE1PIC);
CA_CacheGrChunk (BJCOLLAPSE2PIC);
CA_CacheGrChunk (BJCOLLAPSE3PIC);
CA_CacheGrChunk (BJCOLLAPSE4PIC);
VWB_Bar (0, 0, 320, 200, VIEWCOLOR);
VWB_DrawPic (124, 44, BJCOLLAPSE1PIC);
VW_UpdateScreen ();
VW_FadeIn ();
VW_WaitVBL (2 * 70);
VWB_DrawPic (124, 44, BJCOLLAPSE2PIC);
VW_UpdateScreen ();
VW_WaitVBL (105);
VWB_DrawPic (124, 44, BJCOLLAPSE3PIC);
VW_UpdateScreen ();
VW_WaitVBL (105);
VWB_DrawPic (124, 44, BJCOLLAPSE4PIC);
VW_UpdateScreen ();
VW_WaitVBL (3 * 70);
UNCACHEGRCHUNK (BJCOLLAPSE1PIC);
UNCACHEGRCHUNK (BJCOLLAPSE2PIC);
UNCACHEGRCHUNK (BJCOLLAPSE3PIC);
UNCACHEGRCHUNK (BJCOLLAPSE4PIC);
VL_FadeOut (0, 255, 0, 17, 17, 5);
#endif
StartCPMusic (URAHERO_MUS);
ClearSplitVWB ();
CacheLump (LEVELEND_LUMP_START, LEVELEND_LUMP_END);
CA_CacheGrChunk (STARTFONT);
#ifndef SPEAR
CA_CacheGrChunk (C_TIMECODEPIC);
#endif
VWB_Bar (0, 0, 320, screenHeight / scaleFactor - STATUSLINES + 1, VIEWCOLOR);
if (bordercol != VIEWCOLOR)
DrawStatusBorder (VIEWCOLOR);
#ifdef JAPAN
#ifndef JAPDEMO
CA_CacheGrChunk (C_ENDRATIOSPIC);
VWB_DrawPic (0, 0, C_ENDRATIOSPIC);
UNCACHEGRCHUNK (C_ENDRATIOSPIC);
#endif
#else
Write (18, 2, STR_YOUWIN);
Write (TIMEX, TIMEY - 2, STR_TOTALTIME);
Write (12, RATIOY - 2, "averages");
#ifdef SPANISH
Write (RATIOX + 2, RATIOY, STR_RATKILL);
Write (RATIOX + 2, RATIOY + 2, STR_RATSECRET);
Write (RATIOX + 2, RATIOY + 4, STR_RATTREASURE);
#else
Write (RATIOX + 8, RATIOY, STR_RATKILL);
Write (RATIOX + 4, RATIOY + 2, STR_RATSECRET);
Write (RATIOX, RATIOY + 4, STR_RATTREASURE);
#endif
#endif
#ifndef JAPDEMO
VWB_DrawPic (8, 4, L_BJWINSPIC);
#endif
for (kr = sr = tr = sec = i = 0; i < LRpack; i++)
{
sec += LevelRatios[i].time;
kr += LevelRatios[i].kill;
sr += LevelRatios[i].secret;
tr += LevelRatios[i].treasure;
}
#ifndef SPEAR
kr /= LRpack;
sr /= LRpack;
tr /= LRpack;
#else
kr /= 14;
sr /= 14;
tr /= 14;
#endif
min = sec / 60;
sec %= 60;
if (min > 99)
min = sec = 99;
i = TIMEX * 8 + 1;
VWB_DrawPic (i, TIMEY * 8, L_NUM0PIC + (min / 10));
i += 2 * 8;
VWB_DrawPic (i, TIMEY * 8, L_NUM0PIC + (min % 10));
i += 2 * 8;
Write (i / 8, TIMEY, ":");
i += 1 * 8;
VWB_DrawPic (i, TIMEY * 8, L_NUM0PIC + (sec / 10));
i += 2 * 8;
VWB_DrawPic (i, TIMEY * 8, L_NUM0PIC + (sec % 10));
VW_UpdateScreen ();
itoa (kr, tempstr, 10);
x = RATIOX + 24 - (int) strlen(tempstr) * 2;
Write (x, RATIOY, tempstr);
itoa (sr, tempstr, 10);
x = RATIOX + 24 - (int) strlen(tempstr) * 2;
Write (x, RATIOY + 2, tempstr);
itoa (tr, tempstr, 10);
x = RATIOX + 24 - (int) strlen(tempstr) * 2;
Write (x, RATIOY + 4, tempstr);
#ifndef SPANISH
#ifndef UPLOAD
#ifndef SPEAR
//
// TOTAL TIME VERIFICATION CODE
//
if (gamestate.difficulty >= gd_medium)
{
VWB_DrawPic (30 * 8, TIMEY * 8, C_TIMECODEPIC);
fontnumber = 0;
fontcolor = READHCOLOR;
PrintX = 30 * 8 - 3;
PrintY = TIMEY * 8 + 8;
PrintX += 4;
tempstr[0] = (((min / 10) ^ (min % 10)) ^ 0xa) + 'A';
tempstr[1] = (int) ((((sec / 10) ^ (sec % 10)) ^ 0xa) + 'A');
tempstr[2] = (tempstr[0] ^ tempstr[1]) + 'A';
tempstr[3] = 0;
US_Print (tempstr);
}
#endif
#endif
#endif
fontnumber = 1;
VW_UpdateScreen ();
VW_FadeIn ();
IN_Ack ();
VW_FadeOut ();
if(screenHeight % 200 != 0)
VL_ClearScreen(0);
#ifndef SPEAR
UNCACHEGRCHUNK (C_TIMECODEPIC);
#endif
UnCacheLump (LEVELEND_LUMP_START, LEVELEND_LUMP_END);
#ifndef SPEAR
EndText ();
#else
EndSpear ();
#endif
#endif // SPEARDEMO
}
//==========================================================================
#ifndef JAPAN
/*
==================
=
= PG13
=
==================
*/
void
PG13 (void)
{
VW_FadeOut ();
VWB_Bar (0, 0, 320, 200, 0x82); // background
CA_CacheGrChunk (PG13PIC);
VWB_DrawPic (216, 110, PG13PIC);
VW_UpdateScreen ();
UNCACHEGRCHUNK (PG13PIC);
VW_FadeIn ();
IN_UserInput (TickBase * 7);
VW_FadeOut ();
}
#endif
//==========================================================================
void
Write (int x, int y, const char *string)
{
static const int alpha[] = { L_NUM0PIC, L_NUM1PIC, L_NUM2PIC, L_NUM3PIC, L_NUM4PIC, L_NUM5PIC,
L_NUM6PIC, L_NUM7PIC, L_NUM8PIC, L_NUM9PIC, L_COLONPIC, 0, 0, 0, 0, 0, 0, L_APIC, L_BPIC,
L_CPIC, L_DPIC, L_EPIC, L_FPIC, L_GPIC, L_HPIC, L_IPIC, L_JPIC, L_KPIC,
L_LPIC, L_MPIC, L_NPIC, L_OPIC, L_PPIC, L_QPIC, L_RPIC, L_SPIC, L_TPIC,
L_UPIC, L_VPIC, L_WPIC, L_XPIC, L_YPIC, L_ZPIC
};
int i, ox, nx, ny, len = (int) strlen(string);
char ch;
ox = nx = x * 8;
ny = y * 8;
for (i = 0; i < len; i++)
{
if (string[i] == '\n')
{
nx = ox;
ny += 16;
}
else
{
ch = string[i];
if (ch >= 'a')
ch -= ('a' - 'A');
ch -= '0';
switch (string[i])
{
case '!':
VWB_DrawPic (nx, ny, L_EXPOINTPIC);
nx += 8;
continue;
#ifndef APOGEE_1_0
case '\'':
VWB_DrawPic (nx, ny, L_APOSTROPHEPIC);
nx += 8;
continue;
#endif
case ' ':
break;
case 0x3a: // ':'
VWB_DrawPic (nx, ny, L_COLONPIC);
nx += 8;
continue;
case '%':
VWB_DrawPic (nx, ny, L_PERCENTPIC);
break;
default:
VWB_DrawPic (nx, ny, alpha[ch]);
}
nx += 16;
}
}
}
//
// Breathe Mr. BJ!!!
//
void
BJ_Breathe (void)
{
static int which = 0, max = 10;
int pics[2] = { L_GUYPIC, L_GUY2PIC };
SDL_Delay(5);
if ((int32_t) GetTimeCount () - lastBreathTime > max)
{
which ^= 1;
VWB_DrawPic (0, 16, pics[which]);
VW_UpdateScreen ();
lastBreathTime = GetTimeCount();
max = 35;
}
}
/*
==================
=
= LevelCompleted
=
= Entered with the screen faded out
= Still in split screen mode with the status bar
=
= Exit with the screen faded out
=
==================
*/
void
LevelCompleted (void)
{
#define VBLWAIT 30
#define PAR_AMOUNT 500
#define PERCENT100AMT 10000
typedef struct
{
float time;
char timestr[6];
} times;
int x, i, min, sec, ratio, kr, sr, tr;
char tempstr[10];
int32_t bonus, timeleft = 0;
times parTimes[] = {
#ifndef SPEAR
//
// Episode One Par Times
//
{1.5, "01:30"},
{2, "02:00"},
{2, "02:00"},
{3.5, "03:30"},
{3, "03:00"},
{3, "03:00"},
{2.5, "02:30"},
{2.5, "02:30"},
{0, "??:??"}, // Boss level
{0, "??:??"}, // Secret level
//
// Episode Two Par Times
//
{1.5, "01:30"},
{3.5, "03:30"},
{3, "03:00"},
{2, "02:00"},
{4, "04:00"},
{6, "06:00"},
{1, "01:00"},
{3, "03:00"},
{0, "??:??"},
{0, "??:??"},
//
// Episode Three Par Times
//
{1.5, "01:30"},
{1.5, "01:30"},
{2.5, "02:30"},
{2.5, "02:30"},
{3.5, "03:30"},
{2.5, "02:30"},
{2, "02:00"},
{6, "06:00"},
{0, "??:??"},
{0, "??:??"},
//
// Episode Four Par Times
//
{2, "02:00"},
{2, "02:00"},
{1.5, "01:30"},
{1, "01:00"},
{4.5, "04:30"},
{3.5, "03:30"},
{2, "02:00"},
{4.5, "04:30"},
{0, "??:??"},
{0, "??:??"},
//
// Episode Five Par Times
//
{2.5, "02:30"},
{1.5, "01:30"},
{2.5, "02:30"},
{2.5, "02:30"},
{4, "04:00"},
{3, "03:00"},
{4.5, "04:30"},
{3.5, "03:30"},
{0, "??:??"},
{0, "??:??"},
//
// Episode Six Par Times
//
{6.5, "06:30"},
{4, "04:00"},
{4.5, "04:30"},
{6, "06:00"},
{5, "05:00"},
{5.5, "05:30"},
{5.5, "05:30"},
{8.5, "08:30"},
{0, "??:??"},
{0, "??:??"}
#else
//
// SPEAR OF DESTINY TIMES
//
{1.5, "01:30"},
{3.5, "03:30"},
{2.75, "02:45"},
{3.5, "03:30"},
{0, "??:??"}, // Boss 1
{4.5, "04:30"},
{3.25, "03:15"},
{2.75, "02:45"},
{4.75, "04:45"},
{0, "??:??"}, // Boss 2
{6.5, "06:30"},
{4.5, "04:30"},
{2.75, "02:45"},
{4.5, "04:30"},
{6, "06:00"},
{0, "??:??"}, // Boss 3
{6, "06:00"},
{0, "??:??"}, // Boss 4
{0, "??:??"}, // Secret level 1
{0, "??:??"}, // Secret level 2
#endif
};
CacheLump (LEVELEND_LUMP_START, LEVELEND_LUMP_END);
ClearSplitVWB (); // set up for double buffering in split screen
VWB_Bar (0, 0, 320, screenHeight / scaleFactor - STATUSLINES + 1, VIEWCOLOR);
if (bordercol != VIEWCOLOR)
DrawStatusBorder (VIEWCOLOR);
StartCPMusic (ENDLEVEL_MUS);
//
// do the intermission
//
IN_ClearKeysDown ();
IN_StartAck ();
#ifdef JAPAN
CA_CacheGrChunk (C_INTERMISSIONPIC);
VWB_DrawPic (0, 0, C_INTERMISSIONPIC);
UNCACHEGRCHUNK (C_INTERMISSIONPIC);
#endif
VWB_DrawPic (0, 16, L_GUYPIC);
#ifndef SPEAR
if (mapon < 8)
#else
if (mapon != 4 && mapon != 9 && mapon != 15 && mapon < 17)
#endif
{
#ifndef JAPAN
#ifdef SPANISH
Write (14, 2, "piso\ncompletado");
#else
Write (14, 2, "floor\ncompleted");
#endif
Write (14, 7, STR_BONUS " 0");
Write (16, 10, STR_TIME);
Write (16, 12, STR_PAR);
#ifdef SPANISH
Write (11, 14, STR_RAT2KILL);
Write (11, 16, STR_RAT2SECRET);
Write (11, 18, STR_RAT2TREASURE);
#else
Write (9, 14, STR_RAT2KILL);
Write (5, 16, STR_RAT2SECRET);
Write (1, 18, STR_RAT2TREASURE);
#endif
Write (26, 2, itoa (gamestate.mapon + 1, tempstr, 10));
#endif
#ifdef SPANISH
Write (30, 12, parTimes[gamestate.episode * 10 + mapon].timestr);
#else
Write (26, 12, parTimes[gamestate.episode * 10 + mapon].timestr);
#endif
//
// PRINT TIME
//
sec = gamestate.TimeCount / 70;
if (sec > 99 * 60) // 99 minutes max
sec = 99 * 60;
if (gamestate.TimeCount < parTimes[gamestate.episode * 10 + mapon].time * 4200)
timeleft = (int32_t) ((parTimes[gamestate.episode * 10 + mapon].time * 4200) / 70 - sec);
min = sec / 60;
sec %= 60;
#ifdef SPANISH
i = 30 * 8;
#else
i = 26 * 8;
#endif
VWB_DrawPic (i, 10 * 8, L_NUM0PIC + (min / 10));
i += 2 * 8;
VWB_DrawPic (i, 10 * 8, L_NUM0PIC + (min % 10));
i += 2 * 8;
Write (i / 8, 10, ":");
i += 1 * 8;
VWB_DrawPic (i, 10 * 8, L_NUM0PIC + (sec / 10));
i += 2 * 8;
VWB_DrawPic (i, 10 * 8, L_NUM0PIC + (sec % 10));
VW_UpdateScreen ();
VW_FadeIn ();
//
// FIGURE RATIOS OUT BEFOREHAND
//
kr = sr = tr = 0;
if (gamestate.killtotal)
kr = (gamestate.killcount * 100) / gamestate.killtotal;
if (gamestate.secrettotal)
sr = (gamestate.secretcount * 100) / gamestate.secrettotal;
if (gamestate.treasuretotal)
tr = (gamestate.treasurecount * 100) / gamestate.treasuretotal;
//
// PRINT TIME BONUS
//
bonus = timeleft * PAR_AMOUNT;
if (bonus)
{
for (i = 0; i <= timeleft; i++)
{
ltoa ((int32_t) i * PAR_AMOUNT, tempstr, 10);
x = 36 - (int) strlen(tempstr) * 2;
Write (x, 7, tempstr);
if (!(i % (PAR_AMOUNT / 10)))
SD_PlaySound (ENDBONUS1SND);
if(!usedoublebuffering || !(i % (PAR_AMOUNT / 50))) VW_UpdateScreen ();
while(SD_SoundPlaying ())
BJ_Breathe ();
if (IN_CheckAck ())
goto done;
}
VW_UpdateScreen ();
SD_PlaySound (ENDBONUS2SND);
while (SD_SoundPlaying ())
BJ_Breathe ();
}
#ifdef SPANISH
#define RATIOXX 33
#else
#define RATIOXX 37
#endif
//
// KILL RATIO
//
ratio = kr;
for (i = 0; i <= ratio; i++)
{
itoa (i, tempstr, 10);
x = RATIOXX - (int) strlen(tempstr) * 2;
Write (x, 14, tempstr);
if (!(i % 10))
SD_PlaySound (ENDBONUS1SND);
if(!usedoublebuffering || !(i & 1)) VW_UpdateScreen ();
while (SD_SoundPlaying ())
BJ_Breathe ();
if (IN_CheckAck ())
goto done;
}
if (ratio >= 100)
{
VW_WaitVBL (VBLWAIT);
SD_StopSound ();
bonus += PERCENT100AMT;
ltoa (bonus, tempstr, 10);
x = (RATIOXX - 1) - (int) strlen(tempstr) * 2;
Write (x, 7, tempstr);
VW_UpdateScreen ();
SD_PlaySound (PERCENT100SND);
}
else if (!ratio)
{
VW_WaitVBL (VBLWAIT);
SD_StopSound ();
SD_PlaySound (NOBONUSSND);
}
else
SD_PlaySound (ENDBONUS2SND);
VW_UpdateScreen ();
while (SD_SoundPlaying ())
BJ_Breathe ();
//
// SECRET RATIO
//
ratio = sr;
for (i = 0; i <= ratio; i++)
{
itoa (i, tempstr, 10);
x = RATIOXX - (int) strlen(tempstr) * 2;
Write (x, 16, tempstr);
if (!(i % 10))
SD_PlaySound (ENDBONUS1SND);
if(!usedoublebuffering || !(i & 1)) VW_UpdateScreen ();
while (SD_SoundPlaying ())
BJ_Breathe ();
if (IN_CheckAck ())
goto done;
}
if (ratio >= 100)
{
VW_WaitVBL (VBLWAIT);
SD_StopSound ();
bonus += PERCENT100AMT;
ltoa (bonus, tempstr, 10);
x = (RATIOXX - 1) - (int) strlen(tempstr) * 2;
Write (x, 7, tempstr);
VW_UpdateScreen ();
SD_PlaySound (PERCENT100SND);
}
else if (!ratio)
{
VW_WaitVBL (VBLWAIT);
SD_StopSound ();
SD_PlaySound (NOBONUSSND);
}
else
SD_PlaySound (ENDBONUS2SND);
VW_UpdateScreen ();
while (SD_SoundPlaying ())
BJ_Breathe ();
//
// TREASURE RATIO
//
ratio = tr;
for (i = 0; i <= ratio; i++)
{
itoa (i, tempstr, 10);
x = RATIOXX - (int) strlen(tempstr) * 2;
Write (x, 18, tempstr);
if (!(i % 10))
SD_PlaySound (ENDBONUS1SND);
if(!usedoublebuffering || !(i & 1)) VW_UpdateScreen ();
while (SD_SoundPlaying ())
BJ_Breathe ();
if (IN_CheckAck ())
goto done;
}
if (ratio >= 100)
{
VW_WaitVBL (VBLWAIT);
SD_StopSound ();
bonus += PERCENT100AMT;
ltoa (bonus, tempstr, 10);
x = (RATIOXX - 1) - (int) strlen(tempstr) * 2;
Write (x, 7, tempstr);
VW_UpdateScreen ();
SD_PlaySound (PERCENT100SND);
}
else if (!ratio)
{
VW_WaitVBL (VBLWAIT);
SD_StopSound ();
SD_PlaySound (NOBONUSSND);
}
else
SD_PlaySound (ENDBONUS2SND);
VW_UpdateScreen ();
while (SD_SoundPlaying ())
BJ_Breathe ();
//
// JUMP STRAIGHT HERE IF KEY PRESSED
//
done: itoa (kr, tempstr, 10);
x = RATIOXX - (int) strlen(tempstr) * 2;
Write (x, 14, tempstr);
itoa (sr, tempstr, 10);
x = RATIOXX - (int) strlen(tempstr) * 2;
Write (x, 16, tempstr);
itoa (tr, tempstr, 10);
x = RATIOXX - (int) strlen(tempstr) * 2;
Write (x, 18, tempstr);
bonus = (int32_t) timeleft *PAR_AMOUNT +
(PERCENT100AMT * (kr >= 100)) +
(PERCENT100AMT * (sr >= 100)) + (PERCENT100AMT * (tr >= 100));
GivePoints (bonus);
ltoa (bonus, tempstr, 10);
x = 36 - (int) strlen(tempstr) * 2;
Write (x, 7, tempstr);
//
// SAVE RATIO INFORMATION FOR ENDGAME
//
LevelRatios[mapon].kill = kr;
LevelRatios[mapon].secret = sr;
LevelRatios[mapon].treasure = tr;
LevelRatios[mapon].time = min * 60 + sec;
}
else
{
#ifdef SPEAR
#ifndef SPEARDEMO
switch (mapon)
{
case 4:
Write (14, 4, " trans\n" " grosse\n" STR_DEFEATED);
break;
case 9:
Write (14, 4, "barnacle\n" "wilhelm\n" STR_DEFEATED);
break;
case 15:
Write (14, 4, "ubermutant\n" STR_DEFEATED);
break;
case 17:
Write (14, 4, " death\n" " knight\n" STR_DEFEATED);
break;
case 18:
Write (13, 4, "secret tunnel\n" " area\n" " completed!");
break;
case 19:
Write (13, 4, "secret castle\n" " area\n" " completed!");
break;
}
#endif
#else
Write (14, 4, "secret floor\n completed!");
#endif
Write (10, 16, "15000 bonus!");
VW_UpdateScreen ();
VW_FadeIn ();
GivePoints (15000);
}
DrawScore ();
VW_UpdateScreen ();
lastBreathTime = GetTimeCount();
IN_StartAck ();
while (!IN_CheckAck ())
BJ_Breathe ();
//
// done
//
#ifdef SPEARDEMO
if (gamestate.mapon == 1)
{
SD_PlaySound (BONUS1UPSND);
CA_CacheGrChunk (STARTFONT + 1);
Message ("This concludes your demo\n"
"of Spear of Destiny! Now,\n" "go to your local software\n" "store and buy it!");
UNCACHEGRCHUNK (STARTFONT + 1);
IN_ClearKeysDown ();
IN_Ack ();
}
#endif
#ifdef JAPDEMO
if (gamestate.mapon == 3)
{
SD_PlaySound (BONUS1UPSND);
CA_CacheGrChunk (STARTFONT + 1);
Message ("This concludes your demo\n"
"of Wolfenstein 3-D! Now,\n" "go to your local software\n" "store and buy it!");
UNCACHEGRCHUNK (STARTFONT + 1);
IN_ClearKeysDown ();
IN_Ack ();
}
#endif
VW_FadeOut ();
DrawPlayBorder();
UnCacheLump (LEVELEND_LUMP_START, LEVELEND_LUMP_END);
}
//==========================================================================
/*
=================
=
= PreloadGraphics
=
= Fill the cache up
=
=================
*/
boolean
PreloadUpdate (unsigned current, unsigned total)
{
unsigned w = WindowW - scaleFactor * 10;
VWB_BarScaledCoord (WindowX + scaleFactor * 5, WindowY + WindowH - scaleFactor * 3,
w, scaleFactor * 2, BLACK);
w = ((int32_t) w * current) / total;
if (w)
{
VWB_BarScaledCoord (WindowX + scaleFactor * 5, WindowY + WindowH - scaleFactor * 3,
w, scaleFactor * 2, 0x37); //SECONDCOLOR);
VWB_BarScaledCoord (WindowX + scaleFactor * 5, WindowY + WindowH - scaleFactor * 3,
w - scaleFactor * 1, scaleFactor * 1, 0x32);
}
VW_UpdateScreen ();
// if (LastScan == sc_Escape)
// {
// IN_ClearKeysDown();
// return(true);
// }
// else
return (false);
}
void
PreloadGraphics (void)
{
DrawLevel ();
ClearSplitVWB (); // set up for double buffering in split screen
VWB_BarScaledCoord (0, 0, screenWidth, screenHeight - scaleFactor * (STATUSLINES - 1), bordercol);
LatchDrawPicScaledCoord ((screenWidth-scaleFactor*224)/16,
(screenHeight-scaleFactor*(STATUSLINES+48))/2, GETPSYCHEDPIC);
WindowX = (screenWidth - scaleFactor*224)/2;
WindowY = (screenHeight - scaleFactor*(STATUSLINES+48))/2;
WindowW = scaleFactor * 28 * 8;
WindowH = scaleFactor * 48;
VW_UpdateScreen ();
VW_FadeIn ();
// PM_Preload (PreloadUpdate);
PreloadUpdate (10, 10);
IN_UserInput (70);
VW_FadeOut ();
DrawPlayBorder ();
VW_UpdateScreen ();
}
//==========================================================================
/*
==================
=
= DrawHighScores
=
==================
*/
void
DrawHighScores (void)
{
char buffer[16];
#ifndef SPEAR
char *str;
#ifndef UPLOAD
char buffer1[5];
#endif
#endif
word i, w, h;
HighScore *s;
#ifndef SPEAR
CA_CacheGrChunk (HIGHSCORESPIC);
CA_CacheGrChunk (STARTFONT);
#ifndef APOGEE_1_0
CA_CacheGrChunk (C_LEVELPIC);
CA_CacheGrChunk (C_SCOREPIC);
CA_CacheGrChunk (C_NAMEPIC);
#else
CA_CacheGrChunk (C_CODEPIC);
#endif
ClearMScreen ();
DrawStripes (10);
VWB_DrawPic (48, 0, HIGHSCORESPIC);
UNCACHEGRCHUNK (HIGHSCORESPIC);
#ifndef APOGEE_1_0
VWB_DrawPic (4 * 8, 68, C_NAMEPIC);
VWB_DrawPic (20 * 8, 68, C_LEVELPIC);
VWB_DrawPic (28 * 8, 68, C_SCOREPIC);
#else
VWB_DrawPic(35*8,68,C_CODEPIC);
#endif
fontnumber = 0;
#else
CacheLump (BACKDROP_LUMP_START, BACKDROP_LUMP_END);
ClearMScreen ();
DrawStripes (10);
UnCacheLump (BACKDROP_LUMP_START, BACKDROP_LUMP_END);
CacheLump (HIGHSCORES_LUMP_START, HIGHSCORES_LUMP_END);
CA_CacheGrChunk (STARTFONT + 1);
VWB_DrawPic (0, 0, HIGHSCORESPIC);
fontnumber = 1;
#endif
#ifndef SPEAR
SETFONTCOLOR (15, 0x29);
#else
SETFONTCOLOR (HIGHLIGHT, 0x29);
#endif
for (i = 0, s = Scores; i < MaxScores; i++, s++)
{
PrintY = 76 + (16 * i);
//
// name
//
#ifndef SPEAR
PrintX = 4 * 8;
#else
PrintX = 16;
#endif
US_Print (s->name);
//
// level
//
itoa (s->completed, buffer, 10);
#ifndef SPEAR
for (str = buffer; *str; str++)
*str = *str + (129 - '0'); // Used fixed-width numbers (129...)
USL_MeasureString (buffer, &w, &h);
PrintX = (22 * 8) - w;
#else
USL_MeasureString (buffer, &w, &h);
PrintX = 194 - w;
#endif
#ifndef UPLOAD
#ifndef SPEAR
PrintX -= 6;
itoa (s->episode + 1, buffer1, 10);
US_Print ("E");
US_Print (buffer1);
US_Print ("/L");
#endif
#endif
#ifdef SPEAR
if (s->completed == 21)
VWB_DrawPic (PrintX + 8, PrintY - 1, C_WONSPEARPIC);
else
#endif
US_Print (buffer);
//
// score
//
itoa (s->score, buffer, 10);
#ifndef SPEAR
for (str = buffer; *str; str++)
*str = *str + (129 - '0'); // Used fixed-width numbers (129...)
USL_MeasureString (buffer, &w, &h);
PrintX = (34 * 8) - 8 - w;
#else
USL_MeasureString (buffer, &w, &h);
PrintX = 292 - w;
#endif
US_Print (buffer);
#ifdef APOGEE_1_0
//#ifndef UPLOAD
#ifndef SPEAR
//
// verification #
//
if (!i)
{
char temp = (((s->score >> 28) & 0xf) ^ ((s->score >> 24) & 0xf)) + 'A';
char temp1 = (((s->score >> 20) & 0xf) ^ ((s->score >> 16) & 0xf)) + 'A';
char temp2 = (((s->score >> 12) & 0xf) ^ ((s->score >> 8) & 0xf)) + 'A';
char temp3 = (((s->score >> 4) & 0xf) ^ ((s->score >> 0) & 0xf)) + 'A';
SETFONTCOLOR (0x49, 0x29);
PrintX = 35 * 8;
buffer[0] = temp;
buffer[1] = temp1;
buffer[2] = temp2;
buffer[3] = temp3;
buffer[4] = 0;
US_Print (buffer);
SETFONTCOLOR (15, 0x29);
}
#endif
//#endif
#endif
}
VW_UpdateScreen ();
#ifdef SPEAR
UnCacheLump (HIGHSCORES_LUMP_START, HIGHSCORES_LUMP_END);
fontnumber = 0;
#endif
}
//===========================================================================
/*
=======================
=
= CheckHighScore
=
=======================
*/
void
CheckHighScore (int32_t score, word other)
{
word i, j;
int n;
HighScore myscore;
strcpy (myscore.name, "");
myscore.score = score;
myscore.episode = gamestate.episode;
myscore.completed = other;
for (i = 0, n = -1; i < MaxScores; i++)
{
if ((myscore.score > Scores[i].score)
|| ((myscore.score == Scores[i].score) && (myscore.completed > Scores[i].completed)))
{
for (j = MaxScores; --j > i;)
Scores[j] = Scores[j - 1];
Scores[i] = myscore;
n = i;
break;
}
}
#ifdef SPEAR
StartCPMusic (XAWARD_MUS);
#else
StartCPMusic (ROSTER_MUS);
#endif
DrawHighScores ();
VW_FadeIn ();
if (n != -1)
{
//
// got a high score
//
PrintY = 76 + (16 * n);
#ifndef SPEAR
PrintX = 4 * 8;
backcolor = BORDCOLOR;
fontcolor = 15;
US_LineInput (PrintX, PrintY, Scores[n].name, 0, true, MaxHighName, 100);
#else
PrintX = 16;
fontnumber = 1;
VWB_Bar (PrintX - 2, PrintY - 2, 145, 15, 0x9c);
VW_UpdateScreen ();
backcolor = 0x9c;
fontcolor = 15;
US_LineInput (PrintX, PrintY, Scores[n].name, 0, true, MaxHighName, 130);
#endif
}
else
{
IN_ClearKeysDown ();
IN_UserInput (500);
}
}
#ifndef UPLOAD
#ifndef SPEAR
#ifndef JAPAN
////////////////////////////////////////////////////////
//
// NON-SHAREWARE NOTICE
//
////////////////////////////////////////////////////////
void
NonShareware (void)
{
VW_FadeOut ();
ClearMScreen ();
DrawStripes (10);
CA_CacheGrChunk (STARTFONT + 1);
fontnumber = 1;
SETFONTCOLOR (READHCOLOR, BKGDCOLOR);
PrintX = 110;
PrintY = 15;
#ifdef SPANISH
US_Print ("Atencion");
#else
US_Print ("Attention");
#endif
SETFONTCOLOR (HIGHLIGHT, BKGDCOLOR);
WindowX = PrintX = 40;
PrintY = 60;
#ifdef SPANISH
US_Print ("Este juego NO es gratis y\n");
US_Print ("NO es Shareware; favor de\n");
US_Print ("no distribuirlo.\n\n");
#else
US_Print ("This game is NOT shareware.\n");
US_Print ("Please do not distribute it.\n");
US_Print ("Thanks.\n\n");
#endif
US_Print (" Id Software\n");
VW_UpdateScreen ();
VW_FadeIn ();
IN_Ack ();
}
#endif
#endif
#endif
#ifdef SPEAR
#ifndef GOODTIMES
#ifndef SPEARDEMO
////////////////////////////////////////////////////////
//
// COPY PROTECTION FOR FormGen
//
////////////////////////////////////////////////////////
char CopyProFailedStrs[][100] = {
STR_COPY1,
STR_COPY2,
STR_COPY3,
STR_COPY4,
STR_COPY5,
STR_COPY6,
STR_COPY7,
STR_COPY8,
STR_COPY9,
"",
STR_COPY10,
STR_COPY11,
STR_COPY12,
"",
STR_COPY13,
"",
STR_COPY14,
""
};
char BackDoorStrs[5][16] = {
"a spoon?",
"bite me!",
"joshua",
"pelt",
"snoops"
};
char GoodBoyStrs[10][40] = {
"...is the CORRECT ANSWER!",
"",
"Consider yourself bitten, sir.",
"",
"Greetings Professor Falken, would you",
"like to play Spear of Destiny?",
"Do you have any gold spray paint?",
"",
"I wish I had a 21\" monitor...",
""
};
char bossstrs[4][24] = {
"DEATH KNIGHT",
"BARNACLE WILHELM",
"UBERMUTANTUBER MUTANT",
"TRANS GROSSE"
};
char WordStr[5][20] = {
"New Game",
"Sound...F4",
"Control...F6",
"Change View...F5",
"Quit...F10"
};
char WordCorrect[5][2] = { "3", "4", "4", "5", "5" };
char MemberStr[10][40] = {
STR_COPY15,
"",
STR_COPY16,
"",
STR_COPY17,
STR_COPY18,
STR_COPY19,
STR_COPY20,
STR_COPY21,
STR_COPY22
};
char MemberCorrect[5][24] = {
"adrian carmack",
"john carmackjohn romero",
"tom hall",
"jay wilbur",
"kevin cloud"
};
char DosMessages[9][80] = {
STR_NOPE1,
STR_NOPE2,
STR_NOPE3,
STR_NOPE4,
STR_NOPE5,
STR_NOPE6,
STR_NOPE7,
STR_NOPE8,
STR_NOPE9
};
char MiscTitle[4][20] = {
"BLOOD TEST",
"STRAIGHT-LACED",
"QUITE SHAPELY",
"I AM WHAT I AMMO"
};
char MiscStr[12][40] = {
STR_MISC1,
STR_MISC2,
"",
STR_MISC3,
STR_MISC4,
"",
STR_MISC5,
STR_MISC6,
"",
STR_MISC7,
STR_MISC8,
STR_MISC9
};
char MiscCorrect[4][5] = { "ss", "8", STR_STAR, "45" };
int
BackDoor (char *s)
{
for (int i = 0; i < 5; i++)
{
if (!strcasecmp (s, BackDoorStrs[i]))
{
SETFONTCOLOR (14, 15);
fontnumber = 0;
PrintY = 175;
VWB_DrawPic (0, 20 * 8, COPYPROTBOXPIC);
US_CPrint (GoodBoyStrs[i * 2]);
US_CPrint (GoodBoyStrs[i * 2 + 1]);
VW_UpdateScreen ();
return 1;
}
}
return 0;
}
void
CopyProtection (void)
{
#define TYPEBOX_Y 177
#define TYPEBOX_BKGD 0x9c
#define PRINTCOLOR HIGHLIGHT
unsigned i;
int match, whichboss, bossnum, attempt, whichline;
int enemypicked[4] = { 0, 0, 0, 0 };
int bosses[4] = { BOSSPIC1PIC, BOSSPIC2PIC, BOSSPIC3PIC, BOSSPIC4PIC };
int whichpicked[4] = { 0, 0, 0, 0 };
int whichone, quiztype, whichmem, whichword;
int memberpicked[5] = { 0, 0, 0, 0, 0 };
int wordpicked[5] = { 0, 0, 0, 0, 0 };
char inputbuffer[20];
char message[80];
enum
{
debriefing,
checkmanual,
staffquiz,
miscquiz,
totaltypes
};
attempt = 0;
VW_FadeOut ();
CA_CacheGrChunk (C_BACKDROPPIC);
CacheLump (COPYPROT_LUMP_START, COPYPROT_LUMP_END);
CA_CacheGrChunk (STARTFONT + 1);
CA_LoadAllSounds ();
StartCPMusic (COPYPRO_MUS);
US_InitRndT (true);
while (attempt < 3)
{
fontnumber = 1;
SETFONTCOLOR (PRINTCOLOR - 2, 15);
VWB_DrawPic (0, 0, C_BACKDROPPIC);
VWB_DrawPic (0, 0, COPYPROTTOPPIC);
VWB_DrawPic (0, 20 * 8, COPYPROTBOXPIC);
WindowX = WindowY = 0;
WindowW = 320;
WindowH = 200;
PrintY = 65;
quiztype = US_RndT () % totaltypes;
switch (quiztype)
{
//
// BOSSES QUIZ
//
case debriefing:
{
PrintX = 0;
US_Print (STR_DEBRIEF);
SETFONTCOLOR (PRINTCOLOR, 15);
while (enemypicked[whichboss = US_RndT () & 3]);
enemypicked[whichboss] = 1;
bossnum = bosses[whichboss];
VWB_DrawPic (128, 60, bossnum);
fontnumber = 0;
PrintY = 130;
US_CPrint (STR_ENEMY1 "\n");
US_CPrint (STR_ENEMY2 "\n\n");
VW_UpdateScreen ();
VW_FadeIn ();
PrintX = 100;
fontcolor = 15;
backcolor = TYPEBOX_BKGD;
inputbuffer[0] = 0;
PrintY = TYPEBOX_Y;
fontnumber = 1;
US_LineInput (PrintX, PrintY, inputbuffer, 0, true, 20, 100);
match = 0;
size_t inputlen = strlen(inputbuffer);
if(inputlen > 3)
{
size_t bosslen = strlen(bossstrs[whichboss]);
for (i = 0; i < bosslen; i++)
{
if (!strncasecmp (inputbuffer, bossstrs[whichboss] + i, inputlen))
{
match = 1;
break;
}
}
}
match += BackDoor (inputbuffer);
break;
}
//
// MANUAL CHECK
//
case checkmanual:
{
while (wordpicked[whichword = US_RndT () % 5]);
wordpicked[whichword] = 1;
US_CPrint (STR_CHECKMAN);
SETFONTCOLOR (PRINTCOLOR, 15);
PrintY += 25;
US_CPrint (STR_MAN1);
US_CPrint (STR_MAN2);
sprintf(message, STR_MAN3 " \"%s\" " STR_MAN4, WordStr[whichword]);
US_CPrint (message);
VW_UpdateScreen ();
VW_FadeIn ();
PrintX = 146;
fontcolor = 15;
backcolor = TYPEBOX_BKGD;
inputbuffer[0] = 0;
PrintY = TYPEBOX_Y;
US_LineInput (PrintX, PrintY, inputbuffer, 0, true, 6, 100);
match = 1 - (strcasecmp (inputbuffer, WordCorrect[whichword]) != 0);
match += BackDoor (inputbuffer);
break;
}
//
// STAFF QUIZ
//
case staffquiz:
{
while (memberpicked[whichmem = US_RndT () % 5]);
memberpicked[whichmem] = 1;
US_CPrint (STR_ID1);
SETFONTCOLOR (PRINTCOLOR, 15);
PrintY += 25;
US_CPrint (MemberStr[whichmem * 2]);
US_CPrint (MemberStr[whichmem * 2 + 1]);
VW_UpdateScreen ();
VW_FadeIn ();
PrintX = 100;
fontcolor = 15;
backcolor = TYPEBOX_BKGD;
inputbuffer[0] = 0;
PrintY = TYPEBOX_Y;
US_LineInput (PrintX, PrintY, inputbuffer, 0, true, 20, 120);
match = 0;
size_t inputlen = strlen(inputbuffer);
if(inputlen > 2)
{
size_t memberlen = strlen(MemberCorrect[whichmem]);
for (i = 0; i < memberlen; i++)
{
if (!strncasecmp (inputbuffer, MemberCorrect[whichmem] + i, inputlen))
{
match = 1;
break;
}
}
}
match += BackDoor (inputbuffer);
break;
}
//
// MISCELLANEOUS QUESTIONS
//
case miscquiz:
{
while (whichpicked[whichone = US_RndT () & 3]);
whichpicked[whichone] = 1;
US_CPrint (MiscTitle[whichone]);
SETFONTCOLOR (PRINTCOLOR, 15);
PrintY += 25;
US_CPrint (MiscStr[whichone * 3]);
US_CPrint (MiscStr[whichone * 3 + 1]);
US_CPrint (MiscStr[whichone * 3 + 2]);
VW_UpdateScreen ();
VW_FadeIn ();
PrintX = 146;
fontcolor = 15;
backcolor = TYPEBOX_BKGD;
inputbuffer[0] = 0;
PrintY = TYPEBOX_Y;
US_LineInput (PrintX, PrintY, inputbuffer, 0, true, 6, 100);
match = 1 - (strcasecmp (inputbuffer, MiscCorrect[whichone]) != 0);
match += BackDoor (inputbuffer);
break;
}
}
//
// IF NO MATCH, WE'VE GOT A (MINOR) PROBLEM!
//
if (!match)
{
whichline = 2 * (US_RndT () % 9);
SETFONTCOLOR (14, 15);
fontnumber = 0;
PrintY = 175;
VWB_DrawPic (0, 20 * 8, COPYPROTBOXPIC);
US_CPrint (CopyProFailedStrs[whichline]);
US_CPrint (CopyProFailedStrs[whichline + 1]);
VW_UpdateScreen ();
SD_PlaySound (NOWAYSND);
IN_UserInput (TickBase * 6);
VW_FadeOut ();
attempt++;
}
else
{
int start;
SD_PlaySound (BONUS1UPSND);
SD_WaitSoundDone ();
UNCACHEGRCHUNK (STARTFONT + 1);
UNCACHEGRCHUNK (C_BACKDROPPIC);
UnCacheLump (COPYPROT_LUMP_START, COPYPROT_LUMP_END);
switch (SoundMode)
{
case sdm_Off:
return;
case sdm_PC:
start = STARTPCSOUNDS;
break;
case sdm_AdLib:
start = STARTADLIBSOUNDS;
}
/* for (i=0;i<NUMSOUNDS;i++,start++)
MM_FreePtr ((memptr *)&audiosegs[start]); */
return;
}
}
ClearMemory ();
ShutdownId ();
printf ("%s\n", DosMessages[US_RndT () % 9]);
exit (1);
}
#endif // SPEARDEMO
#endif // GOODTIMES
#endif // SPEAR
//===========================================================================