mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-23 04:22:34 +00:00
- started scriptifying the level intermission screen. This compiles but is not active yet.
- allow treatment as one-character string constants as character constants. This became necessary because name constants already use single quotes and are much harder to repurpose due to a higher degree of ambiguity. - fixed: protected methods in structs were not usable.
This commit is contained in:
parent
ce3c397ec7
commit
1e9ef2b1df
7 changed files with 530 additions and 14 deletions
|
@ -58,6 +58,7 @@
|
||||||
|
|
||||||
extern FRandom pr_exrandom;
|
extern FRandom pr_exrandom;
|
||||||
FMemArena FxAlloc(65536);
|
FMemArena FxAlloc(65536);
|
||||||
|
int utf8_decode(const char *src, int *size);
|
||||||
|
|
||||||
struct FLOP
|
struct FLOP
|
||||||
{
|
{
|
||||||
|
@ -304,6 +305,36 @@ static bool AreCompatiblePointerTypes(PType *dest, PType *source, bool forcompar
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static FxExpression *StringConstToChar(FxExpression *basex)
|
||||||
|
{
|
||||||
|
if (!basex->isConstant()) return false;
|
||||||
|
// Allow single character string literals be convertible to integers.
|
||||||
|
// This serves as workaround for not being able to use single quoted literals because those are taken for names.
|
||||||
|
ExpVal constval = static_cast<FxConstant *>(basex)->GetValue();
|
||||||
|
FString str = constval.GetString();
|
||||||
|
if (str.Len() == 1)
|
||||||
|
{
|
||||||
|
return new FxConstant(str[0], basex->ScriptPosition);
|
||||||
|
}
|
||||||
|
else if (str.Len() > 1)
|
||||||
|
{
|
||||||
|
// If the string is UTF-8, allow a single character UTF-8 sequence.
|
||||||
|
int size;
|
||||||
|
int c = utf8_decode(str.GetChars(), &size);
|
||||||
|
if (c >= 0 && size == str.Len())
|
||||||
|
{
|
||||||
|
return new FxConstant(str[0], basex->ScriptPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -908,6 +939,7 @@ FxExpression *FxIntCast::Resolve(FCompileContext &ctx)
|
||||||
{
|
{
|
||||||
CHECKRESOLVED();
|
CHECKRESOLVED();
|
||||||
SAFE_RESOLVE(basex, ctx);
|
SAFE_RESOLVE(basex, ctx);
|
||||||
|
int c;
|
||||||
|
|
||||||
if (basex->ValueType->GetRegType() == REGT_INT)
|
if (basex->ValueType->GetRegType() == REGT_INT)
|
||||||
{
|
{
|
||||||
|
@ -952,6 +984,17 @@ FxExpression *FxIntCast::Resolve(FCompileContext &ctx)
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
else if (basex->ValueType == TypeString && basex->isConstant())
|
||||||
|
{
|
||||||
|
FxExpression *x = StringConstToChar(basex);
|
||||||
|
if (x)
|
||||||
|
{
|
||||||
|
x->ValueType = ValueType;
|
||||||
|
basex = nullptr;
|
||||||
|
delete this;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
||||||
ScriptPosition.Message(MSG_ERROR, "Numeric type expected");
|
ScriptPosition.Message(MSG_ERROR, "Numeric type expected");
|
||||||
delete this;
|
delete this;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -3302,6 +3345,18 @@ FxExpression *FxCompareRel::Resolve(FCompileContext& ctx)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FxExpression *x;
|
||||||
|
if (left->IsNumeric() && right->ValueType == TypeString && (x = StringConstToChar(right)))
|
||||||
|
{
|
||||||
|
delete right;
|
||||||
|
right = x;
|
||||||
|
}
|
||||||
|
else if (right->IsNumeric() && left->ValueType == TypeString && (x = StringConstToChar(left)))
|
||||||
|
{
|
||||||
|
delete left;
|
||||||
|
left = x;
|
||||||
|
}
|
||||||
|
|
||||||
if (left->ValueType == TypeString || right->ValueType == TypeString)
|
if (left->ValueType == TypeString || right->ValueType == TypeString)
|
||||||
{
|
{
|
||||||
if (left->ValueType != TypeString)
|
if (left->ValueType != TypeString)
|
||||||
|
@ -3528,6 +3583,17 @@ FxExpression *FxCompareEq::Resolve(FCompileContext& ctx)
|
||||||
|
|
||||||
if (left->ValueType != right->ValueType) // identical types are always comparable, if they can be placed in a register, so we can save most checks if this is the case.
|
if (left->ValueType != right->ValueType) // identical types are always comparable, if they can be placed in a register, so we can save most checks if this is the case.
|
||||||
{
|
{
|
||||||
|
FxExpression *x;
|
||||||
|
if (left->IsNumeric() && right->ValueType == TypeString && (x = StringConstToChar(right)))
|
||||||
|
{
|
||||||
|
delete right;
|
||||||
|
right = x;
|
||||||
|
}
|
||||||
|
else if (right->IsNumeric() && left->ValueType == TypeString && (x = StringConstToChar(left)))
|
||||||
|
{
|
||||||
|
delete left;
|
||||||
|
left = x;
|
||||||
|
}
|
||||||
// Special cases: Compare strings and names with names, sounds, colors, state labels and class types.
|
// Special cases: Compare strings and names with names, sounds, colors, state labels and class types.
|
||||||
// These are all types a string can be implicitly cast into, so for convenience, so they should when doing a comparison.
|
// These are all types a string can be implicitly cast into, so for convenience, so they should when doing a comparison.
|
||||||
if ((left->ValueType == TypeString || left->ValueType == TypeName) &&
|
if ((left->ValueType == TypeString || left->ValueType == TypeName) &&
|
||||||
|
|
|
@ -206,10 +206,9 @@ PFunction *FindClassMemberFunction(PStruct *selfcls, PStruct *funccls, FName nam
|
||||||
// private access is only allowed if the symbol table belongs to the class in which the current function is being defined.
|
// private access is only allowed if the symbol table belongs to the class in which the current function is being defined.
|
||||||
sc.Message(MSG_ERROR, "%s is declared private and not accessible", symbol->SymbolName.GetChars());
|
sc.Message(MSG_ERROR, "%s is declared private and not accessible", symbol->SymbolName.GetChars());
|
||||||
}
|
}
|
||||||
else if ((funcsym->Variants[0].Flags & VARF_Protected) && (!cls_ctx || !cls_target || !cls_ctx->IsDescendantOf((PClass*)cls_target)))
|
else if ((funcsym->Variants[0].Flags & VARF_Protected) && symtable != &funccls->Symbols && (!cls_ctx || !cls_target || !cls_ctx->IsDescendantOf((PClass*)cls_target)))
|
||||||
{
|
{
|
||||||
sc.Message(MSG_ERROR, "%s is declared protected and not accessible", symbol->SymbolName.GetChars());
|
sc.Message(MSG_ERROR, "%s is declared protected and not accessible", symbol->SymbolName.GetChars());
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
else if (funcsym->Variants[0].Flags & VARF_Deprecated)
|
else if (funcsym->Variants[0].Flags & VARF_Deprecated)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1199,7 +1199,7 @@ DEFINE_ACTION_FUNCTION(_TexMan, GetSize)
|
||||||
{
|
{
|
||||||
PARAM_PROLOGUE;
|
PARAM_PROLOGUE;
|
||||||
PARAM_INT(texid);
|
PARAM_INT(texid);
|
||||||
auto tex = TexMan[FSetTextureID(texid)];
|
auto tex = TexMan.ByIndex(texid);
|
||||||
int x, y;
|
int x, y;
|
||||||
if (tex != nullptr)
|
if (tex != nullptr)
|
||||||
{
|
{
|
||||||
|
@ -1212,11 +1212,17 @@ DEFINE_ACTION_FUNCTION(_TexMan, GetSize)
|
||||||
return MIN(numret, 2);
|
return MIN(numret, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(_TexMan, GetScaledSize)
|
DEFINE_ACTION_FUNCTION(_TexMan, GetScaledSize)
|
||||||
{
|
{
|
||||||
PARAM_PROLOGUE;
|
PARAM_PROLOGUE;
|
||||||
PARAM_INT(texid);
|
PARAM_INT(texid);
|
||||||
auto tex = TexMan[FSetTextureID(texid)];
|
auto tex = TexMan.ByIndex(texid);
|
||||||
if (tex != nullptr)
|
if (tex != nullptr)
|
||||||
{
|
{
|
||||||
ACTION_RETURN_VEC2(DVector2(tex->GetScaledWidthDouble(), tex->GetScaledHeightDouble()));
|
ACTION_RETURN_VEC2(DVector2(tex->GetScaledWidthDouble(), tex->GetScaledHeightDouble()));
|
||||||
|
@ -1224,6 +1230,24 @@ DEFINE_ACTION_FUNCTION(_TexMan, GetScaledSize)
|
||||||
ACTION_RETURN_VEC2(DVector2(-1, -1));
|
ACTION_RETURN_VEC2(DVector2(-1, -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(_TexMan, CheckRealHeight)
|
||||||
|
{
|
||||||
|
PARAM_PROLOGUE;
|
||||||
|
PARAM_INT(texid);
|
||||||
|
auto tex = TexMan.ByIndex(texid);
|
||||||
|
if (tex != nullptr)
|
||||||
|
{
|
||||||
|
ACTION_RETURN_INT(tex->CheckRealHeight());
|
||||||
|
}
|
||||||
|
ACTION_RETURN_INT(-1);
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FTextureID::operator+
|
// FTextureID::operator+
|
||||||
|
|
|
@ -648,22 +648,22 @@ private:
|
||||||
struct FPatchInfo
|
struct FPatchInfo
|
||||||
{
|
{
|
||||||
FFont *mFont;
|
FFont *mFont;
|
||||||
FTexture *mPatch;
|
FTextureID mPatch;
|
||||||
EColorRange mColor;
|
EColorRange mColor;
|
||||||
|
|
||||||
void Init(FGIFont &gifont)
|
void Init(FGIFont &gifont)
|
||||||
{
|
{
|
||||||
if (gifont.color == NAME_Null)
|
if (gifont.color == NAME_Null)
|
||||||
{
|
{
|
||||||
mPatch = TexMan[gifont.fontname]; // "entering"
|
mPatch = TexMan.CheckForTexture(gifont.fontname, FTexture::TEX_MiscPatch);
|
||||||
mColor = mPatch == NULL ? CR_UNTRANSLATED : CR_UNDEFINED;
|
mColor = mPatch.isValid() ? CR_UNTRANSLATED : CR_UNDEFINED;
|
||||||
mFont = NULL;
|
mFont = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mFont = V_GetFont(gifont.fontname);
|
mFont = V_GetFont(gifont.fontname);
|
||||||
mColor = V_FindFontColor(gifont.color);
|
mColor = V_FindFontColor(gifont.color);
|
||||||
mPatch = NULL;
|
mPatch.SetNull();
|
||||||
}
|
}
|
||||||
if (mFont == NULL)
|
if (mFont == NULL)
|
||||||
{
|
{
|
||||||
|
@ -748,7 +748,7 @@ public:
|
||||||
FPatchInfo finished;
|
FPatchInfo finished;
|
||||||
FPatchInfo entering;
|
FPatchInfo entering;
|
||||||
|
|
||||||
FTextureID Sp_secret; // "secret"
|
FTextureID P_secret; // "secret"
|
||||||
FTextureID Kills; // "Kills", "Scrt", "Items", "Frags"
|
FTextureID Kills; // "Kills", "Scrt", "Items", "Frags"
|
||||||
FTextureID Secret;
|
FTextureID Secret;
|
||||||
FTextureID Items;
|
FTextureID Items;
|
||||||
|
@ -851,10 +851,11 @@ public:
|
||||||
const char *string = GStrings(stringname);
|
const char *string = GStrings(stringname);
|
||||||
int midx = screen->GetWidth() / 2;
|
int midx = screen->GetWidth() / 2;
|
||||||
|
|
||||||
if (pinfo->mPatch != NULL)
|
if (pinfo->mPatch.isValid())
|
||||||
{
|
{
|
||||||
screen->DrawTexture(pinfo->mPatch, midx - pinfo->mPatch->GetScaledWidth()*CleanXfac/2, y, DTA_CleanNoMove, true, TAG_DONE);
|
FTexture *tex = TexMan[pinfo->mPatch];
|
||||||
return y + (pinfo->mPatch->GetScaledHeight() * CleanYfac);
|
screen->DrawTexture(tex, midx - tex->GetScaledWidth()*CleanXfac/2, y, DTA_CleanNoMove, true, TAG_DONE);
|
||||||
|
return y + (tex->GetScaledHeight() * CleanYfac);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1883,7 +1884,7 @@ public:
|
||||||
screen->DrawTexture (TexMan[Items], SP_STATSX, SP_STATSY+lh, DTA_Clean, true, TAG_DONE);
|
screen->DrawTexture (TexMan[Items], SP_STATSX, SP_STATSY+lh, DTA_Clean, true, TAG_DONE);
|
||||||
WI_drawPercent (IntermissionFont, 320 - SP_STATSX, SP_STATSY+lh, cnt_items[0], wbs->maxitems);
|
WI_drawPercent (IntermissionFont, 320 - SP_STATSX, SP_STATSY+lh, cnt_items[0], wbs->maxitems);
|
||||||
|
|
||||||
screen->DrawTexture (TexMan[Sp_secret], SP_STATSX, SP_STATSY+2*lh, DTA_Clean, true, TAG_DONE);
|
screen->DrawTexture (TexMan[P_secret], SP_STATSX, SP_STATSY+2*lh, DTA_Clean, true, TAG_DONE);
|
||||||
WI_drawPercent (IntermissionFont, 320 - SP_STATSX, SP_STATSY+2*lh, cnt_secret[0], wbs->maxsecret);
|
WI_drawPercent (IntermissionFont, 320 - SP_STATSX, SP_STATSY+2*lh, cnt_secret[0], wbs->maxsecret);
|
||||||
|
|
||||||
screen->DrawTexture (TexMan[Timepic], SP_TIMEX, SP_TIMEY, DTA_Clean, true, TAG_DONE);
|
screen->DrawTexture (TexMan[Timepic], SP_TIMEX, SP_TIMEY, DTA_Clean, true, TAG_DONE);
|
||||||
|
@ -2024,7 +2025,7 @@ public:
|
||||||
{
|
{
|
||||||
Kills = TexMan.CheckForTexture("WIOSTK", FTexture::TEX_MiscPatch); // "kills"
|
Kills = TexMan.CheckForTexture("WIOSTK", FTexture::TEX_MiscPatch); // "kills"
|
||||||
Secret = TexMan.CheckForTexture("WIOSTS", FTexture::TEX_MiscPatch); // "scrt"
|
Secret = TexMan.CheckForTexture("WIOSTS", FTexture::TEX_MiscPatch); // "scrt"
|
||||||
Sp_secret = TexMan.CheckForTexture("WISCRT2", FTexture::TEX_MiscPatch); // "secret"
|
P_secret = TexMan.CheckForTexture("WISCRT2", FTexture::TEX_MiscPatch); // "secret"
|
||||||
Items = TexMan.CheckForTexture("WIOSTI", FTexture::TEX_MiscPatch); // "items"
|
Items = TexMan.CheckForTexture("WIOSTI", FTexture::TEX_MiscPatch); // "items"
|
||||||
Timepic = TexMan.CheckForTexture("WITIME", FTexture::TEX_MiscPatch); // "time"
|
Timepic = TexMan.CheckForTexture("WITIME", FTexture::TEX_MiscPatch); // "time"
|
||||||
Sucks = TexMan.CheckForTexture("WISUCKS", FTexture::TEX_MiscPatch); // "sucks"
|
Sucks = TexMan.CheckForTexture("WISUCKS", FTexture::TEX_MiscPatch); // "sucks"
|
||||||
|
@ -2147,3 +2148,41 @@ DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, sucktime);
|
||||||
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, totaltime);
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, totaltime);
|
||||||
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, pnum);
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, pnum);
|
||||||
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, plyr);
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, plyr);
|
||||||
|
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, acceleratestage);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, playerready);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, me);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, bcnt);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, state);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, wbs);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, Plrs);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, cnt);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, cnt_kills);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, cnt_items);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, cnt_secret);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, cnt_frags);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, cnt_deaths);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, cnt_time);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, cnt_total_time);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, cnt_par);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, cnt_pause);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, total_frags);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, total_deaths);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, noautostartmap);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, dofrags);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, ng_state);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, shadowalpha);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, mapname);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, finished);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, entering);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, P_secret);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, Kills);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, Secret);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, Items);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, Timepic);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, Par);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, Sucks);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, lnametexts);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, snl_pointeron);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, player_deaths);
|
||||||
|
DEFINE_FIELD(FIntermissionScreen, sp_state);
|
||||||
|
|
|
@ -27,6 +27,7 @@ version "2.4"
|
||||||
#include "zscript/menu/conversationmenu.txt"
|
#include "zscript/menu/conversationmenu.txt"
|
||||||
|
|
||||||
#include "zscript/statscreen/types.txt"
|
#include "zscript/statscreen/types.txt"
|
||||||
|
#include "zscript/statscreen/statscreen.txt"
|
||||||
|
|
||||||
#include "zscript/inventory/inventory.txt"
|
#include "zscript/inventory/inventory.txt"
|
||||||
#include "zscript/inventory/inv_misc.txt"
|
#include "zscript/inventory/inv_misc.txt"
|
||||||
|
|
|
@ -87,6 +87,7 @@ struct TexMan
|
||||||
native static void ReplaceTextures(String from, String to, int flags);
|
native static void ReplaceTextures(String from, String to, int flags);
|
||||||
native static int, int GetSize(TextureID tex);
|
native static int, int GetSize(TextureID tex);
|
||||||
native static Vector2 GetScaledSize(TextureID tex);
|
native static Vector2 GetScaledSize(TextureID tex);
|
||||||
|
native static int CheckRealHeight(TextureID tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum DrawTextureTags
|
enum DrawTextureTags
|
||||||
|
|
386
wadsrc/static/zscript/statscreen/statscreen.txt
Normal file
386
wadsrc/static/zscript/statscreen/statscreen.txt
Normal file
|
@ -0,0 +1,386 @@
|
||||||
|
|
||||||
|
struct PatchInfo
|
||||||
|
{
|
||||||
|
Font mFont;
|
||||||
|
TextureID mPatch;
|
||||||
|
int mColor;
|
||||||
|
|
||||||
|
void Init(GIFont gifont)
|
||||||
|
{
|
||||||
|
if (gifont.color == 'Null')
|
||||||
|
{
|
||||||
|
mPatch = TexMan.CheckForTexture(gifont.fontname, TexMan.Type_MiscPatch);
|
||||||
|
mColor = mPatch.isValid() ? Font.CR_UNTRANSLATED : Font.CR_UNDEFINED;
|
||||||
|
mFont = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mFont = Font.GetFont(gifont.fontname);
|
||||||
|
mColor = Font.FindFontColor(gifont.color);
|
||||||
|
mPatch.SetInvalid();
|
||||||
|
}
|
||||||
|
if (mFont == NULL)
|
||||||
|
{
|
||||||
|
mFont = BigFont;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Will be made a class later, but for now needs to mirror the internal version.
|
||||||
|
struct IntermissionScreen native
|
||||||
|
{
|
||||||
|
enum EValues
|
||||||
|
{
|
||||||
|
// GLOBAL LOCATIONS
|
||||||
|
WI_TITLEY = 2,
|
||||||
|
|
||||||
|
// SINGPLE-PLAYER STUFF
|
||||||
|
SP_STATSX = 50,
|
||||||
|
SP_STATSY = 50,
|
||||||
|
|
||||||
|
SP_TIMEX = 8,
|
||||||
|
SP_TIMEY = (200 - 32),
|
||||||
|
|
||||||
|
// NET GAME STUFF
|
||||||
|
NG_STATSY = 50,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// States for single-player
|
||||||
|
enum ESPState
|
||||||
|
{
|
||||||
|
SP_KILLS = 0,
|
||||||
|
SP_ITEMS = 2,
|
||||||
|
SP_SECRET = 4,
|
||||||
|
SP_FRAGS = 6,
|
||||||
|
SP_TIME = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
const SHOWNEXTLOCDELAY = 4; // in seconds
|
||||||
|
|
||||||
|
//FInterBackground *bg;
|
||||||
|
native int acceleratestage; // used to accelerate or skip a stage
|
||||||
|
native bool playerready[MAXPLAYERS];
|
||||||
|
native int me; // wbs.pnum
|
||||||
|
native int bcnt;
|
||||||
|
native int state; // specifies current state
|
||||||
|
native wbstartstruct wbs; // contains information passed into intermission
|
||||||
|
native wbplayerstruct Plrs[MAXPLAYERS]; // wbs.plyr[]
|
||||||
|
native int cnt; // used for general timing
|
||||||
|
native int cnt_kills[MAXPLAYERS];
|
||||||
|
native int cnt_items[MAXPLAYERS];
|
||||||
|
native int cnt_secret[MAXPLAYERS];
|
||||||
|
native int cnt_frags[MAXPLAYERS];
|
||||||
|
native int cnt_deaths[MAXPLAYERS];
|
||||||
|
native int cnt_time;
|
||||||
|
native int cnt_total_time;
|
||||||
|
native int cnt_par;
|
||||||
|
native int cnt_pause;
|
||||||
|
native int total_frags;
|
||||||
|
native int total_deaths;
|
||||||
|
native bool noautostartmap;
|
||||||
|
native int dofrags;
|
||||||
|
native int ng_state;
|
||||||
|
native float shadowalpha;
|
||||||
|
|
||||||
|
//
|
||||||
|
// GRAPHICS
|
||||||
|
//
|
||||||
|
|
||||||
|
native PatchInfo mapname;
|
||||||
|
native PatchInfo finished;
|
||||||
|
native PatchInfo entering;
|
||||||
|
|
||||||
|
native TextureID p_secret;
|
||||||
|
native TextureID kills;
|
||||||
|
native TextureID secret;
|
||||||
|
native TextureID items;
|
||||||
|
native TextureID timepic;
|
||||||
|
native TextureID par;
|
||||||
|
native TextureID sucks;
|
||||||
|
|
||||||
|
// [RH] Info to dynamically generate the level name graphics
|
||||||
|
native String lnametexts[2];
|
||||||
|
|
||||||
|
|
||||||
|
native bool snl_pointeron;
|
||||||
|
|
||||||
|
native int player_deaths[MAXPLAYERS];
|
||||||
|
native int sp_state;
|
||||||
|
|
||||||
|
|
||||||
|
//====================================================================
|
||||||
|
//
|
||||||
|
// Draws a single character with a shadow
|
||||||
|
//
|
||||||
|
//====================================================================
|
||||||
|
|
||||||
|
protected int DrawCharPatch(Font fnt, int charcode, int x, int y, int translation = Font.CR_UNTRANSLATED, bool nomove = false)
|
||||||
|
{
|
||||||
|
int width = fnt.GetCharWidth(charcode);
|
||||||
|
screen.DrawChar(fnt, translation, x, y, charcode, nomove ? DTA_CleanNoMove : DTA_Clean, true);
|
||||||
|
return x - width;
|
||||||
|
}
|
||||||
|
|
||||||
|
//====================================================================
|
||||||
|
//
|
||||||
|
// Draws a level name with the big font
|
||||||
|
//
|
||||||
|
// x is no longer passed as a parameter because the text is now broken into several lines
|
||||||
|
// if it is too long
|
||||||
|
//
|
||||||
|
//====================================================================
|
||||||
|
|
||||||
|
protected int DrawName(int y, TextureID tex, String levelname)
|
||||||
|
{
|
||||||
|
// draw <LevelName>
|
||||||
|
if (tex.isValid())
|
||||||
|
{
|
||||||
|
int w,h;
|
||||||
|
[w, h] = TexMan.GetSize(tex);
|
||||||
|
let size = TexMan.GetScaledSize(tex);
|
||||||
|
screen.DrawTexture(tex, true, (screen.GetWidth() - size.X * CleanXfac) /2, y, DTA_CleanNoMove, true);
|
||||||
|
if (h > 50)
|
||||||
|
{ // Fix for Deus Vult II and similar wads that decide to make these hugely tall
|
||||||
|
// patches with vast amounts of empty space at the bottom.
|
||||||
|
size.Y = TexMan.CheckRealHeight(tex) * size.Y / h;
|
||||||
|
}
|
||||||
|
return y + (h + BigFont.GetHeight()/4) * CleanYfac;
|
||||||
|
}
|
||||||
|
else if (levelname.Length() > 0)
|
||||||
|
{
|
||||||
|
int h = 0;
|
||||||
|
int lumph = mapname.mFont.GetHeight() * CleanYfac;
|
||||||
|
|
||||||
|
BrokenLines lines = mapname.mFont.BreakLines(levelname, screen.GetWidth() / CleanXfac);
|
||||||
|
|
||||||
|
int count = lines.Count();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
screen.DrawText(mapname.mFont, mapname.mColor, (screen.GetWidth() - lines.StringWidth(i) * CleanXfac) / 2, y + h, lines.StringAt(i), DTA_CleanNoMove, true);
|
||||||
|
h += lumph;
|
||||||
|
}
|
||||||
|
return y + h + lumph/4;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//====================================================================
|
||||||
|
//
|
||||||
|
// Draws a text, either as patch or as string from the string table
|
||||||
|
//
|
||||||
|
//====================================================================
|
||||||
|
|
||||||
|
protected int DrawPatchText(int y, PatchInfo pinfo, String stringname)
|
||||||
|
{
|
||||||
|
String string = Stringtable.Localize(stringname);
|
||||||
|
int midx = screen.GetWidth() / 2;
|
||||||
|
|
||||||
|
if (pinfo.mPatch.isValid())
|
||||||
|
{
|
||||||
|
let size = TexMan.GetScaledSize(pinfo.mPatch);
|
||||||
|
screen.DrawTexture(pinfo.mPatch, true, midx - size.X * CleanXfac/2, y, DTA_CleanNoMove, true);
|
||||||
|
return y + (size.Y * CleanYfac);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
screen.DrawText(pinfo.mFont, pinfo.mColor, midx - pinfo.mFont.StringWidth(string) * CleanXfac/2, y, string, DTA_CleanNoMove, true);
|
||||||
|
return y + pinfo.mFont.GetHeight() * CleanYfac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//====================================================================
|
||||||
|
//
|
||||||
|
// Draws "<Levelname> Finished!"
|
||||||
|
//
|
||||||
|
// Either uses the specified patch or the big font
|
||||||
|
// A level name patch can be specified for all games now, not just Doom.
|
||||||
|
//
|
||||||
|
//====================================================================
|
||||||
|
|
||||||
|
protected int drawLF ()
|
||||||
|
{
|
||||||
|
int y = WI_TITLEY * CleanYfac;
|
||||||
|
|
||||||
|
y = DrawName(y, wbs.LName0, lnametexts[0]);
|
||||||
|
|
||||||
|
// Adjustment for different font sizes for map name and 'finished'.
|
||||||
|
y -= ((mapname.mFont.GetHeight() - finished.mFont.GetHeight()) * CleanYfac) / 4;
|
||||||
|
|
||||||
|
// draw "Finished!"
|
||||||
|
if (y < (NG_STATSY - finished.mFont.GetHeight()*3/4) * CleanYfac)
|
||||||
|
{
|
||||||
|
// don't draw 'finished' if the level name is too tall
|
||||||
|
y = DrawPatchText(y, finished, "$WI_FINISHED");
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//====================================================================
|
||||||
|
//
|
||||||
|
// Draws "Entering <LevelName>"
|
||||||
|
//
|
||||||
|
// Either uses the specified patch or the big font
|
||||||
|
// A level name patch can be specified for all games now, not just Doom.
|
||||||
|
//
|
||||||
|
//====================================================================
|
||||||
|
|
||||||
|
protected void drawEL ()
|
||||||
|
{
|
||||||
|
int y = WI_TITLEY * CleanYfac;
|
||||||
|
|
||||||
|
y = DrawPatchText(y, entering, "$WI_ENTERING");
|
||||||
|
y += entering.mFont.GetHeight() * CleanYfac / 4;
|
||||||
|
DrawName(y, wbs.LName1, lnametexts[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//====================================================================
|
||||||
|
//
|
||||||
|
// Draws a number.
|
||||||
|
// If digits > 0, then use that many digits minimum,
|
||||||
|
// otherwise only use as many as necessary.
|
||||||
|
// x is the right edge of the number.
|
||||||
|
// Returns new x position, that is, the left edge of the number.
|
||||||
|
//
|
||||||
|
//====================================================================
|
||||||
|
protected int drawNum (Font fnt, int x, int y, int n, int digits, bool leadingzeros = true, int translation = Font.CR_UNTRANSLATED)
|
||||||
|
{
|
||||||
|
int fntwidth = fnt.StringWidth("3");
|
||||||
|
String text;
|
||||||
|
int len;
|
||||||
|
bool nomove = fnt != IntermissionFont;
|
||||||
|
|
||||||
|
if (nomove)
|
||||||
|
{
|
||||||
|
fntwidth *= CleanXfac;
|
||||||
|
}
|
||||||
|
text = String.Format("%d", n);
|
||||||
|
len = text.Length();
|
||||||
|
if (leadingzeros)
|
||||||
|
{
|
||||||
|
int filldigits = digits - len;
|
||||||
|
for(int i = 0; i < filldigits; i++)
|
||||||
|
{
|
||||||
|
text = "0" .. text;
|
||||||
|
}
|
||||||
|
len = text.Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int text_p = len-1; text_p >= 0; text_p--)
|
||||||
|
{
|
||||||
|
// Digits are centered in a box the width of the '3' character.
|
||||||
|
// Other characters (specifically, '-') are right-aligned in their cell.
|
||||||
|
int c = text.CharCodeAt(text_p);
|
||||||
|
if (c >= "0" && c <= "9")
|
||||||
|
{
|
||||||
|
x -= fntwidth;
|
||||||
|
DrawCharPatch(fnt, c, x + (fntwidth - fnt.GetCharWidth(c)) / 2, y, translation, nomove);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawCharPatch(fnt, c, x - fnt.GetCharWidth(c), y, translation, nomove);
|
||||||
|
x -= fntwidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (len < digits)
|
||||||
|
{
|
||||||
|
x -= fntwidth * (digits - len);
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
//====================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//====================================================================
|
||||||
|
|
||||||
|
protected void drawPercent (Font fnt, int x, int y, int p, int b, bool show_total = true, int color = Font.CR_UNTRANSLATED)
|
||||||
|
{
|
||||||
|
if (p < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (wi_percents)
|
||||||
|
{
|
||||||
|
if (fnt != IntermissionFont)
|
||||||
|
{
|
||||||
|
x -= fnt.StringWidth("%") * CleanXfac;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x -= fnt.StringWidth("%");
|
||||||
|
}
|
||||||
|
screen.DrawText(fnt, color, x, y, "%", fnt != IntermissionFont ? DTA_CleanNoMove : DTA_Clean, true);
|
||||||
|
if (fnt != IntermissionFont)
|
||||||
|
{
|
||||||
|
x -= 2*CleanXfac;
|
||||||
|
}
|
||||||
|
drawNum(fnt, x, y, b == 0 ? 100 : p * 100 / b, -1, false, color);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (show_total)
|
||||||
|
{
|
||||||
|
x = drawNum(fnt, x, y, b, 2, false);
|
||||||
|
x -= fnt.StringWidth("/");
|
||||||
|
screen.DrawText (IntermissionFont, color, x, y, "/", DTA_Clean, true);
|
||||||
|
}
|
||||||
|
drawNum (fnt, x, y, p, -1, false, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//====================================================================
|
||||||
|
//
|
||||||
|
// Display level completion time and par, or "sucks" message if overflow.
|
||||||
|
//
|
||||||
|
//====================================================================
|
||||||
|
protected void drawTime (int x, int y, int t, bool no_sucks=false)
|
||||||
|
{
|
||||||
|
bool sucky;
|
||||||
|
|
||||||
|
if (t < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sucky = !no_sucks && t >= wbs.sucktime * 60 * 60 && wbs.sucktime > 0;
|
||||||
|
|
||||||
|
if (sucky)
|
||||||
|
{ // "sucks"
|
||||||
|
if (Sucks.isValid())
|
||||||
|
{
|
||||||
|
let size = TexMan.GetScaledSize(Sucks);
|
||||||
|
screen.DrawTexture (Sucks, true, x - size.X, y - size.Y - 2, DTA_Clean, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
screen.DrawText (BigFont, Font.CR_UNTRANSLATED, x - BigFont.StringWidth("SUCKS"), y - IntermissionFont.GetHeight() - 2, "SUCKS", DTA_Clean, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int hours = t / 3600;
|
||||||
|
t -= hours * 3600;
|
||||||
|
int minutes = t / 60;
|
||||||
|
t -= minutes * 60;
|
||||||
|
int seconds = t;
|
||||||
|
|
||||||
|
// Why were these offsets hard coded? Half the WADs with custom patches
|
||||||
|
// I tested screwed up miserably in this function!
|
||||||
|
int num_spacing = IntermissionFont.GetCharWidth("3");
|
||||||
|
int colon_spacing = IntermissionFont.GetCharWidth(":");
|
||||||
|
|
||||||
|
x = drawNum (IntermissionFont, x, y, seconds, 2) - 1;
|
||||||
|
DrawCharPatch (IntermissionFont, ":", x -= colon_spacing, y);
|
||||||
|
x = drawNum (IntermissionFont, x, y, minutes, 2, hours!=0);
|
||||||
|
if (hours)
|
||||||
|
{
|
||||||
|
DrawCharPatch (IntermissionFont, ":", x -= colon_spacing, y);
|
||||||
|
drawNum (IntermissionFont, x, y, hours, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue