0
0
Fork 0
mirror of https://github.com/ZDoom/gzdoom-gles.git synced 2025-02-27 13:41:06 +00:00

Tactical merge

This commit is contained in:
ZZYZX 2017-02-05 19:14:56 +02:00
commit e4970189b6
57 changed files with 1197 additions and 424 deletions

View file

@ -2934,8 +2934,8 @@ static void DrawMarker (FTexture *tex, double x, double y, int yadjust,
DTA_ClipLeft, f_x, DTA_ClipLeft, f_x,
DTA_ClipRight, f_x + f_w, DTA_ClipRight, f_x + f_w,
DTA_FlipX, flip, DTA_FlipX, flip,
DTA_Translation, TranslationToTable(translation), DTA_TranslationIndex, translation,
DTA_AlphaF, alpha, DTA_Alpha, alpha,
DTA_FillColor, fillcolor, DTA_FillColor, fillcolor,
DTA_RenderStyle, DWORD(renderstyle), DTA_RenderStyle, DWORD(renderstyle),
TAG_DONE); TAG_DONE);

View file

@ -65,11 +65,11 @@ bool DBot::Move (ticcmd_t *cmd)
bool try_ok; bool try_ok;
int good; int good;
if (player->mo->movedir == DI_NODIR) if (player->mo->movedir >= DI_NODIR)
{
player->mo->movedir = DI_NODIR; // make sure it's valid.
return false; return false;
}
if ((unsigned)player->mo->movedir >= 8)
I_Error ("Weird bot movedir!");
tryx = player->mo->X() + 8*xspeed[player->mo->movedir]; tryx = player->mo->X() + 8*xspeed[player->mo->movedir];
tryy = player->mo->Y() + 8*yspeed[player->mo->movedir]; tryy = player->mo->Y() + 8*yspeed[player->mo->movedir];

View file

@ -1005,23 +1005,23 @@ void FNotifyBuffer::Draw()
{ {
if (!center) if (!center)
screen->DrawText (SmallFont, color, 0, line, notify.Text, screen->DrawText (SmallFont, color, 0, line, notify.Text,
DTA_CleanNoMove, true, DTA_AlphaF, alpha, TAG_DONE); DTA_CleanNoMove, true, DTA_Alpha, alpha, TAG_DONE);
else else
screen->DrawText (SmallFont, color, (SCREENWIDTH - screen->DrawText (SmallFont, color, (SCREENWIDTH -
SmallFont->StringWidth (notify.Text)*CleanXfac)/2, SmallFont->StringWidth (notify.Text)*CleanXfac)/2,
line, notify.Text, DTA_CleanNoMove, true, line, notify.Text, DTA_CleanNoMove, true,
DTA_AlphaF, alpha, TAG_DONE); DTA_Alpha, alpha, TAG_DONE);
} }
else if (active_con_scaletext() == 1) else if (active_con_scaletext() == 1)
{ {
if (!center) if (!center)
screen->DrawText (SmallFont, color, 0, line, notify.Text, screen->DrawText (SmallFont, color, 0, line, notify.Text,
DTA_AlphaF, alpha, TAG_DONE); DTA_Alpha, alpha, TAG_DONE);
else else
screen->DrawText (SmallFont, color, (SCREENWIDTH - screen->DrawText (SmallFont, color, (SCREENWIDTH -
SmallFont->StringWidth (notify.Text))/2, SmallFont->StringWidth (notify.Text))/2,
line, notify.Text, line, notify.Text,
DTA_AlphaF, alpha, TAG_DONE); DTA_Alpha, alpha, TAG_DONE);
} }
else else
{ {
@ -1030,7 +1030,7 @@ void FNotifyBuffer::Draw()
DTA_VirtualWidth, screen->GetWidth() / active_con_scaletext(), DTA_VirtualWidth, screen->GetWidth() / active_con_scaletext(),
DTA_VirtualHeight, screen->GetHeight() / active_con_scaletext(), DTA_VirtualHeight, screen->GetHeight() / active_con_scaletext(),
DTA_KeepRatio, true, DTA_KeepRatio, true,
DTA_AlphaF, alpha, TAG_DONE); DTA_Alpha, alpha, TAG_DONE);
else else
screen->DrawText (SmallFont, color, (screen->GetWidth() - screen->DrawText (SmallFont, color, (screen->GetWidth() -
SmallFont->StringWidth (notify.Text) * active_con_scaletext()) / 2 / active_con_scaletext(), SmallFont->StringWidth (notify.Text) * active_con_scaletext()) / 2 / active_con_scaletext(),
@ -1038,7 +1038,7 @@ void FNotifyBuffer::Draw()
DTA_VirtualWidth, screen->GetWidth() / active_con_scaletext(), DTA_VirtualWidth, screen->GetWidth() / active_con_scaletext(),
DTA_VirtualHeight, screen->GetHeight() / active_con_scaletext(), DTA_VirtualHeight, screen->GetHeight() / active_con_scaletext(),
DTA_KeepRatio, true, DTA_KeepRatio, true,
DTA_AlphaF, alpha, TAG_DONE); DTA_Alpha, alpha, TAG_DONE);
} }
line += lineadv; line += lineadv;
canskip = false; canskip = false;
@ -1119,7 +1119,7 @@ void C_DrawConsole (bool hw2d)
DTA_DestWidth, screen->GetWidth(), DTA_DestWidth, screen->GetWidth(),
DTA_DestHeight, screen->GetHeight(), DTA_DestHeight, screen->GetHeight(),
DTA_ColorOverlay, conshade, DTA_ColorOverlay, conshade,
DTA_AlphaF, (hw2d && gamestate != GS_FULLCONSOLE) ? (double)con_alpha : 1., DTA_Alpha, (hw2d && gamestate != GS_FULLCONSOLE) ? (double)con_alpha : 1.,
DTA_Masked, false, DTA_Masked, false,
TAG_DONE); TAG_DONE);
if (conline && visheight < screen->GetHeight()) if (conline && visheight < screen->GetHeight())
@ -1762,11 +1762,10 @@ void C_MidPrintBold (FFont *font, const char *msg)
DEFINE_ACTION_FUNCTION(_Console, MidPrint) DEFINE_ACTION_FUNCTION(_Console, MidPrint)
{ {
PARAM_PROLOGUE; PARAM_PROLOGUE;
PARAM_STRING(font); PARAM_POINTER_NOT_NULL(fnt, FFont);
PARAM_STRING(text); PARAM_STRING(text);
PARAM_BOOL_DEF(bold); PARAM_BOOL_DEF(bold);
FFont *fnt = FFont::FindFont(font);
const char *txt = text[0] == '$'? GStrings(&text[1]) : text.GetChars(); const char *txt = text[0] == '$'? GStrings(&text[1]) : text.GetChars();
if (!bold) C_MidPrint(fnt, txt); if (!bold) C_MidPrint(fnt, txt);
else C_MidPrintBold(fnt, txt); else C_MidPrintBold(fnt, txt);

View file

@ -2475,6 +2475,9 @@ void D_DoomMain (void)
TexMan.Init(); TexMan.Init();
C_InitConback(); C_InitConback();
StartScreen->Progress();
V_InitFonts();
// [CW] Parse any TEAMINFO lumps. // [CW] Parse any TEAMINFO lumps.
if (!batchrun) Printf ("ParseTeamInfo: Load team definitions.\n"); if (!batchrun) Printf ("ParseTeamInfo: Load team definitions.\n");
TeamLibrary.ParseTeamInfo (); TeamLibrary.ParseTeamInfo ();

View file

@ -88,6 +88,7 @@ PColor *TypeColor;
PTextureID *TypeTextureID; PTextureID *TypeTextureID;
PSpriteID *TypeSpriteID; PSpriteID *TypeSpriteID;
PStatePointer *TypeState; PStatePointer *TypeState;
PPointer *TypeFont;
PStateLabel *TypeStateLabel; PStateLabel *TypeStateLabel;
PStruct *TypeVector2; PStruct *TypeVector2;
PStruct *TypeVector3; PStruct *TypeVector3;
@ -437,6 +438,7 @@ void PType::StaticInit()
TypeVoidPtr = NewPointer(TypeVoid, false); TypeVoidPtr = NewPointer(TypeVoid, false);
TypeColorStruct = NewStruct("@ColorStruct", nullptr); //This name is intentionally obfuscated so that it cannot be used explicitly. The point of this type is to gain access to the single channels of a color value. TypeColorStruct = NewStruct("@ColorStruct", nullptr); //This name is intentionally obfuscated so that it cannot be used explicitly. The point of this type is to gain access to the single channels of a color value.
TypeStringStruct = NewNativeStruct("Stringstruct", nullptr); TypeStringStruct = NewNativeStruct("Stringstruct", nullptr);
TypeFont = NewPointer(NewNativeStruct("Font", nullptr));
#ifdef __BIG_ENDIAN__ #ifdef __BIG_ENDIAN__
TypeColorStruct->AddField(NAME_a, TypeUInt8); TypeColorStruct->AddField(NAME_a, TypeUInt8);
TypeColorStruct->AddField(NAME_r, TypeUInt8); TypeColorStruct->AddField(NAME_r, TypeUInt8);

View file

@ -940,6 +940,7 @@ extern PStruct *TypeVector3;
extern PStruct *TypeColorStruct; extern PStruct *TypeColorStruct;
extern PStruct *TypeStringStruct; extern PStruct *TypeStringStruct;
extern PStatePointer *TypeState; extern PStatePointer *TypeState;
extern PPointer *TypeFont;
extern PStateLabel *TypeStateLabel; extern PStateLabel *TypeStateLabel;
extern PPointer *TypeNullPtr; extern PPointer *TypeNullPtr;
extern PPointer *TypeVoidPtr; extern PPointer *TypeVoidPtr;

View file

@ -457,7 +457,7 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight)
{ {
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
DTA_CleanNoMove, clean, DTA_CleanNoMove, clean,
DTA_AlphaF, Alpha, DTA_Alpha, Alpha,
DTA_RenderStyle, Style, DTA_RenderStyle, Style,
TAG_DONE); TAG_DONE);
} }
@ -466,7 +466,7 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight)
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
DTA_VirtualWidth, SCREENWIDTH / active_con_scaletext(), DTA_VirtualWidth, SCREENWIDTH / active_con_scaletext(),
DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(), DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(),
DTA_AlphaF, Alpha, DTA_Alpha, Alpha,
DTA_RenderStyle, Style, DTA_RenderStyle, Style,
DTA_KeepRatio, true, DTA_KeepRatio, true,
TAG_DONE); TAG_DONE);
@ -481,7 +481,7 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight)
DTA_ClipRight, ClipRight, DTA_ClipRight, ClipRight,
DTA_ClipTop, ClipTop, DTA_ClipTop, ClipTop,
DTA_ClipBottom, ClipBot, DTA_ClipBottom, ClipBot,
DTA_AlphaF, Alpha, DTA_Alpha, Alpha,
DTA_RenderStyle, Style, DTA_RenderStyle, Style,
TAG_DONE); TAG_DONE);
} }
@ -560,7 +560,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh
{ {
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
DTA_CleanNoMove, clean, DTA_CleanNoMove, clean,
DTA_AlphaF, trans, DTA_Alpha, trans,
DTA_RenderStyle, Style, DTA_RenderStyle, Style,
TAG_DONE); TAG_DONE);
} }
@ -569,7 +569,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
DTA_VirtualWidth, SCREENWIDTH / active_con_scaletext(), DTA_VirtualWidth, SCREENWIDTH / active_con_scaletext(),
DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(), DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(),
DTA_AlphaF, trans, DTA_Alpha, trans,
DTA_RenderStyle, Style, DTA_RenderStyle, Style,
DTA_KeepRatio, true, DTA_KeepRatio, true,
TAG_DONE); TAG_DONE);
@ -584,7 +584,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh
DTA_ClipRight, ClipRight, DTA_ClipRight, ClipRight,
DTA_ClipTop, ClipTop, DTA_ClipTop, ClipTop,
DTA_ClipBottom, ClipBot, DTA_ClipBottom, ClipBot,
DTA_AlphaF, trans, DTA_Alpha, trans,
DTA_RenderStyle, Style, DTA_RenderStyle, Style,
TAG_DONE); TAG_DONE);
} }
@ -660,7 +660,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu
{ {
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
DTA_CleanNoMove, clean, DTA_CleanNoMove, clean,
DTA_AlphaF, trans, DTA_Alpha, trans,
DTA_RenderStyle, Style, DTA_RenderStyle, Style,
TAG_DONE); TAG_DONE);
} }
@ -669,7 +669,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
DTA_VirtualWidth, SCREENWIDTH / active_con_scaletext(), DTA_VirtualWidth, SCREENWIDTH / active_con_scaletext(),
DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(), DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(),
DTA_AlphaF, trans, DTA_Alpha, trans,
DTA_RenderStyle, Style, DTA_RenderStyle, Style,
DTA_KeepRatio, true, DTA_KeepRatio, true,
TAG_DONE); TAG_DONE);
@ -684,7 +684,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu
DTA_ClipRight, ClipRight, DTA_ClipRight, ClipRight,
DTA_ClipTop, ClipTop, DTA_ClipTop, ClipTop,
DTA_ClipBottom, ClipBot, DTA_ClipBottom, ClipBot,
DTA_AlphaF, trans, DTA_Alpha, trans,
DTA_RenderStyle, Style, DTA_RenderStyle, Style,
TAG_DONE); TAG_DONE);
} }
@ -842,7 +842,7 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
DTA_CleanNoMove, clean, DTA_CleanNoMove, clean,
DTA_TextLen, LineVisible, DTA_TextLen, LineVisible,
DTA_AlphaF, Alpha, DTA_Alpha, Alpha,
DTA_RenderStyle, Style, DTA_RenderStyle, Style,
TAG_DONE); TAG_DONE);
} }
@ -853,7 +853,7 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in
DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(), DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(),
DTA_KeepRatio, true, DTA_KeepRatio, true,
DTA_TextLen, LineVisible, DTA_TextLen, LineVisible,
DTA_AlphaF, Alpha, DTA_Alpha, Alpha,
DTA_RenderStyle, Style, DTA_RenderStyle, Style,
TAG_DONE); TAG_DONE);
} }
@ -867,7 +867,7 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in
DTA_ClipRight, ClipRight, DTA_ClipRight, ClipRight,
DTA_ClipTop, ClipTop, DTA_ClipTop, ClipTop,
DTA_ClipBottom, ClipBot, DTA_ClipBottom, ClipBot,
DTA_AlphaF, Alpha, DTA_Alpha, Alpha,
DTA_TextLen, LineVisible, DTA_TextLen, LineVisible,
DTA_RenderStyle, Style, DTA_RenderStyle, Style,
TAG_DONE); TAG_DONE);

View file

