- trying to bring order to game.cpp

Some reshuffling, plus moving the automap drawer to its own file.
This commit is contained in:
Christoph Oelckers 2020-08-16 18:18:56 +02:00
parent 78d3afb0bf
commit baf1166319
11 changed files with 660 additions and 656 deletions

View file

@ -26,6 +26,7 @@ set( PCH_SOURCES
src/jweapon.cpp
src/lava.cpp
src/light.cpp
src/map2d.cpp
src/mclip.cpp
src/menus.cpp
src/miscactr.cpp

View file

@ -73,7 +73,7 @@ public:
void Logo(const CompletionFunc& completion)
{
StopSound();
PlayTheme();
PlaySong(nullptr, ThemeSongs[0], ThemeTrack[0]);
static const AnimSound logosound[] =
{

View file

@ -58,6 +58,25 @@ short AttackOrRun = 200;
#define CHOOSE2(value) (RANDOM_P2(1024) < (value))
int
Distance(int x1, int y1, int x2, int y2)
{
int min;
if ((x2 = x2 - x1) < 0)
x2 = -x2;
if ((y2 = y2 - y1) < 0)
y2 = -y2;
if (x2 > y2)
min = y2;
else
min = x2;
return x2 + y2 - DIV2(min);
}
void DebugMoveHit(short SpriteNum)
{

View file

@ -71,6 +71,15 @@ extern ParentalStruct aVoxelArray[MAXTILES];
int ConnectCopySprite(uspritetype const * tsp);
void PreDrawStackedWater(void);
void SW_InitMultiPsky(void)
{
// default
psky_t* const defaultsky = tileSetupSky(DEFAULTPSKY);
defaultsky->lognumtiles = 1;
defaultsky->horizfrac = 8192;
}
#if 1
void
ShadeSprite(tspriteptr_t tsp)

View file

@ -90,7 +90,6 @@ CVAR(Bool, sw_darts, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
BEGIN_SW_NS
void pClearSpriteList(PLAYERp pp);
extern SWBOOL mapcheat;
extern int sw_snd_scratch;
@ -106,7 +105,6 @@ SWBOOL InMenuLevel = FALSE;
SWBOOL LoadGameOutsideMoveLoop = FALSE;
//Miscellaneous variables
SWBOOL FinishedLevel = FALSE;
SWBOOL PanelUpdateMode = TRUE;
short screenpeek = 0;
SWBOOL PedanticMode;
@ -157,26 +155,17 @@ SWBOOL CameraTestMode = FALSE;
char ds[645]; // debug string
extern short NormalVisibility;
extern int quotebot, quotebotgoal; // Multiplayer typing buffer
char recbuf[80]; // Used as a temp buffer to hold typing text
#define ACT_STATUE 0
int score;
SWBOOL QuitFlag = FALSE;
SWBOOL InGame = FALSE;
SWBOOL CommandSetup = FALSE;
char buffer[80], ch;
uint8_t DebugPrintColor = 255;
int krandcount;
FString ThemeSongs[6];
int ThemeTrack[6];
/// L O C A L P R O T O T Y P E S /////////////////////////////////////////////////////////
void BOT_DeleteAllBots(void);
void SybexScreen(void);
void MenuLevel(void);
void StatScreen(PLAYERp mpp);
@ -184,9 +173,6 @@ void InitRunLevel(void);
void RunLevel(void);
/////////////////////////////////////////////////////////////////////////////////////////////
static FILE *debug_fout = NULL;
// Transitioning helper.
void Logo(const CompletionFunc& completion);
@ -209,125 +195,34 @@ int SyncScreenJob()
}
extern SWBOOL DrawScreen;
int krand1(void)
{
ASSERT(!DrawScreen);
krandcount++;
randomseed = ((randomseed * 21 + 1) & 65535);
return randomseed;
}
int PointOnLine(int x, int y, int x1, int y1, int x2, int y2)
{
// the closer to 0 the closer to the line the point is
return ((x2 - x1) * (y - y1)) - ((y2 - y1) * (x - x1));
}
int
Distance(int x1, int y1, int x2, int y2)
{
int min;
if ((x2 = x2 - x1) < 0)
x2 = -x2;
if ((y2 = y2 - y1) < 0)
y2 = -y2;
if (x2 > y2)
min = y2;
else
min = x2;
return x2 + y2 - DIV2(min);
}
bool LoadLevel(MapRecord *maprec)
{
int16_t ang;
if (engineLoadBoard(maprec->fileName, SW_SHAREWARE ? 1 : 0, (vec3_t *)&Player[0], &ang, &Player[0].cursectnum) == -1)
{
Printf("Map not found: %s", maprec->fileName.GetChars());
return false;
}
currentLevel = maprec;
SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name);
STAT_NewLevel(currentLevel->fileName);
Player[0].q16ang = fix16_from_int(ang);
return true;
}
void MultiSharewareCheck(void)
{
if (!SW_SHAREWARE) return;
if (numplayers > 4)
{
I_FatalError("To play a Network game with more than 4 players you must purchase "
"the full version. Read the Ordering Info screens for details.");
}
}
// Some mem crap for Jim
// I reserve 1 meg of heap space for our use out side the cache
int TotalMemory = 0;
int ActualHeap = 0;
static int firstnet = 0; // JBF
void SW_InitMultiPsky(void)
{
// default
psky_t* const defaultsky = tileSetupSky(DEFAULTPSKY);
defaultsky->lognumtiles = 1;
defaultsky->horizfrac = 8192;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
bool InitGame()
{
extern int MovesPerPacket;
//void *ReserveMem=NULL;
int i;
engineInit();
auto pal = fileSystem.LoadFile("3drealms.pal", 0);
if (pal.Size() >= 768)
{
auto pal = fileSystem.LoadFile("3drealms.pal", 0);
if (pal.Size() >= 768)
{
for (auto& c : pal)
c <<= 2;
for (auto& c : pal)
c <<= 2;
paletteSetColorTable(DREALMSPAL, pal.Data(), true, true);
}
paletteSetColorTable(DREALMSPAL, pal.Data(), true, true);
}
timerInit(120);
InitPalette();
// sets numplayers, connecthead, connectpoint2, myconnectindex
numplayers = 1; myconnectindex = 0;
connecthead = 0; connectpoint2[0] = -1;
// code to duplicate packets
if (numplayers > 4 && MovesPerPacket == 1)
if (SW_SHAREWARE && numplayers > 4)
{
MovesPerPacket = 2;
}
MultiSharewareCheck();
if (numplayers > 1)
{
CommPlayers = numplayers;
OrigCommPlayers = CommPlayers;
CommEnabled = TRUE;
gNet.MultiGameType = MULTI_GAME_COMMBAT;
I_FatalError("To play a Network game with more than 4 players you must purchase "
"the full version. Read the Ordering Info screens for details.");
}
TileFiles.LoadArtSet("tiles%03d.art");
@ -339,35 +234,29 @@ bool InitGame()
SW_InitMultiPsky();
memset(Track, 0, sizeof(Track));
memset(Player, 0, sizeof(Player));
for (i = 0; i < MAX_SW_PLAYERS; i++)
for (int i = 0; i < MAX_SW_PLAYERS; i++)
INITLIST(&Player[i].PanelSpriteList);
LoadKVXFromScript("swvoxfil.txt"); // Load voxels from script file
LoadPLockFromScript("swplock.txt"); // Get Parental Lock setup info
LoadCustomInfoFromScript("engine/swcustom.txt"); // load the internal definitions. These also apply to the shareware version.
if (!SW_SHAREWARE)
{
LoadCustomInfoFromScript("swcustom.txt"); // Load user customisation information
}
if (!loaddefinitionsfile(G_DefFile())) Printf("Definitions file loaded.\n");
userConfig.AddDefs.reset();
enginePostInit();
videoInit();
InitFX(); // JBF: do it down here so we get a hold of the window handle
InitFX();
return true;
}
FString ThemeSongs[6];
int ThemeTrack[6];
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void InitNewGame(void)
{
@ -390,19 +279,35 @@ void InitNewGame(void)
memset(puser, 0, sizeof(puser));
}
int ChopTics;
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
bool LoadLevel(MapRecord* maprec)
{
int16_t ang;
if (engineLoadBoard(maprec->fileName, SW_SHAREWARE ? 1 : 0, (vec3_t*)&Player[0], &ang, &Player[0].cursectnum) == -1)
{
Printf("Map not found: %s", maprec->fileName.GetChars());
return false;
}
currentLevel = maprec;
SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name);
STAT_NewLevel(currentLevel->fileName);
Player[0].q16ang = fix16_from_int(ang);
return true;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void InitLevelGlobals(void)
{
extern char PlayerGravity;
extern short wait_active_check_offset;
//extern short Zombies;
extern int PlaxCeilGlobZadjust, PlaxFloorGlobZadjust;
extern SWBOOL left_foot;
extern SWBOOL serpwasseen;
extern SWBOOL sumowasseen;
extern SWBOOL zillawasseen;
extern short BossSpriteNum[3];
ChopTics = 0;
dimensionmode = 3;
zoom = 768;
@ -425,19 +330,167 @@ void InitLevelGlobals(void)
PedanticMode = false;
}
//---------------------------------------------------------------------------
//
// GLOBAL RESETS NOT DONE for LOAD GAME
//
//---------------------------------------------------------------------------
void InitLevelGlobals2(void)
{
extern short Bunny_Count;
// GLOBAL RESETS NOT DONE for LOAD GAME
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
InitTimingVars();
TotalKillable = 0;
Bunny_Count = 0;
FinishAnim = 0;
}
void
InitLevel(void)
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void InitPlayerGameSettings(void)
{
int pnum;
if (CommEnabled)
{
// everyone gets the same Auto Aim
TRAVERSE_CONNECT(pnum)
{
if (gNet.AutoAim)
SET(Player[pnum].Flags, PF_AUTO_AIM);
else
RESET(Player[pnum].Flags, PF_AUTO_AIM);
}
}
else
{
if (cl_autoaim)
SET(Player[myconnectindex].Flags, PF_AUTO_AIM);
else
RESET(Player[myconnectindex].Flags, PF_AUTO_AIM);
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void InitRunLevel(void)
{
if (LoadGameOutsideMoveLoop)
{
int SavePlayClock;
extern int PlayClock;
LoadGameOutsideMoveLoop = FALSE;
// contains what is needed from calls below
if (snd_ambience)
StartAmbientSound();
// crappy little hack to prevent play clock from being overwritten
// for load games
SavePlayClock = PlayClock;
InitTimingVars();
PlayClock = SavePlayClock;
return;
}
//SendVersion(GameVersion);
//waitforeverybody();
Mus_Stop();
DoTheCache();
// auto aim / auto run / etc
InitPlayerGameSettings();
// send packets with player info
InitNetPlayerOptions();
// Initialize Game part of network code (When ready2send != 0)
InitNetVars();
if (currentLevel)
{
PlaySong(currentLevel->labelName, currentLevel->music, currentLevel->cdSongId);
}
InitPrediction(&Player[myconnectindex]);
waitforeverybody();
//CheckVersion(GameVersion);
// IMPORTANT - MUST be right before game loop AFTER waitforeverybody
InitTimingVars();
if (snd_ambience)
StartAmbientSound();
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void MoveTicker(void)
{
int pnum;
//getpackets();
if (PredictionOn && CommEnabled)
{
while (predictmovefifoplc < Player[myconnectindex].movefifoend)
{
DoPrediction(ppp);
}
}
//While you have new input packets to process...
if (!CommEnabled)
bufferjitter = 0;
while (Player[myconnectindex].movefifoend - movefifoplc > bufferjitter)
{
//Make sure you have at least 1 packet from everyone else
for (pnum = connecthead; pnum >= 0; pnum = connectpoint2[pnum])
{
if (movefifoplc == Player[pnum].movefifoend)
{
break;
}
}
//Pnum is >= 0 only if last loop was broken, meaning a player wasn't caught up
if (pnum >= 0)
break;
domovethings();
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void InitLevel(void)
{
if (LoadGameOutsideMoveLoop)
{
@ -642,13 +695,11 @@ void NewLevel(void)
TerminateLevel();
InGame = FALSE;
if (SW_SHAREWARE)
{
if (FinishAnim)
{
PlayTheme();
PlaySong(nullptr, ThemeSongs[0], ThemeTrack[0]);
MenuLevel();
STAT_Update(true);
}
@ -657,7 +708,7 @@ void NewLevel(void)
{
if (FinishAnim == ANIM_ZILLA || FinishAnim == ANIM_SERP)
{
PlayTheme();
PlaySong(nullptr, ThemeSongs[0], ThemeTrack[0]);
MenuLevel();
STAT_Update(true);
}
@ -665,12 +716,6 @@ void NewLevel(void)
}
void PlayTheme()
{
// start music at logo
PlaySong(nullptr, ThemeSongs[0], ThemeTrack[0]);
}
// CTW REMOVED END
void DrawMenuLevelScreen(void)
@ -845,7 +890,6 @@ void Control()
{
InitGame();
InGame = TRUE;
GameIntro();
while (!QuitFlag)
@ -861,128 +905,8 @@ void Control()
}
void _Assert(const char *expr, const char *strFile, unsigned uLine)
{
I_FatalError("Assertion failed: %s %s, line %u", expr, strFile, uLine);
}
void getinput(SW_PACKET *, SWBOOL);
void MoveLoop(void)
{
int pnum;
//getpackets();
if (PredictionOn && CommEnabled)
{
while (predictmovefifoplc < Player[myconnectindex].movefifoend)
{
DoPrediction(ppp);
}
}
//While you have new input packets to process...
if (!CommEnabled)
bufferjitter = 0;
while (Player[myconnectindex].movefifoend - movefifoplc > bufferjitter)
{
//Make sure you have at least 1 packet from everyone else
for (pnum=connecthead; pnum>=0; pnum=connectpoint2[pnum])
{
if (movefifoplc == Player[pnum].movefifoend)
{
break;
}
}
//Pnum is >= 0 only if last loop was broken, meaning a player wasn't caught up
if (pnum >= 0)
break;
domovethings();
}
}
void InitPlayerGameSettings(void)
{
int pnum;
if (CommEnabled)
{
// everyone gets the same Auto Aim
TRAVERSE_CONNECT(pnum)
{
if (gNet.AutoAim)
SET(Player[pnum].Flags, PF_AUTO_AIM);
else
RESET(Player[pnum].Flags, PF_AUTO_AIM);
}
}
else
{
if (cl_autoaim)
SET(Player[myconnectindex].Flags, PF_AUTO_AIM);
else
RESET(Player[myconnectindex].Flags, PF_AUTO_AIM);
}
}
void InitRunLevel(void)
{
if (LoadGameOutsideMoveLoop)
{
int SavePlayClock;
extern int PlayClock;
LoadGameOutsideMoveLoop = FALSE;
// contains what is needed from calls below
if (snd_ambience)
StartAmbientSound();
// crappy little hack to prevent play clock from being overwritten
// for load games
SavePlayClock = PlayClock;
InitTimingVars();
PlayClock = SavePlayClock;
return;
}
//SendVersion(GameVersion);
//waitforeverybody();
Mus_Stop();
DoTheCache();
// auto aim / auto run / etc
InitPlayerGameSettings();
// send packets with player info
InitNetPlayerOptions();
// Initialize Game part of network code (When ready2send != 0)
InitNetVars();
if (currentLevel)
{
PlaySong(currentLevel->labelName, currentLevel->music, currentLevel->cdSongId);
}
InitPrediction(&Player[myconnectindex]);
waitforeverybody();
//CheckVersion(GameVersion);
// IMPORTANT - MUST be right before game loop AFTER waitforeverybody
InitTimingVars();
if (snd_ambience)
StartAmbientSound();
}
void RunLevel(void)
{
@ -1015,7 +939,7 @@ void RunLevel(void)
while (ready2send && (totalclock >= ototalclock + synctics))
{
UpdateInputs();
MoveLoop();
MoveTicker();
}
// Get input again to update q16ang/q16horiz.
@ -1113,365 +1037,6 @@ int32_t GameInterface::app_main()
char WangBangMacro[10][64];
#define MAP_WHITE_SECTOR (LT_GREY + 2)
#define MAP_RED_SECTOR (RED + 6)
#define MAP_FLOOR_SPRITE (RED + 8)
#define MAP_ENEMY (RED + 10)
#define MAP_SPRITE (FIRE + 8)
#define MAP_PLAYER (GREEN + 6)
#define MAP_BLOCK_SPRITE (DK_BLUE + 6)
void drawoverheadmap(int cposx, int cposy, int czoom, short cang)
{
int i, j, k, l, x1, y1, x2, y2, x3, y3, x4, y4, ox, oy, xoff, yoff;
int dax, day, cosang, sinang, xspan, yspan, sprx, spry;
int xrepeat, yrepeat, z1, z2, startwall, endwall, tilenum, daang;
int xvect, yvect, xvect2, yvect2;
char col;
walltype *wal, *wal2;
spritetype *spr;
short p;
static int pspr_ndx[8]= {0,0,0,0,0,0,0,0};
SWBOOL sprisplayer = FALSE;
short txt_x, txt_y;
int32_t tmpydim = (xdim * 5) / 8;
renderSetAspect(65536, divscale16(tmpydim * 320, xdim * 200));
// draw location text
if (hud_size == Hud_Nothing)
{
txt_x = 7;
txt_y = 168;
}
else
{
txt_x = 7;
txt_y = 147;
}
if (ScrollMode2D)
{
MNU_DrawSmallString(txt_x, txt_y - 7, "Follow Mode", 0, 0);
}
sprintf(ds,"%s",currentLevel->DisplayName());
MNU_DrawSmallString(txt_x,txt_y,ds,0, 0);
//////////////////////////////////
xvect = sintable[(2048 - cang) & 2047] * czoom;
yvect = sintable[(1536 - cang) & 2047] * czoom;
xvect2 = mulscale16(xvect, yxaspect);
yvect2 = mulscale16(yvect, yxaspect);
// Draw red lines
for (i = 0; i < numsectors; i++)
{
startwall = sector[i].wallptr;
endwall = sector[i].wallptr + sector[i].wallnum - 1;
z1 = sector[i].ceilingz;
z2 = sector[i].floorz;
for (j = startwall, wal = &wall[startwall]; j <= endwall; j++, wal++)
{
k = wal->nextwall;
if ((unsigned)k >= MAXWALLS)
continue;
if (!mapcheat)
{
if ((show2dwall[j >> 3] & (1 << (j & 7))) == 0)
continue;
if ((k > j) && ((show2dwall[k >> 3] & (1 << (k & 7))) > 0))
continue;
}
if (sector[wal->nextsector].ceilingz == z1)
if (sector[wal->nextsector].floorz == z2)
if (((wal->cstat | wall[wal->nextwall].cstat) & (16 + 32)) == 0)
continue;
col = 152;
//if (dimensionmode == 2)
if (dimensionmode == 6)
{
if (sector[i].floorz != sector[i].ceilingz)
if (sector[wal->nextsector].floorz != sector[wal->nextsector].ceilingz)
if (((wal->cstat | wall[wal->nextwall].cstat) & (16 + 32)) == 0)
if (sector[i].floorz == sector[wal->nextsector].floorz)
continue;
if (sector[i].floorpicnum != sector[wal->nextsector].floorpicnum)
continue;
if (sector[i].floorshade != sector[wal->nextsector].floorshade)
continue;
col = 12; // 1=white / 31=black / 44=green / 56=pink / 128=yellow / 210=blue / 248=orange / 255=purple
}
ox = wal->x - cposx;
oy = wal->y - cposy;
x1 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y1 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
wal2 = &wall[wal->point2];
ox = wal2->x - cposx;
oy = wal2->y - cposy;
x2 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y2 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
renderDrawLine(x1 + (xdim << 11), y1 + (ydim << 11), x2 + (xdim << 11), y2 + (ydim << 11), col);
}
}
// Draw sprites
k = Player[screenpeek].PlayerSprite;
for (i = 0; i < numsectors; i++)
for (j = headspritesect[i]; j >= 0; j = nextspritesect[j])
{
for (p=connecthead; p >= 0; p=connectpoint2[p])
{
if (Player[p].PlayerSprite == j)
{
if (sprite[Player[p].PlayerSprite].xvel > 16)
pspr_ndx[myconnectindex] = (((int32_t) totalclock>>4)&3);
sprisplayer = TRUE;
goto SHOWSPRITE;
}
}
if (mapcheat || (show2dsprite[j >> 3] & (1 << (j & 7))) > 0)
{
SHOWSPRITE:
spr = &sprite[j];
col = 56; // 1=white / 31=black / 44=green / 56=pink / 128=yellow / 210=blue / 248=orange / 255=purple
if ((spr->cstat & 1) > 0)
col = 248;
if (j == k)
col = 31;
sprx = spr->x;
spry = spr->y;
k = spr->statnum;
if ((k >= 1) && (k <= 8) && (k != 2)) // Interpolate moving
{
sprx = sprite[j].x;
spry = sprite[j].y;
}
switch (spr->cstat & 48)
{
case 0: // Regular sprite
if (Player[p].PlayerSprite == j)
{
ox = sprx - cposx;
oy = spry - cposy;
x1 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y1 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
if (dimensionmode == 5 && (gNet.MultiGameType != MULTI_GAME_COMMBAT || j == Player[screenpeek].PlayerSprite))
{
ox = (sintable[(spr->ang + 512) & 2047] >> 7);
oy = (sintable[(spr->ang) & 2047] >> 7);
x2 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y2 = mulscale16(oy, xvect) + mulscale16(ox, yvect);
if (j == Player[screenpeek].PlayerSprite)
{
x2 = 0L;
y2 = -(czoom << 5);
}
x3 = mulscale16(x2, yxaspect);
y3 = mulscale16(y2, yxaspect);
renderDrawLine(x1 - x2 + (xdim << 11), y1 - y3 + (ydim << 11),
x1 + x2 + (xdim << 11), y1 + y3 + (ydim << 11), col);
renderDrawLine(x1 - y2 + (xdim << 11), y1 + x3 + (ydim << 11),
x1 + x2 + (xdim << 11), y1 + y3 + (ydim << 11), col);
renderDrawLine(x1 + y2 + (xdim << 11), y1 - x3 + (ydim << 11),
x1 + x2 + (xdim << 11), y1 + y3 + (ydim << 11), col);
}
else
{
if (((gotsector[i >> 3] & (1 << (i & 7))) > 0) && (czoom > 192))
{
daang = (spr->ang - cang) & 2047;
if (j == Player[screenpeek].PlayerSprite)
{
x1 = 0;
//y1 = (yxaspect << 2);
y1 = 0;
daang = 0;
}
// Special case tiles
if (spr->picnum == 3123) break;
int spnum = -1;
if (sprisplayer)
{
if (gNet.MultiGameType != MULTI_GAME_COMMBAT || j == Player[screenpeek].PlayerSprite)
spnum = 1196 + pspr_ndx[myconnectindex];
}
else spnum = spr->picnum;
double xd = ((x1 << 4) + (xdim << 15)) / 65536.;
double yd = ((y1 << 4) + (ydim << 15)) / 65536.;
double sc = mulscale16(czoom * (spr->yrepeat), yxaspect) / 65536.;
if (spnum >= 0)
{
DrawTexture(twod, tileGetTexture(5407, true), xd, yd, DTA_FullscreenScale, FSMode_ScaleToFit43, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200,
DTA_CenterOffsetRel, true, DTA_TranslationIndex, TRANSLATION(Translation_Remap, spr->pal), DTA_Color, shadeToLight(spr->shade),
DTA_Alpha, (spr->cstat & 2) ? 0.33 : 1., TAG_DONE);
}
}
}
}
break;
case 16: // Rotated sprite
x1 = sprx;
y1 = spry;
tilenum = spr->picnum;
xoff = (int)tileLeftOffset(tilenum) + (int)spr->xoffset;
if ((spr->cstat & 4) > 0)
xoff = -xoff;
k = spr->ang;
l = spr->xrepeat;
dax = sintable[k & 2047] * l;
day = sintable[(k + 1536) & 2047] * l;
l = tilesiz[tilenum].x;
k = (l >> 1) + xoff;
x1 -= mulscale16(dax, k);
x2 = x1 + mulscale16(dax, l);
y1 -= mulscale16(day, k);
y2 = y1 + mulscale16(day, l);
ox = x1 - cposx;
oy = y1 - cposy;
x1 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y1 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
ox = x2 - cposx;
oy = y2 - cposy;
x2 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y2 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
renderDrawLine(x1 + (xdim << 11), y1 + (ydim << 11),
x2 + (xdim << 11), y2 + (ydim << 11), col);
break;
case 32: // Floor sprite
if (dimensionmode == 5)
{
tilenum = spr->picnum;
xoff = (int)tileLeftOffset(tilenum) + (int)spr->xoffset;
yoff = (int)tileTopOffset(tilenum) + (int)spr->yoffset;
if ((spr->cstat & 4) > 0)
xoff = -xoff;
if ((spr->cstat & 8) > 0)
yoff = -yoff;
k = spr->ang;
cosang = sintable[(k + 512) & 2047];
sinang = sintable[k];
xspan = tilesiz[tilenum].x;
xrepeat = spr->xrepeat;
yspan = tilesiz[tilenum].y;
yrepeat = spr->yrepeat;
dax = ((xspan >> 1) + xoff) * xrepeat;
day = ((yspan >> 1) + yoff) * yrepeat;
x1 = sprx + mulscale16(sinang, dax) + mulscale16(cosang, day);
y1 = spry + mulscale16(sinang, day) - mulscale16(cosang, dax);
l = xspan * xrepeat;
x2 = x1 - mulscale16(sinang, l);
y2 = y1 + mulscale16(cosang, l);
l = yspan * yrepeat;
k = -mulscale16(cosang, l);
x3 = x2 + k;
x4 = x1 + k;
k = -mulscale16(sinang, l);
y3 = y2 + k;
y4 = y1 + k;
ox = x1 - cposx;
oy = y1 - cposy;
x1 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y1 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
ox = x2 - cposx;
oy = y2 - cposy;
x2 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y2 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
ox = x3 - cposx;
oy = y3 - cposy;
x3 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y3 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
ox = x4 - cposx;
oy = y4 - cposy;
x4 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y4 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
renderDrawLine(x1 + (xdim << 11), y1 + (ydim << 11),
x2 + (xdim << 11), y2 + (ydim << 11), col);
renderDrawLine(x2 + (xdim << 11), y2 + (ydim << 11),
x3 + (xdim << 11), y3 + (ydim << 11), col);
renderDrawLine(x3 + (xdim << 11), y3 + (ydim << 11),
x4 + (xdim << 11), y4 + (ydim << 11), col);
renderDrawLine(x4 + (xdim << 11), y4 + (ydim << 11),
x1 + (xdim << 11), y1 + (ydim << 11), col);
}
break;
}
}
}
// Draw white lines
for (i = 0; i < numsectors; i++)
{
startwall = sector[i].wallptr;
endwall = sector[i].wallptr + sector[i].wallnum - 1;
for (j = startwall, wal = &wall[startwall]; j <= endwall; j++, wal++)
{
if ((uint16_t)wal->nextwall < MAXWALLS)
continue;
if (!mapcheat && (show2dwall[j >> 3] & (1 << (j & 7))) == 0)
continue;
if (!tileGetTexture(wal->picnum)->isValid()) continue;
ox = wal->x - cposx;
oy = wal->y - cposy;
x1 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y1 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
wal2 = &wall[wal->point2];
ox = wal2->x - cposx;
oy = wal2->y - cposy;
x2 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y2 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
renderDrawLine(x1 + (xdim << 11), y1 + (ydim << 11), x2 + (xdim << 11), y2 + (ydim << 11), 24);
}
}
videoSetCorrectedAspect();
}
int RandomRange(int range)
{

View file

@ -108,13 +108,10 @@ enum
//#pragma off(unreferenced)
#define ERR_STD_ARG __FILE__, __LINE__
void _Assert(const char *expr, const char *strFile, unsigned uLine);
#define PRODUCTION_ASSERT(f) \
do { \
if (!(f)) \
_Assert(#f,ERR_STD_ARG); \
I_FatalError("Assertion failed: %s %s, line %u", #f, __FILE__, __LINE__); \
} while (0)
#define ASSERT assert
@ -127,10 +124,14 @@ void _Assert(const char *expr, const char *strFile, unsigned uLine);
int RandomRange(int);
int krand1(void);
#define RANDOM_P2(pwr_of_2) (MOD_P2(krand1(),(pwr_of_2)))
inline int RANDOM(void)
{
randomseed = ((randomseed * 21 + 1) & 65535);
return randomseed;
}
#define RANDOM_P2(pwr_of_2) (MOD_P2(RANDOM(),(pwr_of_2)))
#define RANDOM_RANGE(range) (RandomRange(range))
#define RANDOM() (krand1())
#define PRINT(line,str) DebugPrint(line,str)
@ -744,7 +745,6 @@ struct STATEstruct
typedef enum {WATER_FOOT, BLOOD_FOOT} FOOT_TYPE;
extern FOOT_TYPE FootMode;
extern SWBOOL InGame; // Declared in game.c
int QueueFloorBlood(short hit_sprite); // Weapon.c
int QueueFootPrint(short hit_sprite); // Weapon.c
int QueueGeneric(short SpriteNum, short pic); // Weapon.c
@ -2286,7 +2286,6 @@ void ScaleSectorObject(SECTOR_OBJECTp sop); // morph.c
void MorphTornado(SECTOR_OBJECTp sop); // morph.c
void MorphFloor(SECTOR_OBJECTp sop); // morph.c
void ScaleRandomPoint(SECTOR_OBJECTp sop,short k,short ang,int x,int y,int *dx,int *dy); // morph.c
void PlayTheme(void);
void CopySectorMatch(short match); // copysect.c
@ -2311,12 +2310,26 @@ void LoadSaveMsg(const char *msg);
void UpdateStatusBar(ClockTicks arg);
void InitFonts();
void registerinputcommands();
void SW_InitMultiPsky(void);
extern int PlayClock;
extern short LevelSecrets;
extern short TotalKillable;
extern int OrigCommPlayers;
extern char PlayerGravity;
extern short wait_active_check_offset;
//extern short Zombies;
extern int PlaxCeilGlobZadjust, PlaxFloorGlobZadjust;
extern SWBOOL left_foot;
extern SWBOOL serpwasseen;
extern SWBOOL sumowasseen;
extern SWBOOL zillawasseen;
extern short BossSpriteNum[3];
extern int ChopTics;
extern short Bunny_Count;
#define ANIM_SERP 1
#define ANIM_SUMO 2
#define ANIM_ZILLA 3

402
source/sw/src/map2d.cpp Normal file
View file

@ -0,0 +1,402 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 1997, 2005 - 3D Realms Entertainment
This file is part of Shadow Warrior version 1.2
Shadow Warrior is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Original Source: 1997 - Frank Maddin and Jim Norwood
Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------
#include "ns.h"
#include "build.h"
#include "game.h"
#include "menus.h"
#include "network.h"
#include "pal.h"
#include "v_draw.h"
BEGIN_SW_NS
extern SWBOOL mapcheat;
enum
{
MAP_WHITE_SECTOR = (LT_GREY + 2),
MAP_RED_SECTOR = (RED + 6),
MAP_FLOOR_SPRITE = (RED + 8),
MAP_ENEMY = (RED + 10),
MAP_SPRITE = (FIRE + 8),
MAP_PLAYER = (GREEN + 6),
MAP_BLOCK_SPRITE = (DK_BLUE + 6),
};
void drawoverheadmap(int cposx, int cposy, int czoom, short cang)
{
int i, j, k, l, x1, y1, x2, y2, x3, y3, x4, y4, ox, oy, xoff, yoff;
int dax, day, cosang, sinang, xspan, yspan, sprx, spry;
int xrepeat, yrepeat, z1, z2, startwall, endwall, tilenum, daang;
int xvect, yvect, xvect2, yvect2;
char col;
walltype *wal, *wal2;
spritetype *spr;
short p;
static int pspr_ndx[8]= {0,0,0,0,0,0,0,0};
SWBOOL sprisplayer = FALSE;
short txt_x, txt_y;
int32_t tmpydim = (xdim * 5) / 8;
renderSetAspect(65536, divscale16(tmpydim * 320, xdim * 200));
// draw location text
if (hud_size == Hud_Nothing)
{
txt_x = 7;
txt_y = 168;
}
else
{
txt_x = 7;
txt_y = 147;
}
if (ScrollMode2D)
{
MNU_DrawSmallString(txt_x, txt_y - 7, "Follow Mode", 0, 0);
}
sprintf(ds,"%s",currentLevel->DisplayName());
MNU_DrawSmallString(txt_x,txt_y,ds,0, 0);
//////////////////////////////////
xvect = sintable[(2048 - cang) & 2047] * czoom;
yvect = sintable[(1536 - cang) & 2047] * czoom;
xvect2 = mulscale16(xvect, yxaspect);
yvect2 = mulscale16(yvect, yxaspect);
// Draw red lines
for (i = 0; i < numsectors; i++)
{
startwall = sector[i].wallptr;
endwall = sector[i].wallptr + sector[i].wallnum - 1;
z1 = sector[i].ceilingz;
z2 = sector[i].floorz;
for (j = startwall, wal = &wall[startwall]; j <= endwall; j++, wal++)
{
k = wal->nextwall;
if ((unsigned)k >= MAXWALLS)
continue;
if (!mapcheat)
{
if ((show2dwall[j >> 3] & (1 << (j & 7))) == 0)
continue;
if ((k > j) && ((show2dwall[k >> 3] & (1 << (k & 7))) > 0))
continue;
}
if (sector[wal->nextsector].ceilingz == z1)
if (sector[wal->nextsector].floorz == z2)
if (((wal->cstat | wall[wal->nextwall].cstat) & (16 + 32)) == 0)
continue;
col = 152;
//if (dimensionmode == 2)
if (dimensionmode == 6)
{
if (sector[i].floorz != sector[i].ceilingz)
if (sector[wal->nextsector].floorz != sector[wal->nextsector].ceilingz)
if (((wal->cstat | wall[wal->nextwall].cstat) & (16 + 32)) == 0)
if (sector[i].floorz == sector[wal->nextsector].floorz)
continue;
if (sector[i].floorpicnum != sector[wal->nextsector].floorpicnum)
continue;
if (sector[i].floorshade != sector[wal->nextsector].floorshade)
continue;
col = 12; // 1=white / 31=black / 44=green / 56=pink / 128=yellow / 210=blue / 248=orange / 255=purple
}
ox = wal->x - cposx;
oy = wal->y - cposy;
x1 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y1 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
wal2 = &wall[wal->point2];
ox = wal2->x - cposx;
oy = wal2->y - cposy;
x2 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y2 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
renderDrawLine(x1 + (xdim << 11), y1 + (ydim << 11), x2 + (xdim << 11), y2 + (ydim << 11), col);
}
}
// Draw sprites
k = Player[screenpeek].PlayerSprite;
for (i = 0; i < numsectors; i++)
for (j = headspritesect[i]; j >= 0; j = nextspritesect[j])
{
for (p=connecthead; p >= 0; p=connectpoint2[p])
{
if (Player[p].PlayerSprite == j)
{
if (sprite[Player[p].PlayerSprite].xvel > 16)
pspr_ndx[myconnectindex] = (((int32_t) totalclock>>4)&3);
sprisplayer = TRUE;
goto SHOWSPRITE;
}
}
if (mapcheat || (show2dsprite[j >> 3] & (1 << (j & 7))) > 0)
{
SHOWSPRITE:
spr = &sprite[j];
col = 56; // 1=white / 31=black / 44=green / 56=pink / 128=yellow / 210=blue / 248=orange / 255=purple
if ((spr->cstat & 1) > 0)
col = 248;
if (j == k)
col = 31;
sprx = spr->x;
spry = spr->y;
k = spr->statnum;
if ((k >= 1) && (k <= 8) && (k != 2)) // Interpolate moving
{
sprx = sprite[j].x;
spry = sprite[j].y;
}
switch (spr->cstat & 48)
{
case 0: // Regular sprite
if (Player[p].PlayerSprite == j)
{
ox = sprx - cposx;
oy = spry - cposy;
x1 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y1 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
if (dimensionmode == 5 && (gNet.MultiGameType != MULTI_GAME_COMMBAT || j == Player[screenpeek].PlayerSprite))
{
ox = (sintable[(spr->ang + 512) & 2047] >> 7);
oy = (sintable[(spr->ang) & 2047] >> 7);
x2 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y2 = mulscale16(oy, xvect) + mulscale16(ox, yvect);
if (j == Player[screenpeek].PlayerSprite)
{
x2 = 0L;
y2 = -(czoom << 5);
}
x3 = mulscale16(x2, yxaspect);
y3 = mulscale16(y2, yxaspect);
renderDrawLine(x1 - x2 + (xdim << 11), y1 - y3 + (ydim << 11),
x1 + x2 + (xdim << 11), y1 + y3 + (ydim << 11), col);
renderDrawLine(x1 - y2 + (xdim << 11), y1 + x3 + (ydim << 11),
x1 + x2 + (xdim << 11), y1 + y3 + (ydim << 11), col);
renderDrawLine(x1 + y2 + (xdim << 11), y1 - x3 + (ydim << 11),
x1 + x2 + (xdim << 11), y1 + y3 + (ydim << 11), col);
}
else
{
if (((gotsector[i >> 3] & (1 << (i & 7))) > 0) && (czoom > 192))
{
daang = (spr->ang - cang) & 2047;
if (j == Player[screenpeek].PlayerSprite)
{
x1 = 0;
//y1 = (yxaspect << 2);
y1 = 0;
daang = 0;
}
// Special case tiles
if (spr->picnum == 3123) break;
int spnum = -1;
if (sprisplayer)
{
if (gNet.MultiGameType != MULTI_GAME_COMMBAT || j == Player[screenpeek].PlayerSprite)
spnum = 1196 + pspr_ndx[myconnectindex];
}
else spnum = spr->picnum;
double xd = ((x1 << 4) + (xdim << 15)) / 65536.;
double yd = ((y1 << 4) + (ydim << 15)) / 65536.;
double sc = mulscale16(czoom * (spr->yrepeat), yxaspect) / 65536.;
if (spnum >= 0)
{
DrawTexture(twod, tileGetTexture(5407, true), xd, yd, DTA_FullscreenScale, FSMode_ScaleToFit43, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200,
DTA_CenterOffsetRel, true, DTA_TranslationIndex, TRANSLATION(Translation_Remap, spr->pal), DTA_Color, shadeToLight(spr->shade),
DTA_Alpha, (spr->cstat & 2) ? 0.33 : 1., TAG_DONE);
}
}
}
}
break;
case 16: // Rotated sprite
x1 = sprx;
y1 = spry;
tilenum = spr->picnum;
xoff = (int)tileLeftOffset(tilenum) + (int)spr->xoffset;
if ((spr->cstat & 4) > 0)
xoff = -xoff;
k = spr->ang;
l = spr->xrepeat;
dax = sintable[k & 2047] * l;
day = sintable[(k + 1536) & 2047] * l;
l = tilesiz[tilenum].x;
k = (l >> 1) + xoff;
x1 -= mulscale16(dax, k);
x2 = x1 + mulscale16(dax, l);
y1 -= mulscale16(day, k);
y2 = y1 + mulscale16(day, l);
ox = x1 - cposx;
oy = y1 - cposy;
x1 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y1 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
ox = x2 - cposx;
oy = y2 - cposy;
x2 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y2 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
renderDrawLine(x1 + (xdim << 11), y1 + (ydim << 11),
x2 + (xdim << 11), y2 + (ydim << 11), col);
break;
case 32: // Floor sprite
if (dimensionmode == 5)
{
tilenum = spr->picnum;
xoff = (int)tileLeftOffset(tilenum) + (int)spr->xoffset;
yoff = (int)tileTopOffset(tilenum) + (int)spr->yoffset;
if ((spr->cstat & 4) > 0)
xoff = -xoff;
if ((spr->cstat & 8) > 0)
yoff = -yoff;
k = spr->ang;
cosang = sintable[(k + 512) & 2047];
sinang = sintable[k];
xspan = tilesiz[tilenum].x;
xrepeat = spr->xrepeat;
yspan = tilesiz[tilenum].y;
yrepeat = spr->yrepeat;
dax = ((xspan >> 1) + xoff) * xrepeat;
day = ((yspan >> 1) + yoff) * yrepeat;
x1 = sprx + mulscale16(sinang, dax) + mulscale16(cosang, day);
y1 = spry + mulscale16(sinang, day) - mulscale16(cosang, dax);
l = xspan * xrepeat;
x2 = x1 - mulscale16(sinang, l);
y2 = y1 + mulscale16(cosang, l);
l = yspan * yrepeat;
k = -mulscale16(cosang, l);
x3 = x2 + k;
x4 = x1 + k;
k = -mulscale16(sinang, l);
y3 = y2 + k;
y4 = y1 + k;
ox = x1 - cposx;
oy = y1 - cposy;
x1 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y1 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
ox = x2 - cposx;
oy = y2 - cposy;
x2 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y2 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
ox = x3 - cposx;
oy = y3 - cposy;
x3 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y3 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
ox = x4 - cposx;
oy = y4 - cposy;
x4 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y4 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
renderDrawLine(x1 + (xdim << 11), y1 + (ydim << 11),
x2 + (xdim << 11), y2 + (ydim << 11), col);
renderDrawLine(x2 + (xdim << 11), y2 + (ydim << 11),
x3 + (xdim << 11), y3 + (ydim << 11), col);
renderDrawLine(x3 + (xdim << 11), y3 + (ydim << 11),
x4 + (xdim << 11), y4 + (ydim << 11), col);
renderDrawLine(x4 + (xdim << 11), y4 + (ydim << 11),
x1 + (xdim << 11), y1 + (ydim << 11), col);
}
break;
}
}
}
// Draw white lines
for (i = 0; i < numsectors; i++)
{
startwall = sector[i].wallptr;
endwall = sector[i].wallptr + sector[i].wallnum - 1;
for (j = startwall, wal = &wall[startwall]; j <= endwall; j++, wal++)
{
if ((uint16_t)wal->nextwall < MAXWALLS)
continue;
if (!mapcheat && (show2dwall[j >> 3] & (1 << (j & 7))) == 0)
continue;
if (!tileGetTexture(wal->picnum)->isValid()) continue;
ox = wal->x - cposx;
oy = wal->y - cposy;
x1 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y1 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
wal2 = &wall[wal->point2];
ox = wal2->x - cposx;
oy = wal2->y - cposy;
x2 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
y2 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
renderDrawLine(x1 + (xdim << 11), y1 + (ydim << 11), x2 + (xdim << 11), y2 + (ydim << 11), 24);
}
}
videoSetCorrectedAspect();
}
END_SW_NS

View file

@ -50,7 +50,6 @@ int PlayClock;
gNET gNet;
extern short PlayerQuitMenuLevel;
extern SWBOOL QuitFlag;
#define TIMERUPDATESIZ 32

View file

@ -96,7 +96,6 @@ void pHotHeadOverlays(PANEL_SPRITEp psp, short mode);
char UziRecoilYadj = 0;
extern SWBOOL QuitFlag;
extern short screenpeek;
ANIMATOR NullAnimator;

View file

@ -127,6 +127,7 @@ extern SWBOOL DebugOperate;
//unsigned char synctics, lastsynctics;
int dimensionmode, zoom;
int ChopTics;
PLAYER Player[MAX_SW_PLAYERS_REG + 1];
@ -7432,8 +7433,6 @@ void PlayerTimers(PLAYERp pp)
void ChopsCheck(PLAYERp pp)
{
extern int ChopTics;
if (!M_Active() && !TEST(pp->Flags, PF_DEAD) && !pp->sop_riding && numplayers <= 1)
{
if ((pp->input.bits|pp->input.vel|pp->input.svel|pp->input.q16angvel|pp->input.q16aimvel) ||

View file

@ -142,8 +142,6 @@ STATE s_DebrisStarFish[] =
{426, 100, DoActorDebris, &s_DebrisStarFish[0]},
};
extern int score;
ANIMATOR DoGet, DoKey, DoSpriteFade;
// temporary