SBarInfo Update #17:

- Fixed: SBarInfo tried to calculate scaled offsets on unscaled status bars.
- Added: createpopup to SBarInfo.  No we don't have custom popups yet.  It only
  defines the transition effect.  Currently none or slideinbottom.
- Made the first argument of DrawMugShot optional (think of it as an overloaded
  function).  The use of the first argument is deprecated due to the event of
  per player class faces.
- More changes from DrawImage to screen->DrawTexture().  I guess I didn't get
  them all just yet.


SVN r897 (trunk)
This commit is contained in:
Christoph Oelckers 2008-04-09 07:32:33 +00:00
parent 6535283ff1
commit a0356a45cd
4 changed files with 229 additions and 34 deletions

View file

@ -1,3 +1,13 @@
April 9, 2008 (SBarInfo Update #17)
- Fixed: SBarInfo tried to calculate scaled offsets on unscaled status bars.
- Added: createpopup to SBarInfo. No we don't have custom popups yet. It only
defines the transition effect. Currently none or slideinbottom.
- Made the first argument of DrawMugShot optional (think of it as an overloaded
function). The use of the first argument is deprecated due to the event of
per player class faces.
- More changes from DrawImage to screen->DrawTexture(). I guess I didn't get
them all just yet.
April 8, 2008
- Added the FCriticalSection class in critsec.h to make it easier to
use critical sections in other places besides the OPL player.

View file

@ -40,6 +40,7 @@
#include "v_collection.h"
#define NUMHUDS 9
#define NUMPOPUPS 3
class FBarTexture;
class FScanner;
@ -47,6 +48,35 @@ class FScanner;
struct SBarInfoCommand; //we need to be able to use this before it is defined.
struct MugShotState;
//Popups!
enum PopupTransition
{
TRANSITION_NONE,
TRANSITION_SLIDEINBOTTOM,
};
struct Popup
{
PopupTransition transition;
bool opened;
bool moving;
int height;
int width;
int speed;
int x;
int y;
Popup();
void init();
void tick();
void open();
void close();
bool isDoneMoving();
int getXOffset();
int getYOffset();
};
//SBarInfo
struct SBarInfoBlock
{
TArray<SBarInfoCommand> commands;
@ -82,6 +112,7 @@ struct SBarInfo
{
TArray<FString> Images;
SBarInfoBlock huds[NUMHUDS];
Popup popups[NUMPOPUPS];
bool automapbar;
bool interpolateHealth;
bool interpolateArmor;
@ -276,6 +307,7 @@ enum //Key words
SBARINFO_LOWERHEALTHCAP,
SBARINFO_STATUSBAR,
SBARINFO_MUGSHOT,
SBARINFO_CREATEPOPUP,
};
enum //Bar types
@ -340,7 +372,7 @@ public:
void ShowPop(int popnum);
void SetMugShotState(const char* stateName, bool waitTillDone=false);
private:
void doCommands(SBarInfoBlock &block);
void doCommands(SBarInfoBlock &block, int xOffset=0, int yOffset=0);
void DrawGraphic(FTexture* texture, int x, int y, int flags=0);
void DrawString(const char* str, int x, int y, EColorRange translation, int spacing=0);
void DrawNumber(int num, int len, int x, int y, EColorRange translation, int spacing=0, bool fillzeros=false);
@ -366,6 +398,7 @@ private:
int mugshotHealth;
int chainWiggle;
int artiflash;
int pendingPopup;
int currentPopup;
unsigned int invBarOffset;
FBarShader shader_horz_normal;

View file

@ -267,6 +267,8 @@ DSBarInfo::DSBarInfo () : DBaseStatusBar (SBarInfoScript->height),
chainWiggle = 0;
artiflash = 4;
currentState = NULL;
currentPopup = POP_None;
pendingPopup = POP_None;
}
DSBarInfo::~DSBarInfo ()
@ -320,11 +322,11 @@ void DSBarInfo::Draw (EHudState state)
if(currentPopup != POP_None)
{
if(currentPopup == POP_Log)
doCommands(SBarInfoScript->huds[STBAR_POPUPLOG]);
doCommands(SBarInfoScript->huds[STBAR_POPUPLOG], SBarInfoScript->popups[currentPopup].getXOffset(), SBarInfoScript->popups[currentPopup].getYOffset());
else if(currentPopup == POP_Keys)
doCommands(SBarInfoScript->huds[STBAR_POPUPKEYS]);
doCommands(SBarInfoScript->huds[STBAR_POPUPKEYS], SBarInfoScript->popups[currentPopup].getXOffset(), SBarInfoScript->popups[currentPopup].getYOffset());
else if(currentPopup == POP_Status)
doCommands(SBarInfoScript->huds[STBAR_POPUPSTATUS]);
doCommands(SBarInfoScript->huds[STBAR_POPUPSTATUS], SBarInfoScript->popups[currentPopup].getXOffset(), SBarInfoScript->popups[currentPopup].getYOffset());
}
}
@ -410,6 +412,16 @@ void DSBarInfo::Tick ()
rampageTimer = 0;
}
mugshotHealth = CPlayer->health;
if(currentPopup != POP_None)
{
SBarInfoScript->popups[currentPopup].tick();
if(SBarInfoScript->popups[currentPopup].opened == false && SBarInfoScript->popups[currentPopup].isDoneMoving())
{
currentPopup = pendingPopup;
if(currentPopup != POP_None)
SBarInfoScript->popups[currentPopup].open();
}
}
}
void DSBarInfo::ReceivedWeapon (AWeapon *weapon)
@ -426,9 +438,20 @@ void DSBarInfo::ShowPop(int popnum)
{
DBaseStatusBar::ShowPop(popnum);
if(popnum != currentPopup)
currentPopup = popnum;
{
pendingPopup = popnum;
}
else
currentPopup = POP_None;
pendingPopup = POP_None;
if(currentPopup != POP_None)
SBarInfoScript->popups[currentPopup].close();
else
{
currentPopup = pendingPopup;
pendingPopup = POP_None;
if(currentPopup != POP_None)
SBarInfoScript->popups[currentPopup].open();
}
}
//Public so it can be called by ACS
@ -447,7 +470,7 @@ void DSBarInfo::SetMugShotState(const char* stateName, bool waitTillDone)
}
}
void DSBarInfo::doCommands(SBarInfoBlock &block)
void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
{
//prepare ammo counts
AAmmo *ammo1, *ammo2;
@ -467,6 +490,8 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
for(unsigned int i = 0;i < block.commands.Size();i++)
{
SBarInfoCommand& cmd = block.commands[i];
cmd.x += xOffset;
cmd.y += yOffset;
switch(cmd.type) //read and execute all the commands
{
case SBARINFO_DRAWSWITCHABLEIMAGE: //draw the alt image if we don't have the item else this is like a normal drawimage
@ -712,7 +737,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
}
else if((cmd.flags & DRAWSELECTEDINVENTORY_ALTERNATEONEMPTY))
{
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
}
break;
case SBARINFO_DRAWINVENTORYBAR:
@ -1063,7 +1088,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
((cmd.flags & GAMETYPE_COOPERATIVE) && multiplayer && !deathmatch) ||
((cmd.flags & GAMETYPE_TEAMGAME) && teamplay))
{
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
}
break;
case SBARINFO_PLAYERCLASS:
@ -1072,14 +1097,14 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
int spawnClass = CPlayer->cls->ClassIndex;
if(cmd.special == spawnClass || cmd.special2 == spawnClass || cmd.special3 == spawnClass)
{
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
}
break;
}
case SBARINFO_ASPECTRATIO:
if(CheckRatio(screen->GetWidth(), screen->GetHeight()) == cmd.value)
{
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
}
break;
case SBARINFO_ISSELECTED:
@ -1090,16 +1115,16 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
if(weapon2 != NULL)
{
if((cmd.flags & SBARINFOEVENT_NOT) && (weapon1 != CPlayer->ReadyWeapon->GetSpecies() && weapon2 != CPlayer->ReadyWeapon->GetSpecies()))
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
else if(!(cmd.flags & SBARINFOEVENT_NOT) && (weapon1 == CPlayer->ReadyWeapon->GetSpecies() || weapon2 == CPlayer->ReadyWeapon->GetSpecies()))
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
}
else
{
if(!(cmd.flags & SBARINFOEVENT_NOT) && weapon1 == CPlayer->ReadyWeapon->GetSpecies())
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
else if((cmd.flags & SBARINFOEVENT_NOT) && weapon1 != CPlayer->ReadyWeapon->GetSpecies())
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
}
}
break;
@ -1115,7 +1140,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
bool usesammo2 = (AmmoType2 != NULL);
if(!(cmd.flags & SBARINFOEVENT_NOT) && !usesammo1 && !usesammo2) //if the weapon doesn't use ammo don't go though the trouble.
{
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
break;
}
//Or means only 1 ammo type needs to match and means both need to match.
@ -1126,11 +1151,11 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
if(((cmd.flags & SBARINFOEVENT_OR) && (match1 || match2)) || ((cmd.flags & SBARINFOEVENT_AND) && (match1 && match2)))
{
if(!(cmd.flags & SBARINFOEVENT_NOT))
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
}
else if(cmd.flags & SBARINFOEVENT_NOT)
{
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
}
}
else //Every thing here could probably be one long if statement but then it would be more confusing.
@ -1138,11 +1163,11 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
if((usesammo1 && (AmmoType1 == IfAmmo1)) || (usesammo2 && (AmmoType2 == IfAmmo1)))
{
if(!(cmd.flags & SBARINFOEVENT_NOT))
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
}
else if(cmd.flags & SBARINFOEVENT_NOT)
{
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
}
}
}
@ -1154,24 +1179,26 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
if(cmd.flags & SBARINFOEVENT_AND)
{
if((item1 != NULL && item2 != NULL) && !(cmd.flags & SBARINFOEVENT_NOT))
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
else if((item1 == NULL || item2 == NULL) && (cmd.flags & SBARINFOEVENT_NOT))
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
}
else if(cmd.flags & SBARINFOEVENT_OR)
{
if((item1 != NULL || item2 != NULL) && !(cmd.flags & SBARINFOEVENT_NOT))
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
else if((item1 == NULL && item2 == NULL) && (cmd.flags & SBARINFOEVENT_NOT))
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
}
else if((item1 != NULL) && !(cmd.flags & SBARINFOEVENT_NOT))
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
else if((item1 == NULL) && (cmd.flags & SBARINFOEVENT_NOT))
doCommands(cmd.subBlock);
doCommands(cmd.subBlock, xOffset, yOffset);
break;
}
}
cmd.x -= xOffset;
cmd.y -= yOffset;
}
}
@ -1191,7 +1218,8 @@ void DSBarInfo::DrawGraphic(FTexture* texture, int x, int y, int flags)
y += ST_Y;
int w = texture->GetScaledWidth();
int h = texture->GetScaledHeight() + y;
screen->VirtualToRealCoordsInt(x, y, w, h, 320, 200, true);
if(Scaled)
screen->VirtualToRealCoordsInt(x, y, w, h, 320, 200, true);
h -= y;
if((flags & DRAWIMAGE_TRANSLATABLE))
{
@ -1238,7 +1266,8 @@ void DSBarInfo::DrawString(const char* str, int x, int y, EColorRange translatio
int ry = y + ST_Y;
int rw = character->GetScaledWidth();
int rh = character->GetScaledHeight();
screen->VirtualToRealCoordsInt(rx, ry, rw, rh, 320, 200, true);
if(Scaled)
screen->VirtualToRealCoordsInt(rx, ry, rw, rh, 320, 200, true);
screen->DrawTexture(character, rx, ry,
DTA_DestWidth, rw,
DTA_DestHeight, rh,
@ -1297,7 +1326,8 @@ void DSBarInfo::DrawFace(FString &defaultFace, int accuracy, bool xdth, bool ani
y += ST_Y;
int w = face->GetScaledWidth();
int h = face->GetScaledHeight();
screen->VirtualToRealCoordsInt(x, y, w, h, 320, 200, true);
if(Scaled)
screen->VirtualToRealCoordsInt(x, y, w, h, 320, 200, true);
screen->DrawTexture(face, x, y,
DTA_DestWidth, w,
DTA_DestHeight, h,
@ -1492,10 +1522,10 @@ void DSBarInfo::DrawGem(FTexture* chain, FTexture* gem, int value, int x, int y,
int offset = (int) (((double) (chainWidth-padleft-padright)/100)*value);
if(chain != NULL)
{
DrawImage(chain, x+(offset%chainsize), y);
DrawGraphic(chain, x+(offset%chainsize), y);
}
if(gem != NULL)
DrawImage(gem, x+padleft+offset, y, translate ? getTranslation() : NULL);
DrawGraphic(gem, x+padleft+offset, y, translate ? DRAWIMAGE_TRANSLATABLE : 0);
}
FRemapTable* DSBarInfo::getTranslation()

View file

@ -60,6 +60,7 @@ static const char *SBarInfoTopLevel[] =
"lowerhealthcap",
"statusbar",
"mugshot",
"createpopup",
NULL
};
@ -305,6 +306,43 @@ void SBarInfo::ParseSBarInfo(int lump)
MugShotStates.Push(state);
break;
}
case SBARINFO_CREATEPOPUP:
{
int pop = 0;
sc.MustGetToken(TK_Identifier);
if(sc.Compare("keys"))
pop = 0;
else if(sc.Compare("log"))
pop = 1;
else if(sc.Compare("status"))
pop = 2;
else
sc.ScriptError("Unkown popup: '%s'", sc.String);
Popup &popup = popups[pop];
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
popup.width = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
popup.height = sc.Number;
sc.MustGetToken(',');
if(!sc.CheckToken(TK_None))
{
sc.MustGetToken(TK_Identifier);
if(sc.Compare("slideinbottom"))
{
popup.transition = TRANSITION_SLIDEINBOTTOM;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
popup.speed = sc.Number;
}
else
sc.ScriptError("Unkown transition type: '%s'", sc.String);
}
popup.init();
sc.MustGetToken(';');
break;
}
}
}
}
@ -553,9 +591,11 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block)
sc.MustGetToken(';');
break;
case SBARINFO_DRAWMUGSHOT:
sc.MustGetToken(TK_StringConst);
cmd.setString(sc, sc.String, 0, 3, true);
sc.MustGetToken(',');
if(sc.CheckToken(TK_StringConst))
{
cmd.setString(sc, sc.String, 0, 3, true);
sc.MustGetToken(',');
}
sc.MustGetToken(TK_IntConst); //accuracy
if(sc.Number < 1 || sc.Number > 9)
sc.ScriptError("Expected a number between 1 and 9, got %d instead.", sc.Number);
@ -1237,6 +1277,88 @@ const MugShotState *FindMugShotState(FString state)
return NULL;
}
//Popup
Popup::Popup()
{
transition = TRANSITION_NONE;
height = 320;
width = 200;
speed = 0;
x = 320;
y = 200;
opened = false;
moving = false;
}
void Popup::init()
{
x = width;
y = height;
if(transition == TRANSITION_SLIDEINBOTTOM)
{
x = 0;
}
}
void Popup::tick()
{
if(transition == TRANSITION_SLIDEINBOTTOM)
{
if(moving)
{
if(opened)
y -= clamp(height + (y - height), 1, speed);
else
y += clamp(height - y, 1, speed);
}
if(y != 0 && y != height)
moving = true;
else
moving = false;
}
else
{
moving = false;
if(opened)
{
y = 0;
x = 0;
}
else
{
y = height;
x = width;
}
}
}
bool Popup::isDoneMoving()
{
return !moving;
}
int Popup::getXOffset()
{
return x;
}
int Popup::getYOffset()
{
return y;
}
void Popup::open()
{
opened = true;
moving = true;
}
void Popup::close()
{
opened = false;
moving = true;
}
//Used to allow replacements of states
int FindMugShotStateIndex(FName state)
{