From f73275ad8892fc6ce46d78b1318e6966ee5e8d44 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 21 Sep 2013 12:46:19 -0400 Subject: [PATCH] - Applied Tesseract's patch for drawimage extensions. (Extended icon support and maximum width/height.) --- src/g_shared/sbar.h | 16 ++- src/g_shared/sbarinfo.cpp | 8 +- src/g_shared/sbarinfo_commands.cpp | 165 +++++++++++++++++++++++------ src/g_shared/shared_hud.cpp | 48 ++++++--- 4 files changed, 188 insertions(+), 49 deletions(-) diff --git a/src/g_shared/sbar.h b/src/g_shared/sbar.h index 3d8c620017..b8dde58506 100644 --- a/src/g_shared/sbar.h +++ b/src/g_shared/sbar.h @@ -444,6 +444,20 @@ void ST_LoadCrosshair(bool alwaysload=false); void ST_Clear(); extern FTexture *CrosshairImage; -FTextureID GetWeaponIcon(AWeapon *weapon); +FTextureID GetInventoryIcon(AInventory *item, DWORD flags, bool *applyscale); + +enum DI_Flags +{ + DI_SKIPICON = 0x1, + DI_SKIPALTICON = 0x2, + DI_SKIPSPAWN = 0x4, + DI_SKIPREADY = 0x8, + DI_ALTICONFIRST = 0x10, + + DI_DRAWINBOX = 0x20, // Set when either width or height is not zero + + DI_FORCESCALE = 0x40, + DI_ALTERNATEONFAIL = 0x80 +}; #endif /* __SBAR_H__ */ diff --git a/src/g_shared/sbarinfo.cpp b/src/g_shared/sbarinfo.cpp index 09be473630..3e1c364e25 100644 --- a/src/g_shared/sbarinfo.cpp +++ b/src/g_shared/sbarinfo.cpp @@ -1187,8 +1187,12 @@ public: if((offsetflags & SBarInfoCommand::CENTER) == SBarInfoCommand::CENTER) { - dx -= (texture->GetScaledWidthDouble()/2.0)-texture->GetScaledLeftOffsetDouble(); - dy -= (texture->GetScaledHeightDouble()/2.0)-texture->GetScaledTopOffsetDouble(); + if (forceWidth < 0) dx -= (texture->GetScaledWidthDouble()/2.0)-texture->GetScaledLeftOffsetDouble(); + else dx -= forceWidth*(0.5-(texture->GetScaledLeftOffsetDouble()/texture->GetScaledWidthDouble())); + //Unoptimalized formula is dx -= forceWidth/2.0-(texture->GetScaledLeftOffsetDouble()*forceWidth/texture->GetScaledWidthDouble()); + + if (forceHeight < 0) dy -= (texture->GetScaledHeightDouble()/2.0)-texture->GetScaledTopOffsetDouble(); + else dy -= forceHeight*(0.5-(texture->GetScaledTopOffsetDouble()/texture->GetScaledHeightDouble())); } dx += xOffset; diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index febf32b809..d5ee06d113 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -41,28 +41,65 @@ // classes. //////////////////////////////////////////////////////////////////////////////// - -class CommandDrawImage : public SBarInfoCommand +class CommandDrawImage : public SBarInfoCommandFlowControl { public: - CommandDrawImage(SBarInfo *script) : SBarInfoCommand(script), - translatable(false), type(NORMAL_IMAGE), image(-1), offset(static_cast (TOP|LEFT)), + CommandDrawImage(SBarInfo *script) : SBarInfoCommandFlowControl(script), + translatable(false), type(NORMAL_IMAGE), image(-1), maxwidth(-1), + maxheight(-1), spawnScaleX(1.0f), spawnScaleY(1.0f), flags(0), + applyscale(false), offset(static_cast (TOP|LEFT)), texture(NULL), alpha(FRACUNIT) { } void Draw(const SBarInfoMainBlock *block, const DSBarInfo *statusBar) { + if(flags & DI_ALTERNATEONFAIL) + SBarInfoCommandFlowControl::Draw(block, statusBar); + if(texture == NULL) return; + int w = maxwidth, h = maxheight; + // We must calculate this per frame in order to prevent glitches with cl_capfps true. fixed_t frameAlpha = block->Alpha(); if(alpha != FRACUNIT) frameAlpha = fixed_t(((double) block->Alpha() / (double) FRACUNIT) * ((double) alpha / (double) OPAQUE) * FRACUNIT); - + + if(flags & DI_DRAWINBOX) + { + double scale1, scale2; + scale1 = scale2 = 1.0f; + double texwidth = (int) (texture->GetScaledWidthDouble()*spawnScaleX); + double texheight = (int) (texture->GetScaledHeightDouble()*spawnScaleY); + + if (w != -1 && (wGetScaledWidthDouble()*spawnScaleX); + h=(int) (texture->GetScaledHeightDouble()*spawnScaleY); + } statusBar->DrawGraphic(texture, imgx, imgy, block->XOffset(), block->YOffset(), frameAlpha, block->FullScreenOffsets(), - translatable, false, offset); + translatable, false, offset, false, w, h); } void Parse(FScanner &sc, bool fullScreenOffsets) { @@ -98,7 +135,7 @@ class CommandDrawImage : public SBarInfoCommand type = HEXENARMOR_AMULET; else { - sc.ScriptMessage("Unkown armor type: '%s'", sc.String); + sc.ScriptMessage("Unknown armor type: '%s'", sc.String); type = HEXENARMOR_ARMOR; } sc.MustGetToken(','); @@ -141,48 +178,90 @@ class CommandDrawImage : public SBarInfoCommand offset = CENTER; else if(sc.Compare("centerbottom")) offset = static_cast (HMIDDLE|BOTTOM); - else + else if(!sc.Compare("lefttop")) //That's already set sc.ScriptError("'%s' is not a valid alignment.", sc.String); } - sc.MustGetToken(';'); + if(sc.CheckToken(',')) + { + sc.MustGetToken(TK_IntConst); + if((maxwidth = sc.Number) > 0) + flags |= DI_DRAWINBOX; + else + maxwidth = -1; + sc.MustGetToken(','); + sc.MustGetToken(TK_IntConst); + if ((maxheight = sc.Number) > 0) + flags |= DI_DRAWINBOX; + else + maxheight = -1; + } + if(sc.CheckToken(',')) + { + while(sc.CheckToken(TK_Identifier)) + { + if(sc.Compare("skipicon")) + flags |= DI_SKIPICON; + else if(sc.Compare("skipalticon")) + flags |= DI_SKIPALTICON; + else if(sc.Compare("skipspawn")) + flags |= DI_SKIPSPAWN; + else if(sc.Compare("skipready")) + flags |= DI_SKIPREADY; + else if(sc.Compare("alticonfirst")) + flags |= DI_ALTICONFIRST; + else if(sc.Compare("forcescale")) + { + if(flags & DI_DRAWINBOX) + flags |= DI_FORCESCALE; + } + else if(sc.Compare("alternateonfail")) + flags |= DI_ALTERNATEONFAIL; + else + sc.ScriptError("Unknown flag '%s'.", sc.String); + if(!sc.CheckToken('|') && !sc.CheckToken(',')) break; + } + } + if(flags & DI_ALTERNATEONFAIL) + SBarInfoCommandFlowControl::Parse(sc, fullScreenOffsets); + else + sc.MustGetToken(';'); } void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged) { + SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged); + texture = NULL; alpha = FRACUNIT; + if (applyscale) + { + spawnScaleX = spawnScaleY = 1.0f; + applyscale = false; + } if(type == PLAYERICON) texture = TexMan[statusBar->CPlayer->mo->ScoreIcon]; else if(type == AMMO1) { - if(statusBar->ammo1 != NULL) - texture = TexMan[statusBar->ammo1->Icon]; + AAmmo *ammo = statusBar->ammo1; + if(ammo != NULL) + GetIcon(ammo); } else if(type == AMMO2) { - if(statusBar->ammo2 != NULL) - texture = TexMan[statusBar->ammo2->Icon]; + AAmmo *ammo = statusBar->ammo2; + if(ammo != NULL) + GetIcon(ammo); } else if(type == ARMOR) { - if(statusBar->armor != NULL && statusBar->armor->Amount != 0) - texture = TexMan(statusBar->armor->Icon); + ABasicArmor *armor = statusBar->armor; + if(armor != NULL && armor->Amount != 0) + GetIcon(armor); } else if(type == WEAPONICON) { AWeapon *weapon = statusBar->CPlayer->ReadyWeapon; if(weapon != NULL) - { - FTextureID icon; - if (weapon->Icon.isValid()) - { - icon = weapon->Icon; - } - else - { - icon = GetWeaponIcon(weapon); - } - texture = TexMan[icon]; - } + GetIcon(weapon); } else if(type == SIGIL) { @@ -213,8 +292,26 @@ class CommandDrawImage : public SBarInfoCommand texture = TexMan(statusBar->CPlayer->mo->InvSel->Icon); else if(image >= 0) texture = statusBar->Images[image]; + + if (flags & DI_ALTERNATEONFAIL) + { + SetTruth(texture == NULL || !(texture->GetID().isValid()), block, statusBar); + } } protected: + void GetIcon(AInventory *item) + { + FTextureID icon = GetInventoryIcon(item, flags, &applyscale); + + if (applyscale) + { + spawnScaleX = FIXED2FLOAT(item->scaleX); + spawnScaleY = FIXED2FLOAT(item->scaleY); + } + + texture = TexMan[icon]; + } + enum ImageType { PLAYERICON, @@ -238,6 +335,12 @@ class CommandDrawImage : public SBarInfoCommand ImageType type; int image; FTextureID sprite; + int maxwidth; + int maxheight; + double spawnScaleX; + double spawnScaleY; + DWORD flags; + bool applyscale; //Set remotely from from GetInventoryIcon when selected sprite comes from Spawn state // I'm using imgx/imgy here so that I can inherit drawimage with drawnumber for some commands. SBarInfoCoordinate imgx; SBarInfoCoordinate imgy; @@ -1479,11 +1582,11 @@ class CommandDrawMugShot : public SBarInfoCommand //////////////////////////////////////////////////////////////////////////////// -class CommandDrawSelectedInventory : public SBarInfoCommandFlowControl, private CommandDrawImage, private CommandDrawNumber +class CommandDrawSelectedInventory : public CommandDrawImage, private CommandDrawNumber { public: - CommandDrawSelectedInventory(SBarInfo *script) : SBarInfoCommandFlowControl(script), - CommandDrawImage(script), CommandDrawNumber(script), alternateOnEmpty(false), + CommandDrawSelectedInventory(SBarInfo *script) : CommandDrawImage(script), + CommandDrawNumber(script), alternateOnEmpty(false), artiflash(false), alwaysShowCounter(false) { length = INT_MAX; // Counter size @@ -3011,7 +3114,7 @@ class CommandDrawGem : public SBarInfoCommand else sc.ScriptError("Unknown drawgem flag '%s'.", sc.String); if(!sc.CheckToken('|')) - sc.MustGetToken(','); + sc.MustGetToken(','); } sc.MustGetToken(TK_StringConst); //chain chain = script->newImage(sc.String); diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 3416bb82de..964a28e2b0 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -135,12 +135,12 @@ static void DrawImageToBox(FTexture * tex, int x, int y, int w, int h, int trans if (tex) { - int texwidth=tex->GetWidth(); - int texheight=tex->GetHeight(); + double texwidth=tex->GetScaledWidthDouble(); + double texheight=tex->GetScaledHeightDouble(); - if (wGetClass()); + FTextureID picnum, AltIcon = GetHUDIcon(item->GetClass()); FState * state=NULL, *ReadyState; - FTextureID picnum = !AltIcon.isNull()? AltIcon : weapon->Icon; - - if (picnum.isNull()) + picnum.SetNull(); + if (flags & DI_ALTICONFIRST) { - if (weapon->SpawnState && weapon->SpawnState->sprite!=0) + if (!(flags & DI_SKIPALTICON) && AltIcon.isValid()) + picnum = AltIcon; + else if (!(flags & DI_SKIPICON)) + picnum = item->Icon; + } + else + { + if (!(flags & DI_SKIPICON) && item->Icon.isValid()) + picnum = item->Icon; + else if (!(flags & DI_SKIPALTICON)) + picnum = AltIcon; + } + + if (!picnum.isValid()) //isNull() is bad for checking, because picnum could be also invalid (-1) + { + if (!(flags & DI_SKIPSPAWN) && item->SpawnState && item->SpawnState->sprite!=0) { - state = weapon->SpawnState; + state = item->SpawnState; + + if (applyscale != NULL && !(flags & DI_FORCESCALE)) + { + *applyscale = true; + } } - // no spawn state - now try the ready state - else if ((ReadyState = weapon->FindState(NAME_Ready)) && ReadyState->sprite!=0) + // no spawn state - now try the ready state if it's weapon + else if (!(flags & DI_SKIPREADY) && item->GetClass()->IsDescendantOf(RUNTIME_CLASS(AWeapon)) && (ReadyState = item->FindState(NAME_Ready)) && ReadyState->sprite!=0) { state = ReadyState; } @@ -651,7 +669,7 @@ static void DrawOneWeapon(player_t * CPlayer, int x, int & y, AWeapon * weapon) if (weapon==CPlayer->ReadyWeapon || weapon==CPlayer->ReadyWeapon->SisterWeapon) trans=0xd999; } - FTextureID picnum = GetWeaponIcon(weapon); + FTextureID picnum = GetInventoryIcon(weapon, DI_ALTICONFIRST); if (picnum.isValid()) {