@ -138,7 +138,7 @@ void SetHUDIcon(PClassInventory *cls, FTextureID tex)
// center of the box. The image is scaled down if it doesn't fit // center of the box. The image is scaled down if it doesn't fit
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void DrawImageToBox(FTexture * tex, int x, int y, int w, int h, int trans=0xc000) static void DrawImageToBox(FTexture * tex, int x, int y, int w, int h, double trans = 0.75)
{ {
double scale1, scale2; double scale1, scale2;
@ -174,7 +174,7 @@ static void DrawImageToBox(FTexture * tex, int x, int y, int w, int h, int trans
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void DrawHudText(FFont *font, int color, char * text, int x, int y, int trans=0xc000) static void DrawHudText(FFont *font, int color, char * text, int x, int y, double trans = 0.75)
{ {
int zerowidth; int zerowidth;
FTexture *tex_zero = font->GetChar('0', &zerowidth); FTexture *tex_zero = font->GetChar('0', &zerowidth);
@ -207,7 +207,7 @@ static void DrawHudText(FFont *font, int color, char * text, int x, int y, int t
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void DrawHudNumber(FFont *font, int color, int num, int x, int y, int trans=0xc000) static void DrawHudNumber(FFont *font, int color, int num, int x, int y, double trans = 0.75)
{ {
char text[15]; char text[15];
@ -227,11 +227,11 @@ static void DrawStatLine(int x, int &y, const char *prefix, const char *string)
y -= SmallFont->GetHeight()-1; y -= SmallFont->GetHeight()-1;
screen->DrawText(SmallFont, hudcolor_statnames, x, y, prefix, screen->DrawText(SmallFont, hudcolor_statnames, x, y, prefix,
DTA_KeepRatio, true, DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE); DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0.75, TAG_DONE);
screen->DrawText(SmallFont, hudcolor_stats, x+statspace, y, string, screen->DrawText(SmallFont, hudcolor_stats, x+statspace, y, string,
DTA_KeepRatio, true, DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE); DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0.75, TAG_DONE);
} }
static void DrawStatus(player_t * CPlayer, int x, int y) static void DrawStatus(player_t * CPlayer, int x, int y)
@ -654,7 +654,7 @@ static int DrawAmmo(player_t *CPlayer, int x, int y)
FTextureID icon = !AltIcon.isNull()? AltIcon : inv->Icon; FTextureID icon = !AltIcon.isNull()? AltIcon : inv->Icon;
if (!icon.isValid()) continue; if (!icon.isValid()) continue;
int trans= (wi && (type==wi->AmmoType1 || type==wi->AmmoType2)) ? 0xc000:0x6000; double trans= (wi && (type==wi->AmmoType1 || type==wi->AmmoType2)) ? 0.75 : 0.375;
int maxammo = inv->MaxAmount; int maxammo = inv->MaxAmount;
int ammo = ammoitem? ammoitem->Amount : 0; int ammo = ammoitem? ammoitem->Amount : 0;
@ -731,16 +731,16 @@ FTextureID GetInventoryIcon(AInventory *item, DWORD flags, bool *applyscale=NULL
static void DrawOneWeapon(player_t * CPlayer, int x, int & y, AWeapon * weapon) static void DrawOneWeapon(player_t * CPlayer, int x, int & y, AWeapon * weapon)
{ {
int trans; double trans;
// Powered up weapons and inherited sister weapons are not displayed. // Powered up weapons and inherited sister weapons are not displayed.
if (weapon->WeaponFlags & WIF_POWERED_UP) return; if (weapon->WeaponFlags & WIF_POWERED_UP) return;
if (weapon->SisterWeapon && weapon->IsKindOf(weapon->SisterWeapon->GetClass())) return; if (weapon->SisterWeapon && weapon->IsKindOf(weapon->SisterWeapon->GetClass())) return;
trans=0x6666; trans=0.4;
if (CPlayer->ReadyWeapon) if (CPlayer->ReadyWeapon)
{ {
if (weapon==CPlayer->ReadyWeapon || weapon==CPlayer->ReadyWeapon->SisterWeapon) trans=0xd999; if (weapon==CPlayer->ReadyWeapon || weapon==CPlayer->ReadyWeapon->SisterWeapon) trans = 0.85;
} }
FTextureID picnum = GetInventoryIcon(weapon, DI_ALTICONFIRST); FTextureID picnum = GetInventoryIcon(weapon, DI_ALTICONFIRST);
@ -809,7 +809,7 @@ static void DrawInventory(player_t * CPlayer, int x,int y)
{ {
screen->DrawTexture(invgems[!!(level.time&4)], x-10, y, screen->DrawTexture(invgems[!!(level.time&4)], x-10, y,
DTA_KeepRatio, true, DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0x6666, TAG_DONE); DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0.4, TAG_DONE);
} }
for(i=0;i<numitems && rover;rover=rover->NextInv()) for(i=0;i<numitems && rover;rover=rover->NextInv())
@ -820,7 +820,7 @@ static void DrawInventory(player_t * CPlayer, int x,int y)
if (AltIcon.Exists() && (rover->Icon.isValid() || AltIcon.isValid()) ) if (AltIcon.Exists() && (rover->Icon.isValid() || AltIcon.isValid()) )
{ {
int trans = rover==CPlayer->mo->InvSel ? 0x10000 : 0x6666; double trans = rover==CPlayer->mo->InvSel ? 1.0 : 0.4;
DrawImageToBox(TexMan[AltIcon.isValid()? AltIcon : rover->Icon], x, y, 19, 25, trans); DrawImageToBox(TexMan[AltIcon.isValid()? AltIcon : rover->Icon], x, y, 19, 25, trans);
if (rover->Amount>1) if (rover->Amount>1)
@ -845,7 +845,7 @@ static void DrawInventory(player_t * CPlayer, int x,int y)
{ {
screen->DrawTexture(invgems[2 + !!(level.time&4)], x-10, y, screen->DrawTexture(invgems[2 + !!(level.time&4)], x-10, y,
DTA_KeepRatio, true, DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0x6666, TAG_DONE); DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0.4, TAG_DONE);
} }
} }
} }

View file

@ -1267,10 +1267,10 @@ public:
DTA_ClipTop, static_cast<int>(dcy), DTA_ClipTop, static_cast<int>(dcy),
DTA_ClipRight, static_cast<int>(MIN<double>(INT_MAX, dcr)), DTA_ClipRight, static_cast<int>(MIN<double>(INT_MAX, dcr)),
DTA_ClipBottom, static_cast<int>(MIN<double>(INT_MAX, dcb)), DTA_ClipBottom, static_cast<int>(MIN<double>(INT_MAX, dcb)),
DTA_Translation, translate ? GetTranslation() : 0, DTA_TranslationIndex, translate ? GetTranslation() : 0,
DTA_ColorOverlay, dim ? DIM_OVERLAY : 0, DTA_ColorOverlay, dim ? DIM_OVERLAY : 0,
DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM, DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM,
DTA_AlphaF, Alpha, DTA_Alpha, Alpha,
DTA_AlphaChannel, alphaMap, DTA_AlphaChannel, alphaMap,
DTA_FillColor, 0, DTA_FillColor, 0,
TAG_DONE); TAG_DONE);
@ -1284,10 +1284,10 @@ public:
DTA_ClipTop, static_cast<int>(dcy), DTA_ClipTop, static_cast<int>(dcy),
DTA_ClipRight, static_cast<int>(MIN<double>(INT_MAX, dcr)), DTA_ClipRight, static_cast<int>(MIN<double>(INT_MAX, dcr)),
DTA_ClipBottom, static_cast<int>(MIN<double>(INT_MAX, dcb)), DTA_ClipBottom, static_cast<int>(MIN<double>(INT_MAX, dcb)),
DTA_Translation, translate ? GetTranslation() : 0, DTA_TranslationIndex, translate ? GetTranslation() : 0,
DTA_ColorOverlay, dim ? DIM_OVERLAY : 0, DTA_ColorOverlay, dim ? DIM_OVERLAY : 0,
DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM, DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM,
DTA_AlphaF, Alpha, DTA_Alpha, Alpha,
TAG_DONE); TAG_DONE);
} }
} }
@ -1344,10 +1344,10 @@ public:
DTA_ClipTop, static_cast<int>(rcy), DTA_ClipTop, static_cast<int>(rcy),
DTA_ClipRight, static_cast<int>(rcr), DTA_ClipRight, static_cast<int>(rcr),
DTA_ClipBottom, static_cast<int>(rcb), DTA_ClipBottom, static_cast<int>(rcb),
DTA_Translation, translate ? GetTranslation() : 0, DTA_TranslationIndex, translate ? GetTranslation() : 0,
DTA_ColorOverlay, dim ? DIM_OVERLAY : 0, DTA_ColorOverlay, dim ? DIM_OVERLAY : 0,
DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM, DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM,
DTA_AlphaF, Alpha, DTA_Alpha, Alpha,
DTA_AlphaChannel, alphaMap, DTA_AlphaChannel, alphaMap,
DTA_FillColor, 0, DTA_FillColor, 0,
TAG_DONE); TAG_DONE);
@ -1361,10 +1361,10 @@ public:
DTA_ClipTop, static_cast<int>(rcy), DTA_ClipTop, static_cast<int>(rcy),
DTA_ClipRight, static_cast<int>(rcr), DTA_ClipRight, static_cast<int>(rcr),
DTA_ClipBottom, static_cast<int>(rcb), DTA_ClipBottom, static_cast<int>(rcb),
DTA_Translation, translate ? GetTranslation() : 0, DTA_TranslationIndex, translate ? GetTranslation() : 0,
DTA_ColorOverlay, dim ? DIM_OVERLAY : 0, DTA_ColorOverlay, dim ? DIM_OVERLAY : 0,
DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM, DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM,
DTA_AlphaF, Alpha, DTA_Alpha, Alpha,
TAG_DONE); TAG_DONE);
} }
} }
@ -1382,7 +1382,7 @@ public:
const BYTE* str = (const BYTE*) cstring; const BYTE* str = (const BYTE*) cstring;
const EColorRange boldTranslation = EColorRange(translation ? translation - 1 : NumTextColors - 1); const EColorRange boldTranslation = EColorRange(translation ? translation - 1 : NumTextColors - 1);
FRemapTable *remap = font->GetColorTranslation(translation); int fontcolor = translation;
if(fullScreenOffsets) if(fullScreenOffsets)
{ {
@ -1408,7 +1408,7 @@ public:
{ {
EColorRange newColor = V_ParseFontColor(++str, translation, boldTranslation); EColorRange newColor = V_ParseFontColor(++str, translation, boldTranslation);
if(newColor != CR_UNDEFINED) if(newColor != CR_UNDEFINED)
remap = font->GetColorTranslation(newColor); fontcolor = newColor;
continue; continue;
} }
@ -1417,20 +1417,22 @@ public:
width = font->GetCharWidth((unsigned char) *str); width = font->GetCharWidth((unsigned char) *str);
else else
width = font->GetCharWidth((unsigned char) script->spacingCharacter); width = font->GetCharWidth((unsigned char) script->spacingCharacter);
FTexture* character = font->GetChar((unsigned char) *str, &width); FTexture* c = font->GetChar((unsigned char) *str, &width);
if(character == NULL) //missing character. if(c == NULL) //missing character.
{ {
str++; str++;
continue; continue;
} }
int character = (unsigned char)*str;
if(script->spacingCharacter == '\0') //If we are monospaced lets use the offset if(script->spacingCharacter == '\0') //If we are monospaced lets use the offset
ax += (character->LeftOffset+1); //ignore x offsets since we adapt to character size ax += (c->LeftOffset+1); //ignore x offsets since we adapt to character size
double rx, ry, rw, rh; double rx, ry, rw, rh;
rx = ax + xOffset; rx = ax + xOffset;
ry = ay + yOffset; ry = ay + yOffset;
rw = character->GetScaledWidthDouble(); rw = c->GetScaledWidthDouble();
rh = character->GetScaledHeightDouble(); rh = c->GetScaledHeightDouble();
if(script->spacingCharacter != '\0') if(script->spacingCharacter != '\0')
{ {
@ -1484,32 +1486,31 @@ public:
double salpha = (Alpha *HR_SHADOW); double salpha = (Alpha *HR_SHADOW);
double srx = rx + (shadowX*xScale); double srx = rx + (shadowX*xScale);
double sry = ry + (shadowY*yScale); double sry = ry + (shadowY*yScale);
screen->DrawTexture(character, srx, sry, screen->DrawChar(font, CR_UNTRANSLATED, srx, sry, character,
DTA_DestWidthF, rw, DTA_DestWidthF, rw,
DTA_DestHeightF, rh, DTA_DestHeightF, rh,
DTA_AlphaF, salpha, DTA_Alpha, salpha,
DTA_FillColor, 0, DTA_FillColor, 0,
TAG_DONE); TAG_DONE);
} }
screen->DrawTexture(character, rx, ry, screen->DrawChar(font, fontcolor, rx, ry, character,
DTA_DestWidthF, rw, DTA_DestWidthF, rw,
DTA_DestHeightF, rh, DTA_DestHeightF, rh,
DTA_Translation, remap, DTA_Alpha, Alpha,
DTA_AlphaF, Alpha,
TAG_DONE); TAG_DONE);
if(script->spacingCharacter == '\0') if(script->spacingCharacter == '\0')
ax += width + spacing - (character->LeftOffset+1); ax += width + spacing - (c->LeftOffset+1);
else //width gets changed at the call to GetChar() else //width gets changed at the call to GetChar()
ax += font->GetCharWidth((unsigned char) script->spacingCharacter) + spacing; ax += font->GetCharWidth((unsigned char) script->spacingCharacter) + spacing;
str++; str++;
} }
} }
FRemapTable* GetTranslation() const uint32_t GetTranslation() const
{ {
if(gameinfo.gametype & GAME_Raven) if(gameinfo.gametype & GAME_Raven)
return translationtables[TRANSLATION_PlayersExtra][int(CPlayer - players)]; return TRANSLATION(TRANSLATION_PlayersExtra, int(CPlayer - players));
return translationtables[TRANSLATION_Players][int(CPlayer - players)]; return TRANSLATION(TRANSLATION_Players, int(CPlayer - players));
} }
AInventory *ammo1, *ammo2; AInventory *ammo1, *ammo2;

View file

@ -451,7 +451,7 @@ private:
screen->DrawTexture (Images[CursorImage], screen->DrawTexture (Images[CursorImage],
42 + 35*i + ST_X, 12 + ST_Y, 42 + 35*i + ST_X, 12 + ST_Y,
DTA_Bottom320x200, Scaled, DTA_Bottom320x200, Scaled,
DTA_AlphaF, 1. - ItemFlash, DTA_Alpha, 1. - ItemFlash,
TAG_DONE); TAG_DONE);
} }
if (item->Icon.isValid()) if (item->Icon.isValid())
@ -523,7 +523,7 @@ private:
DTA_HUDRules, HUD_Normal, DTA_HUDRules, HUD_Normal,
DTA_LeftOffset, cursor->GetWidth(), DTA_LeftOffset, cursor->GetWidth(),
DTA_TopOffset, cursor->GetHeight(), DTA_TopOffset, cursor->GetHeight(),
DTA_AlphaF, ItemFlash, DTA_Alpha, ItemFlash,
TAG_DONE); TAG_DONE);
} }
DrINumberOuter (CPlayer->mo->InvSel->Amount, -51, -10, false, 7); DrINumberOuter (CPlayer->mo->InvSel->Amount, -51, -10, false, 7);
@ -547,7 +547,7 @@ private:
{ {
screen->DrawTexture (Images[CursorImage], -100+i*35, -21, screen->DrawTexture (Images[CursorImage], -100+i*35, -21,
DTA_HUDRules, HUD_HorizCenter, DTA_HUDRules, HUD_HorizCenter,
DTA_Alpha, TRANSLUC75, DTA_Alpha, 0.75,
TAG_DONE); TAG_DONE);
} }
if (item->Icon.isValid()) if (item->Icon.isValid())
@ -580,7 +580,7 @@ private:
left = screen->GetWidth()/2 - 160*CleanXfac; left = screen->GetWidth()/2 - 160*CleanXfac;
top = bottom + height * yscale; top = bottom + height * yscale;
screen->DrawTexture (Images[back], left, top, DTA_CleanNoMove, true, DTA_AlphaF, 0.75, TAG_DONE); screen->DrawTexture (Images[back], left, top, DTA_CleanNoMove, true, DTA_Alpha, 0.75, TAG_DONE);
screen->DrawTexture (Images[bars], left, top, DTA_CleanNoMove, true, TAG_DONE); screen->DrawTexture (Images[bars], left, top, DTA_CleanNoMove, true, TAG_DONE);
@ -849,7 +849,7 @@ private:
void DrINumberOuter(signed int val, int x, int y, bool center = false, int w = 9) const; void DrINumberOuter(signed int val, int x, int y, bool center = false, int w = 9) const;
void DrBNumberOuterFont(signed int val, int x, int y, int w = 3) const; void DrBNumberOuterFont(signed int val, int x, int y, int w = 3) const;
void DrawDimImage(FTexture *image, int x, int y, bool dimmed) const; void DrawDimImage(FTexture *image, int x, int y, bool dimmed) const;
void DrawImage(FTexture *image, int x, int y, FRemapTable *translation = NULL) const; void DrawImage(FTexture *image, int x, int y/*, FRemapTable *translation = NULL*/) const;
}; };
@ -874,7 +874,7 @@ void DStrifeStatusBar::DrINumberOuter(signed int val, int x, int y, bool center,
else if (val == 0) else if (val == 0)
{ {
screen->DrawTexture(Images[imgINumbers], x + 1, y + 1, screen->DrawTexture(Images[imgINumbers], x + 1, y + 1,
DTA_FillColor, 0, DTA_AlphaF, HR_SHADOW, DTA_FillColor, 0, DTA_Alpha, HR_SHADOW,
DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal, TAG_DONE); DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal, TAG_DONE);
screen->DrawTexture(Images[imgINumbers], x, y, screen->DrawTexture(Images[imgINumbers], x, y,
DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal, TAG_DONE); DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal, TAG_DONE);
@ -888,7 +888,7 @@ void DStrifeStatusBar::DrINumberOuter(signed int val, int x, int y, bool center,
while (val != 0) while (val != 0)
{ {
screen->DrawTexture(Images[imgINumbers + val % 10], x + 1, y + 1, screen->DrawTexture(Images[imgINumbers + val % 10], x + 1, y + 1,
DTA_FillColor, 0, DTA_AlphaF, HR_SHADOW, DTA_FillColor, 0, DTA_Alpha, HR_SHADOW,
DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal, TAG_DONE); DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal, TAG_DONE);
x -= w; x -= w;
val /= 10; val /= 10;
@ -896,7 +896,7 @@ void DStrifeStatusBar::DrINumberOuter(signed int val, int x, int y, bool center,
if (negative) if (negative)
{ {
screen->DrawTexture(Images[imgNEGATIVE], x + 1, y + 1, screen->DrawTexture(Images[imgNEGATIVE], x + 1, y + 1,
DTA_FillColor, 0, DTA_AlphaF, HR_SHADOW, DTA_FillColor, 0, DTA_Alpha, HR_SHADOW,
DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal, TAG_DONE); DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal, TAG_DONE);
} }
@ -945,15 +945,13 @@ void DStrifeStatusBar::DrBNumberOuterFont(signed int val, int x, int y, int size
if (val == 0) if (val == 0)
{ {
pic = BigFont->GetChar('0', &v); pic = BigFont->GetChar('0', &v);
screen->DrawTexture(pic, xpos - v / 2 + 2, y + 2, screen->DrawChar(BigFont, CR_UNTRANSLATED, xpos - v / 2 + 2, y + 2, '0',
DTA_HUDRules, HUD_Normal, DTA_HUDRules, HUD_Normal,
DTA_AlphaF, HR_SHADOW, DTA_Alpha, HR_SHADOW,
DTA_FillColor, 0, DTA_FillColor, 0,
DTA_Translation, BigFont->GetColorTranslation(CR_UNTRANSLATED),
TAG_DONE); TAG_DONE);
screen->DrawTexture(pic, xpos - v / 2, y, screen->DrawChar(BigFont, CR_UNTRANSLATED, xpos - v / 2, y, '0',
DTA_HUDRules, HUD_Normal, DTA_HUDRules, HUD_Normal,
DTA_Translation, BigFont->GetColorTranslation(CR_UNTRANSLATED),
TAG_DONE); TAG_DONE);
return; return;
} }
@ -970,11 +968,10 @@ void DStrifeStatusBar::DrBNumberOuterFont(signed int val, int x, int y, int size
while (val != 0) while (val != 0)
{ {
pic = BigFont->GetChar('0' + val % 10, &v); pic = BigFont->GetChar('0' + val % 10, &v);
screen->DrawTexture(pic, xpos - v / 2 + 2, y + 2, screen->DrawChar(BigFont, CR_UNTRANSLATED, xpos - v / 2 + 2, y + 2,
DTA_HUDRules, HUD_Normal, DTA_HUDRules, HUD_Normal,
DTA_AlphaF, HR_SHADOW, DTA_Alpha, HR_SHADOW,
DTA_FillColor, 0, DTA_FillColor, 0,
DTA_Translation, BigFont->GetColorTranslation(CR_UNTRANSLATED),
TAG_DONE); TAG_DONE);
val /= 10; val /= 10;
xpos -= w; xpos -= w;
@ -984,11 +981,10 @@ void DStrifeStatusBar::DrBNumberOuterFont(signed int val, int x, int y, int size
pic = BigFont->GetChar('-', &v); pic = BigFont->GetChar('-', &v);
if (pic != NULL) if (pic != NULL)
{ {
screen->DrawTexture(pic, xpos - v / 2 + 2, y + 2, screen->DrawChar(BigFont, CR_UNTRANSLATED, xpos - v / 2 + 2, y + 2, '-',
DTA_HUDRules, HUD_Normal, DTA_HUDRules, HUD_Normal,
DTA_AlphaF, HR_SHADOW, DTA_Alpha, HR_SHADOW,
DTA_FillColor, 0, DTA_FillColor, 0,
DTA_Translation, BigFont->GetColorTranslation(CR_UNTRANSLATED),
TAG_DONE); TAG_DONE);
} }
} }
@ -999,9 +995,8 @@ void DStrifeStatusBar::DrBNumberOuterFont(signed int val, int x, int y, int size
while (val != 0) while (val != 0)
{ {
pic = BigFont->GetChar('0' + val % 10, &v); pic = BigFont->GetChar('0' + val % 10, &v);
screen->DrawTexture(pic, xpos - v / 2, y, screen->DrawChar(BigFont, CR_UNTRANSLATED, xpos - v / 2, y, '0',
DTA_HUDRules, HUD_Normal, DTA_HUDRules, HUD_Normal,
DTA_Translation, BigFont->GetColorTranslation(CR_UNTRANSLATED),
TAG_DONE); TAG_DONE);
val /= 10; val /= 10;
xpos -= w; xpos -= w;
@ -1011,9 +1006,8 @@ void DStrifeStatusBar::DrBNumberOuterFont(signed int val, int x, int y, int size
pic = BigFont->GetChar('-', &v); pic = BigFont->GetChar('-', &v);
if (pic != NULL) if (pic != NULL)
{ {
screen->DrawTexture(pic, xpos - v / 2, y, screen->DrawChar(BigFont, CR_UNTRANSLATED, xpos - v / 2, y, '-',
DTA_HUDRules, HUD_Normal, DTA_HUDRules, HUD_Normal,
DTA_Translation, BigFont->GetColorTranslation(CR_UNTRANSLATED),
TAG_DONE); TAG_DONE);
} }
} }
@ -1028,12 +1022,11 @@ void DStrifeStatusBar::DrBNumberOuterFont(signed int val, int x, int y, int size
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void DStrifeStatusBar::DrawImage(FTexture *img, void DStrifeStatusBar::DrawImage(FTexture *img,
int x, int y, FRemapTable *translation) const int x, int y) const
{ {
if (img != NULL) if (img != NULL)
{ {
screen->DrawTexture(img, x + ST_X, y + ST_Y, screen->DrawTexture(img, x + ST_X, y + ST_Y,
DTA_Translation, translation,
DTA_Bottom320x200, Scaled, DTA_Bottom320x200, Scaled,
TAG_DONE); TAG_DONE);
} }

View file

@ -388,15 +388,8 @@ void DIntermissionScreenText::Drawer ()
w *= CleanXfac; w *= CleanXfac;
if (cx + w > SCREENWIDTH) if (cx + w > SCREENWIDTH)
continue; continue;
if (pic != NULL)
{ screen->DrawChar(SmallFont, mTextColor, cx, cy, c, DTA_CleanNoMove, true, TAG_DONE);
screen->DrawTexture (pic,
cx,
cy,
DTA_Translation, range,
DTA_CleanNoMove, true,
TAG_DONE);
}
cx += w; cx += w;
} }
} }
@ -432,16 +425,15 @@ void DIntermissionScreenCast::Init(FIntermissionAction *desc, bool first)
if (mClass->IsDescendantOf(RUNTIME_CLASS(APlayerPawn))) if (mClass->IsDescendantOf(RUNTIME_CLASS(APlayerPawn)))
{ {
advplayerstate = mDefaults->MissileState; advplayerstate = mDefaults->MissileState;
casttranslation = translationtables[TRANSLATION_Players][consoleplayer]; casttranslation = TRANSLATION(TRANSLATION_Players, consoleplayer);
} }
else else
{ {
advplayerstate = NULL; advplayerstate = NULL;
casttranslation = NULL; casttranslation = 0;
if (mDefaults->Translation != 0) if (mDefaults->Translation != 0)
{ {
casttranslation = translationtables[GetTranslationType(mDefaults->Translation)] casttranslation = mDefaults->Translation;
[GetTranslationIndex(mDefaults->Translation)];
} }
} }
castdeath = false; castdeath = false;
@ -630,8 +622,8 @@ void DIntermissionScreenCast::Drawer ()
DTA_DestHeightF, pic->GetScaledHeightDouble() * castscale.Y, DTA_DestHeightF, pic->GetScaledHeightDouble() * castscale.Y,
DTA_DestWidthF, pic->GetScaledWidthDouble() * castscale.X, DTA_DestWidthF, pic->GetScaledWidthDouble() * castscale.X,
DTA_RenderStyle, mDefaults->RenderStyle, DTA_RenderStyle, mDefaults->RenderStyle,
DTA_AlphaF, mDefaults->Alpha, DTA_Alpha, mDefaults->Alpha,
DTA_Translation, casttranslation, DTA_TranslationIndex, casttranslation,
TAG_DONE); TAG_DONE);
} }
} }

View file

@ -234,7 +234,7 @@ class DIntermissionScreenCast : public DIntermissionScreen
TArray<FICastSound> mCastSounds; TArray<FICastSound> mCastSounds;
int casttics; int casttics;
const FRemapTable *casttranslation; // [RH] Draw "our hero" with their chosen suit color uint32_t casttranslation; // [RH] Draw "our hero" with their chosen suit color
FState* caststate; FState* caststate;
FState* basestate; FState* basestate;
FState* advplayerstate; FState* advplayerstate;

View file

@ -89,6 +89,10 @@ public:
desc->mItems[mStartItem+5] = new DOptionMenuItemStaticText(" ", false); desc->mItems[mStartItem+5] = new DOptionMenuItemStaticText(" ", false);
desc->mItems[mStartItem+6] = new DOptionMenuItemCommand("Undo changes", "undocolorpic"); desc->mItems[mStartItem+6] = new DOptionMenuItemCommand("Undo changes", "undocolorpic");
desc->mItems[mStartItem+7] = new DOptionMenuItemStaticText(" ", false); desc->mItems[mStartItem+7] = new DOptionMenuItemStaticText(" ", false);
for (auto &p : desc->mItems)
{
GC::WriteBarrier(p);
}
desc->mSelectedItem = mStartItem + 2; desc->mSelectedItem = mStartItem + 2;
Init(parent, desc); Init(parent, desc);
desc->mIndent = 0; desc->mIndent = 0;

View file

@ -322,6 +322,10 @@ FOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy)
opt->mItems.Push(it); opt->mItems.Push(it);
} }
} }
for (auto &p : opt->mItems)
{
GC::WriteBarrier(p);
}
opt->mScrollPos = 0; opt->mScrollPos = 0;
opt->mSelectedItem = -1; opt->mSelectedItem = -1;
opt->mIndent = 0; opt->mIndent = 0;
@ -402,6 +406,10 @@ void UpdateJoystickMenu(IJoystickConfig *selected)
if (i == itemnum) opt->mSelectedItem = opt->mItems.Size(); if (i == itemnum) opt->mSelectedItem = opt->mItems.Size();
} }
} }
for (auto &p : opt->mItems)
{
GC::WriteBarrier(p);
}
if (opt->mSelectedItem >= (int)opt->mItems.Size()) if (opt->mSelectedItem >= (int)opt->mItems.Size())
{ {
opt->mSelectedItem = opt->mItems.Size() - 1; opt->mSelectedItem = opt->mItems.Size() - 1;

View file

@ -44,6 +44,10 @@
IMPLEMENT_CLASS(DListMenu, false, false) IMPLEMENT_CLASS(DListMenu, false, false)
IMPLEMENT_POINTERS_START(DListMenu)
IMPLEMENT_POINTER(mFocusControl)
IMPLEMENT_POINTERS_END
//============================================================================= //=============================================================================
// //
// //
@ -101,7 +105,7 @@ void DListMenu::Init(DMenu *parent, FListMenuDescriptor *desc)
// //
//============================================================================= //=============================================================================
DListMenuItem *DListMenu::GetItem(FName name) DMenuItemBase *DListMenu::GetItem(FName name)
{ {
for(unsigned i=0;i<mDesc->mItems.Size(); i++) for(unsigned i=0;i<mDesc->mItems.Size(); i++)
{ {
@ -274,27 +278,27 @@ void DListMenu::Drawer ()
// base class for menu items // base class for menu items
// //
//============================================================================= //=============================================================================
IMPLEMENT_CLASS(DListMenuItem, true, false) IMPLEMENT_CLASS(DMenuItemBase, true, false)
bool DListMenuItem::CheckCoordinate(int x, int y) bool DMenuItemBase::CheckCoordinate(int x, int y)
{ {
return false; return false;
} }
void DListMenuItem::Ticker() void DMenuItemBase::Ticker()
{ {
} }
void DListMenuItem::Drawer(bool selected) void DMenuItemBase::Drawer(bool selected)
{ {
} }
bool DListMenuItem::Selectable() bool DMenuItemBase::Selectable()
{ {
return false; return false;
} }
void DListMenuItem::DrawSelector(int xofs, int yofs, FTextureID tex) void DMenuItemBase::DrawSelector(int xofs, int yofs, FTextureID tex)
{ {
if (tex.isNull()) if (tex.isNull())
{ {
@ -315,57 +319,57 @@ void DListMenuItem::DrawSelector(int xofs, int yofs, FTextureID tex)
} }
} }
bool DListMenuItem::Activate() bool DMenuItemBase::Activate()
{ {
return false; // cannot be activated return false; // cannot be activated
} }
FName DListMenuItem::GetAction(int *pparam) FName DMenuItemBase::GetAction(int *pparam)
{ {
return mAction; return mAction;
} }
bool DListMenuItem::SetString(int i, const char *s) bool DMenuItemBase::SetString(int i, const char *s)
{ {
return false; return false;
} }
bool DListMenuItem::GetString(int i, char *s, int len) bool DMenuItemBase::GetString(int i, char *s, int len)
{ {
return false; return false;
} }
bool DListMenuItem::SetValue(int i, int value) bool DMenuItemBase::SetValue(int i, int value)
{ {
return false; return false;
} }
bool DListMenuItem::GetValue(int i, int *pvalue) bool DMenuItemBase::GetValue(int i, int *pvalue)
{ {
return false; return false;
} }
void DListMenuItem::Enable(bool on) void DMenuItemBase::Enable(bool on)
{ {
mEnabled = on; mEnabled = on;
} }
bool DListMenuItem::MenuEvent(int mkey, bool fromcontroller) bool DMenuItemBase::MenuEvent(int mkey, bool fromcontroller)
{ {
return false; return false;
} }
bool DListMenuItem::MouseEvent(int type, int x, int y) bool DMenuItemBase::MouseEvent(int type, int x, int y)
{ {
return false; return false;
} }
bool DListMenuItem::CheckHotkey(int c) bool DMenuItemBase::CheckHotkey(int c)
{ {
return false; return false;
} }
int DListMenuItem::GetWidth() int DMenuItemBase::GetWidth()
{ {
return 0; return 0;
} }
@ -379,7 +383,7 @@ int DListMenuItem::GetWidth()
IMPLEMENT_CLASS(DListMenuItemStaticPatch, false, false) IMPLEMENT_CLASS(DListMenuItemStaticPatch, false, false)
DListMenuItemStaticPatch::DListMenuItemStaticPatch(int x, int y, FTextureID patch, bool centered) DListMenuItemStaticPatch::DListMenuItemStaticPatch(int x, int y, FTextureID patch, bool centered)
: DListMenuItem(x, y) : DMenuItemBase(x, y)
{ {
mTexture = patch; mTexture = patch;
mCentered = centered; mCentered = centered;
@ -415,7 +419,7 @@ void DListMenuItemStaticPatch::Drawer(bool selected)
IMPLEMENT_CLASS(DListMenuItemStaticText, false, false) IMPLEMENT_CLASS(DListMenuItemStaticText, false, false)
DListMenuItemStaticText::DListMenuItemStaticText(int x, int y, const char *text, FFont *font, EColorRange color, bool centered) DListMenuItemStaticText::DListMenuItemStaticText(int x, int y, const char *text, FFont *font, EColorRange color, bool centered)
: DListMenuItem(x, y) : DMenuItemBase(x, y)
{ {
mText = text; mText = text;
mFont = font; mFont = font;
@ -452,7 +456,7 @@ void DListMenuItemStaticText::Drawer(bool selected)
IMPLEMENT_CLASS(DListMenuItemSelectable, false, false) IMPLEMENT_CLASS(DListMenuItemSelectable, false, false)
DListMenuItemSelectable::DListMenuItemSelectable(int x, int y, int height, FName action, int param) DListMenuItemSelectable::DListMenuItemSelectable(int x, int y, int height, FName action, int param)
: DListMenuItem(x, y, action) : DMenuItemBase(x, y, action)
{ {
mHeight = height; mHeight = height;
mParam = param; mParam = param;

View file

@ -305,7 +305,7 @@ void DMenu::Drawer ()
} }
else else
{ {
screen->DrawTexture(tex, x, y, DTA_CleanNoMove, true, DTA_AlphaF, BackbuttonAlpha, TAG_DONE); screen->DrawTexture(tex, x, y, DTA_CleanNoMove, true, DTA_Alpha, BackbuttonAlpha, TAG_DONE);
} }
} }
} }

View file

@ -92,12 +92,12 @@ struct FMenuDescriptor
virtual size_t PropagateMark() { return 0; } virtual size_t PropagateMark() { return 0; }
}; };
class DListMenuItem; class DMenuItemBase;
class DOptionMenuItem; class DOptionMenuItem;
struct FListMenuDescriptor : public FMenuDescriptor struct FListMenuDescriptor : public FMenuDescriptor
{ {
TArray<DListMenuItem *> mItems; TArray<DMenuItemBase *> mItems;
int mSelectedItem; int mSelectedItem;
int mSelectOfsX; int mSelectOfsX;
int mSelectOfsY; int mSelectOfsY;
@ -255,9 +255,9 @@ public:
// //
//============================================================================= //=============================================================================
class DListMenuItem : public DObject class DMenuItemBase : public DObject
{ {
DECLARE_CLASS(DListMenuItem, DObject) DECLARE_CLASS(DMenuItemBase, DObject)
protected: protected:
int mXpos, mYpos; int mXpos, mYpos;
FName mAction; FName mAction;
@ -265,7 +265,7 @@ protected:
public: public:
bool mEnabled; bool mEnabled;
DListMenuItem(int xpos = 0, int ypos = 0, FName action = NAME_None) DMenuItemBase(int xpos = 0, int ypos = 0, FName action = NAME_None)
{ {
mXpos = xpos; mXpos = xpos;
mYpos = ypos; mYpos = ypos;
@ -295,9 +295,9 @@ public:
void SetX(int x) { mXpos = x; } void SetX(int x) { mXpos = x; }
}; };
class DListMenuItemStaticPatch : public DListMenuItem class DListMenuItemStaticPatch : public DMenuItemBase
{ {
DECLARE_CLASS(DListMenuItemStaticPatch, DListMenuItem) DECLARE_CLASS(DListMenuItemStaticPatch, DMenuItemBase)
protected: protected:
FTextureID mTexture; FTextureID mTexture;
bool mCentered; bool mCentered;
@ -308,9 +308,9 @@ public:
void Drawer(bool selected); void Drawer(bool selected);
}; };
class DListMenuItemStaticText : public DListMenuItem class DListMenuItemStaticText : public DMenuItemBase
{ {
DECLARE_CLASS(DListMenuItemStaticText, DListMenuItem) DECLARE_CLASS(DListMenuItemStaticText, DMenuItemBase)
protected: protected:
FString mText; FString mText;
FFont *mFont; FFont *mFont;
@ -329,9 +329,9 @@ public:
// //
//============================================================================= //=============================================================================
class DListMenuItemPlayerDisplay : public DListMenuItem class DListMenuItemPlayerDisplay : public DMenuItemBase
{ {
DECLARE_CLASS(DListMenuItemPlayerDisplay, DListMenuItem) DECLARE_CLASS(DListMenuItemPlayerDisplay, DMenuItemBase)
FListMenuDescriptor *mOwner; FListMenuDescriptor *mOwner;
FTexture *mBackdrop; FTexture *mBackdrop;
@ -379,9 +379,9 @@ public:
// //
//============================================================================= //=============================================================================
class DListMenuItemSelectable : public DListMenuItem class DListMenuItemSelectable : public DMenuItemBase
{ {
DECLARE_CLASS(DListMenuItemSelectable, DListMenuItem) DECLARE_CLASS(DListMenuItemSelectable, DMenuItemBase)
protected: protected:
int mHotkey; int mHotkey;
int mHeight; int mHeight;
@ -520,25 +520,26 @@ public:
class DListMenu : public DMenu class DListMenu : public DMenu
{ {
DECLARE_CLASS(DListMenu, DMenu) DECLARE_CLASS(DListMenu, DMenu)
HAS_OBJECT_POINTERS;
protected: protected:
FListMenuDescriptor *mDesc; FListMenuDescriptor *mDesc;
DListMenuItem *mFocusControl; DMenuItemBase *mFocusControl;
public: public:
DListMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); DListMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL);
virtual void Init(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); virtual void Init(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL);
DListMenuItem *GetItem(FName name); DMenuItemBase *GetItem(FName name);
bool Responder (event_t *ev); bool Responder (event_t *ev);
bool MenuEvent (int mkey, bool fromcontroller); bool MenuEvent (int mkey, bool fromcontroller);
bool MouseEvent(int type, int x, int y); bool MouseEvent(int type, int x, int y);
void Ticker (); void Ticker ();
void Drawer (); void Drawer ();
void SetFocus(DListMenuItem *fc) void SetFocus(DMenuItemBase *fc)
{ {
mFocusControl = fc; mFocusControl = fc;
} }
bool CheckFocus(DListMenuItem *fc) bool CheckFocus(DMenuItemBase *fc)
{ {
return mFocusControl == fc; return mFocusControl == fc;
} }
@ -555,9 +556,9 @@ public:
// //
//============================================================================= //=============================================================================
class DOptionMenuItem : public DListMenuItem class DOptionMenuItem : public DMenuItemBase
{ {
DECLARE_ABSTRACT_CLASS(DOptionMenuItem, DListMenuItem) DECLARE_ABSTRACT_CLASS(DOptionMenuItem, DMenuItemBase)
protected: protected:
FString mLabel; FString mLabel;
bool mCentered; bool mCentered;
@ -566,7 +567,7 @@ protected:
public: public:
DOptionMenuItem(const char *text = nullptr, FName action = NAME_None, bool center = false) DOptionMenuItem(const char *text = nullptr, FName action = NAME_None, bool center = false)
: DListMenuItem(0, 0, action) : DMenuItemBase(0, 0, action)
{ {
mLabel = text; mLabel = text;
mCentered = center; mCentered = center;
@ -609,6 +610,7 @@ extern FOptionMap OptionValues;
class DOptionMenu : public DMenu class DOptionMenu : public DMenu
{ {
DECLARE_CLASS(DOptionMenu, DMenu) DECLARE_CLASS(DOptionMenu, DMenu)
HAS_OBJECT_POINTERS;
bool CanScrollUp; bool CanScrollUp;
bool CanScrollDown; bool CanScrollDown;

View file

@ -294,7 +294,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
sc.MustGetString(); sc.MustGetString();
FTextureID tex = GetMenuTexture(sc.String); FTextureID tex = GetMenuTexture(sc.String);
DListMenuItem *it = new DListMenuItemStaticPatch(x, y, tex, centered); DMenuItemBase *it = new DListMenuItemStaticPatch(x, y, tex, centered);
desc->mItems.Push(it); desc->mItems.Push(it);
} }
else if (sc.Compare("StaticText") || sc.Compare("StaticTextCentered")) else if (sc.Compare("StaticText") || sc.Compare("StaticTextCentered"))
@ -315,7 +315,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
cr = V_FindFontColor(sc.String); cr = V_FindFontColor(sc.String);
if (cr == CR_UNTRANSLATED && !sc.Compare("untranslated")) cr = desc->mFontColor; if (cr == CR_UNTRANSLATED && !sc.Compare("untranslated")) cr = desc->mFontColor;
} }
DListMenuItem *it = new DListMenuItemStaticText(x, y, label, desc->mFont, cr, centered); DMenuItemBase *it = new DListMenuItemStaticText(x, y, label, desc->mFont, cr, centered);
desc->mItems.Push(it); desc->mItems.Push(it);
} }
else if (sc.Compare("PatchItem")) else if (sc.Compare("PatchItem"))
@ -335,7 +335,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
param = sc.Number; param = sc.Number;
} }
DListMenuItem *it = new DListMenuItemPatch(desc->mXpos, desc->mYpos, desc->mLinespacing, hotkey, tex, action, param); DMenuItemBase *it = new DListMenuItemPatch(desc->mXpos, desc->mYpos, desc->mLinespacing, hotkey, tex, action, param);
desc->mItems.Push(it); desc->mItems.Push(it);
desc->mYpos += desc->mLinespacing; desc->mYpos += desc->mLinespacing;
if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1;
@ -357,7 +357,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
param = sc.Number; param = sc.Number;
} }
DListMenuItem *it = new DListMenuItemText(desc->mXpos, desc->mYpos, desc->mLinespacing, hotkey, text, desc->mFont, desc->mFontColor, desc->mFontColor2, action, param); DMenuItemBase *it = new DListMenuItemText(desc->mXpos, desc->mYpos, desc->mLinespacing, hotkey, text, desc->mFont, desc->mFontColor, desc->mFontColor2, action, param);
desc->mItems.Push(it); desc->mItems.Push(it);
desc->mYpos += desc->mLinespacing; desc->mYpos += desc->mLinespacing;
if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1;
@ -426,7 +426,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
int ofs = sc.Number; int ofs = sc.Number;
sc.MustGetStringName(","); sc.MustGetStringName(",");
sc.MustGetString(); sc.MustGetString();
DListMenuItem *it = new DPlayerNameBox(desc->mXpos, desc->mYpos, desc->mLinespacing, ofs, text, desc->mFont, desc->mFontColor, sc.String); DMenuItemBase *it = new DPlayerNameBox(desc->mXpos, desc->mYpos, desc->mLinespacing, ofs, text, desc->mFont, desc->mFontColor, sc.String);
desc->mItems.Push(it); desc->mItems.Push(it);
desc->mYpos += desc->mLinespacing; desc->mYpos += desc->mLinespacing;
if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1;
@ -444,7 +444,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
sc.MustGetString(); sc.MustGetString();
values = sc.String; values = sc.String;
} }
DListMenuItem *it = new DValueTextItem(desc->mXpos, desc->mYpos, desc->mLinespacing, text, desc->mFont, desc->mFontColor, desc->mFontColor2, action, values); DMenuItemBase *it = new DValueTextItem(desc->mXpos, desc->mYpos, desc->mLinespacing, text, desc->mFont, desc->mFontColor, desc->mFontColor2, action, values);
desc->mItems.Push(it); desc->mItems.Push(it);
desc->mYpos += desc->mLinespacing; desc->mYpos += desc->mLinespacing;
if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1;
@ -465,7 +465,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
sc.MustGetStringName(","); sc.MustGetStringName(",");
sc.MustGetNumber(); sc.MustGetNumber();
int step = sc.Number; int step = sc.Number;
DListMenuItem *it = new DSliderItem(desc->mXpos, desc->mYpos, desc->mLinespacing, text, desc->mFont, desc->mFontColor, action, min, max, step); DMenuItemBase *it = new DSliderItem(desc->mXpos, desc->mYpos, desc->mLinespacing, text, desc->mFont, desc->mFontColor, action, min, max, step);
desc->mItems.Push(it); desc->mItems.Push(it);
desc->mYpos += desc->mLinespacing; desc->mYpos += desc->mLinespacing;
if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1;
@ -475,6 +475,10 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
sc.ScriptError("Unknown keyword '%s'", sc.String); sc.ScriptError("Unknown keyword '%s'", sc.String);
} }
} }
for (auto &p : desc->mItems)
{
GC::WriteBarrier(p);
}
} }
//============================================================================= //=============================================================================
@ -927,6 +931,10 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc)
sc.ScriptError("Unknown keyword '%s'", sc.String); sc.ScriptError("Unknown keyword '%s'", sc.String);
} }
} }
for (auto &p : desc->mItems)
{
GC::WriteBarrier(p);
}
} }
//============================================================================= //=============================================================================
@ -1081,7 +1089,7 @@ static void BuildEpisodeMenu()
ld->mSelectedItem = ld->mItems.Size(); ld->mSelectedItem = ld->mItems.Size();
for(unsigned i = 0; i < AllEpisodes.Size(); i++) for(unsigned i = 0; i < AllEpisodes.Size(); i++)
{ {
DListMenuItem *it; DMenuItemBase *it;
if (AllEpisodes[i].mPicName.IsNotEmpty()) if (AllEpisodes[i].mPicName.IsNotEmpty())
{ {
FTextureID tex = GetMenuTexture(AllEpisodes[i].mPicName); FTextureID tex = GetMenuTexture(AllEpisodes[i].mPicName);
@ -1101,6 +1109,10 @@ static void BuildEpisodeMenu()
ld->mAutoselect = ld->mSelectedItem; ld->mAutoselect = ld->mSelectedItem;
} }
success = true; success = true;
for (auto &p : ld->mItems)
{
GC::WriteBarrier(p);
}
} }
} }
} }
@ -1125,6 +1137,7 @@ static void BuildEpisodeMenu()
{ {
DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu(AllEpisodes[i].mEpisodeName, "Skillmenu", i); DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu(AllEpisodes[i].mEpisodeName, "Skillmenu", i);
od->mItems.Push(it); od->mItems.Push(it);
GC::WriteBarrier(it);
} }
} }
} }
@ -1230,6 +1243,10 @@ static void BuildPlayerclassMenu()
} }
} }
success = true; success = true;
for (auto &p : ld->mItems)
{
GC::WriteBarrier(p);
}
} }
} }
} }
@ -1261,11 +1278,13 @@ static void BuildPlayerclassMenu()
{ {
DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu(pname, "Episodemenu", i); DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu(pname, "Episodemenu", i);
od->mItems.Push(it); od->mItems.Push(it);
GC::WriteBarrier(it);
} }
} }
} }
DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu("Random", "Episodemenu", -1); DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu("Random", "Episodemenu", -1);
od->mItems.Push(it); od->mItems.Push(it);
GC::WriteBarrier(it);
} }
} }
@ -1355,6 +1374,10 @@ static void InitKeySections()
menu->mItems.Push(item); menu->mItems.Push(item);
} }
} }
for (auto &p : menu->mItems)
{
GC::WriteBarrier(p);
}
} }
} }
} }
@ -1465,7 +1488,7 @@ void M_StartupSkillMenu(FGameStartup *gs)
for(unsigned int i = 0; i < AllSkills.Size(); i++) for(unsigned int i = 0; i < AllSkills.Size(); i++)
{ {
FSkillInfo &skill = AllSkills[i]; FSkillInfo &skill = AllSkills[i];
DListMenuItem *li; DMenuItemBase *li;
// Using a different name for skills that must be confirmed makes handling this easier. // Using a different name for skills that must be confirmed makes handling this easier.
FName action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ? FName action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ?
NAME_StartgameConfirm : NAME_Startgame; NAME_StartgameConfirm : NAME_Startgame;
@ -1488,6 +1511,7 @@ void M_StartupSkillMenu(FGameStartup *gs)
pItemText? *pItemText : skill.MenuName, ld->mFont, color,ld->mFontColor2, action, i); pItemText? *pItemText : skill.MenuName, ld->mFont, color,ld->mFontColor2, action, i);
} }
ld->mItems.Push(li); ld->mItems.Push(li);
GC::WriteBarrier(li);
y += ld->mLinespacing; y += ld->mLinespacing;
} }
if (AllEpisodes[gs->Episode].mNoSkill || AllSkills.Size() == 1) if (AllEpisodes[gs->Episode].mNoSkill || AllSkills.Size() == 1)
@ -1541,6 +1565,7 @@ fail:
} }
li = new DOptionMenuItemSubmenu(pItemText? *pItemText : skill.MenuName, action, i); li = new DOptionMenuItemSubmenu(pItemText? *pItemText : skill.MenuName, action, i);
od->mItems.Push(li); od->mItems.Push(li);
GC::WriteBarrier(li);
if (!done) if (!done)
{ {
done = true; done = true;

View file

@ -332,29 +332,25 @@ void DTextEnterMenu::Drawer ()
const int ch = InputGridChars[y * INPUTGRID_WIDTH + x]; const int ch = InputGridChars[y * INPUTGRID_WIDTH + x];
FTexture *pic = SmallFont->GetChar(ch, &width); FTexture *pic = SmallFont->GetChar(ch, &width);
EColorRange color; EColorRange color;
FRemapTable *remap;
// The highlighted character is yellow; the rest are dark gray. // The highlighted character is yellow; the rest are dark gray.
color = (x == InputGridX && y == InputGridY) ? CR_YELLOW : CR_DARKGRAY; color = (x == InputGridX && y == InputGridY) ? CR_YELLOW : CR_DARKGRAY;
remap = SmallFont->GetColorTranslation(color);
if (pic != NULL) if (pic != NULL)
{ {
// Draw a normal character. // Draw a normal character.
screen->DrawTexture(pic, xx + cell_width/2 - width*CleanXfac/2, yy + top_padding, screen->DrawChar(SmallFont, color, xx + cell_width/2 - width*CleanXfac/2, yy + top_padding, ch, DTA_CleanNoMove, true, TAG_DONE);
DTA_Translation, remap,
DTA_CleanNoMove, true,
TAG_DONE);
} }
else if (ch == ' ') else if (ch == ' ')
{ {
FRemapTable *remap = SmallFont->GetColorTranslation(color);
// Draw the space as a box outline. We also draw it 50% wider than it really is. // Draw the space as a box outline. We also draw it 50% wider than it really is.
const int x1 = xx + cell_width/2 - width * CleanXfac * 3 / 4; const int x1 = xx + cell_width/2 - width * CleanXfac * 3 / 4;
const int x2 = x1 + width * 3 * CleanXfac / 2; const int x2 = x1 + width * 3 * CleanXfac / 2;
const int y1 = yy + top_padding; const int y1 = yy + top_padding;
const int y2 = y1 + SmallFont->GetHeight() * CleanYfac; const int y2 = y1 + SmallFont->GetHeight() * CleanYfac;
const int palentry = remap->Remap[remap->NumEntries*2/3]; const int palentry = remap->Remap[remap->NumEntries * 2 / 3];
const uint32 palcolor = remap->Palette[remap->NumEntries*2/3]; const uint32 palcolor = remap->Palette[remap->NumEntries * 2 / 3];
screen->Clear(x1, y1, x2, y1+CleanYfac, palentry, palcolor); // top screen->Clear(x1, y1, x2, y1+CleanYfac, palentry, palcolor); // top
screen->Clear(x1, y2, x2, y2+CleanYfac, palentry, palcolor); // bottom screen->Clear(x1, y2, x2, y2+CleanYfac, palentry, palcolor); // bottom
screen->Clear(x1, y1+CleanYfac, x1+CleanXfac, y2, palentry, palcolor); // left screen->Clear(x1, y1+CleanYfac, x1+CleanXfac, y2, palentry, palcolor); // left

View file

@ -66,6 +66,10 @@ void M_DrawConText (int color, int x, int y, const char *str)
IMPLEMENT_CLASS(DOptionMenu, false, false) IMPLEMENT_CLASS(DOptionMenu, false, false)
IMPLEMENT_POINTERS_START(DOptionMenu)
IMPLEMENT_POINTER(mFocusControl)
IMPLEMENT_POINTERS_END
//============================================================================= //=============================================================================
// //
// //

View file

@ -402,7 +402,7 @@ public:
if (mParentMenu->IsKindOf(RUNTIME_CLASS(DOptionMenu))) if (mParentMenu->IsKindOf(RUNTIME_CLASS(DOptionMenu)))
{ {
DOptionMenu *m = barrier_cast<DOptionMenu*>(mParentMenu); DOptionMenu *m = barrier_cast<DOptionMenu*>(mParentMenu);
DListMenuItem *it = m->GetItem(NAME_Controlmessage); DMenuItemBase *it = m->GetItem(NAME_Controlmessage);
if (it != NULL) if (it != NULL)
{ {
it->SetValue(0, which); it->SetValue(0, which);
@ -1242,7 +1242,7 @@ IMPLEMENT_CLASS(DOptionMenuTextField, false, false)
//============================================================================= //=============================================================================
// //
// [TP] DOptionMenuNumberField // [TP] FOptionMenuNumberField
// //
// A numeric input field widget, for use with number CVars where sliders are inappropriate (i.e. // A numeric input field widget, for use with number CVars where sliders are inappropriate (i.e.
// where the user is interested in the exact value specifically) // where the user is interested in the exact value specifically)

View file

@ -355,19 +355,19 @@ void FBackdropTexture::Render()
// //
//============================================================================= //=============================================================================
IMPLEMENT_CLASS(DListMenuItemPlayerDisplay, false, false) IMPLEMENT_CLASS(DListMenuItemPlayerDisplay, false, false)
DListMenuItemPlayerDisplay::DListMenuItemPlayerDisplay(FListMenuDescriptor *menu, int x, int y, PalEntry c1, PalEntry c2, bool np, FName action) DListMenuItemPlayerDisplay::DListMenuItemPlayerDisplay(FListMenuDescriptor *menu, int x, int y, PalEntry c1, PalEntry c2, bool np, FName action)
: DListMenuItem(x, y, action) : DMenuItemBase(x, y, action)
{ {
mOwner = menu; mOwner = menu;
FRemapTable *bdremap = translationtables[TRANSLATION_Players][MAXPLAYERS + 1];
for (int i = 0; i < 256; i++) for (int i = 0; i < 256; i++)
{ {
int r = c1.r + c2.r * i / 255; int r = c1.r + c2.r * i / 255;
int g = c1.g + c2.g * i / 255; int g = c1.g + c2.g * i / 255;
int b = c1.b + c2.b * i / 255; int b = c1.b + c2.b * i / 255;
mRemap.Remap[i] = ColorMatcher.Pick (r, g, b); bdremap->Remap[i] = ColorMatcher.Pick (r, g, b);
mRemap.Palette[i] = PalEntry(255, r, g, b); bdremap->Palette[i] = PalEntry(255, r, g, b);
} }
mBackdrop = new FBackdropTexture; mBackdrop = new FBackdropTexture;
mPlayerClass = NULL; mPlayerClass = NULL;
@ -575,10 +575,10 @@ void DListMenuItemPlayerDisplay::Drawer(bool selected)
int x = (mXpos - 160) * CleanXfac + (SCREENWIDTH>>1); int x = (mXpos - 160) * CleanXfac + (SCREENWIDTH>>1);
int y = (mYpos - 100) * CleanYfac + (SCREENHEIGHT>>1); int y = (mYpos - 100) * CleanYfac + (SCREENHEIGHT>>1);
screen->DrawTexture (mBackdrop, x, y - 1, screen->DrawTexture(mBackdrop, x, y - 1,
DTA_DestWidth, 72 * CleanXfac, DTA_DestWidth, 72 * CleanXfac,
DTA_DestHeight, 80 * CleanYfac, DTA_DestHeight, 80 * CleanYfac,
DTA_Translation, &mRemap, DTA_TranslationIndex, TRANSLATION(TRANSLATION_Players, MAXPLAYERS + 1),
DTA_Masked, true, DTA_Masked, true,
TAG_DONE); TAG_DONE);
@ -606,13 +606,12 @@ void DListMenuItemPlayerDisplay::Drawer(bool selected)
FTexture *tex = TexMan(sprframe->Texture[mRotation]); FTexture *tex = TexMan(sprframe->Texture[mRotation]);
if (tex != NULL && tex->UseType != FTexture::TEX_Null) if (tex != NULL && tex->UseType != FTexture::TEX_Null)
{ {
FRemapTable *trans = NULL; int trans = mTranslate? TRANSLATION(TRANSLATION_Players, MAXPLAYERS) : 0;
if (mTranslate) trans = translationtables[TRANSLATION_Players](MAXPLAYERS);
screen->DrawTexture (tex, screen->DrawTexture (tex,
x + 36*CleanXfac, y + 71*CleanYfac, x + 36*CleanXfac, y + 71*CleanYfac,
DTA_DestWidthF, tex->GetScaledWidthDouble() * CleanXfac * Scale.X, DTA_DestWidthF, tex->GetScaledWidthDouble() * CleanXfac * Scale.X,
DTA_DestHeightF, tex->GetScaledHeightDouble() * CleanYfac * Scale.Y, DTA_DestHeightF, tex->GetScaledHeightDouble() * CleanYfac * Scale.Y,
DTA_Translation, trans, DTA_TranslationIndex, trans,
DTA_FlipX, sprframe->Flip & (1 << mRotation), DTA_FlipX, sprframe->Flip & (1 << mRotation),
TAG_DONE); TAG_DONE);
} }

View file

@ -499,11 +499,11 @@ class DPlayerMenu : public DListMenu
void UpdateTranslation(); void UpdateTranslation();
void SendNewColor (int red, int green, int blue); void SendNewColor (int red, int green, int blue);
void PlayerNameChanged(DListMenuItem *li); void PlayerNameChanged(DMenuItemBase *li);
void ColorSetChanged (DListMenuItem *li); void ColorSetChanged (DMenuItemBase *li);
void ClassChanged (DListMenuItem *li); void ClassChanged (DMenuItemBase *li);
void AutoaimChanged (DListMenuItem *li); void AutoaimChanged (DMenuItemBase *li);
void SkinChanged (DListMenuItem *li); void SkinChanged (DMenuItemBase *li);
public: public:
@ -527,7 +527,7 @@ IMPLEMENT_CLASS(DPlayerMenu, false, false)
void DPlayerMenu::Init(DMenu *parent, FListMenuDescriptor *desc) void DPlayerMenu::Init(DMenu *parent, FListMenuDescriptor *desc)
{ {
DListMenuItem *li; DMenuItemBase *li;
Super::Init(parent, desc); Super::Init(parent, desc);
PickPlayerClass(); PickPlayerClass();
@ -655,7 +655,7 @@ bool DPlayerMenu::Responder (event_t *ev)
{ {
// turn the player sprite around // turn the player sprite around
mRotation = 8 - mRotation; mRotation = 8 - mRotation;
DListMenuItem *li = GetItem(NAME_Playerdisplay); DMenuItemBase *li = GetItem(NAME_Playerdisplay);
if (li != NULL) if (li != NULL)
{ {
li->SetValue(DListMenuItemPlayerDisplay::PDF_ROTATION, mRotation); li->SetValue(DListMenuItemPlayerDisplay::PDF_ROTATION, mRotation);
@ -745,7 +745,7 @@ void DPlayerMenu::SendNewColor (int red, int green, int blue)
void DPlayerMenu::UpdateColorsets() void DPlayerMenu::UpdateColorsets()
{ {
DListMenuItem *li = GetItem(NAME_Color); DMenuItemBase *li = GetItem(NAME_Color);
if (li != NULL) if (li != NULL)
{ {
int sel = 0; int sel = 0;
@ -781,7 +781,7 @@ void DPlayerMenu::UpdateSkins()
{ {
int sel = 0; int sel = 0;
int skin; int skin;
DListMenuItem *li = GetItem(NAME_Skin); DMenuItemBase *li = GetItem(NAME_Skin);
if (li != NULL) if (li != NULL)
{ {
if (GetDefaultByType (PlayerClass->Type)->flags4 & MF4_NOSKIN || if (GetDefaultByType (PlayerClass->Type)->flags4 & MF4_NOSKIN ||
@ -824,7 +824,7 @@ void DPlayerMenu::UpdateSkins()
// //
//============================================================================= //=============================================================================
void DPlayerMenu::PlayerNameChanged(DListMenuItem *li) void DPlayerMenu::PlayerNameChanged(DMenuItemBase *li)
{ {
char pp[MAXPLAYERNAME+1]; char pp[MAXPLAYERNAME+1];
const char *p; const char *p;
@ -852,7 +852,7 @@ void DPlayerMenu::PlayerNameChanged(DListMenuItem *li)
// //
//============================================================================= //=============================================================================
void DPlayerMenu::ColorSetChanged (DListMenuItem *li) void DPlayerMenu::ColorSetChanged (DMenuItemBase *li)
{ {
int sel; int sel;
@ -862,9 +862,9 @@ void DPlayerMenu::ColorSetChanged (DListMenuItem *li)
if (sel > 0) mycolorset = PlayerColorSets[sel-1]; if (sel > 0) mycolorset = PlayerColorSets[sel-1];
DListMenuItem *red = GetItem(NAME_Red); DMenuItemBase *red = GetItem(NAME_Red);
DListMenuItem *green = GetItem(NAME_Green); DMenuItemBase *green = GetItem(NAME_Green);
DListMenuItem *blue = GetItem(NAME_Blue); DMenuItemBase *blue = GetItem(NAME_Blue);
// disable the sliders if a valid colorset is selected // disable the sliders if a valid colorset is selected
if (red != NULL) red->Enable(mycolorset == -1); if (red != NULL) red->Enable(mycolorset == -1);
@ -885,7 +885,7 @@ void DPlayerMenu::ColorSetChanged (DListMenuItem *li)
// //
//============================================================================= //=============================================================================
void DPlayerMenu::ClassChanged (DListMenuItem *li) void DPlayerMenu::ClassChanged (DMenuItemBase *li)
{ {
if (PlayerClasses.Size () == 1) if (PlayerClasses.Size () == 1)
{ {
@ -919,7 +919,7 @@ void DPlayerMenu::ClassChanged (DListMenuItem *li)
// //
//============================================================================= //=============================================================================
void DPlayerMenu::SkinChanged (DListMenuItem *li) void DPlayerMenu::SkinChanged (DMenuItemBase *li)
{ {
if (GetDefaultByType (PlayerClass->Type)->flags4 & MF4_NOSKIN || if (GetDefaultByType (PlayerClass->Type)->flags4 & MF4_NOSKIN ||
players[consoleplayer].userinfo.GetPlayerClassNum() == -1) players[consoleplayer].userinfo.GetPlayerClassNum() == -1)
@ -950,7 +950,7 @@ void DPlayerMenu::SkinChanged (DListMenuItem *li)
// //
//============================================================================= //=============================================================================
void DPlayerMenu::AutoaimChanged (DListMenuItem *li) void DPlayerMenu::AutoaimChanged (DMenuItemBase *li)
{ {
int sel; int sel;
@ -971,7 +971,7 @@ bool DPlayerMenu::MenuEvent (int mkey, bool fromcontroller)
int v; int v;
if (mDesc->mSelectedItem >= 0) if (mDesc->mSelectedItem >= 0)
{ {
DListMenuItem *li = mDesc->mItems[mDesc->mSelectedItem]; DMenuItemBase *li = mDesc->mItems[mDesc->mSelectedItem];
if (li->MenuEvent(mkey, fromcontroller)) if (li->MenuEvent(mkey, fromcontroller))
{ {
FName current = li->GetAction(NULL); FName current = li->GetAction(NULL);
@ -1067,7 +1067,7 @@ bool DPlayerMenu::MenuEvent (int mkey, bool fromcontroller)
bool DPlayerMenu::MouseEvent(int type, int x, int y) bool DPlayerMenu::MouseEvent(int type, int x, int y)
{ {
int v; int v;
DListMenuItem *li = mFocusControl; DMenuItemBase *li = mFocusControl;
bool res = Super::MouseEvent(type, x, y); bool res = Super::MouseEvent(type, x, y);
if (li == NULL) li = mFocusControl; if (li == NULL) li = mFocusControl;
if (li != NULL) if (li != NULL)

View file

@ -105,7 +105,7 @@ void DReadThisMenu::Drawer()
{ {
screen->DrawTexture (prevpic, 0, 0, DTA_Fullscreen, true, TAG_DONE); screen->DrawTexture (prevpic, 0, 0, DTA_Fullscreen, true, TAG_DONE);
} }
screen->DrawTexture (tex, 0, 0, DTA_Fullscreen, true, DTA_AlphaF, alpha, TAG_DONE); screen->DrawTexture (tex, 0, 0, DTA_Fullscreen, true, DTA_Alpha, alpha, TAG_DONE);
} }

View file

@ -346,6 +346,7 @@ xx(SinH)
xx(TanH) xx(TanH)
xx(ATan2) xx(ATan2)
xx(VectorAngle) xx(VectorAngle)
xx(New)
xx(Alpha) xx(Alpha)
xx(Angle) xx(Angle)
xx(Args) xx(Args)

View file

@ -79,6 +79,7 @@
#include "thingdef.h" #include "thingdef.h"
#include "math/cmath.h" #include "math/cmath.h"
#include "g_levellocals.h" #include "g_levellocals.h"
#include "r_utility.h"
AActor *SingleActorFromTID(int tid, AActor *defactor); AActor *SingleActorFromTID(int tid, AActor *defactor);
@ -6913,3 +6914,27 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetSize)
ACTION_RETURN_BOOL(true); ACTION_RETURN_BOOL(true);
} }
DEFINE_ACTION_FUNCTION(AActor, SetCamera)
{
PARAM_ACTION_PROLOGUE(AActor);
PARAM_OBJECT(cam, AActor);
PARAM_BOOL_DEF(revert);
if (self->player == nullptr || self->player->mo != self) return 0;
if (camera == nullptr)
{
camera = self;
revert = false;
}
AActor *oldcamera = self->player->camera;
self->player->camera = camera;
if (revert) self->player->cheats |= CF_REVERTPLEASE;
if (oldcamera != camera)
{
R_ClearPastViewer(camera);
}
return 0;
}

View file

@ -1061,10 +1061,10 @@ public:
mysnprintf(goldstr, countof(goldstr), "%d", coin != NULL ? coin->Amount : 0); mysnprintf(goldstr, countof(goldstr), "%d", coin != NULL ? coin->Amount : 0);
screen->DrawText(SmallFont, CR_GRAY, 21, 191, goldstr, DTA_320x200, true, screen->DrawText(SmallFont, CR_GRAY, 21, 191, goldstr, DTA_320x200, true,
DTA_FillColor, 0, DTA_AlphaF, HR_SHADOW, TAG_DONE); DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, TAG_DONE);
screen->DrawTexture(TexMan(((AInventory *)GetDefaultByType(cointype))->Icon), screen->DrawTexture(TexMan(((AInventory *)GetDefaultByType(cointype))->Icon),
3, 190, DTA_320x200, true, 3, 190, DTA_320x200, true,
DTA_FillColor, 0, DTA_AlphaF, HR_SHADOW, TAG_DONE); DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, TAG_DONE);
screen->DrawText(SmallFont, CR_GRAY, 20, 190, goldstr, DTA_320x200, true, TAG_DONE); screen->DrawText(SmallFont, CR_GRAY, 20, 190, goldstr, DTA_320x200, true, TAG_DONE);
screen->DrawTexture(TexMan(((AInventory *)GetDefaultByType(cointype))->Icon), screen->DrawTexture(TexMan(((AInventory *)GetDefaultByType(cointype))->Icon),
2, 189, DTA_320x200, true, TAG_DONE); 2, 189, DTA_320x200, true, TAG_DONE);

View file

@ -570,8 +570,9 @@ bool P_Move (AActor *actor)
return true; return true;
} }
if (actor->movedir == DI_NODIR) if (actor->movedir >= DI_NODIR)
{ {
actor->movedir = DI_NODIR; // make sure it's valid.
return false; return false;
} }
@ -585,9 +586,6 @@ bool P_Move (AActor *actor)
return false; return false;
} }
if ((unsigned)actor->movedir >= 8)
I_Error ("Weird actor->movedir!");
// killough 10/98: allow dogs to drop off of taller ledges sometimes. // killough 10/98: allow dogs to drop off of taller ledges sometimes.
// dropoff==1 means always allow it, dropoff==2 means only up to 128 high, // dropoff==1 means always allow it, dropoff==2 means only up to 128 high,
// and only if the target is immediately on the other side of the line. // and only if the target is immediately on the other side of the line.

View file

@ -740,6 +740,8 @@ void R_InitTranslationTables ()
} }
// The menu player also gets a separate translation table // The menu player also gets a separate translation table
PushIdentityTable(TRANSLATION_Players); PushIdentityTable(TRANSLATION_Players);
// This one is for the backdrop in the menu
PushIdentityTable(TRANSLATION_Players);
// The three standard translations from Doom or Heretic (seven for Strife), // The three standard translations from Doom or Heretic (seven for Strife),
// plus the generic ice translation. // plus the generic ice translation.

View file

@ -1713,7 +1713,7 @@ void R_DrawRemainingPlayerSprites()
viewwindowy + viewheight/2 - vis->texturemid * vis->yscale - 0.5, viewwindowy + viewheight/2 - vis->texturemid * vis->yscale - 0.5,
DTA_DestWidthF, FIXED2DBL(vis->pic->GetWidth() * vis->xscale), DTA_DestWidthF, FIXED2DBL(vis->pic->GetWidth() * vis->xscale),
DTA_DestHeightF, vis->pic->GetHeight() * vis->yscale, DTA_DestHeightF, vis->pic->GetHeight() * vis->yscale,
DTA_Translation, TranslationToTable(vis->Translation), DTA_TranslationIndex, vis->Translation,
DTA_FlipX, flip, DTA_FlipX, flip,
DTA_TopOffset, 0, DTA_TopOffset, 0,
DTA_LeftOffset, 0, DTA_LeftOffset, 0,
@ -1721,7 +1721,7 @@ void R_DrawRemainingPlayerSprites()
DTA_ClipTop, viewwindowy, DTA_ClipTop, viewwindowy,
DTA_ClipRight, viewwindowx + viewwidth, DTA_ClipRight, viewwindowx + viewwidth,
DTA_ClipBottom, viewwindowy + viewheight, DTA_ClipBottom, viewwindowy + viewheight,
DTA_AlphaF, vis->Style.Alpha, DTA_Alpha, vis->Style.Alpha,
DTA_RenderStyle, vis->RenderStyle, DTA_RenderStyle, vis->RenderStyle,
DTA_FillColor, vis->FillColor, DTA_FillColor, vis->FillColor,
DTA_SpecialColormap, special, DTA_SpecialColormap, special,

View file

@ -337,8 +337,6 @@ void R_Init ()
{ {
atterm (R_Shutdown); atterm (R_Shutdown);
StartScreen->Progress();
V_InitFonts();
StartScreen->Progress(); StartScreen->Progress();
// Colormap init moved back to InitPalette() // Colormap init moved back to InitPalette()
//R_InitColormaps (); //R_InitColormaps ();

View file

@ -1420,6 +1420,76 @@ ExpEmit FxSoundCast::Emit(VMFunctionBuilder *build)
return to; return to;
} }
//==========================================================================
//
//
//
//==========================================================================
FxFontCast::FxFontCast(FxExpression *x)
: FxExpression(EFX_FontCast, x->ScriptPosition)
{
basex = x;
ValueType = TypeSound;
}
//==========================================================================
//
//
//
//==========================================================================
FxFontCast::~FxFontCast()
{
SAFE_DELETE(basex);
}
//==========================================================================
//
//
//
//==========================================================================
FxExpression *FxFontCast::Resolve(FCompileContext &ctx)
{
CHECKRESOLVED();
SAFE_RESOLVE(basex, ctx);
if (basex->ValueType == TypeFont)
{
FxExpression *x = basex;
basex = nullptr;
delete this;
return x;
}
// This intentionally does not convert non-constants.
// The sole reason for this cast is to allow passing both font pointers and string constants to printing functions and have the font names checked at compile time.
else if ((basex->ValueType == TypeString || basex->ValueType == TypeName) && basex->isConstant())
{
ExpVal constval = static_cast<FxConstant *>(basex)->GetValue();
FFont *font = V_GetFont(constval.GetString());
// Font must exist. Most internal functions working with fonts do not like null pointers.
// If checking is needed scripts will have to call Font.GetFont themselves.
if (font == nullptr)
{
ScriptPosition.Message(MSG_ERROR, "Unknown font '%s'", constval.GetString().GetChars());
delete this;
return nullptr;
}
FxExpression *x = new FxConstant(font, ScriptPosition);
delete this;
return x;
}
else
{
ScriptPosition.Message(MSG_ERROR, "Cannot convert to font");
delete this;
return nullptr;
}
}
//========================================================================== //==========================================================================
// //
// generic type cast operator // generic type cast operator
@ -1649,6 +1719,14 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx)
{ {
goto basereturn; goto basereturn;
} }
else if (ValueType == TypeFont)
{
FxExpression *x = new FxFontCast(basex);
x = x->Resolve(ctx);
basex = nullptr;
delete this;
return x;
}
// todo: pointers to class objects. // todo: pointers to class objects.
// All other types are only compatible to themselves and have already been handled above by the equality check. // All other types are only compatible to themselves and have already been handled above by the equality check.
// Anything that falls through here is not compatible and must print an error. // Anything that falls through here is not compatible and must print an error.
@ -4918,6 +4996,70 @@ ExpEmit FxATan2::Emit(VMFunctionBuilder *build)
return out; return out;
} }
//==========================================================================
//
//
//
//==========================================================================
FxNew::FxNew(FxExpression *v)
: FxExpression(EFX_New, v->ScriptPosition)
{
val = new FxClassTypeCast(NewClassPointer(RUNTIME_CLASS(DObject)), v, false);
ValueType = NewPointer(RUNTIME_CLASS(DObject));
}
//==========================================================================
//
//
//
//==========================================================================
FxNew::~FxNew()
{
SAFE_DELETE(val);
}
//==========================================================================
//
//
//
//==========================================================================
FxExpression *FxNew::Resolve(FCompileContext &ctx)
{
CHECKRESOLVED();
SAFE_RESOLVE(val, ctx);
if (!val->ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)))
{
ScriptPosition.Message(MSG_ERROR, "Class type expected");
delete this;
return nullptr;
}
if (val->isConstant())
{
auto cls = static_cast<PClass *>(static_cast<FxConstant*>(val)->GetValue().GetPointer());
ValueType = NewPointer(cls);
}
return this;
}
//==========================================================================
//
//
//
//==========================================================================
ExpEmit FxNew::Emit(VMFunctionBuilder *build)
{
assert(ValueType == val->ValueType);
ExpEmit from = val->Emit(build);
from.Free(build);
ExpEmit to(build, REGT_POINTER);
build->Emit(from.Konst ? OP_NEW_K : OP_NEW, to.RegNum, from.RegNum);
return to;
}
//========================================================================== //==========================================================================
// //
// The atan2 opcode only takes registers as parameters, so any constants // The atan2 opcode only takes registers as parameters, so any constants
@ -6489,7 +6631,9 @@ ExpEmit FxStackVariable::Emit(VMFunctionBuilder *build)
if (membervar->BitValue == -1) if (membervar->BitValue == -1)
{ {
if (offsetreg == -1) offsetreg = build->GetConstantInt(0); if (offsetreg == -1) offsetreg = build->GetConstantInt(0);
build->Emit(membervar->Type->GetLoadOp(), loc.RegNum, build->FramePointer.RegNum, offsetreg); auto op = membervar->Type->GetLoadOp();
if (op == OP_LO) op = OP_LOS;
build->Emit(op, loc.RegNum, build->FramePointer.RegNum, offsetreg);
} }
else else
{ {
@ -7428,6 +7572,15 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
} }
break; break;
case NAME_New:
if (CheckArgSize(MethodName, ArgList, 1, 1, ScriptPosition))
{
func = new FxNew(ArgList[0]);
ArgList[0] = nullptr;
}
break;
default: default:
ScriptPosition.Message(MSG_ERROR, "Call to unknown function '%s'", MethodName.GetChars()); ScriptPosition.Message(MSG_ERROR, "Call to unknown function '%s'", MethodName.GetChars());
break; break;

View file

@ -242,6 +242,7 @@ enum EFxType
EFX_Conditional, EFX_Conditional,
EFX_Abs, EFX_Abs,
EFX_ATan2, EFX_ATan2,
EFX_New,
EFX_MinMax, EFX_MinMax,
EFX_Random, EFX_Random,
EFX_RandomPick, EFX_RandomPick,
@ -293,6 +294,7 @@ enum EFxType
EFX_StrLen, EFX_StrLen,
EFX_ColorLiteral, EFX_ColorLiteral,
EFX_GetDefaultByType, EFX_GetDefaultByType,
EFX_FontCast,
EFX_COUNT EFX_COUNT
}; };
@ -487,6 +489,13 @@ public:
isresolved = true; isresolved = true;
} }
FxConstant(FFont *state, const FScriptPosition &pos) : FxExpression(EFX_Constant, pos)
{
value.pointer = state;
ValueType = value.Type = TypeFont;
isresolved = true;
}
FxConstant(const FScriptPosition &pos) : FxExpression(EFX_Constant, pos) FxConstant(const FScriptPosition &pos) : FxExpression(EFX_Constant, pos)
{ {
value.pointer = nullptr; value.pointer = nullptr;
@ -663,6 +672,18 @@ public:
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
class FxFontCast : public FxExpression
{
FxExpression *basex;
public:
FxFontCast(FxExpression *x);
~FxFontCast();
FxExpression *Resolve(FCompileContext&);
};
//========================================================================== //==========================================================================
// //
// FxTypeCast // FxTypeCast
@ -1176,6 +1197,26 @@ public:
private: private:
ExpEmit ToReg(VMFunctionBuilder *build, FxExpression *val); ExpEmit ToReg(VMFunctionBuilder *build, FxExpression *val);
}; };
//==========================================================================
//
//
//
//==========================================================================
class FxNew : public FxExpression
{
FxExpression *val;
public:
FxNew(FxExpression *v);
~FxNew();
FxExpression *Resolve(FCompileContext&);
ExpEmit Emit(VMFunctionBuilder *build);
};
//========================================================================== //==========================================================================
// //
// //

View file

@ -53,6 +53,7 @@
#include "vm.h" #include "vm.h"
#include "p_checkposition.h" #include "p_checkposition.h"
#include "r_sky.h" #include "r_sky.h"
#include "v_font.h"
static TArray<FPropertyInfo*> properties; static TArray<FPropertyInfo*> properties;
static TArray<AFuncDesc> AFTable; static TArray<AFuncDesc> AFTable;
@ -801,34 +802,51 @@ void InitThingdef()
pstruct->Size = sizeof(player_t); pstruct->Size = sizeof(player_t);
pstruct->Align = alignof(player_t); pstruct->Align = alignof(player_t);
PArray *parray = NewArray(pstruct, MAXPLAYERS); PArray *parray = NewArray(pstruct, MAXPLAYERS);
PField *playerf = new PField("players", parray, VARF_Native | VARF_Static, (intptr_t)&players); PField *fieldptr = new PField("players", parray, VARF_Native | VARF_Static, (intptr_t)&players);
Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf); Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
pstruct->AddNativeField("weapons", NewNativeStruct("WeaponSlots", nullptr), myoffsetof(player_t, weapons), VARF_Native); pstruct->AddNativeField("weapons", NewNativeStruct("WeaponSlots", nullptr), myoffsetof(player_t, weapons), VARF_Native);
parray = NewArray(TypeBool, MAXPLAYERS); parray = NewArray(TypeBool, MAXPLAYERS);
playerf = new PField("playeringame", parray, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&playeringame); fieldptr = new PField("playeringame", parray, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&playeringame);
Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf); Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
playerf = new PField("gameaction", TypeUInt8, VARF_Native | VARF_Static, (intptr_t)&gameaction); fieldptr = new PField("gameaction", TypeUInt8, VARF_Native | VARF_Static, (intptr_t)&gameaction);
Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf); Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
playerf = new PField("skyflatnum", TypeTextureID, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&skyflatnum); fieldptr = new PField("skyflatnum", TypeTextureID, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&skyflatnum);
Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf); Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
playerf = new PField("globalfreeze", TypeUInt8, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&bglobal.freeze); fieldptr = new PField("globalfreeze", TypeUInt8, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&bglobal.freeze);
Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf); Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
playerf = new PField("consoleplayer", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&consoleplayer); fieldptr = new PField("consoleplayer", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&consoleplayer);
Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf); Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
auto fontptr = NewPointer(NewNativeStruct("Font", nullptr));
fieldptr = new PField("smallfont", fontptr, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&SmallFont);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
fieldptr = new PField("smallfont2", fontptr, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&SmallFont2);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
fieldptr = new PField("bigfont", fontptr, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&BigFont);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
fieldptr = new PField("confont", fontptr, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&ConFont);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
fieldptr = new PField("intermissionfont", fontptr, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&IntermissionFont);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
// Argh. It sucks when bad hacks need to be supported. WP_NOCHANGE is just a bogus pointer but it used everywhere as a special flag. // Argh. It sucks when bad hacks need to be supported. WP_NOCHANGE is just a bogus pointer but it used everywhere as a special flag.
// It cannot be defined as constant because constants can either be numbers or strings but nothing else, so the only 'solution' // It cannot be defined as constant because constants can either be numbers or strings but nothing else, so the only 'solution'
// is to create a static variable from it and reference that in the script. Yuck!!! // is to create a static variable from it and reference that in the script. Yuck!!!
static AWeapon *wpnochg = WP_NOCHANGE; static AWeapon *wpnochg = WP_NOCHANGE;
playerf = new PField("WP_NOCHANGE", NewPointer(RUNTIME_CLASS(AWeapon), false), VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&wpnochg); fieldptr = new PField("WP_NOCHANGE", NewPointer(RUNTIME_CLASS(AWeapon), false), VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&wpnochg);
Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf); Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
// synthesize a symbol for each flag from the flag name tables to avoid redundant declaration of them. // synthesize a symbol for each flag from the flag name tables to avoid redundant declaration of them.
for (auto &fl : FlagLists) for (auto &fl : FlagLists)

View file

@ -193,6 +193,7 @@ enum
enum EVMAbortException enum EVMAbortException
{ {
X_OTHER,
X_READ_NIL, X_READ_NIL,
X_WRITE_NIL, X_WRITE_NIL,
X_TOO_MANY_TRIES, X_TOO_MANY_TRIES,

View file

@ -281,8 +281,8 @@ unsigned VMFunctionBuilder::GetConstantAddress(void *ptr, VM_ATAG tag)
AddrKonst *locp = AddressConstantMap.CheckKey(ptr); AddrKonst *locp = AddressConstantMap.CheckKey(ptr);
if (locp != NULL) if (locp != NULL)
{ {
// There should only be one tag associated with a memory location. // There should only be one tag associated with a memory location. Exceptions are made for null pointers that got allocated through constant arrays.
assert(locp->Tag == tag); assert(ptr == nullptr || locp->Tag == tag);
return locp->KonstNum; return locp->KonstNum;
} }
else else

View file

@ -72,6 +72,7 @@
#define RFRF MODE_AF | MODE_BF | MODE_CUNUSED #define RFRF MODE_AF | MODE_BF | MODE_CUNUSED
#define RSRS MODE_AS | MODE_BS | MODE_CUNUSED #define RSRS MODE_AS | MODE_BS | MODE_CUNUSED
#define RPRP MODE_AP | MODE_BP | MODE_CUNUSED #define RPRP MODE_AP | MODE_BP | MODE_CUNUSED
#define RPKP MODE_AP | MODE_BKP | MODE_CUNUSED
#define RXRXI8 MODE_AX | MODE_BX | MODE_CIMMZ #define RXRXI8 MODE_AX | MODE_BX | MODE_CIMMZ
#define RPRPRP MODE_AP | MODE_BP | MODE_CP #define RPRPRP MODE_AP | MODE_BP | MODE_CP
#define RPRPKP MODE_AP | MODE_BP | MODE_CKP #define RPRPKP MODE_AP | MODE_BP | MODE_CKP

View file

@ -209,6 +209,18 @@ begin:
reg.a[a] = GC::ReadBarrier(*(DObject **)ptr); reg.a[a] = GC::ReadBarrier(*(DObject **)ptr);
reg.atag[a] = ATAG_OBJECT; reg.atag[a] = ATAG_OBJECT;
NEXTOP; NEXTOP;
OP(LOS):
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
GETADDR(PB,KC,X_READ_NIL);
reg.a[a] = *(DObject **)ptr;
reg.atag[a] = ATAG_OBJECT;
NEXTOP;
OP(LOS_R):
ASSERTA(a); ASSERTA(B); ASSERTD(C);
GETADDR(PB,RC,X_READ_NIL);
reg.a[a] = *(DObject **)ptr;
reg.atag[a] = ATAG_OBJECT;
NEXTOP;
OP(LP): OP(LP):
ASSERTA(a); ASSERTA(B); ASSERTKD(C); ASSERTA(a); ASSERTA(B); ASSERTKD(C);
GETADDR(PB,KC,X_READ_NIL); GETADDR(PB,KC,X_READ_NIL);
@ -759,6 +771,14 @@ begin:
assert(0); assert(0);
NEXTOP; NEXTOP;
OP(NEW_K):
OP(NEW):
{
PClass *cls = (PClass*)(pc->op == OP_NEW ? reg.a[C] : konsta[C].v);
reg.a[B] = cls->CreateNew();
NEXTOP;
}
OP(TRY): OP(TRY):
assert(try_depth < MAX_TRY_DEPTH); assert(try_depth < MAX_TRY_DEPTH);
if (try_depth >= MAX_TRY_DEPTH) if (try_depth >= MAX_TRY_DEPTH)

View file

@ -554,6 +554,10 @@ CVMAbortException::CVMAbortException(EVMAbortException reason, const char *morei
AppendMessage("string format failed."); AppendMessage("string format failed.");
break; break;
case X_OTHER:
// no prepended message.
break;
default: default:
{ {
size_t len = strlen(m_Message); size_t len = strlen(m_Message);

View file

@ -44,6 +44,8 @@ xx(LS, ls, RSRPKI, LS_R, 4, REGT_INT), // load string
xx(LS_R, ls, RSRPRI, NOP, 0, 0), xx(LS_R, ls, RSRPRI, NOP, 0, 0),
xx(LO, lo, RPRPKI, LO_R, 4, REGT_INT), // load object xx(LO, lo, RPRPKI, LO_R, 4, REGT_INT), // load object
xx(LO_R, lo, RPRPRI, NOP, 0, 0), xx(LO_R, lo, RPRPRI, NOP, 0, 0),
xx(LOS, los, RPRPKI, LOS_R, 4, REGT_INT), // load object (stack version without read barrier)
xx(LOS_R, lo, RPRPRI, NOP, 0, 0),
xx(LP, lp, RPRPKI, LP_R, 4, REGT_INT), // load pointer xx(LP, lp, RPRPKI, LP_R, 4, REGT_INT), // load pointer
xx(LP_R, lp, RPRPRI, NOP, 0, 0), xx(LP_R, lp, RPRPRI, NOP, 0, 0),
xx(LV2, lv2, RVRPKI, LV2_R, 4, REGT_INT), // load vector2 xx(LV2, lv2, RVRPKI, LV2_R, 4, REGT_INT), // load vector2
@ -104,6 +106,8 @@ xx(TAIL_K, tail, KPI8, TAIL, 1, REGT_POINTER),
xx(RESULT, result, __BCP, NOP, 0, 0), // Result should go in register encoded in BC (in caller, after CALL) xx(RESULT, result, __BCP, NOP, 0, 0), // Result should go in register encoded in BC (in caller, after CALL)
xx(RET, ret, I8BCP, NOP, 0, 0), // Copy value from register encoded in BC to return value A, possibly returning xx(RET, ret, I8BCP, NOP, 0, 0), // Copy value from register encoded in BC to return value A, possibly returning
xx(RETI, reti, I8I16, NOP, 0, 0), // Copy immediate from BC to return value A, possibly returning xx(RETI, reti, I8I16, NOP, 0, 0), // Copy immediate from BC to return value A, possibly returning
xx(NEW, new, RPRP, NOP, 0, 0),
xx(NEW_K, new, RPKP, NOP, 0, 0),
xx(TRY, try, I24, NOP, 0, 0), // When an exception is thrown, start searching for a handler at pc + ABC xx(TRY, try, I24, NOP, 0, 0), // When an exception is thrown, start searching for a handler at pc + ABC
xx(UNTRY, untry, I8, NOP, 0, 0), // Pop A entries off the exception stack xx(UNTRY, untry, I8, NOP, 0, 0), // Pop A entries off the exception stack
xx(THROW, throw, THROW, NOP, 0, 0), // A == 0: Throw exception object pB xx(THROW, throw, THROW, NOP, 0, 0), // A == 0: Throw exception object pB

View file

@ -2187,17 +2187,17 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FFont *&fon
{ {
if (arc.isWriting()) if (arc.isWriting())
{ {
const char *n = font->GetName(); FName n = font->GetName();
return arc.StringPtr(key, n); return arc(key, n);
} }
else else
{ {
const char *n; FName n;
arc.StringPtr(key, n); arc(key, n);
font = V_GetFont(n); font = V_GetFont(n);
if (font == nullptr) if (font == nullptr)
{ {
Printf(TEXTCOLOR_ORANGE "Could not load font %s\n", n); Printf(TEXTCOLOR_ORANGE "Could not load font %s\n", n.GetChars());
font = SmallFont; font = SmallFont;
} }
return arc; return arc;

View file

@ -91,6 +91,17 @@ CVAR (Bool, hud_scale, true, CVAR_ARCHIVE);
static int LastPal = -1; static int LastPal = -1;
static uint32 LastRGB; static uint32 LastRGB;
DEFINE_ACTION_FUNCTION(_Screen, GetWidth)
{
PARAM_PROLOGUE;
ACTION_RETURN_INT(screen->GetWidth());
}
DEFINE_ACTION_FUNCTION(_Screen, GetHeight)
{
PARAM_PROLOGUE;
ACTION_RETURN_INT(screen->GetHeight());
}
static int PalFromRGB(uint32 rgb) static int PalFromRGB(uint32 rgb)
{ {
@ -115,6 +126,7 @@ static int PalFromRGB(uint32 rgb)
return LastPal; return LastPal;
} }
void DCanvas::DrawTexture (FTexture *img, double x, double y, int tags_first, ...) void DCanvas::DrawTexture (FTexture *img, double x, double y, int tags_first, ...)
{ {
va_list tags; va_list tags;
@ -130,6 +142,31 @@ void DCanvas::DrawTexture (FTexture *img, double x, double y, int tags_first, ..
DrawTextureParms(img, parms); DrawTextureParms(img, parms);
} }
int ListGetInt(VMVa_List &tags);
void DCanvas::DrawTexture(FTexture *img, double x, double y, VMVa_List &args)
{
DrawParms parms;
uint32_t tag = ListGetInt(args);
bool res = ParseDrawTextureTags(img, x, y, tag, args, &parms, false);
if (!res) return;
DrawTextureParms(img, parms);
}
DEFINE_ACTION_FUNCTION(_Screen, DrawTexture)
{
PARAM_PROLOGUE;
PARAM_INT(texid);
PARAM_BOOL(animate);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
FTexture *tex = animate ? TexMan(FSetTextureID(texid)) : TexMan[FSetTextureID(texid)];
VMVa_List args = { param + 4, 0, numparam - 4 };
screen->DrawTexture(tex, x, y, args);
return 0;
}
DEFINE_ACTION_FUNCTION(_Screen, DrawHUDTexture) DEFINE_ACTION_FUNCTION(_Screen, DrawHUDTexture)
{ {
PARAM_PROLOGUE; PARAM_PROLOGUE;
@ -164,7 +201,7 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
{ {
parms.colorOverlay = PalEntry(parms.colorOverlay).InverseColor(); parms.colorOverlay = PalEntry(parms.colorOverlay).InverseColor();
} }
// Note that this overrides DTA_Translation in software, but not in hardware. // Note that this overrides the translation in software, but not in hardware.
FDynamicColormap *colormap = GetSpecialLights(MAKERGB(255,255,255), FDynamicColormap *colormap = GetSpecialLights(MAKERGB(255,255,255),
parms.colorOverlay & MAKEARGB(0,255,255,255), 0); parms.colorOverlay & MAKEARGB(0,255,255,255), 0);
translation = &colormap->Maps[(APART(parms.colorOverlay)*NUMCOLORMAPS/255)*256]; translation = &colormap->Maps[(APART(parms.colorOverlay)*NUMCOLORMAPS/255)*256];
@ -420,7 +457,70 @@ bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double
return false; return false;
} }
bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag, va_list tags, DrawParms *parms, bool fortext) const static void ListEnd(va_list &tags)
{
va_end(tags);
}
static int ListGetInt(va_list &tags)
{
return va_arg(tags, int);
}
static inline double ListGetDouble(va_list &tags)
{
return va_arg(tags, double);
}
// These two options are only being used by the D3D version of the HUD weapon drawer, they serve no purpose anywhere else.
static inline FSpecialColormap * ListGetSpecialColormap(va_list &tags)
{
return va_arg(tags, FSpecialColormap *);
}
static inline FColormapStyle * ListGetColormapStyle(va_list &tags)
{
return va_arg(tags, FColormapStyle *);
}
static void ListEnd(VMVa_List &tags)
{
}
int ListGetInt(VMVa_List &tags)
{
if (tags.curindex < tags.numargs && tags.args[tags.curindex].Type == REGT_INT)
{
return tags.args[tags.curindex++].i;
}
ThrowAbortException(X_OTHER, "Invalid parameter in draw function, int expected");
return 0;
}
static inline double ListGetDouble(VMVa_List &tags)
{
if (tags.curindex < tags.numargs && tags.args[tags.curindex].Type == REGT_FLOAT)
{
return tags.args[tags.curindex++].f;
}
ThrowAbortException(X_OTHER, "Invalid parameter in draw function, float expected");
return 0;
}
static inline FSpecialColormap * ListGetSpecialColormap(VMVa_List &tags)
{
ThrowAbortException(X_OTHER, "Invalid tag in draw function");
return nullptr;
}
static inline FColormapStyle * ListGetColormapStyle(VMVa_List &tags)
{
ThrowAbortException(X_OTHER, "Invalid tag in draw function");
return nullptr;
}
template<class T>
bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, DWORD tag, T& tags, DrawParms *parms, bool fortext) const
{ {
INTBOOL boolval; INTBOOL boolval;
int intval; int intval;
@ -431,7 +531,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
{ {
if (img == NULL || img->UseType == FTexture::TEX_Null) if (img == NULL || img->UseType == FTexture::TEX_Null)
{ {
va_end(tags); ListEnd(tags);
return false; return false;
} }
} }
@ -439,7 +539,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
// Do some sanity checks on the coordinates. // Do some sanity checks on the coordinates.
if (x < -16383 || x > 16383 || y < -16383 || y > 16383) if (x < -16383 || x > 16383 || y < -16383 || y > 16383)
{ {
va_end(tags); ListEnd(tags);
return false; return false;
} }
@ -481,44 +581,42 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
// doubles when passed as function arguments.) // doubles when passed as function arguments.)
while (tag != TAG_DONE) while (tag != TAG_DONE)
{ {
DWORD data;
switch (tag) switch (tag)
{ {
default: default:
data = va_arg(tags, DWORD); ListGetInt(tags);
break; break;
case DTA_DestWidth: case DTA_DestWidth:
assert(fortext == false); assert(fortext == false);
if (fortext) return false; if (fortext) return false;
parms->cleanmode = DTA_Base; parms->cleanmode = DTA_Base;
parms->destwidth = va_arg(tags, int); parms->destwidth = ListGetInt(tags);
break; break;
case DTA_DestWidthF: case DTA_DestWidthF:
assert(fortext == false); assert(fortext == false);
if (fortext) return false; if (fortext) return false;
parms->cleanmode = DTA_Base; parms->cleanmode = DTA_Base;
parms->destwidth = va_arg(tags, double); parms->destwidth = ListGetDouble(tags);
break; break;
case DTA_DestHeight: case DTA_DestHeight:
assert(fortext == false); assert(fortext == false);
if (fortext) return false; if (fortext) return false;
parms->cleanmode = DTA_Base; parms->cleanmode = DTA_Base;
parms->destheight = va_arg(tags, int); parms->destheight = ListGetInt(tags);
break; break;
case DTA_DestHeightF: case DTA_DestHeightF:
assert(fortext == false); assert(fortext == false);
if (fortext) return false; if (fortext) return false;
parms->cleanmode = DTA_Base; parms->cleanmode = DTA_Base;
parms->destheight = va_arg(tags, double); parms->destheight = ListGetDouble(tags);
break; break;
case DTA_Clean: case DTA_Clean:
boolval = va_arg(tags, INTBOOL); boolval = ListGetInt(tags);
if (boolval) if (boolval)
{ {
parms->scalex = 1; parms->scalex = 1;
@ -528,7 +626,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
break; break;
case DTA_CleanNoMove: case DTA_CleanNoMove:
boolval = va_arg(tags, INTBOOL); boolval = ListGetInt(tags);
if (boolval) if (boolval)
{ {
parms->scalex = CleanXfac; parms->scalex = CleanXfac;
@ -538,7 +636,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
break; break;
case DTA_CleanNoMove_1: case DTA_CleanNoMove_1:
boolval = va_arg(tags, INTBOOL); boolval = ListGetInt(tags);
if (boolval) if (boolval)
{ {
parms->scalex = CleanXfac_1; parms->scalex = CleanXfac_1;
@ -548,7 +646,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
break; break;
case DTA_320x200: case DTA_320x200:
boolval = va_arg(tags, INTBOOL); boolval = ListGetInt(tags);
if (boolval) if (boolval)
{ {
parms->cleanmode = DTA_Base; parms->cleanmode = DTA_Base;
@ -560,7 +658,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
break; break;
case DTA_Bottom320x200: case DTA_Bottom320x200:
boolval = va_arg(tags, INTBOOL); boolval = ListGetInt(tags);
if (boolval) if (boolval)
{ {
parms->cleanmode = DTA_Base; parms->cleanmode = DTA_Base;
@ -573,32 +671,32 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
break; break;
case DTA_HUDRules: case DTA_HUDRules:
intval = va_arg(tags, int); intval = ListGetInt(tags);
parms->cleanmode = intval == HUD_HorizCenter ? DTA_HUDRulesC : DTA_HUDRules; parms->cleanmode = intval == HUD_HorizCenter ? DTA_HUDRulesC : DTA_HUDRules;
break; break;
case DTA_VirtualWidth: case DTA_VirtualWidth:
parms->cleanmode = DTA_Base; parms->cleanmode = DTA_Base;
parms->virtWidth = va_arg(tags, int); parms->virtWidth = ListGetInt(tags);
break; break;
case DTA_VirtualWidthF: case DTA_VirtualWidthF:
parms->cleanmode = DTA_Base; parms->cleanmode = DTA_Base;
parms->virtWidth = va_arg(tags, double); parms->virtWidth = ListGetDouble(tags);
break; break;
case DTA_VirtualHeight: case DTA_VirtualHeight:
parms->cleanmode = DTA_Base; parms->cleanmode = DTA_Base;
parms->virtHeight = va_arg(tags, int); parms->virtHeight = ListGetInt(tags);
break; break;
case DTA_VirtualHeightF: case DTA_VirtualHeightF:
parms->cleanmode = DTA_Base; parms->cleanmode = DTA_Base;
parms->virtHeight = va_arg(tags, double); parms->virtHeight = ListGetDouble(tags);
break; break;
case DTA_Fullscreen: case DTA_Fullscreen:
boolval = va_arg(tags, INTBOOL); boolval = ListGetInt(tags);
if (boolval) if (boolval)
{ {
assert(fortext == false); assert(fortext == false);
@ -610,66 +708,58 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
break; break;
case DTA_Alpha: case DTA_Alpha:
parms->Alpha = FIXED2FLOAT(MIN<fixed_t>(OPAQUE, va_arg (tags, fixed_t))); parms->Alpha = (float)(MIN<double>(1., ListGetDouble(tags)));
break;
case DTA_AlphaF:
parms->Alpha = (float)(MIN<double>(1., va_arg(tags, double)));
break; break;
case DTA_AlphaChannel: case DTA_AlphaChannel:
parms->alphaChannel = va_arg(tags, INTBOOL); parms->alphaChannel = ListGetInt(tags);
break; break;
case DTA_FillColor: case DTA_FillColor:
parms->fillcolor = va_arg(tags, uint32); parms->fillcolor = ListGetInt(tags);
fillcolorset = true; fillcolorset = true;
break; break;
case DTA_Translation: case DTA_TranslationIndex:
parms->remap = va_arg(tags, FRemapTable *); parms->remap = TranslationToTable(ListGetInt(tags));
if (parms->remap != NULL && parms->remap->Inactive)
{ // If it's inactive, pretend we were passed NULL instead.
parms->remap = NULL;
}
break; break;
case DTA_ColorOverlay: case DTA_ColorOverlay:
parms->colorOverlay = va_arg(tags, DWORD); parms->colorOverlay = ListGetInt(tags);
break; break;
case DTA_FlipX: case DTA_FlipX:
parms->flipX = va_arg(tags, INTBOOL); parms->flipX = ListGetInt(tags);
break; break;
case DTA_TopOffset: case DTA_TopOffset:
assert(fortext == false); assert(fortext == false);
if (fortext) return false; if (fortext) return false;
parms->top = va_arg(tags, int); parms->top = ListGetInt(tags);
break; break;
case DTA_TopOffsetF: case DTA_TopOffsetF:
assert(fortext == false); assert(fortext == false);
if (fortext) return false; if (fortext) return false;
parms->top = va_arg(tags, double); parms->top = ListGetDouble(tags);
break; break;
case DTA_LeftOffset: case DTA_LeftOffset:
assert(fortext == false); assert(fortext == false);
if (fortext) return false; if (fortext) return false;
parms->left = va_arg(tags, int); parms->left = ListGetInt(tags);
break; break;
case DTA_LeftOffsetF: case DTA_LeftOffsetF:
assert(fortext == false); assert(fortext == false);
if (fortext) return false; if (fortext) return false;
parms->left = va_arg(tags, double); parms->left = ListGetDouble(tags);
break; break;
case DTA_CenterOffset: case DTA_CenterOffset:
assert(fortext == false); assert(fortext == false);
if (fortext) return false; if (fortext) return false;
if (va_arg(tags, int)) if (ListGetInt(tags))
{ {
parms->left = img->GetScaledWidthDouble() * 0.5; parms->left = img->GetScaledWidthDouble() * 0.5;
parms->top = img->GetScaledHeightDouble() * 0.5; parms->top = img->GetScaledHeightDouble() * 0.5;
@ -679,7 +769,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
case DTA_CenterBottomOffset: case DTA_CenterBottomOffset:
assert(fortext == false); assert(fortext == false);
if (fortext) return false; if (fortext) return false;
if (va_arg(tags, int)) if (ListGetInt(tags))
{ {
parms->left = img->GetScaledWidthDouble() * 0.5; parms->left = img->GetScaledWidthDouble() * 0.5;
parms->top = img->GetScaledHeightDouble(); parms->top = img->GetScaledHeightDouble();
@ -689,29 +779,29 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
case DTA_WindowLeft: case DTA_WindowLeft:
assert(fortext == false); assert(fortext == false);
if (fortext) return false; if (fortext) return false;
parms->windowleft = va_arg(tags, int); parms->windowleft = ListGetInt(tags);
break; break;
case DTA_WindowLeftF: case DTA_WindowLeftF:
assert(fortext == false); assert(fortext == false);
if (fortext) return false; if (fortext) return false;
parms->windowleft = va_arg(tags, double); parms->windowleft = ListGetDouble(tags);
break; break;
case DTA_WindowRight: case DTA_WindowRight:
assert(fortext == false); assert(fortext == false);
if (fortext) return false; if (fortext) return false;
parms->windowright = va_arg(tags, int); parms->windowright = ListGetInt(tags);
break; break;
case DTA_WindowRightF: case DTA_WindowRightF:
assert(fortext == false); assert(fortext == false);
if (fortext) return false; if (fortext) return false;
parms->windowright = va_arg(tags, double); parms->windowright = ListGetDouble(tags);
break; break;
case DTA_ClipTop: case DTA_ClipTop:
parms->uclip = va_arg(tags, int); parms->uclip = ListGetInt(tags);
if (parms->uclip < 0) if (parms->uclip < 0)
{ {
parms->uclip = 0; parms->uclip = 0;
@ -719,7 +809,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
break; break;
case DTA_ClipBottom: case DTA_ClipBottom:
parms->dclip = va_arg(tags, int); parms->dclip = ListGetInt(tags);
if (parms->dclip > this->GetHeight()) if (parms->dclip > this->GetHeight())
{ {
parms->dclip = this->GetHeight(); parms->dclip = this->GetHeight();
@ -727,7 +817,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
break; break;
case DTA_ClipLeft: case DTA_ClipLeft:
parms->lclip = va_arg(tags, int); parms->lclip = ListGetInt(tags);
if (parms->lclip < 0) if (parms->lclip < 0)
{ {
parms->lclip = 0; parms->lclip = 0;
@ -735,7 +825,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
break; break;
case DTA_ClipRight: case DTA_ClipRight:
parms->rclip = va_arg(tags, int); parms->rclip = ListGetInt(tags);
if (parms->rclip > this->GetWidth()) if (parms->rclip > this->GetWidth())
{ {
parms->rclip = this->GetWidth(); parms->rclip = this->GetWidth();
@ -743,18 +833,18 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
break; break;
case DTA_ShadowAlpha: case DTA_ShadowAlpha:
parms->shadowAlpha = MIN<fixed_t>(OPAQUE, va_arg (tags, fixed_t)); parms->shadowAlpha = (float)MIN(1., ListGetDouble(tags));
break; break;
case DTA_ShadowColor: case DTA_ShadowColor:
parms->shadowColor = va_arg(tags, int); parms->shadowColor = ListGetInt(tags);
break; break;
case DTA_Shadow: case DTA_Shadow:
boolval = va_arg(tags, INTBOOL); boolval = ListGetInt(tags);
if (boolval) if (boolval)
{ {
parms->shadowAlpha = FRACUNIT/2; parms->shadowAlpha = 0.5;
parms->shadowColor = 0; parms->shadowColor = 0;
} }
else else
@ -764,47 +854,52 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
break; break;
case DTA_Masked: case DTA_Masked:
parms->masked = va_arg(tags, INTBOOL); parms->masked = ListGetInt(tags);
break; break;
case DTA_BilinearFilter: case DTA_BilinearFilter:
parms->bilinear = va_arg(tags, INTBOOL); parms->bilinear = ListGetInt(tags);
break; break;
case DTA_KeepRatio: case DTA_KeepRatio:
// I think this is a terribly misleading name, since it actually turns // I think this is a terribly misleading name, since it actually turns
// *off* aspect ratio correction. // *off* aspect ratio correction.
parms->keepratio = va_arg(tags, INTBOOL); parms->keepratio = ListGetInt(tags);
break; break;
case DTA_RenderStyle: case DTA_RenderStyle:
parms->style.AsDWORD = va_arg(tags, DWORD); parms->style.AsDWORD = ListGetInt(tags);
break; break;
case DTA_SpecialColormap: case DTA_SpecialColormap:
parms->specialcolormap = va_arg(tags, FSpecialColormap *); parms->specialcolormap = ListGetSpecialColormap(tags);
break; break;
case DTA_ColormapStyle: case DTA_ColormapStyle:
parms->colormapstyle = va_arg(tags, FColormapStyle *); parms->colormapstyle = ListGetColormapStyle(tags);
break; break;
case DTA_TextLen: case DTA_TextLen:
parms->maxstrlen = va_arg(tags, int); parms->maxstrlen = ListGetInt(tags);
break; break;
case DTA_CellX: case DTA_CellX:
parms->cellx = va_arg(tags, int); parms->cellx = ListGetInt(tags);
break; break;
case DTA_CellY: case DTA_CellY:
parms->celly = va_arg(tags, int); parms->celly = ListGetInt(tags);
break; break;
} }
tag = va_arg(tags, DWORD); tag = ListGetInt(tags);
}
ListEnd(tags);
if (parms->remap != nullptr && parms->remap->Inactive)
{ // If it's inactive, pretend we were passed NULL instead.
parms->remap = nullptr;
} }
va_end (tags);
if (parms->uclip >= parms->dclip || parms->lclip >= parms->rclip) if (parms->uclip >= parms->dclip || parms->lclip >= parms->rclip)
{ {
@ -849,6 +944,10 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
} }
return true; return true;
} }
// explicitly instantiate both versions for v_text.cpp.
template bool DCanvas::ParseDrawTextureTags<va_list>(FTexture *img, double x, double y, DWORD tag, va_list& tags, DrawParms *parms, bool fortext) const;
template bool DCanvas::ParseDrawTextureTags<VMVa_List>(FTexture *img, double x, double y, DWORD tag, VMVa_List& tags, DrawParms *parms, bool fortext) const;
void DCanvas::VirtualToRealCoords(double &x, double &y, double &w, double &h, void DCanvas::VirtualToRealCoords(double &x, double &y, double &w, double &h,
double vwidth, double vheight, bool vbottom, bool handleaspect) const double vwidth, double vheight, bool vbottom, bool handleaspect) const

View file

@ -94,6 +94,7 @@ The FON2 header is followed by variable length data:
#include "r_data/r_translate.h" #include "r_data/r_translate.h"
#include "colormatcher.h" #include "colormatcher.h"
#include "v_palette.h" #include "v_palette.h"
#include "v_text.h"
// MACROS ------------------------------------------------------------------ // MACROS ------------------------------------------------------------------
@ -340,6 +341,14 @@ FFont *V_GetFont(const char *name)
return font; return font;
} }
DEFINE_ACTION_FUNCTION(FFont, GetFont)
{
PARAM_PROLOGUE;
PARAM_NAME(name);
ACTION_RETURN_POINTER(V_GetFont(name.GetChars()));
}
//========================================================================== //==========================================================================
// //
// FFont :: FFont // FFont :: FFont
@ -366,7 +375,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
LastChar = first + count - 1; LastChar = first + count - 1;
FontHeight = 0; FontHeight = 0;
GlobalKerning = false; GlobalKerning = false;
Name = copystring (name); FontName = name;
Next = FirstFont; Next = FirstFont;
FirstFont = this; FirstFont = this;
Cursor = '_'; Cursor = '_';
@ -478,11 +487,6 @@ FFont::~FFont ()
delete[] PatchRemap; delete[] PatchRemap;
PatchRemap = NULL; PatchRemap = NULL;
} }
if (Name)
{
delete[] Name;
Name = NULL;
}
FFont **prev = &FirstFont; FFont **prev = &FirstFont;
FFont *font = *prev; FFont *font = *prev;
@ -508,21 +512,27 @@ FFont::~FFont ()
// //
//========================================================================== //==========================================================================
FFont *FFont::FindFont (const char *name) FFont *FFont::FindFont (FName name)
{ {
if (name == NULL) if (name == NAME_None)
{ {
return NULL; return nullptr;
} }
FFont *font = FirstFont; FFont *font = FirstFont;
while (font != NULL) while (font != nullptr)
{ {
if (stricmp (font->Name, name) == 0) if (font->FontName == name) return font;
break;
font = font->Next; font = font->Next;
} }
return font; return nullptr;
}
DEFINE_ACTION_FUNCTION(FFont, FindFont)
{
PARAM_PROLOGUE;
PARAM_NAME(name);
ACTION_RETURN_POINTER(FFont::FindFont(name));
} }
//========================================================================== //==========================================================================
@ -836,6 +846,65 @@ int FFont::GetCharWidth (int code) const
return (code < 0) ? SpaceWidth : Chars[code - FirstChar].XMove; return (code < 0) ? SpaceWidth : Chars[code - FirstChar].XMove;
} }
DEFINE_ACTION_FUNCTION(FFont, GetCharWidth)
{
PARAM_SELF_STRUCT_PROLOGUE(FFont);
PARAM_INT(code);
ACTION_RETURN_INT(self->GetCharWidth(code));
}
//==========================================================================
//
// Find string width using this font
//
//==========================================================================
int FFont::StringWidth(const BYTE *string) const
{
int w = 0;
int maxw = 0;
while (*string)
{
if (*string == TEXTCOLOR_ESCAPE)
{
++string;
if (*string == '[')
{
while (*string != '\0' && *string != ']')
{
++string;
}
}
if (*string != '\0')
{
++string;
}
continue;
}
else if (*string == '\n')
{
if (w > maxw)
maxw = w;
w = 0;
++string;
}
else
{
w += GetCharWidth(*string++) + GlobalKerning;
}
}
return MAX(maxw, w);
}
DEFINE_ACTION_FUNCTION(FFont, StringWidth)
{
PARAM_SELF_STRUCT_PROLOGUE(FFont);
PARAM_STRING(str);
ACTION_RETURN_INT(self->StringWidth(str));
}
//========================================================================== //==========================================================================
// //
// FFont :: LoadTranslations // FFont :: LoadTranslations
@ -928,7 +997,7 @@ FFont::FFont (int lump)
Lump = lump; Lump = lump;
Chars = NULL; Chars = NULL;
PatchRemap = NULL; PatchRemap = NULL;
Name = NULL; FontName = NAME_None;
Cursor = '_'; Cursor = '_';
} }
@ -944,7 +1013,7 @@ FSingleLumpFont::FSingleLumpFont (const char *name, int lump) : FFont(lump)
{ {
assert(lump >= 0); assert(lump >= 0);
Name = copystring (name); FontName = name;
FMemLump data1 = Wads.ReadLump (lump); FMemLump data1 = Wads.ReadLump (lump);
const BYTE *data = (const BYTE *)data1.GetMem(); const BYTE *data = (const BYTE *)data1.GetMem();
@ -1182,7 +1251,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data)
if (destSize < 0) if (destSize < 0)
{ {
i += FirstChar; i += FirstChar;
I_FatalError ("Overflow decompressing char %d (%c) of %s", i, i, Name); I_FatalError ("Overflow decompressing char %d (%c) of %s", i, i, FontName.GetChars());
} }
} }
@ -1484,7 +1553,7 @@ FSinglePicFont::FSinglePicFont(const char *picname) :
FTexture *pic = TexMan[picnum]; FTexture *pic = TexMan[picnum];
Name = copystring(picname); FontName = picname;
FontHeight = pic->GetScaledHeight(); FontHeight = pic->GetScaledHeight();
SpaceWidth = pic->GetScaledWidth(); SpaceWidth = pic->GetScaledWidth();
GlobalKerning = 0; GlobalKerning = 0;
@ -1896,7 +1965,7 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
memcpy(this->notranslate, notranslate, 256*sizeof(bool)); memcpy(this->notranslate, notranslate, 256*sizeof(bool));
Name = copystring(name); FontName = name;
Chars = new CharData[count]; Chars = new CharData[count];
charlumps = new FTexture*[count]; charlumps = new FTexture*[count];
PatchRemap = new BYTE[256]; PatchRemap = new BYTE[256];
@ -2483,6 +2552,13 @@ EColorRange V_FindFontColor (FName name)
return CR_UNTRANSLATED; return CR_UNTRANSLATED;
} }
DEFINE_ACTION_FUNCTION(FFont, FindFontColor)
{
PARAM_SELF_STRUCT_PROLOGUE(FFont);
PARAM_NAME(code);
ACTION_RETURN_INT((int)V_FindFontColor(code));
}
//========================================================================== //==========================================================================
// //
// V_LogColorFromColorRange // V_LogColorFromColorRange
@ -2657,12 +2733,3 @@ void V_ClearFonts()
SmallFont = SmallFont2 = BigFont = ConFont = IntermissionFont = NULL; SmallFont = SmallFont2 = BigFont = ConFont = IntermissionFont = NULL;
} }
void V_RetranslateFonts()
{
FFont *font = FFont::FirstFont;
while(font)
{
font->LoadTranslations();
font = font->Next;
}
}

View file

@ -66,7 +66,8 @@ enum EColorRange
CR_PURPLE, CR_PURPLE,
CR_DARKGRAY, CR_DARKGRAY,
CR_CYAN, CR_CYAN,
NUM_TEXT_COLORS NUM_TEXT_COLORS,
FORCE_DWORD = 0x7fffffff // required for script access.
}; };
extern int NumTextColors; extern int NumTextColors;
@ -87,9 +88,9 @@ public:
int GetDefaultKerning () const { return GlobalKerning; } int GetDefaultKerning () const { return GlobalKerning; }
virtual void LoadTranslations(); virtual void LoadTranslations();
void Preload() const; void Preload() const;
const char *GetName() const { return Name; } FName GetName() const { return FontName; }
static FFont *FindFont (const char *fontname); static FFont *FindFont(FName fontname);
static void StaticPreloadFonts(); static void StaticPreloadFonts();
// Return width of string in pixels (unscaled) // Return width of string in pixels (unscaled)
@ -126,14 +127,13 @@ protected:
BYTE *PatchRemap; BYTE *PatchRemap;
int Lump; int Lump;
char *Name; FName FontName;
FFont *Next; FFont *Next;
static FFont *FirstFont; static FFont *FirstFont;
friend struct FontsDeleter; friend struct FontsDeleter;
friend void V_ClearFonts(); friend void V_ClearFonts();
friend void V_RetranslateFonts();
}; };
@ -146,6 +146,5 @@ PalEntry V_LogColorFromColorRange (EColorRange range);
EColorRange V_ParseFontColor (const BYTE *&color_value, int normalcolor, int boldcolor); EColorRange V_ParseFontColor (const BYTE *&color_value, int normalcolor, int boldcolor);
FFont *V_GetFont(const char *); FFont *V_GetFont(const char *);
void V_InitFontColors(); void V_InitFontColors();
void V_RetranslateFonts();
#endif //__V_FONT_H__ #endif //__V_FONT_H__

View file

@ -47,12 +47,17 @@
#include "doomstat.h" #include "doomstat.h"
#include "templates.h" #include "templates.h"
int ListGetInt(VMVa_List &tags);
//==========================================================================
// //
// DrawChar // DrawChar
// //
// Write a single character using the given font // Write a single character using the given font
// //
void DCanvas::DrawChar (FFont *font, int normalcolor, int x, int y, BYTE character, int tag_first, ...) //==========================================================================
void DCanvas::DrawChar (FFont *font, int normalcolor, double x, double y, int character, int tag_first, ...)
{ {
if (font == NULL) if (font == NULL)
return; return;
@ -79,37 +84,61 @@ void DCanvas::DrawChar (FFont *font, int normalcolor, int x, int y, BYTE charact
} }
} }
void DCanvas::DrawChar(FFont *font, int normalcolor, double x, double y, int character, VMVa_List &args)
{
if (font == NULL)
return;
if (normalcolor >= NumTextColors)
normalcolor = CR_UNTRANSLATED;
FTexture *pic;
int dummy;
if (NULL != (pic = font->GetChar(character, &dummy)))
{
DrawParms parms;
uint32_t tag = ListGetInt(args);
bool res = ParseDrawTextureTags(pic, x, y, tag, args, &parms, false);
if (!res) return;
parms.remap = font->GetColorTranslation((EColorRange)normalcolor);
DrawTextureParms(pic, parms);
}
}
DEFINE_ACTION_FUNCTION(_Screen, DrawChar)
{
PARAM_PROLOGUE;
PARAM_POINTER(font, FFont);
PARAM_INT(cr);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_INT(chr);
VMVa_List args = { param + 5, 0, numparam - 5 };
screen->DrawChar(font, cr, x, y, chr, args);
return 0;
}
//==========================================================================
// //
// DrawText // DrawText
// //
// Write a string using the given font // Write a string using the given font
// //
void DCanvas::DrawText(FFont *font, int normalcolor, int x, int y, const char *string, int tag_first, ...) //==========================================================================
void DCanvas::DrawTextCommon(FFont *font, int normalcolor, double x, double y, const char *string, DrawParms &parms)
{ {
int w; int w;
const BYTE *ch; const BYTE *ch;
int c; int c;
int cx; double cx;
int cy; double cy;
int boldcolor; int boldcolor;
FRemapTable *range; FRemapTable *range;
int kerning; int kerning;
FTexture *pic; FTexture *pic;
DrawParms parms;
va_list tags;
if (font == NULL || string == NULL)
return;
va_start(tags, tag_first);
bool res = ParseDrawTextureTags(nullptr, 0, 0, tag_first, tags, &parms, true);
va_end(tags);
if (!res)
{
return;
}
if (parms.celly == 0) parms.celly = font->GetHeight() + 1; if (parms.celly == 0) parms.celly = font->GetHeight() + 1;
parms.celly *= parms.scaley; parms.celly *= parms.scaley;
@ -118,15 +147,15 @@ void DCanvas::DrawText(FFont *font, int normalcolor, int x, int y, const char *s
normalcolor = CR_UNTRANSLATED; normalcolor = CR_UNTRANSLATED;
boldcolor = normalcolor ? normalcolor - 1 : NumTextColors - 1; boldcolor = normalcolor ? normalcolor - 1 : NumTextColors - 1;
range = font->GetColorTranslation ((EColorRange)normalcolor); range = font->GetColorTranslation((EColorRange)normalcolor);
kerning = font->GetDefaultKerning (); kerning = font->GetDefaultKerning();
ch = (const BYTE *)string; ch = (const BYTE *)string;
cx = x; cx = x;
cy = y; cy = y;
while ((const char *)ch - string < parms.maxstrlen) while ((const char *)ch - string < parms.maxstrlen)
{ {
c = *ch++; c = *ch++;
@ -135,14 +164,14 @@ void DCanvas::DrawText(FFont *font, int normalcolor, int x, int y, const char *s
if (c == TEXTCOLOR_ESCAPE) if (c == TEXTCOLOR_ESCAPE)
{ {
EColorRange newcolor = V_ParseFontColor (ch, normalcolor, boldcolor); EColorRange newcolor = V_ParseFontColor(ch, normalcolor, boldcolor);
if (newcolor != CR_UNDEFINED) if (newcolor != CR_UNDEFINED)
{ {
range = font->GetColorTranslation (newcolor); range = font->GetColorTranslation(newcolor);
} }
continue; continue;
} }
if (c == '\n') if (c == '\n')
{ {
cx = x; cx = x;
@ -150,7 +179,7 @@ void DCanvas::DrawText(FFont *font, int normalcolor, int x, int y, const char *s
continue; continue;
} }
if (NULL != (pic = font->GetChar (c, &w))) if (NULL != (pic = font->GetChar(c, &w)))
{ {
parms.remap = range; parms.remap = range;
SetTextureParms(&parms, pic, cx, cy); SetTextureParms(&parms, pic, cx, cy);
@ -166,52 +195,61 @@ void DCanvas::DrawText(FFont *font, int normalcolor, int x, int y, const char *s
} }
} }
void DCanvas::DrawText(FFont *font, int normalcolor, double x, double y, const char *string, int tag_first, ...)
//
// Find string width using this font
//
int FFont::StringWidth (const BYTE *string) const
{ {
int w = 0; va_list tags;
int maxw = 0; DrawParms parms;
while (*string) if (font == NULL || string == NULL)
return;
va_start(tags, tag_first);
bool res = ParseDrawTextureTags(nullptr, 0, 0, tag_first, tags, &parms, true);
va_end(tags);
if (!res)
{ {
if (*string == TEXTCOLOR_ESCAPE) return;
{
++string;
if (*string == '[')
{
while (*string != '\0' && *string != ']')
{
++string;
}
}
if (*string != '\0')
{
++string;
}
continue;
}
else if (*string == '\n')
{
if (w > maxw)
maxw = w;
w = 0;
++string;
}
else
{
w += GetCharWidth (*string++) + GlobalKerning;
}
} }
DrawTextCommon(font, normalcolor, x, y, string, parms);
return MAX (maxw, w);
} }
void DCanvas::DrawText(FFont *font, int normalcolor, double x, double y, const char *string, VMVa_List &args)
{
DrawParms parms;
if (font == NULL || string == NULL)
return;
uint32_t tag = ListGetInt(args);
bool res = ParseDrawTextureTags(nullptr, 0, 0, tag, args, &parms, true);
if (!res)
{
return;
}
DrawTextCommon(font, normalcolor, x, y, string, parms);
}
DEFINE_ACTION_FUNCTION(_Screen, DrawText)
{
PARAM_PROLOGUE;
PARAM_POINTER(font, FFont);
PARAM_INT(cr);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_STRING(chr);
VMVa_List args = { param + 5, 0, numparam - 5 };
screen->DrawText(font, cr, x, y, chr, args);
return 0;
}
//==========================================================================
// //
// Break long lines of text into multiple lines no longer than maxwidth pixels // Break long lines of text into multiple lines no longer than maxwidth pixels
// //
//==========================================================================
static void breakit (FBrokenLines *line, FFont *font, const BYTE *start, const BYTE *stop, FString &linecolor) static void breakit (FBrokenLines *line, FFont *font, const BYTE *start, const BYTE *stop, FString &linecolor)
{ {
if (!linecolor.IsEmpty()) if (!linecolor.IsEmpty())
@ -223,20 +261,19 @@ static void breakit (FBrokenLines *line, FFont *font, const BYTE *start, const B
line->Width = font->StringWidth (line->Text); line->Width = font->StringWidth (line->Text);
} }
FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string, bool preservecolor) FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string, bool preservecolor, unsigned int *count)
{ {
FBrokenLines lines[128]; // Support up to 128 lines (should be plenty) TArray<FBrokenLines> Lines(128);
const BYTE *space = NULL, *start = string; const BYTE *space = NULL, *start = string;
size_t i, ii;
int c, w, nw; int c, w, nw;
FString lastcolor, linecolor; FString lastcolor, linecolor;
bool lastWasSpace = false; bool lastWasSpace = false;
int kerning = font->GetDefaultKerning (); int kerning = font->GetDefaultKerning ();
i = w = 0; w = 0;
while ( (c = *string++) && i < countof(lines) ) while ( (c = *string++) )
{ {
if (c == TEXTCOLOR_ESCAPE) if (c == TEXTCOLOR_ESCAPE)
{ {
@ -283,14 +320,14 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string, bool
if (!space) if (!space)
space = string - 1; space = string - 1;
breakit (&lines[i], font, start, space, linecolor); auto index = Lines.Reserve(1);
breakit (&Lines[index], font, start, space, linecolor);
if (c == '\n' && !preservecolor) if (c == '\n' && !preservecolor)
{ {
lastcolor = ""; // Why, oh why, did I do it like this? lastcolor = ""; // Why, oh why, did I do it like this?
} }
linecolor = lastcolor; linecolor = lastcolor;
i++;
w = 0; w = 0;
lastWasSpace = false; lastWasSpace = false;
start = space; start = space;
@ -312,7 +349,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string, bool
} }
// String here is pointing one character after the '\0' // String here is pointing one character after the '\0'
if (i < countof(lines) && --string - start >= 1) if (--string - start >= 1)
{ {
const BYTE *s = start; const BYTE *s = start;
@ -321,20 +358,25 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string, bool
// If there is any non-white space in the remainder of the string, add it. // If there is any non-white space in the remainder of the string, add it.
if (!isspace (*s++)) if (!isspace (*s++))
{ {
breakit (&lines[i++], font, start, string, linecolor); auto i = Lines.Reserve(1);
breakit (&Lines[i], font, start, string, linecolor);
break; break;
} }
} }
} }
// Make a copy of the broken lines and return them // Make a copy of the broken lines and return them
FBrokenLines *broken = new FBrokenLines[i+1]; FBrokenLines *broken = new FBrokenLines[Lines.Size() + 1];
for (ii = 0; ii < i; ++ii) for (unsigned ii = 0; ii < Lines.Size(); ++ii)
{ {
broken[ii] = lines[ii]; broken[ii] = Lines[ii];
}
broken[Lines.Size()].Width = -1;
if (count != nullptr)
{
*count = Lines.Size();
} }
broken[ii].Width = -1;
return broken; return broken;
} }
@ -346,3 +388,56 @@ void V_FreeBrokenLines (FBrokenLines *lines)
delete[] lines; delete[] lines;
} }
} }
class DBrokenLines : public DObject
{
DECLARE_ABSTRACT_CLASS(DBrokenLines, DObject)
public:
FBrokenLines *mBroken;
unsigned int mCount;
DBrokenLines(FBrokenLines *broken, unsigned int count)
{
mBroken = broken;
mCount = count;
}
void OnDestroy() override
{
V_FreeBrokenLines(mBroken);
}
};
IMPLEMENT_CLASS(DBrokenLines, true, false);
DEFINE_ACTION_FUNCTION(DBrokenLines, Count)
{
PARAM_SELF_PROLOGUE(DBrokenLines);
ACTION_RETURN_INT(self->mCount);
}
DEFINE_ACTION_FUNCTION(DBrokenLines, StringWidth)
{
PARAM_SELF_PROLOGUE(DBrokenLines);
PARAM_INT(index);
ACTION_RETURN_INT((unsigned)index >= self->mCount? -1 : self->mBroken[index].Width);
}
DEFINE_ACTION_FUNCTION(DBrokenLines, StringAt)
{
PARAM_SELF_PROLOGUE(DBrokenLines);
PARAM_INT(index);
ACTION_RETURN_STRING((unsigned)index >= self->mCount? -1 : self->mBroken[index].Text);
}
DEFINE_ACTION_FUNCTION(FFont, BreakLines)
{
PARAM_SELF_STRUCT_PROLOGUE(FFont);
PARAM_STRING(text);
PARAM_INT(maxwidth);
unsigned int count;
FBrokenLines *broken = V_BreakLines(self, maxwidth, text, true, &count);
ACTION_RETURN_OBJECT(new DBrokenLines(broken, count));
}

View file

@ -75,11 +75,11 @@ struct FBrokenLines
#define TEXTCOLOR_CHAT "\034*" #define TEXTCOLOR_CHAT "\034*"
#define TEXTCOLOR_TEAMCHAT "\034!" #define TEXTCOLOR_TEAMCHAT "\034!"
FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *str, bool preservecolor = false); FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *str, bool preservecolor = false, unsigned int *count = nullptr);
void V_FreeBrokenLines (FBrokenLines *lines); void V_FreeBrokenLines (FBrokenLines *lines);
inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const char *str, bool preservecolor = false) inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const char *str, bool preservecolor = false, unsigned int *count = nullptr)
{ return V_BreakLines (font, maxwidth, (const BYTE *)str, preservecolor); } { return V_BreakLines (font, maxwidth, (const BYTE *)str, preservecolor, count); }
inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const FString &str, bool preservecolor = false) inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const FString &str, bool preservecolor = false, unsigned int *count = nullptr)
{ return V_BreakLines (font, maxwidth, (const BYTE *)str.GetChars(), preservecolor); } { return V_BreakLines (font, maxwidth, (const BYTE *)str.GetChars(), preservecolor, count); }
#endif //__V_TEXT_H__ #endif //__V_TEXT_H__

View file

@ -75,9 +75,8 @@ enum
DTA_DestWidth, // width of area to draw to DTA_DestWidth, // width of area to draw to
DTA_DestHeight, // height of area to draw to DTA_DestHeight, // height of area to draw to
DTA_Alpha, // alpha value for translucency DTA_Alpha, // alpha value for translucency
DTA_AlphaF, // alpha value for translucency
DTA_FillColor, // color to stencil onto the destination (RGB is the color for truecolor drawers, A is the palette index for paletted drawers) DTA_FillColor, // color to stencil onto the destination (RGB is the color for truecolor drawers, A is the palette index for paletted drawers)
DTA_Translation, // translation table to recolor the source DTA_TranslationIndex, // translation table to recolor the source
DTA_AlphaChannel, // bool: the source is an alpha channel; used with DTA_FillColor DTA_AlphaChannel, // bool: the source is an alpha channel; used with DTA_FillColor
DTA_Clean, // bool: scale texture size and position by CleanXfac and CleanYfac DTA_Clean, // bool: scale texture size and position by CleanXfac and CleanYfac
DTA_320x200, // bool: scale texture size and position to fit on a virtual 320x200 screen DTA_320x200, // bool: scale texture size and position to fit on a virtual 320x200 screen
@ -163,7 +162,7 @@ struct DrawParms
uint32 colorOverlay; uint32 colorOverlay;
INTBOOL alphaChannel; INTBOOL alphaChannel;
INTBOOL flipX; INTBOOL flipX;
fixed_t shadowAlpha; float shadowAlpha;
int shadowColor; int shadowColor;
INTBOOL keepratio; INTBOOL keepratio;
INTBOOL masked; INTBOOL masked;
@ -178,6 +177,12 @@ struct DrawParms
bool virtBottom; bool virtBottom;
}; };
struct VMVa_List
{
VMValue *args;
int curindex;
int numargs;
};
// //
// VIDEO // VIDEO
// //
@ -252,6 +257,7 @@ public:
// 2D Texture drawing // 2D Texture drawing
bool SetTextureParms(DrawParms *parms, FTexture *img, double x, double y) const; bool SetTextureParms(DrawParms *parms, FTexture *img, double x, double y) const;
void DrawTexture (FTexture *img, double x, double y, int tags, ...); void DrawTexture (FTexture *img, double x, double y, int tags, ...);
void DrawTexture(FTexture *img, double x, double y, VMVa_List &);
void FillBorder (FTexture *img); // Fills the border around a 4:3 part of the screen on non-4:3 displays void FillBorder (FTexture *img); // Fills the border around a 4:3 part of the screen on non-4:3 displays
void VirtualToRealCoords(double &x, double &y, double &w, double &h, double vwidth, double vheight, bool vbottom=false, bool handleaspect=true) const; void VirtualToRealCoords(double &x, double &y, double &w, double &h, double vwidth, double vheight, bool vbottom=false, bool handleaspect=true) const;
@ -263,8 +269,10 @@ public:
#undef DrawText // See WinUser.h for the definition of DrawText as a macro #undef DrawText // See WinUser.h for the definition of DrawText as a macro
#endif #endif
// 2D Text drawing // 2D Text drawing
void DrawText (FFont *font, int normalcolor, int x, int y, const char *string, int tag_first, ...); void DrawText(FFont *font, int normalcolor, double x, double y, const char *string, int tag_first, ...);
void DrawChar (FFont *font, int normalcolor, int x, int y, BYTE character, int tag_first, ...); void DrawText(FFont *font, int normalcolor, double x, double y, const char *string, VMVa_List &args);
void DrawChar(FFont *font, int normalcolor, double x, double y, int character, int tag_first, ...);
void DrawChar(FFont *font, int normalcolor, double x, double y, int character, VMVa_List &args);
protected: protected:
BYTE *Buffer; BYTE *Buffer;
@ -273,10 +281,14 @@ protected:
int Pitch; int Pitch;
int LockCount; int LockCount;
void DrawTextCommon(FFont *font, int normalcolor, double x, double y, const char *string, DrawParms &parms);
bool ClipBox (int &left, int &top, int &width, int &height, const BYTE *&src, const int srcpitch) const; bool ClipBox (int &left, int &top, int &width, int &height, const BYTE *&src, const int srcpitch) const;
void DrawTextureV(FTexture *img, double x, double y, uint32 tag, va_list tags) = delete; void DrawTextureV(FTexture *img, double x, double y, uint32 tag, va_list tags) = delete;
virtual void DrawTextureParms(FTexture *img, DrawParms &parms); virtual void DrawTextureParms(FTexture *img, DrawParms &parms);
bool ParseDrawTextureTags (FTexture *img, double x, double y, uint32 tag, va_list tags, DrawParms *parms, bool fortext) const;
template<class T>
bool ParseDrawTextureTags(FTexture *img, double x, double y, DWORD tag, T& tags, DrawParms *parms, bool fortext) const;
DCanvas() {} DCanvas() {}

View file

@ -722,10 +722,10 @@ void WI_drawBackground()
static int WI_DrawCharPatch (FFont *font, int charcode, int x, int y, EColorRange translation=CR_UNTRANSLATED, bool nomove=false) static int WI_DrawCharPatch (FFont *font, int charcode, int x, int y, EColorRange translation=CR_UNTRANSLATED, bool nomove=false)
{ {
int width; int width;
screen->DrawTexture(font->GetChar(charcode, &width), x, y, font->GetChar(charcode, &width);
screen->DrawChar(font, translation, x, y, charcode,
nomove ? DTA_CleanNoMove : DTA_Clean, true, nomove ? DTA_CleanNoMove : DTA_Clean, true,
DTA_ShadowAlpha, (gameinfo.gametype & GAME_DoomChex) ? 0 : OPAQUE/2, DTA_ShadowAlpha, (gameinfo.gametype & GAME_DoomChex) ? 0 : 0.5,
DTA_Translation, font->GetColorTranslation(translation),
TAG_DONE); TAG_DONE);
return x - width; return x - width;
} }

View file

@ -1417,6 +1417,9 @@ TXT_KILLED_ORACLE = "You've Killed The Oracle!";
TXT_KILLED_MACIL = "You Killed Macil!"; TXT_KILLED_MACIL = "You Killed Macil!";
TXT_KILLED_LOREMASTER = "You've Killed the Loremaster!"; TXT_KILLED_LOREMASTER = "You've Killed the Loremaster!";
TXT_YOUFOOL = "You Fool! You've set off the alarm.";
TXT_YOUREDEAD = "You're dead! You set off the alarm.";
// Strife pickup messages // Strife pickup messages
TXT_METALARMOR = "You picked up the Metal Armor."; TXT_METALARMOR = "You picked up the Metal Armor.";

View file

@ -7,6 +7,9 @@
#include "zscript/actor_checks.txt" #include "zscript/actor_checks.txt"
#include "zscript/events.txt" #include "zscript/events.txt"
#include "zscript/menu/menu.txt"
#include "zscript/menu/menuitembase.txt"
#include "zscript/inventory/inventory.txt" #include "zscript/inventory/inventory.txt"
#include "zscript/inventory/inv_misc.txt" #include "zscript/inventory/inv_misc.txt"
#include "zscript/inventory/stateprovider.txt" #include "zscript/inventory/stateprovider.txt"

View file

@ -498,6 +498,7 @@ class Actor : Thinker native
native bool UsePuzzleItem(int PuzzleItemType); native bool UsePuzzleItem(int PuzzleItemType);
native float AccuracyFactor(); native float AccuracyFactor();
native bool MorphMonster (Class<Actor> spawntype, int duration, int style, Class<Actor> enter_flash, Class<Actor> exit_flash); native bool MorphMonster (Class<Actor> spawntype, int duration, int style, Class<Actor> enter_flash, Class<Actor> exit_flash);
native void SetCamera(Actor cam, bool revert = false);
// DECORATE compatible functions // DECORATE compatible functions
native int CountInv(class<Inventory> itemtype, int ptr_select = AAPTR_DEFAULT); native int CountInv(class<Inventory> itemtype, int ptr_select = AAPTR_DEFAULT);

View file

@ -32,16 +32,126 @@ struct TexMan
native static TextureID CheckForTexture(String name, int usetype, int flags = TryAny); native static TextureID CheckForTexture(String name, int usetype, int flags = TryAny);
} }
enum DrawTextureTags
{
TAG_USER = (1<<30),
DTA_Base = TAG_USER + 5000,
DTA_DestWidth, // width of area to draw to
DTA_DestHeight, // height of area to draw to
DTA_Alpha, // alpha value for translucency
DTA_FillColor, // color to stencil onto the destination (RGB is the color for truecolor drawers, A is the palette index for paletted drawers)
DTA_TranslationIndex, // translation table to recolor the source
DTA_AlphaChannel, // bool: the source is an alpha channel; used with DTA_FillColor
DTA_Clean, // bool: scale texture size and position by CleanXfac and CleanYfac
DTA_320x200, // bool: scale texture size and position to fit on a virtual 320x200 screen
DTA_Bottom320x200, // bool: same as DTA_320x200 but centers virtual screen on bottom for 1280x1024 targets
DTA_CleanNoMove, // bool: like DTA_Clean but does not reposition output position
DTA_CleanNoMove_1, // bool: like DTA_CleanNoMove, but uses Clean[XY]fac_1 instead
DTA_FlipX, // bool: flip image horizontally //FIXME: Does not work with DTA_Window(Left|Right)
DTA_ShadowColor, // color of shadow
DTA_ShadowAlpha, // alpha of shadow
DTA_Shadow, // set shadow color and alphas to defaults
DTA_VirtualWidth, // pretend the canvas is this wide
DTA_VirtualHeight, // pretend the canvas is this tall
DTA_TopOffset, // override texture's top offset
DTA_LeftOffset, // override texture's left offset
DTA_CenterOffset, // bool: override texture's left and top offsets and set them for the texture's middle
DTA_CenterBottomOffset,// bool: override texture's left and top offsets and set them for the texture's bottom middle
DTA_WindowLeft, // don't draw anything left of this column (on source, not dest)
DTA_WindowRight, // don't draw anything at or to the right of this column (on source, not dest)
DTA_ClipTop, // don't draw anything above this row (on dest, not source)
DTA_ClipBottom, // don't draw anything at or below this row (on dest, not source)
DTA_ClipLeft, // don't draw anything to the left of this column (on dest, not source)
DTA_ClipRight, // don't draw anything at or to the right of this column (on dest, not source)
DTA_Masked, // true(default)=use masks from texture, false=ignore masks
DTA_HUDRules, // use fullscreen HUD rules to position and size textures
DTA_HUDRulesC, // only used internally for marking HUD_HorizCenter
DTA_KeepRatio, // doesn't adjust screen size for DTA_Virtual* if the aspect ratio is not 4:3
DTA_RenderStyle, // same as render style for actors
DTA_ColorOverlay, // DWORD: ARGB to overlay on top of image; limited to black for software
DTA_Internal1,
DTA_Internal2,
DTA_Internal3,
DTA_Fullscreen, // Draw image fullscreen (same as DTA_VirtualWidth/Height with graphics size.)
// floating point duplicates of some of the above:
DTA_DestWidthF,
DTA_DestHeightF,
DTA_TopOffsetF,
DTA_LeftOffsetF,
DTA_VirtualWidthF,
DTA_VirtualHeightF,
DTA_WindowLeftF,
DTA_WindowRightF,
// For DrawText calls only:
DTA_TextLen, // stop after this many characters, even if \0 not hit
DTA_CellX, // horizontal size of character cell
DTA_CellY, // vertical size of character cell
};
struct Screen native struct Screen native
{ {
enum EColorRange
{
CR_UNDEFINED = -1,
CR_BRICK,
CR_TAN,
CR_GRAY,
CR_GREY = CR_GRAY,
CR_GREEN,
CR_BROWN,
CR_GOLD,
CR_RED,
CR_BLUE,
CR_ORANGE,
CR_WHITE,
CR_YELLOW,
CR_UNTRANSLATED,
CR_BLACK,
CR_LIGHTBLUE,
CR_CREAM,
CR_OLIVE,
CR_DARKGREEN,
CR_DARKRED,
CR_DARKBROWN,
CR_PURPLE,
CR_DARKGRAY,
CR_CYAN,
NUM_TEXT_COLORS
};
native static int GetWidth();
native static int GetHeight();
native static void DrawHUDTexture(TextureID tex, double x, double y); native static void DrawHUDTexture(TextureID tex, double x, double y);
native static vararg void DrawTexture(TextureID tex, bool animate, double x, double y, ...);
native static vararg void DrawChar(Font font, int normalcolor, double x, double y, int character, ...);
native static vararg void DrawText(Font font, int normalcolor, double x, double y, String text, ...);
}
class BrokenLines : Object native
{
native int Count();
native int StringWidth(int line);
native String StringAt(int line);
}
struct Font native
{
native int GetCharWidth(int code);
native int StringWidth(String code);
native static int FindFontColor(Name color);
native static Font FindFont(Name fontname);
native static Font GetFont(Name fontname);
native static BrokenLines BreakLines(String text, int maxlen);
} }
struct Console native struct Console native
{ {
native static void HideConsole(); native static void HideConsole();
native static void MidPrint(string fontname, string textlabel, bool bold = false); // always uses the stringtable. native static void MidPrint(Font fontname, string textlabel, bool bold = false);
native static vararg void Printf(string fmt, ...); native static vararg void Printf(string fmt, ...);
} }
struct DamageTypeDefinition native struct DamageTypeDefinition native
@ -310,7 +420,7 @@ struct StringStruct native
{ {
native void Replace(String pattern, String replacement); native void Replace(String pattern, String replacement);
native static vararg String Format(String fmt, ...); native static vararg String Format(String fmt, ...);
native vararg void AppendFormat(String fmt, ...); native vararg void AppendFormat(String fmt, ...);
} }
class Floor : Thinker native class Floor : Thinker native

View file

@ -9,7 +9,9 @@ extend class Object
deprecated static void C_MidPrint(string fontname, string textlabel, bool bold = false) // deprecated for 2.4.x deprecated static void C_MidPrint(string fontname, string textlabel, bool bold = false) // deprecated for 2.4.x
{ {
return Console.MidPrint(fontname, textlabel, bold); let f = Font.GetFont(fontname);
if (f == null) return;
return Console.MidPrint(f, textlabel, bold);
} }
} }

View file

@ -40,7 +40,7 @@ extend class Actor
void AdjustPlayerAngle(FTranslatedLineTarget t) void AdjustPlayerAngle(FTranslatedLineTarget t)
{ {
double difference = t.angleFromSource; double difference = deltaangle(angle, t.angleFromSource);
if (abs(difference) > MAX_ANGLE_ADJUST) if (abs(difference) > MAX_ANGLE_ADJUST)
{ {
if (difference > 0) if (difference > 0)

View file

@ -0,0 +1,17 @@
class Menu : Object native
{
//native static int MenuTime();
}
struct FOptionMenuSettings
{
int mTitleColor;
int mFontColor;
int mFontColorValue;
int mFontColorMore;
int mFontColorHeader;
int mFontColorHighlight;
int mFontColorSelection;
int mLinespacing;
}

View file

@ -0,0 +1,66 @@
//=============================================================================
//
// base class for menu items
//
//=============================================================================
class MenuItemBase : Object native
{
protected int mXpos, mYpos;
protected Name mAction;
bool mEnabled;
protected void Init(int xpos = 0, int ypos = 0, Name actionname = 'None')
{
mXpos = xpos;
mYpos = ypos;
mAction = actionname;
mEnabled = true;
}
virtual bool CheckCoordinate(int x, int y) { return false; }
virtual void Ticker() {}
virtual void Drawer(bool selected) {}
virtual bool Selectable() {return false; }
virtual bool Activate() { return false; }
virtual Name, int GetAction() { return mAction, 0; }
virtual bool SetString(int i, String s) { return false; }
virtual bool, String GetString(int i) { return false, ""; }
virtual bool SetValue(int i, int value) { return false; }
virtual bool, int GetValue(int i) { return false, 0; }
virtual void Enable(bool on) { mEnabled = on; }
virtual bool MenuEvent (int mkey, bool fromcontroller) { return false; }
virtual bool MouseEvent(int type, int x, int y) { return false; }
virtual bool CheckHotkey(int c) { return false; }
virtual int GetWidth() { return 0; }
virtual void OffsetPositionY(int ydelta) { mYpos += ydelta; }
virtual int GetY() { return mYpos; }
virtual int GetX() { return mXpos; }
virtual void SetX(int x) { mXpos = x; }
/*
virtual void DrawSelector(int xofs, int yofs, TextureID tex)
{
if (tex.isNull())
{
if ((Menu.MenuTime() % 8) < 6)
{
screen.DrawText(ConFont, OptionSettings.mFontColorSelection,
(mXpos + xofs - 160) * CleanXfac + screen.GetWidth() / 2,
(mYpos + yofs - 100) * CleanYfac + screen.GetHeight() / 2,
"\xd",
DTA_CellX, 8 * CleanXfac,
DTA_CellY, 8 * CleanYfac,
TAG_DONE);
}
}
else
{
screen.DrawTexture (tex, mXpos + xofs, mYpos + yofs, DTA_Clean, true, TAG_DONE);
}
}
*/
}

View file

@ -632,7 +632,7 @@ class RaiseAlarm : DummyStrifeItem
dropper.target.SoundAlert(dropper.target); dropper.target.SoundAlert(dropper.target);
if (dropper.target.CheckLocalView(consoleplayer)) if (dropper.target.CheckLocalView(consoleplayer))
{ {
A_Log("You Fool! You've set off the alarm."); Console.MidPrint(SmallFont, "$TXT_YOUFOOL");
} }
} }
Destroy (); Destroy ();
@ -672,7 +672,7 @@ class CloseDoor222 : DummyStrifeItem
{ {
if (dropper.target.CheckLocalView(consoleplayer)) if (dropper.target.CheckLocalView(consoleplayer))
{ {
A_Log("You're dead! You set off the alarm."); Console.MidPrint(SmallFont, "$TXT_YOUREDEAD");
} }
dropper.target.SoundAlert(dropper.target); dropper.target.SoundAlert(dropper.target);
} }