- Exhumed status bar work.

Unfortunately this is a bit limited due to how the data was designed.
This commit is contained in:
Christoph Oelckers 2020-08-20 00:55:31 +02:00
parent 37d687e4e9
commit 78bfbdb253
18 changed files with 477 additions and 573 deletions

View File

@ -769,7 +769,6 @@ static void app_init()
registerinputcommands();
gChoke.sub_83ff0(518, sub_84230);
videoSetViewableArea(0, 0, xdim - 1, ydim - 1);
UpdateDacs(0, true);
}

View File

@ -416,7 +416,9 @@ void DBaseStatusBar::DrawGraphic(FGameTexture* tex, double x, double y, int flag
DTA_AlphaChannel, !!(flags & DI_ALPHAMAPPED),
DTA_FillColor, (flags & DI_ALPHAMAPPED) ? 0 : -1,
DTA_FlipX, !!(flags & DI_MIRROR),
DTA_FlipY, !!(flags& DI_MIRRORY),
DTA_Rotate, rotate,
DTA_FlipOffsets, true,
DTA_LegacyRenderStyle, style,
TAG_DONE);
}

View File

@ -274,6 +274,7 @@ enum DI_Flags
DI_DONTANIMATE = 0x800, // do not animate the texture
DI_MIRROR = 0x1000, // flip the texture horizontally, like a mirror
DI_ITEM_RELCENTER = 0x2000,
DI_MIRRORY = 0x40000000,
DI_SCREEN_AUTO = 0, // decide based on given offsets.
DI_SCREEN_MANUAL_ALIGN = 0x4000, // If this is on, the following flags will have an effect

View File

@ -63,6 +63,7 @@ int menu_Menu(int nVal)
overwritesprite(270, 150, kTile3512 + ((dword_9AB5F + 2) & 3), 32, 3, kPalNormal);
HandleAsync();
D_ProcessEvents();
videoNextPage();
}

View File

@ -55,6 +55,7 @@ BEGIN_PS_NS
void FinishLevel();
void uploadCinemaPalettes();
int32_t registerosdcommands(void);
void InitFonts();
int htimer = 0;
@ -467,22 +468,15 @@ void ResetEngine()
void InstallEngine()
{
// initgroupfile("stuff.dat");
TileFiles.LoadArtSet("tiles%03d.art");
// TEMP
//nScreenWidth *= 2;
//nScreenHeight *= 2;
bHiRes = true;
// TEMP
if (engineInit())
{
G_FatalEngineError();
}
uploadCinemaPalettes();
LoadPaletteLookups();
InitFonts();
videoInit();
enginecompatibility_mode = ENGINECOMPATIBILITY_19950829;
@ -548,7 +542,6 @@ short nShadowPic;
short nCreaturesLeft = 0;
short nFreeze;
short bFullScreen;
short nSnakeCam = -1;
@ -586,7 +579,6 @@ short forcelevel = -1;
int lLocalButtons = 0;
int lLocalCodes = 0;
short bHiRes = false;
short bCoordinates = false;
int nNetTime = -1;
@ -607,7 +599,6 @@ short nCurBodyNum = 0;
short nBodyTotal = 0;
short textpages;
short lastfps;
short nMapMode = 0;
@ -621,8 +612,6 @@ short nFirstPassword = 0;
short nFirstPassInfo = 0;
short nPasswordCount = 0;
short screensize;
short bSnakeCam = false;
short bRecord = false;
short bPlayback = false;
@ -632,6 +621,7 @@ short bDoFlashes = true;
short bHolly = false;
short nItemTextIndex;
short besttarget;
short scan_char = 0;
@ -700,21 +690,6 @@ int MyGetStringWidth(const char *str)
return nWidth;
}
void UpdateScreenSize()
{
int xsize = xdim - scale(screensize*16, xdim, 320);
int ysize = scale(ydim, xsize, xdim);
int y1 = ((ydim >> 1) - (ysize >> 1));
MySetView(
(xdim >> 1) - (xsize >> 1),
y1,
(xdim >> 1) - (xsize >> 1) + xsize - 1,
(y1 + ysize - 1));
RefreshStatus();
}
void ResetPassword()
{
nCodeMin = nFirstPassword;
@ -862,13 +837,33 @@ void CheckKeys()
if (buttonMap.ButtonDown(gamefunc_Enlarge_Screen))
{
buttonMap.ClearButton(gamefunc_Enlarge_Screen);
if (!nMapMode) G_ChangeHudLayout(1);
if (!nMapMode)
{
if (!SHIFTS_IS_PRESSED)
{
G_ChangeHudLayout(1);
}
else
{
hud_scale = hud_scale + 4;
}
}
}
if (buttonMap.ButtonDown(gamefunc_Shrink_Screen))
{
buttonMap.ClearButton(gamefunc_Shrink_Screen);
if (!nMapMode) G_ChangeHudLayout(-1);
if (!nMapMode)
{
if (!SHIFTS_IS_PRESSED)
{
G_ChangeHudLayout(-1);
}
else
{
hud_scale = hud_scale - 4;
}
}
}
// go to 3rd person view?
@ -1153,8 +1148,6 @@ void DoCredits()
HandleAsync();
inputState.keyGetChar();
}
Clip();
}
void FinishLevel()
@ -1177,8 +1170,6 @@ void FinishLevel()
videoNextPage();
WaitTicks(12);
WaitVBL();
RefreshBackground();
RefreshStatus();
DrawView(65536);
videoNextPage();
}
@ -1243,9 +1234,6 @@ uint8_t ReadPlaybackInputs()
void SetHiRes()
{
//nScreenWidth = 640;
//nScreenHeight = 400;
bHiRes = true;
}
void DoClockBeep()
@ -1384,12 +1372,16 @@ static void GameDisplay(void)
auto smoothRatio = calc_smoothratio(totalclock, tclocks);
DrawView(smoothRatio);
DrawStatusBar();
if (paused && !M_Active())
{
int nLen = MyGetStringWidth("PAUSED");
myprintext((320 - nLen) / 2, 100, "PAUSED", 0);
}
if (M_Active())
{
D_ProcessEvents();
}
videoNextPage();
}
@ -1711,10 +1703,6 @@ int GameInterface::app_main()
ResetPassword();
// GetCurPal(NULL);
Printf("Initializing OSD...\n");
registerosdcommands();
if (nNetPlayerCount == -1)
@ -2289,7 +2277,6 @@ void DoGameOverScene()
NoClip();
overwritesprite(0, 0, kTile3591, 0, 2, kPalNormal, 16);
Clip();
videoNextPage();
CinemaFadeIn();
PlayGameOverSound();
@ -2443,8 +2430,6 @@ void DoTitle()
}
WaitNoKey(1, KeyFn1);
videoSetViewableArea(nViewLeft, nViewTop, nViewRight, nViewBottom);
}
void CopyTileToBitmap(short nSrcTile, short nDestTile, int xPos, int yPos)
@ -3034,44 +3019,18 @@ bool GameInterface::CanSave()
return !bRecord && !bPlayback && !paused && !bInDemo && nTotalPlayers == 1;
}
#if 0
void GameInterface::UpdateScreenSize()
{
if (hud_size == 8)
{
if (!bFullScreen)
{
bFullScreen = true;
screensize = 0;
UnMaskStatus();
}
}
else
{
screensize = (7 - clamp(*hud_size, 0, 7)) * 2;
bFullScreen = false;
Powerslave::UpdateScreenSize();
}
}
#endif
::GameInterface* CreateInterface()
{
return new GameInterface;
}
//short lastlevel;
//short forcelevel = -1;
//int lLocalCodes = 0;
//int flash;
//short textpages;
// This is only the static global data.
static SavegameHelper sgh("exhumed",
SA(cPupData),
SV(nPupData),
SV(nPixels),
SV(besttarget),
SA(curx),
SA(cury),
SA(destvelx),

View File

@ -277,18 +277,12 @@ extern short bNoCreatures;
extern short nLocalSpr;
extern short levelnew;
extern short textpages;
extern short nSnakeCam;
extern short bHiRes;
extern short bCoordinates;
extern short bFullScreen;
extern short bHolly;
extern short screensize;
extern int totalmoves;
extern int lCountDown;
@ -364,6 +358,7 @@ struct GameInterface : ::GameInterface
bool LoadGame(FSaveGameNode* sv) override;
bool SaveGame(FSaveGameNode* sv) override;
bool CanSave() override;
ReservedSpace GetReservedScreenSpace(int viewsize) override { return { 0, 24 }; }
FString statFPS() override;
//GameStats getStats() override;

View File

@ -470,7 +470,6 @@ void DrawMap()
if (nMapMode == 2)
{
twod->ClearScreen();
RefreshBackground();
renderDrawMapView(initx, inity, lMapZoom, inita);
}
G_DrawOverheadMap(initx, inity, lMapZoom, inita);

View File

@ -626,7 +626,6 @@ int menu_DrawTheMap(int nLevel, int nLevelNew, int nLevelBest)
int startTime = (int)totalclock;
inputState.ClearAllInput();
UnMaskStatus();
videoSetViewableArea(0, 0, xdim - 1, ydim - 1);
// 0-offset the level numbers
@ -834,7 +833,6 @@ int menu_DrawTheMap(int nLevel, int nLevelNew, int nLevelBest)
}
}
MySetView(nViewLeft, nViewTop, nViewRight, nViewBottom);
return nLevelNew + 1;
}
@ -1163,8 +1161,6 @@ void DoCinemaText(short nVal)
void GoToTheCinema(int nVal)
{
UnMaskStatus();
switch (nVal - 1)
{
default:
@ -1292,7 +1288,6 @@ void GoToTheCinema(int nVal)
videoNextPage();
GrabPalette();
Clip();
// quit the game if we've finished level 4 and displayed the advert text
if (ISDEMOVER && nVal == 3) {
@ -1430,7 +1425,6 @@ void DoStatic(int a, int b)
void DoLastLevelCinema()
{
FadeOut(0);
UnMaskStatus();
videoSetViewableArea(0, 0, xdim - 1, ydim - 1);
@ -1592,8 +1586,6 @@ LABEL_28:
EraseScreen(-1);
tileLoad(kTileLoboLaptop);
FadeOut(0);
MySetView(nViewLeft, nViewTop, nViewRight, nViewBottom);
MaskStatus();
}
static SavegameHelper sgh("menu",

View File

@ -43,7 +43,6 @@ short nPilotLightFrame;
short nPilotLightCount;
short nPilotLightBase;
short laststatustile;
short nShadowWidth = 1;
short nFlameHeight = 1;
@ -349,47 +348,6 @@ void seq_LoadSequences()
}
}
void seq_DrawStatusSequence(short nSequence, uint16_t edx, short ebx)
{
edx += SeqBase[nSequence];
short nFrameBase = FrameBase[edx];
int16_t nFrameSize = FrameSize[edx];
int const nPal = RemapPLU(kPalNormal);
while (1)
{
nFrameSize--;
if (nFrameSize < 0)
break;
uint8_t nStat = 1; // (thex, they) is middle
laststatusx = ChunkXpos[nFrameBase] + 160;
laststatusy = ChunkYpos[nFrameBase] + 100 + ebx;
short chunkFlag = ChunkFlag[nFrameBase];
if (chunkFlag & 1) {
nStat = 0x9; // (thex, they) is middle, and x-flipped
}
if (chunkFlag & 2) {
nStat |= 0x10; // y-flipped
}
laststatustile = ChunkPict[nFrameBase];
if (bHiRes) {
nStat |= 0x2; // scale and clip to viewing window
}
overwritesprite(laststatusx, laststatusy, laststatustile, 0, nStat, nPal);
nFrameBase++;
}
}
short seq_GetFrameFlag(short val, short nFrame)
{
return FrameFlag[SeqBase[val] + nFrame];
@ -677,7 +635,6 @@ static SavegameHelper sgh("sequence",
SV(nPilotLightFrame),
SV(nPilotLightCount),
SV(nPilotLightBase),
SV(laststatustile),
SV(nShadowWidth),
SV(nFlameHeight),
nullptr);

View File

@ -124,11 +124,17 @@ extern short nFlameHeight;
extern short nPilotLightFrame;
extern short nPilotLightCount;
extern short laststatustile;
extern int laststatusx;
extern int laststatusy;
extern short ChunkYpos[];
extern short ChunkXpos[];
extern short ChunkPict[];
extern short ChunkFlag[];
extern short FrameSize[];
extern short FrameBase[];
void seq_LoadSequences();
int seq_GetFrameSound(int val, int edx);
void seq_MoveSequence(short nSprite, short nSeq, short bx);

View File

@ -88,9 +88,6 @@ void DestroySnake(int nSnake)
if (nSnake == nSnakeCam)
{
nSnakeCam = -1;
if (!bFullScreen) {
RefreshStatus();
}
}
}

View File

@ -24,6 +24,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "sequence.h"
#include "names.h"
#include "view.h"
#include "v_2ddrawer.h"
#include "multipatchtexture.h"
#include "texturemanager.h"
#include "statusbar.h"
#include "v_draw.h"
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
@ -31,6 +36,107 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_PS_NS
void InitFonts()
{
GlyphSet fontdata;
fontdata.Insert(127, TexMan.FindGameTexture("TINYBLAK")); // this is only here to widen the color range of the font to produce a better translation.
auto tile = tileGetTexture(159);
auto pixels = tile->GetTexture()->Get8BitPixels(false);
// Convert the sheet font to a proportional font by checking the actual character sizes.
for (int i = 1; i < 128; i++)
{
int xpos = (i % 16) * 8;
int ypos = (i / 16) * 8;
bool rowset[8]{};
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
{
int pixel = pixels[xpos + x + 128 * (ypos + y)];
if (pixel)
{
rowset[x] = true;
break;
}
}
}
int left = 0;
int right = 7;
while (left <= right)
{
bool didit = false;
if (!rowset[left]) left++, didit = true;
if (!rowset[right]) right--, didit = true;
if (!didit) break;
}
if (left < right)
{
xpos += left;
int width = right - left + 1;
int height = 8;
TArray<TexPartBuild> part(1, true);
part[0].OriginX = -xpos;
part[0].OriginY = -ypos;
part[0].TexImage = static_cast<FImageTexture*>(tile->GetTexture());
FMultiPatchTexture* image = new FMultiPatchTexture(width, height, part, false, false);
FImageTexture* tex = new FImageTexture(image);
auto gtex = MakeGameTexture(tex, nullptr, ETextureType::FontChar);
gtex->SetWorldPanning(true);
gtex->SetOffsets(0, 0, 0);
gtex->SetOffsets(1, 0, 0);
TexMan.AddGameTexture(gtex);
fontdata.Insert(i, gtex);
}
}
SmallFont2 = new ::FFont("SmallFont2", nullptr, "defsmallfont2", 0, 0, 0, -1, 4, false, false, false, &fontdata);
SmallFont2->SetKerning(1);
fontdata.Clear();
for (int i = 0; i < 26; i++)
{
fontdata.Insert('A' + i, tileGetTexture(3522 + i));
}
for (int i = 0; i < 10; i++)
{
fontdata.Insert('0' + i, tileGetTexture(3555 + i));
}
fontdata.Insert('.', tileGetTexture(3548));
fontdata.Insert('!', tileGetTexture(3549));
fontdata.Insert('?', tileGetTexture(3550));
fontdata.Insert(',', tileGetTexture(3551));
fontdata.Insert('`', tileGetTexture(3552));
fontdata.Insert('"', tileGetTexture(3553));
fontdata.Insert('-', tileGetTexture(3554));
fontdata.Insert('_', tileGetTexture(3554));
fontdata.Insert(127, TexMan.FindGameTexture("TINYBLAK")); // this is only here to widen the color range of the font to produce a better translation.
GlyphSet::Iterator it(fontdata);
GlyphSet::Pair* pair;
while (it.NextPair(pair)) pair->Value->SetOffsetsNotForFont();
SmallFont = new ::FFont("SmallFont", nullptr, "defsmallfont", 0, 0, 0, -1, 4, false, false, false, &fontdata);
SmallFont->SetKerning(1);
fontdata.Clear();
}
// All this must be moved into the status bar once it is made persistent!
const int kMaxStatusAnims = 50;
short word_9AD54[kMaxPlayers] = { 0, 0, 0, 0, 0, 0, 0, 0 };
int dword_9AD64[kMaxPlayers] = { 0, 0, 0, 0, 0, 0, 0, 0 };
short nStatusSeqOffset;
short nHealthFrames;
short nMagicFrames;
short nHealthLevel;
short nMagicLevel;
short nHealthFrame;
short nMagicFrame;
short nMaskY;
static short nAnimsFree = 0;
@ -45,26 +151,16 @@ int nAirFrames;
int nCounter;
int nCounterDest;
short nStatusSeqOffset;
short nItemFrames;
int laststatusx;
int laststatusy;
int16_t nItemSeq;
short nDigit[3];
short nMagicFrames;
short nHealthLevel;
short nItemFrame;
short nMeterRange;
short nMagicLevel;
short nHealthFrame;
short nMagicFrame;
short statusx;
short statusy;
short nHealthFrames;
short airframe;
@ -89,7 +185,6 @@ struct statusAnim
int8_t nNextAnim;
};
#define kMaxStatusAnims 50
statusAnim StatusAnim[kMaxStatusAnims];
uint8_t StatusAnimsFree[kMaxStatusAnims];
@ -97,15 +192,50 @@ uint8_t StatusAnimFlags[kMaxStatusAnims];
short nItemSeqOffset[] = {91, 72, 76, 79, 68, 87, 83};
short word_9AD54[kMaxPlayers] = {0, 0, 0, 0, 0, 0, 0, 0};
int dword_9AD64[kMaxPlayers] = {0, 0, 0, 0, 0, 0, 0, 0};
void SetCounterDigits();
void SetItemSeq();
void SetItemSeq2(int nSeqOffset);
void DestroyStatusAnim(short nAnim);
void InitStatus()
{
nStatusSeqOffset = SeqOffsets[kSeqStatus];
nHealthFrames = SeqSize[nStatusSeqOffset + 1];
int nPicNum = seq_GetSeqPicnum(kSeqStatus, 1, 0);
nMagicFrames = SeqSize[nStatusSeqOffset + 129];
nHealthFrame = 0;
nMagicFrame = 0;
nHealthLevel = 0;
nMagicLevel = 0;
nMeterRange = tilesiz[nPicNum].y;
magicperline = 1000 / nMeterRange;
healthperline = 800 / nMeterRange;
nAirFrames = SeqSize[nStatusSeqOffset + 133];
airperline = 100 / nAirFrames;
nCounter = 0;
nCounterDest = 0;
memset(nDigit, 0, sizeof(nDigit));
SetCounter(0);
SetHealthFrame(0);
SetMagicFrame();
for (int i = 0; i < kMaxStatusAnims; i++) {
StatusAnimsFree[i] = i;
}
nLastAnim = -1;
nFirstAnim = -1;
nItemSeq = -1;
nAnimsFree = kMaxStatusAnims;
statusx = xdim - 320;
message_timer = 0;
statusy = ydim - 200;
}
int BuildStatusAnim(int val, int nFlags)
{
// destroy this anim if it already exists
@ -147,7 +277,8 @@ void RefreshStatus()
{
short nLives = nPlayerLives[nLocalPlayer];
if (nLives < 0 || nLives > kMaxPlayerLives) {
I_Error("illegal value for nPlayerLives #%d\n", nLocalPlayer);
//Error("illegal value for nPlayerLives #%d\n", nLocalPlayer);
nLives = 0;
}
// draws the red dots that indicate the lives amount
@ -173,44 +304,6 @@ void RefreshStatus()
SetAirFrame();
}
void InitStatus()
{
nStatusSeqOffset = SeqOffsets[kSeqStatus];
nHealthFrames = SeqSize[nStatusSeqOffset + 1];
int nPicNum = seq_GetSeqPicnum(kSeqStatus, 1, 0);
nMagicFrames = SeqSize[nStatusSeqOffset + 129];
nHealthFrame = 0;
nMagicFrame = 0;
nHealthLevel = 0;
nMagicLevel = 0;
nMeterRange = tilesiz[nPicNum].y;
magicperline = 1000 / nMeterRange;
healthperline = 800 / nMeterRange;
nAirFrames = SeqSize[nStatusSeqOffset + 133];
airperline = 100 / nAirFrames;
nCounter = 0;
nCounterDest = 0;
memset(nDigit, 0, sizeof(nDigit));
SetCounter(0);
SetHealthFrame(0);
SetMagicFrame();
for (int i = 0; i < kMaxStatusAnims; i++) {
StatusAnimsFree[i] = i;
}
nLastAnim = -1;
nFirstAnim = -1;
nItemSeq = -1;
nAnimsFree = kMaxStatusAnims;
statusx = xdim - 320;
textpages = 0;
message_timer = 0;
statusy = ydim - 200;
}
void MoveStatusAnims()
{
for (int i = nFirstAnim; i >= 0; i = StatusAnim[i].nPrevAnim)
@ -258,29 +351,6 @@ void DestroyStatusAnim(short nAnim)
nAnimsFree++;
}
void DrawStatusAnims()
{
for (int i = nFirstAnim; i >= 0; i = StatusAnim[i].nPrevAnim)
{
int nSequence = nStatusSeqOffset + StatusAnim[i].s1;
//seq_DrawStatusSequence(nSequence, StatusAnim[i].s2, 0);
/*
if (StatusAnim[nAnim].s2 >= (SeqSize[nSequence] - 1))
{
if (!(StatusAnimFlags[nAnim] & 0x10))
{
StatusAnim[nAnim].nPage--;
if (StatusAnim[nAnim].nPage <= 0) {
DestroyStatusAnim(nAnim);
}
}
}
*/
}
}
void SetMagicFrame()
{
nMagicLevel = (1000 - PlayerList[nLocalPlayer].nMagic) / magicperline;
@ -483,10 +553,6 @@ void MoveStatus()
message_timer -= 4;
if (message_timer <= 0)
{
if (screensize > 0) {
textpages = numpages;
}
message_timer = 0;
}
}
@ -584,269 +650,336 @@ void MoveStatus()
}
}
void UnMaskStatus()
{
#if 0
for (int i = 0; i < xdim; i++) {
startdmost[i] = ydim;
}
#endif
}
void MaskStatus()
{
#if 0
for (int i = 0; i < xdim; i++)
{
short bx = startdmost[i];
short cx = statusmask[i];
if (bx > cx) {
startdmost[i] = cx;
}
}
#endif
}
void LoadStatus()
{
#if 0
int i;
short nSize;
short tmp;
short buffer[1024];
// memset(buffer, 0, sizeof(buffer)); // bjd - added by me
for (i = 0; i < xdim; i++) {
statusmask[i] = ydim;
}
nMaskY = ydim;
int hStatus = kopen4load("status.msk", 1);
if (!hStatus) {
return;
}
kread(hStatus, &nSize, sizeof(nSize));
int nCount = nSize >> 1;
kread(hStatus, &tmp, sizeof(tmp));
kread(hStatus, buffer, nSize);
kclose(hStatus);
short *pStatusMask = statusmask;
for (i = 0; i < nCount; i++)
{
int v8 = ydim - ((ydim * buffer[i]) / 200);
*pStatusMask++ = ydim - v8;
if (bHiRes) {
*pStatusMask++ = ydim - v8;
}
if (ydim - v8 < nMaskY) {
nMaskY = ydim - v8;
}
}
#endif
}
void StatusMessage(int messageTime, const char *fmt, ...)
{
message_timer = messageTime;
va_list args;
va_start(args, fmt);
vsprintf(message_text, fmt, args);
if (screensize > 0) {
textpages = numpages;
}
}
void DrawSnakeCamStatus()
{
printext(0, 0, "S E R P E N T C A M", kTile159, 255);
}
void DrawStatus()
class DExhumedStatusBar : public DBaseStatusBar
{
char numberBuf[10] = {0};
char stringBuf[20] = {0};
char coordBuf[50] = {0}; // not sure of the size for this?
DHUDFont textfont;
if (!bFullScreen && nNetTime)
public:
DExhumedStatusBar()
{
// bjd - commenting out this check seems to fix the black status bar at 320x200 resolution
// if (bHiRes) {
NoClip();
// }
// draw the main bar itself
seq_DrawStatusSequence(nStatusSeqOffset, 0, 0);
seq_DrawStatusSequence(nStatusSeqOffset + 128, 0, 0);
seq_DrawStatusSequence(nStatusSeqOffset + 127, 0, 0);
seq_DrawStatusSequence(nStatusSeqOffset + 1, nHealthFrame, nHealthLevel);
seq_DrawStatusSequence(nStatusSeqOffset + 129, nMagicFrame, nMagicLevel);
seq_DrawStatusSequence(nStatusSeqOffset + 125, 0, 0); // draw ankh on health pool
seq_DrawStatusSequence(nStatusSeqOffset + 130, 0, 0); // draw health pool frame (top)
seq_DrawStatusSequence(nStatusSeqOffset + 131, 0, 0); // magic pool frame (bottom)
if (nItemSeq >= 0) {
seq_DrawStatusSequence(nItemSeq + nStatusSeqOffset, nItemFrame, 0);
}
// draws health level dots, animates breathing lungs and other things
DrawStatusAnims();
// draw the blue air level meter when underwater (but not responsible for animating the breathing lungs otherwise)
if (airpages)
{
seq_DrawStatusSequence(nStatusSeqOffset + 133, airframe, 0);
// airpages--;
}
// draw compass
seq_DrawStatusSequence(nStatusSeqOffset + 35, ((inita + 128) & kAngleMask) >> 8, 0);
/*
if (bCoordinates)
{
sprintf(numberBuf, "%i", lastfps);
// char *cFPS = itoa(lastfps, numberBuf, 10);
printext(xdim - 20, nViewTop, numberBuf, kTile159, -1);
}
*/
// draw ammo count
seq_DrawStatusSequence(nStatusSeqOffset + 44, nDigit[2], 0);
seq_DrawStatusSequence(nStatusSeqOffset + 45, nDigit[1], 0);
seq_DrawStatusSequence(nStatusSeqOffset + 46, nDigit[0], 0);
// bjd - commenting out this check seems to fix the black status bar at 320x200 resolution
// if (bHiRes) {
Clip();
// }
textfont = { SmallFont2, 1, Off, 1, 1 };
}
if (nNetPlayerCount)
private:
//---------------------------------------------------------------------------
//
// draws a sequence animation to the status bar
//
//---------------------------------------------------------------------------
void DrawStatusSequence(short nSequence, uint16_t edx, short ebx, int xoffset = 0)
{
NoClip();
edx += SeqBase[nSequence];
int shade;
short nFrameBase = FrameBase[edx];
int16_t nFrameSize = FrameSize[edx];
if ((int)totalclock / kTimerTicks & 1) {
shade = -100;
}
else {
shade = 127;
}
int nTile = kTile3593;
int x = 320 / (nTotalPlayers + 1);
for (int i = 0; i < nTotalPlayers; i++)
while (1)
{
int nScore = nPlayerScore[i];
if (word_9AD54[i] == nScore)
nFrameSize--;
if (nFrameSize < 0)
break;
int flags = DI_ITEM_RELCENTER;
int x = ChunkXpos[nFrameBase];
int y = ChunkYpos[nFrameBase] + ebx;
if (hud_size <= Hud_StbarOverlay)
{
int v9 = dword_9AD64[i];
if (v9 && v9 <= (int)totalclock) {
dword_9AD64[i] = 0;
}
x += 160;
y += 100;
}
else
{
word_9AD54[i] = nScore;
dword_9AD64[i] = (int)totalclock + 30;
if (x < 0)
{
x += 160;
flags |= DI_SCREEN_LEFT_BOTTOM;
}
else if (x > 0)
{
x -= 159; // graphics do not match up precisely.
flags |= DI_SCREEN_RIGHT_BOTTOM;
}
y -= 100;
if (hud_size == Hud_full)
{
x += xoffset;
}
}
overwritesprite(x, 7, nTile, 0, 3, kPalNormal);
int tile = ChunkPict[nFrameBase];
if (i != nLocalPlayer) {
short chunkFlag = ChunkFlag[nFrameBase];
if (chunkFlag & 1) flags |= DI_MIRROR;
if (chunkFlag & 2) flags |= DI_MIRRORY;
DrawGraphic(tileGetTexture(tile), x, y, flags, 1, -1, -1, 1, 1);
//overwritesprite(x, y, tile, 0, nStat, 0);
nFrameBase++;
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DrawStatusAnims()
{
for (int i = nFirstAnim; i >= 0; i = StatusAnim[i].nPrevAnim)
{
int nSequence = nStatusSeqOffset + StatusAnim[i].s1;
int xoffs = 0;
if (StatusAnim[i].s1 == 132) xoffs = -32;
DrawStatusSequence(nSequence, StatusAnim[i].s2, 0, xoffs);
/*
if (StatusAnim[nAnim].s2 >= (SeqSize[nSequence] - 1))
{
if (!(StatusAnimFlags[nAnim] & 0x10))
{
StatusAnim[nAnim].nPage--;
if (StatusAnim[nAnim].nPage <= 0) {
DestroyStatusAnim(nAnim);
}
}
}
*/
}
}
//---------------------------------------------------------------------------
//
// Frag display - very ugly and may have to be redone if multiplayer suppoer gets added.
//
//---------------------------------------------------------------------------
void DrawMulti()
{
char stringBuf[30];
if (nNetPlayerCount)
{
BeginHUD(320, 200, 1);
int shade;
if ((int)totalclock / kTimerTicks & 1) {
shade = -100;
}
else {
shade = 127;
}
sprintf(stringBuf, "%d", nPlayerScore[i]);
int nStringLen = MyGetStringWidth(stringBuf);
int nTile = kTile3593;
myprintext(x - (nStringLen / 2), 4, stringBuf, shade);
int xx = 320 / (nTotalPlayers + 1);
int x = xx - 160;
x *= 2;
nTile++;
}
if (nNetTime >= 0)
{
int y = nViewTop;
if (nNetTime)
for (int i = 0; i < nTotalPlayers; i++)
{
int v12 = (nNetTime + 29) / 30 % 60;
int v13 = (nNetTime + 29) / 1800;
nNetTime += 29;
sprintf(stringBuf, "%d.%02d", v13, v12);
if (bHiRes) {
y = nViewTop / 2;
int nScore = nPlayerScore[i];
if (word_9AD54[i] == nScore)
{
int v9 = dword_9AD64[i];
if (v9 && v9 <= (int)totalclock) {
dword_9AD64[i] = 0;
}
}
else
{
word_9AD54[i] = nScore;
dword_9AD64[i] = (int)totalclock + 30;
}
if (nViewTop <= 0) {
DrawGraphic(tileGetTexture(nTile), x, 7, DI_ITEM_TOP|DI_MIRROR|DI_MIRRORY, 1, -1, -1, 1, 1);
if (i != nLocalPlayer) {
shade = -100;
}
sprintf(stringBuf, "%d", nPlayerScore[i]);
SBar_DrawString(this, &textfont, stringBuf, x, 0, DI_ITEM_TOP|DI_TEXT_ALIGN_CENTER, i != nLocalPlayer ? CR_UNTRANSLATED : CR_GOLD, 1, -1, 0, 1, 1);
x += xx;
nTile++;
}
if (nNetTime >= 0)
{
int y = 0;
if (nNetTime)
{
int v12 = (nNetTime + 29) / 30 % 60;
int v13 = (nNetTime + 29) / 1800;
nNetTime += 29;
sprintf(stringBuf, "%d.%02d", v13, v12);
y += 20;
nNetTime -= 29;
SBar_DrawString(this, &textfont, stringBuf, 0, 10, DI_ITEM_TOP | DI_TEXT_ALIGN_LEFT, CR_UNTRANSLATED, 1, -1, 0, 1, 1);
}
else {
y += 15;
}
nNetTime -= 29;
}
else
{
y = 100;
strcpy(stringBuf, "GAME OVER");
}
int nLenString = MyGetStringWidth(stringBuf);
myprintext((320 - nLenString) / 2, y, stringBuf, 0);
}
}
//---------------------------------------------------------------------------
//
// draw the full status bar
//
//---------------------------------------------------------------------------
void DrawStatus()
{
BeginStatusBar(320, 200, 40);
char numberBuf[10] = { 0 };
char stringBuf[20] = { 0 };
char coordBuf[50] = { 0 }; // not sure of the size for this?
if (hud_size <= Hud_StbarOverlay)
{
// draw the main bar itself
BeginStatusBar(320, 200, 40);
DrawStatusSequence(nStatusSeqOffset, 0, 0);
}
else if (hud_size == Hud_Mini)
{
auto lh = TexMan.GetGameTextureByName("hud_l");
auto rh = TexMan.GetGameTextureByName("hud_r");
BeginHUD(320, 200, 1);
if (lh) DrawGraphic(lh, 0, 0, DI_ITEM_LEFT_BOTTOM | DI_SCREEN_LEFT_BOTTOM, 1, -1, -1, 1, 1);
if (rh) DrawGraphic(rh, 0, 0, DI_ITEM_RIGHT_BOTTOM | DI_SCREEN_RIGHT_BOTTOM, 1, -1, -1, 1, 1);
}
else if (hud_size == Hud_full)
{
BeginHUD(320, 200, 1);
}
Clip();
}
if (/*!bFullScreen &&*/ nNetTime)
{
DrawStatusSequence(nStatusSeqOffset + 127, 0, 0, -4);
DrawStatusSequence(nStatusSeqOffset + 129, nMagicFrame, nMagicLevel, -4);
DrawStatusSequence(nStatusSeqOffset + 131, 0, 0, -4); // magic pool frame (bottom)
if (bCoordinates)
{
int nSprite = PlayerList[nLocalPlayer].nSprite;
DrawStatusSequence(nStatusSeqOffset + 128, 0, 0, 4);
DrawStatusSequence(nStatusSeqOffset + 1, nHealthFrame, nHealthLevel, 4);
DrawStatusSequence(nStatusSeqOffset + 125, 0, 0, 4); // draw ankh on health pool
DrawStatusSequence(nStatusSeqOffset + 130, 0, 0, 4); // draw health pool frame (top)
int x = (nViewLeft + nViewRight) / 2;
if (nItemSeq >= 0) {
DrawStatusSequence(nItemSeq + nStatusSeqOffset, nItemFrame, 0);
}
// draw the blue air level meter when underwater (but not responsible for animating the breathing lungs otherwise)
DrawStatusSequence(nStatusSeqOffset + 133, airframe, 0, -32);
snprintf(coordBuf, 50, "X %d", (int)sprite[nSprite].x);
printext(x, nViewTop + 1, coordBuf, kTile159, 255);
// draws health level dots, animates breathing lungs and other things
DrawStatusAnims();
snprintf(coordBuf, 50, "Y %d", sprite[nSprite].y);
printext(x, nViewTop + 10, coordBuf, kTile159, 255);
}
if (bHolly)
{
snprintf(message_text, 80, "HOLLY: %s", sHollyStr);
printext(0, 0, message_text, kTile159, 255);
}
else if (nSnakeCam < 0)
{
if (message_timer) {
// draw compass
if (hud_size <= Hud_StbarOverlay) DrawStatusSequence(nStatusSeqOffset + 35, ((inita + 128) & kAngleMask) >> 8, 0);
//if (hud_size < Hud_full)
{
// draw ammo count
DrawStatusSequence(nStatusSeqOffset + 44, nDigit[2], 0, -35);
DrawStatusSequence(nStatusSeqOffset + 45, nDigit[1], 0, -35);
DrawStatusSequence(nStatusSeqOffset + 46, nDigit[0], 0, -35);
}
}
DrawMulti();
#if 0
if (bCoordinates)
{
int nSprite = PlayerList[nLocalPlayer].nSprite;
int x = 160;
snprintf(coordBuf, 50, "X %d", (int)sprite[nSprite].x);
printext(x, 1, coordBuf, kTile159, 255);
snprintf(coordBuf, 50, "Y %d", sprite[nSprite].y);
printext(x, 10, coordBuf, kTile159, 255);
}
if (bHolly)
{
snprintf(message_text, 80, "HOLLY: %s", sHollyStr);
printext(0, 0, message_text, kTile159, 255);
}
else if (nSnakeCam < 0)
{
if (message_timer) {
printext(0, 0, message_text, kTile159, 255);
}
}
#endif
}
public:
void Draw()
{
if (hud_size <= Hud_full)
{
DrawStatus();
}
}
};
void UpdateFrame()
{
auto tex = tileGetTexture(nBackgroundPic);
twod->AddFlatFill(0, 0, xdim, windowxy1.y - 3, tex);
twod->AddFlatFill(0, windowxy2.y + 4, xdim, ydim, tex);
twod->AddFlatFill(0, windowxy1.y - 3, windowxy1.x - 3, windowxy2.y + 4, tex);
twod->AddFlatFill(windowxy2.x + 4, windowxy1.y - 3, xdim, windowxy2.y + 4, tex);
twod->AddFlatFill(windowxy1.x - 3, windowxy1.y - 3, windowxy1.x, windowxy2.y + 1, tex, 0, 1, 0xff545454);
twod->AddFlatFill(windowxy1.x, windowxy1.y - 3, windowxy2.x + 4, windowxy1.y, tex, 0, 1, 0xff545454);
twod->AddFlatFill(windowxy2.x + 1, windowxy1.y, windowxy2.x + 4, windowxy2.y + 4, tex, 0, 1, 0xff2a2a2a);
twod->AddFlatFill(windowxy1.x - 3, windowxy2.y + 1, windowxy2.x + 1, windowxy2.y + 4, tex, 0, 1, 0xff2a2a2a);
}
void StatusMessage(int messageTime, const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
VPrintf(PRINT_NOTIFY, fmt, ap);
Printf(PRINT_NOTIFY, "\n");
va_end(ap);
}
void DrawStatusBar()
{
if (hud_size <= Hud_Stbar)
{
UpdateFrame();
}
DExhumedStatusBar sbar;
sbar.Draw();
}
#if 0
// I'm not sure this really needs to be saved.
static SavegameHelper sgh("status",
SV(nMaskY),
@ -858,7 +991,6 @@ static SavegameHelper sgh("status",
SV(nAirFrames),
SV(nCounter),
SV(nCounterDest),
SV(nStatusSeqOffset),
SV(nItemFrames),
SV(laststatusx),
SV(laststatusy),
@ -872,7 +1004,6 @@ static SavegameHelper sgh("status",
SV(nMagicFrame),
SV(statusx),
SV(statusy),
SV(nHealthFrames),
SV(airframe),
SV(nFirstAnim),
SV(nLastAnim),
@ -887,9 +1018,7 @@ static SavegameHelper sgh("status",
SA(StatusAnimsFree),
SA(StatusAnimFlags),
SA(nItemSeqOffset),
SA(word_9AD54),
SA(dword_9AD64),
nullptr);
#endif
END_PS_NS

View File

@ -28,9 +28,6 @@ extern short airpages;
void RefreshStatus();
void InitStatus();
void UnMaskStatus();
void MaskStatus();
void LoadStatus();
void SetPlayerItem(short nPlayer, short nItem);
void SetMagicFrame();
void SetHealthFrame(short nVal);

View File

@ -42,6 +42,7 @@ int nCamerax;
int nCameray;
int nCameraz;
short bTouchFloor;
short nQuake[kMaxPlayers] = { 0 };
@ -51,15 +52,8 @@ short nChunkTotal = 0;
fix16_t nCameraa;
fix16_t nCamerapan;
short nViewTop;
short bClip = false;
short nViewBottom;
short nViewRight;
short besttarget;
short nViewLeft;
short bCamera = false;
short nViewy;
int viewz;
short enemy;
@ -128,10 +122,7 @@ void viewRestoreInterpolations(void) //Stick at end of drawscreen
void InitView()
{
screensize = 0;
#ifdef USE_OPENGL
polymostcenterhoriz = 92;
#endif
}
// NOTE - not to be confused with Ken's analyzesprites()
@ -237,86 +228,12 @@ void ResetView()
#ifdef USE_OPENGL
videoTintBlood(0, 0, 0);
#endif
LoadStatus();
}
void SetView1()
{
}
void RefreshBackground()
{
if (screensize <= 0)
return;
int nTileOffset = 0;
int tileX = tilesiz[nBackgroundPic].x;
int tileY = tilesiz[nBackgroundPic].y;
videoSetViewableArea(0, 0, xdim - 1, ydim - 1);
MaskStatus();
for (int y = 0; y < nViewTop; y += tileY)
{
nTileOffset = (y/tileY)&1;
for (int x = 0; x < xdim; x += tileX)
{
rotatesprite(x<<16, y<<16, 65536L, 0, nBackgroundPic + nTileOffset, -32, kPalNormal, 8 + 16 + 64, 0, 0, xdim-1, nViewTop-1);
nTileOffset ^= 1;
}
}
for (int y = (nViewTop/tileY)*tileY; y <= nViewBottom; y += tileY)
{
nTileOffset = (y/tileY)&1;
for (int x = 0; x < nViewLeft; x += tileX)
{
rotatesprite(x<<16, y<<16, 65536L, 0, nBackgroundPic + nTileOffset, -32, kPalNormal, 8 + 16 + 64, 0, nViewTop, nViewLeft-1, nViewBottom);
nTileOffset ^= 1;
}
}
for (int y = (nViewTop/tileY)*tileY; y <= nViewBottom; y += tileY)
{
nTileOffset = ((y/tileY)^((nViewRight+1)/tileX))&1;
for (int x = ((nViewRight+1)/tileX)*tileX; x < xdim; x += tileX)
{
rotatesprite(x<<16, y<<16, 65536L, 0, nBackgroundPic + nTileOffset, -32, kPalNormal, 8 + 16 + 64, nViewRight+1, nViewTop, xdim-1, nViewBottom);
nTileOffset ^= 1;
}
}
for (int y = ((nViewBottom+1)/tileY)*tileY; y < ydim; y += tileY)
{
nTileOffset = (y/tileY)&1;
for (int x = 0; x < xdim; x += tileX)
{
rotatesprite(x<<16, y<<16, 65536L, 0, nBackgroundPic + nTileOffset, -32, kPalNormal, 8 + 16 + 64, 0, nViewBottom+1, xdim-1, ydim-1);
nTileOffset ^= 1;
}
}
videoSetViewableArea(nViewLeft, nViewTop, nViewRight, nViewBottom);
}
void MySetView(int x1, int y1, int x2, int y2)
{
if (!bFullScreen) {
MaskStatus();
}
nViewLeft = x1;
nViewTop = y1;
nViewRight = x2;
nViewBottom = y2;
videoSetViewableArea(x1, y1, x2, y2);
nViewy = y1;
}
// unused function
void TestLava()
{
}
static inline int interpolate16(int a, int b, int smooth)
{
@ -332,16 +249,6 @@ void DrawView(int smoothRatio, bool sceneonly)
fix16_t nAngle;
fix16_t pan;
if (!sceneonly)
{
RefreshBackground();
if (!bFullScreen) {
MaskStatus();
}
}
zbob = Sin(2 * bobangle) >> 3;
int nPlayerSprite = PlayerList[nLocalPlayer].nSprite;
@ -359,7 +266,6 @@ void DrawView(int smoothRatio, bool sceneonly)
nAngle = fix16_from_int(sprite[nSprite].ang);
SetGreenPal();
UnMaskStatus();
enemy = SnakeList[nSnakeCam].nEnemy;
@ -445,7 +351,6 @@ void DrawView(int smoothRatio, bool sceneonly)
{
nSnakeCam = -1;
videoSetViewableArea(0, 0, xdim - 1, ydim - 1);
UnMaskStatus();
}
UpdateMap();
@ -547,8 +452,6 @@ void DrawView(int smoothRatio, bool sceneonly)
fadecdaudio();
}
}
videoSetViewableArea(nViewLeft, nViewTop, nViewRight, nViewBottom);
}
}
}
@ -558,7 +461,6 @@ void DrawView(int smoothRatio, bool sceneonly)
{
DrawWeapons(smoothRatio);
DrawMap();
DrawStatus();
}
else
{
@ -569,10 +471,6 @@ void DrawView(int smoothRatio, bool sceneonly)
DrawMap();
if (!bFullScreen) {
MaskStatus();
}
DrawSnakeCamStatus();
}
}
@ -580,7 +478,6 @@ void DrawView(int smoothRatio, bool sceneonly)
else
{
twod->ClearScreen();
DrawStatus();
}
sprite[nPlayerSprite].cstat = nPlayerOldCstat;
@ -597,19 +494,10 @@ bool GameInterface::GenerateSavePic()
void NoClip()
{
videoSetViewableArea(0, 0, xdim - 1, ydim - 1);
bClip = false;
}
void Clip()
{
videoSetViewableArea(nViewLeft, nViewTop, nViewRight, nViewBottom);
if (!bFullScreen) {
MaskStatus();
}
bClip = true;
}
@ -621,14 +509,7 @@ static SavegameHelper sgh("view",
SV(nChunkTotal),
SV(nCameraa),
SV(nCamerapan),
SV(nViewTop),
SV(bClip),
SV(nViewBottom),
SV(nViewRight),
SV(besttarget),
SV(nViewLeft),
SV(bCamera),
SV(nViewy),
SV(viewz),
SV(enemy),
SV(nEnemyPal),

View File

@ -24,19 +24,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_PS_NS
extern short bSubTitles;
extern short nViewTop;
extern short bClip;
extern short nViewBottom;
extern short nViewRight;
extern short nViewLeft;
extern short besttarget;
extern short bCamera;
void InitView();
void SetView1();
void RefreshBackground();
void DrawStatusBar();
void DrawView(int smoothRatio, bool sceneonly = false);
void MySetView(int x1, int y1, int x2, int y2);
void ResetView();
void NoClip();
void Clip();

View File

@ -261,11 +261,6 @@ void DrawBorder()
twod->AddFlatFill(x1, y2 - 4, x1 + 4, y2, ve, 2);
twod->AddFlatFill(x2 - 4, y2 - 4, x2, y2, ve, 4);
}
else
{
// If we got no frame just clear the screen.
twod->ClearScreen();
}
}
//==========================================================================

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB