mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 20:21:26 +00:00
SVN r314 (trunk)
This commit is contained in:
parent
2fb55622e7
commit
603e905c42
35 changed files with 365 additions and 199 deletions
|
@ -1,3 +1,21 @@
|
|||
August 30, 2006
|
||||
- Added the FNameNoInit class that is exactly like FName except it does not
|
||||
initialize its index, so it can be used from inside Actors without
|
||||
overwriting the runtime default value.
|
||||
- V_BreakLines() now returns an array of FStrings instead of char *'s.
|
||||
- Added support for custom text colors in messages like this:
|
||||
print (s:"\c[Chartreuce]This text is in the color 'Bleargh'");
|
||||
This also obsoletes some of the functionality of the r: print specifier
|
||||
before it was even saw a release version, because you can do this with the
|
||||
standard colors too:
|
||||
print (s:"\c[Green]Some text");
|
||||
- Added two new decorate functionns: A_PlaySoundEx("sound_name", "channel"
|
||||
[, bLooping]) and A_StopSoundEx("channel"), where "channel" is "Auto",
|
||||
"Weapon", "Voice", "Item", "Body", "SoundSlot5", "SoundSlot6", or
|
||||
"SoundSlot7".
|
||||
- Added a third parameter to S_IsActorPlayingSomething() to allow it to check
|
||||
if the actor is playing a specific sound.
|
||||
|
||||
August 29, 2006
|
||||
- Moved the text color definitions out of the executable and into an external
|
||||
data file.
|
||||
|
@ -9,7 +27,7 @@ August 29, 2006
|
|||
#RGB color strings.
|
||||
|
||||
August 27, 2006 (Changes by Graf Zahl)
|
||||
- fixed: callstatechain didn`t check for NULL code pointers
|
||||
- fixed: callstatechain didn't check for NULL code pointers
|
||||
|
||||
August 25, 2006
|
||||
- Fixed: Multiple-choice sound sequences could not be assigned IDs for use
|
||||
|
|
|
@ -165,9 +165,9 @@ CVAR (String, con_ctrl_d, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|||
|
||||
static struct NotifyText
|
||||
{
|
||||
int timeout;
|
||||
int printlevel;
|
||||
byte text[256];
|
||||
int TimeOut;
|
||||
int PrintLevel;
|
||||
FString Text;
|
||||
} NotifyStrings[NUMNOTIFIES];
|
||||
|
||||
static int NotifyTop, NotifyTopGoal;
|
||||
|
@ -556,7 +556,7 @@ void C_AddNotifyString (int printlevel, const char *source)
|
|||
REPLACELINE
|
||||
} addtype = NEWLINE;
|
||||
|
||||
brokenlines_t *lines;
|
||||
FBrokenLines *lines;
|
||||
int i, len, width;
|
||||
|
||||
if ((printlevel != 128 && !show_messages) ||
|
||||
|
@ -573,11 +573,9 @@ void C_AddNotifyString (int printlevel, const char *source)
|
|||
|
||||
width = con_scaletext > 1 ? DisplayWidth/2 : con_scaletext == 1 ? DisplayWidth / CleanXfac : DisplayWidth;
|
||||
|
||||
if (addtype == APPENDLINE && NotifyStrings[NUMNOTIFIES-1].printlevel == printlevel)
|
||||
if (addtype == APPENDLINE && NotifyStrings[NUMNOTIFIES-1].PrintLevel == printlevel)
|
||||
{
|
||||
FString str;
|
||||
|
||||
str.Format("%s%s", NotifyStrings[NUMNOTIFIES-1].text, source);
|
||||
FString str = NotifyStrings[NUMNOTIFIES-1].Text + source;
|
||||
lines = V_BreakLines (width, str);
|
||||
}
|
||||
else
|
||||
|
@ -589,17 +587,23 @@ void C_AddNotifyString (int printlevel, const char *source)
|
|||
if (lines == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; lines[i].width != -1; i++)
|
||||
for (i = 0; lines[i].Width >= 0; i++)
|
||||
{
|
||||
if (addtype == NEWLINE)
|
||||
memmove (&NotifyStrings[0], &NotifyStrings[1], sizeof(struct NotifyText) * (NUMNOTIFIES-1));
|
||||
strcpy ((char *)NotifyStrings[NUMNOTIFIES-1].text, lines[i].string);
|
||||
NotifyStrings[NUMNOTIFIES-1].timeout = gametic + (int)(con_notifytime * TICRATE);
|
||||
NotifyStrings[NUMNOTIFIES-1].printlevel = printlevel;
|
||||
{
|
||||
for (int j = 0; j < NUMNOTIFIES-1; ++j)
|
||||
{
|
||||
NotifyStrings[j] = NotifyStrings[j+1];
|
||||
}
|
||||
}
|
||||
NotifyStrings[NUMNOTIFIES-1].Text = lines[i].Text;
|
||||
NotifyStrings[NUMNOTIFIES-1].TimeOut = gametic + (int)(con_notifytime * TICRATE);
|
||||
NotifyStrings[NUMNOTIFIES-1].PrintLevel = printlevel;
|
||||
addtype = NEWLINE;
|
||||
}
|
||||
|
||||
V_FreeBrokenLines (lines);
|
||||
lines = NULL;
|
||||
|
||||
switch (source[len-1])
|
||||
{
|
||||
|
@ -662,7 +666,7 @@ void AddToConsole (int printlevel, const char *text)
|
|||
|
||||
char *work_p;
|
||||
char *linestart;
|
||||
int cc = CR_TAN;
|
||||
FString cc = 'A' + CR_TAN;
|
||||
int size, len;
|
||||
int x;
|
||||
int maxwidth;
|
||||
|
@ -738,8 +742,23 @@ void AddToConsole (int printlevel, const char *text)
|
|||
if (*work_p == TEXTCOLOR_ESCAPE)
|
||||
{
|
||||
work_p++;
|
||||
if (*work_p)
|
||||
if (*work_p == '[')
|
||||
{
|
||||
char *start = work_p;
|
||||
while (*work_p != ']' && *work_p != '\0')
|
||||
{
|
||||
work_p++;
|
||||
}
|
||||
if (*work_p != '\0')
|
||||
{
|
||||
work_p++;
|
||||
}
|
||||
cc = FString(start, work_p - start);
|
||||
}
|
||||
else if (*work_p != '\0')
|
||||
{
|
||||
cc = *work_p++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
int w = ConFont->GetCharWidth (*work_p);
|
||||
|
@ -757,9 +776,9 @@ void AddToConsole (int printlevel, const char *text)
|
|||
}
|
||||
if (*work_p)
|
||||
{
|
||||
linestart = work_p - 2;
|
||||
linestart = work_p - 1 - cc.Len();
|
||||
linestart[0] = TEXTCOLOR_ESCAPE;
|
||||
linestart[1] = cc;
|
||||
strncpy (linestart + 1, cc, cc.Len());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -908,7 +927,7 @@ void C_FlushDisplay ()
|
|||
int i;
|
||||
|
||||
for (i = 0; i < NUMNOTIFIES; i++)
|
||||
NotifyStrings[i].timeout = 0;
|
||||
NotifyStrings[i].TimeOut = 0;
|
||||
}
|
||||
|
||||
void C_AdjustBottom ()
|
||||
|
@ -996,13 +1015,13 @@ static void C_DrawNotifyText ()
|
|||
|
||||
for (i = 0; i < NUMNOTIFIES; i++)
|
||||
{
|
||||
if (NotifyStrings[i].timeout == 0)
|
||||
if (NotifyStrings[i].TimeOut == 0)
|
||||
continue;
|
||||
|
||||
j = NotifyStrings[i].timeout - gametic;
|
||||
j = NotifyStrings[i].TimeOut - gametic;
|
||||
if (j > 0)
|
||||
{
|
||||
if (!show_messages && NotifyStrings[i].printlevel != 128)
|
||||
if (!show_messages && NotifyStrings[i].PrintLevel != 128)
|
||||
continue;
|
||||
|
||||
fixed_t alpha;
|
||||
|
@ -1016,45 +1035,45 @@ static void C_DrawNotifyText ()
|
|||
alpha = OPAQUE;
|
||||
}
|
||||
|
||||
if (NotifyStrings[i].printlevel >= PRINTLEVELS)
|
||||
if (NotifyStrings[i].PrintLevel >= PRINTLEVELS)
|
||||
color = CR_UNTRANSLATED;
|
||||
else
|
||||
color = PrintColors[NotifyStrings[i].printlevel];
|
||||
color = PrintColors[NotifyStrings[i].PrintLevel];
|
||||
|
||||
if (con_scaletext == 1)
|
||||
{
|
||||
if (!center)
|
||||
screen->DrawText (color, 0, line, (char *)NotifyStrings[i].text,
|
||||
DTA_CleanNoMove, true, DTA_Alpha, alpha, TAG_DONE);
|
||||
screen->DrawText (color, 0, line, NotifyStrings[i].Text,
|
||||
DTA_CleanNoMove, true, DTA_Alpha, alpha, TAG_DONE);
|
||||
else
|
||||
screen->DrawText (color, (SCREENWIDTH -
|
||||
SmallFont->StringWidth (NotifyStrings[i].text)*CleanXfac)/2,
|
||||
line, (char *)NotifyStrings[i].text, DTA_CleanNoMove, true,
|
||||
SmallFont->StringWidth (NotifyStrings[i].Text)*CleanXfac)/2,
|
||||
line, NotifyStrings[i].Text, DTA_CleanNoMove, true,
|
||||
DTA_Alpha, alpha, TAG_DONE);
|
||||
}
|
||||
else if (con_scaletext == 0)
|
||||
{
|
||||
if (!center)
|
||||
screen->DrawText (color, 0, line, (char *)NotifyStrings[i].text,
|
||||
screen->DrawText (color, 0, line, NotifyStrings[i].Text,
|
||||
DTA_Alpha, alpha, TAG_DONE);
|
||||
else
|
||||
screen->DrawText (color, (SCREENWIDTH -
|
||||
SmallFont->StringWidth (NotifyStrings[i].text))/2,
|
||||
line, (char *)NotifyStrings[i].text,
|
||||
SmallFont->StringWidth (NotifyStrings[i].Text))/2,
|
||||
line, NotifyStrings[i].Text,
|
||||
DTA_Alpha, alpha, TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!center)
|
||||
screen->DrawText (color, 0, line, (char *)NotifyStrings[i].text,
|
||||
screen->DrawText (color, 0, line, NotifyStrings[i].Text,
|
||||
DTA_VirtualWidth, screen->GetWidth() / 2,
|
||||
DTA_VirtualHeight, screen->GetHeight() / 2,
|
||||
DTA_KeepRatio, true,
|
||||
DTA_Alpha, alpha, TAG_DONE);
|
||||
else
|
||||
screen->DrawText (color, (screen->GetWidth() / 2 -
|
||||
SmallFont->StringWidth (NotifyStrings[i].text))/2,
|
||||
line, (char *)NotifyStrings[i].text,
|
||||
SmallFont->StringWidth (NotifyStrings[i].Text))/2,
|
||||
line, NotifyStrings[i].Text,
|
||||
DTA_VirtualWidth, screen->GetWidth() / 2,
|
||||
DTA_VirtualHeight, screen->GetHeight() / 2,
|
||||
DTA_KeepRatio, true,
|
||||
|
@ -1071,7 +1090,7 @@ static void C_DrawNotifyText ()
|
|||
line += lineadv;
|
||||
skip++;
|
||||
}
|
||||
NotifyStrings[i].timeout = 0;
|
||||
NotifyStrings[i].TimeOut = 0;
|
||||
}
|
||||
}
|
||||
if (canskip)
|
||||
|
|
|
@ -110,7 +110,7 @@ public:
|
|||
fixed_t SideMove1, SideMove2;
|
||||
int ScoreIcon;
|
||||
int SpawnMask;
|
||||
int MorphWeapon; // actually a name
|
||||
FNameNoInit MorphWeapon;
|
||||
|
||||
int GetMaxHealth() const;
|
||||
};
|
||||
|
|
|
@ -2534,7 +2534,7 @@ void A_SkullRodStorm (AActor *actor)
|
|||
mo->momz = -mo->Speed;
|
||||
mo->special2 = actor->special2; // Transfer player number
|
||||
P_CheckMissileSpawn (mo);
|
||||
if (actor->special1 != -1 && !S_IsActorPlayingSomething (actor, CHAN_BODY))
|
||||
if (actor->special1 != -1 && !S_IsActorPlayingSomething (actor, CHAN_BODY, -1))
|
||||
{
|
||||
S_LoopedSoundID (actor, CHAN_BODY, actor->special1, 1, ATTN_NORM);
|
||||
}
|
||||
|
@ -2909,7 +2909,7 @@ void A_FirePhoenixPL2 (AActor *actor)
|
|||
mo->momx = pmo->momx + FixedMul (mo->Speed, finecosine[angle>>ANGLETOFINESHIFT]);
|
||||
mo->momy = pmo->momy + FixedMul (mo->Speed, finesine[angle>>ANGLETOFINESHIFT]);
|
||||
mo->momz = FixedMul (mo->Speed, slope);
|
||||
if (!player->refire || !S_IsActorPlayingSomething (pmo, CHAN_WEAPON))
|
||||
if (!player->refire || !S_IsActorPlayingSomething (pmo, CHAN_WEAPON, -1))
|
||||
{
|
||||
S_LoopedSoundID (pmo, CHAN_WEAPON, soundid, 1, ATTN_NORM);
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ int ALightning::SpecialMissileHit (AActor *thing)
|
|||
{
|
||||
P_DamageMobj(thing, this, target, 3, MOD_ELECTRIC);
|
||||
}
|
||||
if (!(S_IsActorPlayingSomething (this, CHAN_WEAPON)))
|
||||
if (!(S_IsActorPlayingSomething (this, CHAN_WEAPON, -1)))
|
||||
{
|
||||
S_Sound (this, CHAN_WEAPON, "MageLightningZap", 1, ATTN_NORM);
|
||||
}
|
||||
|
|
|
@ -704,7 +704,7 @@ void A_SerpentHeadCheck (AActor *actor)
|
|||
|
||||
void A_SerpentFXSound (AActor *actor)
|
||||
{
|
||||
if (!S_IsActorPlayingSomething (actor, CHAN_BODY))
|
||||
if (!S_IsActorPlayingSomething (actor, CHAN_BODY, -1))
|
||||
{
|
||||
S_LoopedSound (actor, CHAN_BODY, "SerpentFXContinuous", 1, ATTN_NORM);
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ END_DEFAULTS
|
|||
|
||||
void A_WindSound (AActor *self)
|
||||
{
|
||||
if (!S_IsActorPlayingSomething (self, 6))
|
||||
if (!S_IsActorPlayingSomething (self, 6, -1))
|
||||
{
|
||||
S_LoopedSound (self, 6, "world/wind", 1, ATTN_NORM);
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ void A_WindSound (AActor *self)
|
|||
|
||||
void A_WaterfallSound (AActor *self)
|
||||
{
|
||||
if (!S_IsActorPlayingSomething (self, 6))
|
||||
if (!S_IsActorPlayingSomething (self, 6, -1))
|
||||
{
|
||||
S_LoopedSound (self, 6, "world/waterfall", 1, ATTN_NORM);
|
||||
}
|
||||
|
|
|
@ -302,11 +302,11 @@ int AMorphProjectile::DoSpecialDamage (AActor *target, int damage)
|
|||
{
|
||||
if (target->player)
|
||||
{
|
||||
P_MorphPlayer (target->player, PClass::FindClass (ENamedName(PlayerClass)));
|
||||
P_MorphPlayer (target->player, PClass::FindClass (PlayerClass));
|
||||
}
|
||||
else
|
||||
{
|
||||
P_MorphMonster (target, PClass::FindClass (ENamedName(MonsterClass)));
|
||||
P_MorphMonster (target, PClass::FindClass (MonsterClass));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -314,18 +314,7 @@ int AMorphProjectile::DoSpecialDamage (AActor *target, int damage)
|
|||
void AMorphProjectile::Serialize (FArchive &arc)
|
||||
{
|
||||
Super::Serialize (arc);
|
||||
|
||||
// Hack alert: The classes have to be serialized as names.
|
||||
// But due to the way an actor is constructed they cannot
|
||||
// be declared as names.
|
||||
FName PlayerClassName = ENamedName(PlayerClass);
|
||||
FName MonsterClassName = ENamedName(MonsterClass);
|
||||
|
||||
arc << PlayerClassName << MonsterClassName;
|
||||
|
||||
PlayerClass = PlayerClassName;
|
||||
MonsterClass = MonsterClassName;
|
||||
|
||||
arc << PlayerClass << MonsterClass;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ public:
|
|||
int DoSpecialDamage (AActor *target, int damage);
|
||||
void Serialize (FArchive &arc);
|
||||
|
||||
int PlayerClass, MonsterClass; // really FNames but they would be destroyed by the construction process
|
||||
FNameNoInit PlayerClass, MonsterClass;
|
||||
};
|
||||
|
||||
class AMorphedMonster : public AActor
|
||||
|
|
|
@ -222,10 +222,10 @@ void DHUDMessage::ResetText (const char *text)
|
|||
|
||||
if (Lines)
|
||||
{
|
||||
for (; Lines[NumLines].width != -1; NumLines++)
|
||||
for (; Lines[NumLines].Width >= 0; NumLines++)
|
||||
{
|
||||
Height += Font->GetHeight ();
|
||||
Width = MAX<int> (Width, Lines[NumLines].width);
|
||||
Width = MAX<int> (Width, Lines[NumLines].Width);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,7 +360,7 @@ void DHUDMessage::Draw (int bottom)
|
|||
{
|
||||
int drawx;
|
||||
|
||||
drawx = CenterX ? x - Lines[i].width*xscale/2 : x;
|
||||
drawx = CenterX ? x - Lines[i].Width*xscale/2 : x;
|
||||
DoDraw (i, drawx, y, clean, hudheight);
|
||||
y += ystep;
|
||||
}
|
||||
|
@ -390,13 +390,13 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight)
|
|||
{
|
||||
if (con_scaletext <= 1)
|
||||
{
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].string,
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_CleanNoMove, clean,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].string,
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, SCREENWIDTH/2,
|
||||
DTA_VirtualHeight, SCREENHEIGHT/2,
|
||||
DTA_KeepRatio, true,
|
||||
|
@ -405,7 +405,7 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight)
|
|||
}
|
||||
else
|
||||
{
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].string,
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, HUDWidth,
|
||||
DTA_VirtualHeight, hudheight,
|
||||
TAG_DONE);
|
||||
|
@ -483,14 +483,14 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh
|
|||
{
|
||||
if (con_scaletext <= 1)
|
||||
{
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].string,
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_CleanNoMove, clean,
|
||||
DTA_Alpha, trans,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].string,
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, SCREENWIDTH/2,
|
||||
DTA_VirtualHeight, SCREENHEIGHT/2,
|
||||
DTA_Alpha, trans,
|
||||
|
@ -500,7 +500,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh
|
|||
}
|
||||
else
|
||||
{
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].string,
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, HUDWidth,
|
||||
DTA_VirtualHeight, hudheight,
|
||||
DTA_Alpha, trans,
|
||||
|
@ -576,14 +576,14 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu
|
|||
{
|
||||
if (con_scaletext <= 1)
|
||||
{
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].string,
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_CleanNoMove, clean,
|
||||
DTA_Alpha, trans,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].string,
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, SCREENWIDTH/2,
|
||||
DTA_VirtualHeight, SCREENHEIGHT/2,
|
||||
DTA_Alpha, trans,
|
||||
|
@ -593,7 +593,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu
|
|||
}
|
||||
else
|
||||
{
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].string,
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, HUDWidth,
|
||||
DTA_VirtualHeight, hudheight,
|
||||
DTA_Alpha, trans,
|
||||
|
@ -626,14 +626,7 @@ DHUDMessageTypeOnFadeOut::DHUDMessageTypeOnFadeOut (const char *text, float x, f
|
|||
if (TypeOnTime == 0.f)
|
||||
TypeOnTime = 0.1f;
|
||||
CurrLine = 0;
|
||||
if (Lines[0].string != NULL)
|
||||
{
|
||||
LineLen = (int)strlen (Lines[0].string);
|
||||
}
|
||||
else
|
||||
{
|
||||
LineLen = 0;
|
||||
}
|
||||
LineLen = (int)Lines[0].Text.Len();
|
||||
LineVisible = 0;
|
||||
State = 3;
|
||||
}
|
||||
|
@ -674,7 +667,7 @@ bool DHUDMessageTypeOnFadeOut::Tick ()
|
|||
}
|
||||
else
|
||||
{
|
||||
LineLen = (int)strlen (Lines[CurrLine].string);
|
||||
LineLen = (int)Lines[CurrLine].Text.Len();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -695,7 +688,7 @@ void DHUDMessageTypeOnFadeOut::ScreenSizeChanged ()
|
|||
|
||||
for (i = 0; i < CurrLine; ++i)
|
||||
{
|
||||
charCount += (int)strlen (Lines[i].string);
|
||||
charCount += (int)Lines[i].Text.Len();
|
||||
}
|
||||
charCount += LineVisible;
|
||||
|
||||
|
@ -703,7 +696,7 @@ void DHUDMessageTypeOnFadeOut::ScreenSizeChanged ()
|
|||
if (State == 3)
|
||||
{
|
||||
CurrLine = 0;
|
||||
LineLen = (int)strlen (Lines[0].string);
|
||||
LineLen = (int)Lines[0].Text.Len();
|
||||
Tics = (int)(charCount * TypeOnTime) - 1;
|
||||
Tick ();
|
||||
}
|
||||
|
@ -725,35 +718,33 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in
|
|||
}
|
||||
else if (linenum == CurrLine)
|
||||
{
|
||||
char stop;
|
||||
|
||||
stop = Lines[linenum].string[LineVisible];
|
||||
Lines[linenum].string[LineVisible] = 0;
|
||||
if (hudheight == 0)
|
||||
{
|
||||
if (con_scaletext <= 1)
|
||||
{
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].string,
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_CleanNoMove, clean,
|
||||
DTA_TextLen, LineVisible,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].string,
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, SCREENWIDTH/2,
|
||||
DTA_VirtualHeight, SCREENHEIGHT/2,
|
||||
DTA_KeepRatio, true,
|
||||
DTA_TextLen, LineVisible,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].string,
|
||||
screen->DrawText (TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, HUDWidth,
|
||||
DTA_VirtualHeight, hudheight,
|
||||
DTA_TextLen, LineVisible,
|
||||
TAG_DONE);
|
||||
}
|
||||
Lines[linenum].string[LineVisible] = stop;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -69,7 +69,7 @@ public:
|
|||
virtual void ScreenSizeChanged ();
|
||||
|
||||
protected:
|
||||
brokenlines_t *Lines;
|
||||
FBrokenLines *Lines;
|
||||
int Width, Height, NumLines;
|
||||
float Left, Top;
|
||||
bool CenterX;
|
||||
|
|
|
@ -277,7 +277,7 @@ void A_InquisitorCheckLand (AActor *self)
|
|||
A_ShutUp (self);
|
||||
return;
|
||||
}
|
||||
if (!S_IsActorPlayingSomething (self, CHAN_ITEM))
|
||||
if (!S_IsActorPlayingSomething (self, CHAN_ITEM, -1))
|
||||
{
|
||||
S_LoopedSound (self, CHAN_ITEM, "inquisitor/jump", 1, ATTN_NORM);
|
||||
}
|
||||
|
|
|
@ -806,7 +806,7 @@ void A_Countdown (AActor *self)
|
|||
|
||||
void A_LoopActiveSound (AActor *self)
|
||||
{
|
||||
if (self->ActiveSound != 0 && !S_IsActorPlayingSomething (self, CHAN_VOICE))
|
||||
if (self->ActiveSound != 0 && !S_IsActorPlayingSomething (self, CHAN_VOICE, -1))
|
||||
{
|
||||
S_LoopedSoundID (self, CHAN_VOICE, self->ActiveSound, 1, ATTN_NORM);
|
||||
}
|
||||
|
|
|
@ -584,11 +584,11 @@ private:
|
|||
|
||||
if (CPlayer->LogText != NULL)
|
||||
{
|
||||
brokenlines_t *lines = V_BreakLines (272, CPlayer->LogText);
|
||||
for (i = 0; lines[i].width >= 0; ++i)
|
||||
FBrokenLines *lines = V_BreakLines (272, CPlayer->LogText);
|
||||
for (i = 0; lines[i].Width >= 0; ++i)
|
||||
{
|
||||
screen->DrawText (CR_UNTRANSLATED, left+24*xscale, top+(18+i*12)*yscale,
|
||||
lines[i].string, DTA_CleanNoMove, true, TAG_DONE);
|
||||
lines[i].Text, DTA_CleanNoMove, true, TAG_DONE);
|
||||
}
|
||||
V_FreeBrokenLines (lines);
|
||||
}
|
||||
|
|
|
@ -230,7 +230,7 @@ static int PlayerTics;
|
|||
static int PlayerRotation;
|
||||
|
||||
static DCanvas *SavePic;
|
||||
static brokenlines_t *SaveComment;
|
||||
static FBrokenLines *SaveComment;
|
||||
static List SaveGames;
|
||||
static FSaveGameNode *TopSaveGame;
|
||||
static FSaveGameNode *SelSaveGame;
|
||||
|
@ -1079,10 +1079,10 @@ static void M_DrawSaveLoadCommon ()
|
|||
// I'm not sure why SaveComment would go NULL in this loop, but I got
|
||||
// a crash report where it was NULL when i reached 1, so now I check
|
||||
// for that.
|
||||
for (i = 0; SaveComment != NULL && SaveComment[i].width != -1 && i < 6; ++i)
|
||||
for (i = 0; SaveComment != NULL && SaveComment[i].Width >= 0 && i < 6; ++i)
|
||||
{
|
||||
screen->DrawText (CR_GOLD, commentLeft, commentTop
|
||||
+ SmallFont->GetHeight()*i*CleanYfac, SaveComment[i].string,
|
||||
+ SmallFont->GetHeight()*i*CleanYfac, SaveComment[i].Text,
|
||||
DTA_CleanNoMove, true, TAG_DONE);
|
||||
}
|
||||
}
|
||||
|
@ -3099,15 +3099,15 @@ void M_Drawer ()
|
|||
BorderNeedRefresh = screen->GetPageCount ();
|
||||
SB_state = screen->GetPageCount ();
|
||||
|
||||
brokenlines_t *lines = V_BreakLines (320, messageString);
|
||||
FBrokenLines *lines = V_BreakLines (320, messageString);
|
||||
y = 100;
|
||||
|
||||
for (i = 0; lines[i].width != -1; i++)
|
||||
for (i = 0; lines[i].Width >= 0; i++)
|
||||
y -= screen->Font->GetHeight () / 2;
|
||||
|
||||
for (i = 0; lines[i].width != -1; i++)
|
||||
for (i = 0; lines[i].Width >= 0; i++)
|
||||
{
|
||||
screen->DrawText (CR_UNTRANSLATED, 160 - lines[i].width/2, y, lines[i].string,
|
||||
screen->DrawText (CR_UNTRANSLATED, 160 - lines[i].Width/2, y, lines[i].Text,
|
||||
DTA_Clean, true, TAG_DONE);
|
||||
y += screen->Font->GetHeight ();
|
||||
}
|
||||
|
|
44
src/name.cpp
44
src/name.cpp
|
@ -122,6 +122,50 @@ int FName::NameManager::FindName (const char *text, bool noCreate)
|
|||
return AddName (text, hash, bucket);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// The same as above, but the text length is also passed, for creating
|
||||
// a name from a substring.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FName::NameManager::FindName (const char *text, size_t textLen, bool noCreate)
|
||||
{
|
||||
if (!Inited)
|
||||
{
|
||||
InitBuckets ();
|
||||
}
|
||||
|
||||
if (text == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int hash = MakeKey (text, textLen);
|
||||
unsigned int bucket = hash % HASH_SIZE;
|
||||
int scanner = Buckets[bucket];
|
||||
|
||||
// See if the name already exists.
|
||||
while (scanner >= 0)
|
||||
{
|
||||
if (NameArray[scanner].Hash == hash &&
|
||||
strnicmp (NameArray[scanner].Text, text, textLen) == 0 &&
|
||||
NameArray[scanner].Text[textLen] == '\0')
|
||||
{
|
||||
return scanner;
|
||||
}
|
||||
scanner = NameArray[scanner].NextHash;
|
||||
}
|
||||
|
||||
// If we get here, then the name does not exist.
|
||||
if (noCreate)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return AddName (text, hash, bucket);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FName :: NameManager :: InitBuckets
|
||||
|
|
17
src/name.h
17
src/name.h
|
@ -49,6 +49,7 @@ public:
|
|||
FName () : Index(0) {}
|
||||
FName (const char *text) { Index = NameData.FindName (text, false); }
|
||||
FName (const char *text, bool noCreate) { Index = NameData.FindName (text, noCreate); }
|
||||
FName (const char *text, size_t textlen, bool noCreate) { Index = NameData.FindName (text, textlen, noCreate); }
|
||||
FName (const FName &other) { Index = other.Index; }
|
||||
FName (ENamedName index) { Index = index; }
|
||||
// ~FName () {} // Names can be added but never removed.
|
||||
|
@ -82,7 +83,7 @@ public:
|
|||
bool operator > (ENamedName index) const { return Index > index; }
|
||||
bool operator >= (ENamedName index) const { return Index >= index; }
|
||||
|
||||
private:
|
||||
protected:
|
||||
int Index;
|
||||
|
||||
struct NameEntry
|
||||
|
@ -108,6 +109,7 @@ private:
|
|||
int Buckets[HASH_SIZE];
|
||||
|
||||
int FindName (const char *text, bool noCreate);
|
||||
int FindName (const char *text, size_t textlen, bool noCreate);
|
||||
int AddName (const char *text, unsigned int hash, unsigned int bucket);
|
||||
NameBlock *AddBlock (size_t len);
|
||||
void InitBuckets ();
|
||||
|
@ -115,6 +117,19 @@ private:
|
|||
};
|
||||
|
||||
static NameManager NameData;
|
||||
|
||||
enum EDummy { NoInit };
|
||||
FName (EDummy) {}
|
||||
};
|
||||
|
||||
class FNameNoInit : public FName
|
||||
{
|
||||
public:
|
||||
FNameNoInit() : FName(NoInit) {}
|
||||
|
||||
FName &operator = (const char *text) { Index = NameData.FindName (text, false); return *this; }
|
||||
FName &operator = (const FName &other) { Index = int(other); return *this; }
|
||||
FName &operator = (ENamedName index) { Index = index; return *this; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,6 +6,16 @@ xx(Object)
|
|||
|
||||
xx(Untranslated)
|
||||
|
||||
// Per-actor sound channels
|
||||
xx(Auto)
|
||||
xx(Weapon)
|
||||
xx(Voice)
|
||||
xx(Item)
|
||||
xx(Body)
|
||||
xx(SoundSlot5)
|
||||
xx(SoundSlot6)
|
||||
xx(SoundSlot7)
|
||||
|
||||
// Hexen sound sequence names
|
||||
xx(Platform)
|
||||
xx(PlatformMetal)
|
||||
|
|
|
@ -82,7 +82,7 @@ static void CleanupConversationMenu ();
|
|||
static void ConversationMenuEscaped ();
|
||||
|
||||
static FStrifeDialogueNode *CurNode, *PrevNode;
|
||||
static brokenlines_t *DialogueLines;
|
||||
static FBrokenLines *DialogueLines;
|
||||
static AActor *ConversationNPC, *ConversationPC;
|
||||
static angle_t ConversationNPCAngle;
|
||||
static bool ConversationFaceTalker;
|
||||
|
@ -695,9 +695,9 @@ void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveang
|
|||
}
|
||||
ShowGold |= reply->NeedsGold;
|
||||
reply->ReplyLines = V_BreakLines (320-50-10, reply->Reply);
|
||||
for (j = 0; reply->ReplyLines[j].width != -1; ++j)
|
||||
for (j = 0; reply->ReplyLines[j].Width >= 0; ++j)
|
||||
{
|
||||
item.label = reply->ReplyLines[j].string;
|
||||
item.label = reply->ReplyLines[j].Text.LockBuffer();
|
||||
item.b.position = j == 0 ? i : 0;
|
||||
item.c.extra = reply;
|
||||
ConversationItems.Push (item);
|
||||
|
@ -715,7 +715,7 @@ void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveang
|
|||
// Determine where the top of the reply list should be positioned.
|
||||
i = (gameinfo.gametype & GAME_Raven) ? 9 : 8;
|
||||
ConversationMenu.y = MIN<int> (140, 192 - ConversationItems.Size() * i);
|
||||
for (i = 0; DialogueLines[i].width != -1; ++i)
|
||||
for (i = 0; DialogueLines[i].Width >= 0; ++i)
|
||||
{ }
|
||||
i = 44 + i * 10;
|
||||
if (ConversationMenu.y - 100 < i - screen->GetHeight() / CleanYfac / 2)
|
||||
|
@ -808,7 +808,7 @@ static void DrawConversationMenu ()
|
|||
// Dim the screen behind the dialogue (but only if there is no backdrop).
|
||||
if (CurNode->Backdrop <= 0)
|
||||
{
|
||||
for (i = 0; DialogueLines[i].width != -1; ++i)
|
||||
for (i = 0; DialogueLines[i].Width >= 0; ++i)
|
||||
{ }
|
||||
screen->Dim (0, 0.45f, 14 * screen->GetWidth() / 320, 13 * screen->GetHeight() / 200,
|
||||
308 * screen->GetWidth() / 320 - 14 * screen->GetWidth () / 320,
|
||||
|
@ -830,9 +830,9 @@ static void DrawConversationMenu ()
|
|||
y += linesize * 3 / 2;
|
||||
}
|
||||
x = 24 * screen->GetWidth() / 320;
|
||||
for (i = 0; DialogueLines[i].width >= 0; ++i)
|
||||
for (i = 0; DialogueLines[i].Width >= 0; ++i)
|
||||
{
|
||||
screen->DrawText (CR_UNTRANSLATED, x, y, DialogueLines[i].string,
|
||||
screen->DrawText (CR_UNTRANSLATED, x, y, DialogueLines[i].Text,
|
||||
DTA_CleanNoMove, true, TAG_DONE);
|
||||
y += linesize;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
struct FStrifeDialogueReply;
|
||||
class FTexture;
|
||||
struct brokenlines_t;
|
||||
struct FBrokenLines;
|
||||
|
||||
// FStrifeDialogueNode holds text an NPC says to the player
|
||||
struct FStrifeDialogueNode
|
||||
|
@ -45,7 +45,7 @@ struct FStrifeDialogueReply
|
|||
char *QuickNo;
|
||||
bool NeedsGold;
|
||||
|
||||
brokenlines_t *ReplyLines;
|
||||
FBrokenLines *ReplyLines;
|
||||
};
|
||||
|
||||
extern TArray<FStrifeDialogueNode *> StrifeDialogues;
|
||||
|
|
|
@ -2391,7 +2391,7 @@ bool AActor::AdjustReflectionAngle (AActor *thing, angle_t &angle)
|
|||
|
||||
void AActor::PlayActiveSound ()
|
||||
{
|
||||
if (ActiveSound && !S_IsActorPlayingSomething (this, CHAN_VOICE))
|
||||
if (ActiveSound && !S_IsActorPlayingSomething (this, CHAN_VOICE, -1))
|
||||
{
|
||||
S_SoundID (this, CHAN_VOICE, ActiveSound, 1,
|
||||
(flags3 & MF3_FULLVOLACTIVE) ? ATTN_NONE : ATTN_IDLE);
|
||||
|
|
|
@ -400,12 +400,8 @@ void APlayerPawn::Serialize (FArchive &arc)
|
|||
<< SideMove2
|
||||
<< ScoreIcon
|
||||
<< InvFirst
|
||||
<< InvSel;
|
||||
|
||||
// Serialize the name, not the index
|
||||
FName MorphWeaponName = ENamedName(MorphWeapon);
|
||||
arc << MorphWeaponName;
|
||||
MorphWeapon = MorphWeaponName;
|
||||
<< InvSel
|
||||
<< MorphWeapon;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -917,7 +913,7 @@ void APlayerPawn::MorphPlayerThink ()
|
|||
|
||||
void APlayerPawn::ActivateMorphWeapon ()
|
||||
{
|
||||
const PClass *morphweapon = PClass::FindClass (ENamedName(MorphWeapon));
|
||||
const PClass *morphweapon = PClass::FindClass (MorphWeapon);
|
||||
player->PendingWeapon = WP_NOCHANGE;
|
||||
player->psprites[ps_weapon].sy = WEAPONTOP;
|
||||
|
||||
|
|
|
@ -1584,7 +1584,7 @@ void AAmbientSound::Tick ()
|
|||
|
||||
if ((ambient->type & CONTINUOUS) == CONTINUOUS)
|
||||
{
|
||||
if (S_IsActorPlayingSomething (this, CHAN_BODY))
|
||||
if (S_IsActorPlayingSomething (this, CHAN_BODY, -1))
|
||||
return;
|
||||
|
||||
if (ambient->sound[0])
|
||||
|
|
|
@ -1195,7 +1195,7 @@ bool S_GetSoundPlayingInfo (AActor *ent, int sound_id)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool S_IsActorPlayingSomething (AActor *actor, int channel)
|
||||
bool S_IsActorPlayingSomething (AActor *actor, int channel, int sound_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -1210,7 +1210,7 @@ bool S_IsActorPlayingSomething (AActor *actor, int channel)
|
|||
{
|
||||
if (channel == 0 || Channel[i].entchannel == channel)
|
||||
{
|
||||
return true;
|
||||
return sound_id < 0 || Channel[i].sound_id == sound_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ void S_StopAllChannels (void);
|
|||
// Is the sound playing on one of the entity's channels?
|
||||
bool S_GetSoundPlayingInfo (AActor *ent, int sound_id);
|
||||
bool S_GetSoundPlayingInfo (fixed_t *pt, int sound_id);
|
||||
bool S_IsActorPlayingSomething (AActor *actor, int channel);
|
||||
bool S_IsActorPlayingSomething (AActor *actor, int channel, int sound_id);
|
||||
|
||||
// Moves all sounds from one mobj to another
|
||||
void S_RelinkSound (AActor *from, AActor *to);
|
||||
|
|
|
@ -451,6 +451,8 @@ ACTOR(PlayWeaponSound)
|
|||
ACTOR(FLoopActiveSound)
|
||||
ACTOR(LoopActiveSound)
|
||||
ACTOR(StopSound)
|
||||
ACTOR(PlaySoundEx)
|
||||
ACTOR(StopSoundEx)
|
||||
ACTOR(SeekerMissile)
|
||||
ACTOR(Jump)
|
||||
ACTOR(ExplodeParms)
|
||||
|
@ -668,6 +670,8 @@ AFuncDesc AFTable[]=
|
|||
FUNC(A_FLoopActiveSound, NULL )
|
||||
FUNC(A_LoopActiveSound, NULL )
|
||||
FUNC(A_StopSound, NULL )
|
||||
FUNC(A_PlaySoundEx, "STi" )
|
||||
FUNC(A_StopSoundEx, "T" )
|
||||
FUNC(A_SeekerMissile, "XX" )
|
||||
FUNC(A_Jump, "XL" )
|
||||
FUNC(A_CustomMissile, "MXXxxx" )
|
||||
|
|
|
@ -287,6 +287,46 @@ void A_StopSound(AActor * self)
|
|||
S_StopSound(self, CHAN_VOICE);
|
||||
}
|
||||
|
||||
void A_PlaySoundEx (AActor *self)
|
||||
{
|
||||
int index = CheckIndex(3);
|
||||
if (index < 0) return;
|
||||
|
||||
int soundid = StateParameters[index];
|
||||
ENamedName channel = ENamedName(StateParameters[index + 1]);
|
||||
BOOL looping = StateParameters[index + 2];
|
||||
|
||||
if (channel < NAME_Auto || channel > NAME_SoundSlot7)
|
||||
{
|
||||
channel = NAME_Auto;
|
||||
}
|
||||
|
||||
if (!looping)
|
||||
{
|
||||
S_SoundID (self, channel - NAME_Auto, soundid, 1, ATTN_NORM);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!S_IsActorPlayingSomething (self, channel - NAME_Auto, soundid))
|
||||
{
|
||||
S_LoopedSoundID (self, channel - NAME_Auto, soundid, 1, ATTN_NORM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void A_StopSoundEx (AActor *self)
|
||||
{
|
||||
int index = CheckIndex (1);
|
||||
if (index < 0) return;
|
||||
|
||||
ENamedName channel = ENamedName(StateParameters[index]);
|
||||
|
||||
if (channel > NAME_Auto && channel <= NAME_SoundSlot7)
|
||||
{
|
||||
S_StopSound (self, channel - NAME_Auto);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Generic seeker missile function
|
||||
|
|
|
@ -123,6 +123,7 @@ static int STACK_ARGS TranslationMapCompare (const void *a, const void *b);
|
|||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
FFont *FFont::FirstFont = NULL;
|
||||
int NumTextColors;
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
|
@ -148,7 +149,6 @@ static const byte myislower[256] =
|
|||
|
||||
static TArray<TranslationParm> TranslationParms[2];
|
||||
static TArray<TranslationMap> TranslationLookup;
|
||||
static int NumTextColors;
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
|
@ -1788,10 +1788,9 @@ static int STACK_ARGS TranslationMapCompare (const void *a, const void *b)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
EColorRange V_FindFontColor (const char *daname)
|
||||
EColorRange V_FindFontColor (FName name)
|
||||
{
|
||||
FName name(daname, true);
|
||||
unsigned int min = 0, max = TranslationLookup.Size() - 1;
|
||||
int min = 0, max = TranslationLookup.Size() - 1;
|
||||
|
||||
while (min <= max)
|
||||
{
|
||||
|
|
|
@ -67,6 +67,8 @@ enum EColorRange
|
|||
NUM_TEXT_COLORS
|
||||
};
|
||||
|
||||
extern int NumTextColors;
|
||||
|
||||
inline FArchive &operator<< (FArchive &arc, EColorRange &i)
|
||||
{
|
||||
BYTE val = (BYTE)i;
|
||||
|
@ -149,6 +151,6 @@ extern FFont *SmallFont, *SmallFont2, *BigFont, *ConFont;
|
|||
|
||||
void V_InitCustomFonts ();
|
||||
void V_InitFontColors ();
|
||||
EColorRange V_FindFontColor (const char *name);
|
||||
EColorRange V_FindFontColor (FName name);
|
||||
|
||||
#endif //__V_FONT_H__
|
||||
|
|
145
src/v_text.cpp
145
src/v_text.cpp
|
@ -62,7 +62,7 @@ void STACK_ARGS DCanvas::DrawChar (int normalcolor, int x, int y, byte character
|
|||
if (Font == NULL)
|
||||
return;
|
||||
|
||||
if (normalcolor >= NUM_TEXT_COLORS)
|
||||
if (normalcolor >= NumTextColors)
|
||||
normalcolor = CR_UNTRANSLATED;
|
||||
|
||||
FTexture *pic;
|
||||
|
@ -89,6 +89,7 @@ void STACK_ARGS DCanvas::DrawText (int normalcolor, int x, int y, const char *st
|
|||
DWORD tag;
|
||||
BOOL boolval;
|
||||
|
||||
int maxstrlen = INT_MAX;
|
||||
int w, maxwidth;
|
||||
const byte *ch;
|
||||
int c;
|
||||
|
@ -104,9 +105,9 @@ void STACK_ARGS DCanvas::DrawText (int normalcolor, int x, int y, const char *st
|
|||
if (Font == NULL || string == NULL)
|
||||
return;
|
||||
|
||||
if (normalcolor >= NUM_TEXT_COLORS)
|
||||
if (normalcolor >= NumTextColors)
|
||||
normalcolor = CR_UNTRANSLATED;
|
||||
boldcolor = normalcolor ? normalcolor - 1 : NUM_TEXT_COLORS - 1;
|
||||
boldcolor = normalcolor ? normalcolor - 1 : NumTextColors - 1;
|
||||
|
||||
range = Font->GetColorTranslation ((EColorRange)normalcolor);
|
||||
height = Font->GetHeight () + 1;
|
||||
|
@ -181,13 +182,17 @@ void STACK_ARGS DCanvas::DrawText (int normalcolor, int x, int y, const char *st
|
|||
maxwidth = va_arg (tags, int);
|
||||
scalex = scaley = 1;
|
||||
break;
|
||||
|
||||
case DTA_TextLen:
|
||||
maxstrlen = va_arg (tags, int);
|
||||
break;
|
||||
}
|
||||
tag = va_arg (tags, DWORD);
|
||||
}
|
||||
|
||||
height *= scaley;
|
||||
|
||||
for (;;)
|
||||
while ((const char *)ch - string < maxstrlen)
|
||||
{
|
||||
c = *ch++;
|
||||
if (!c)
|
||||
|
@ -195,25 +200,43 @@ void STACK_ARGS DCanvas::DrawText (int normalcolor, int x, int y, const char *st
|
|||
|
||||
if (c == TEXTCOLOR_ESCAPE)
|
||||
{
|
||||
int newcolor = toupper(*ch++);
|
||||
int newcolor = *ch++;
|
||||
|
||||
if (newcolor == 0)
|
||||
if (newcolor == '\0')
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (newcolor == '-')
|
||||
else if (newcolor == '-') // Normal
|
||||
{
|
||||
newcolor = normalcolor;
|
||||
}
|
||||
else if (newcolor >= 'A' && newcolor < NUM_TEXT_COLORS + 'A')
|
||||
{
|
||||
newcolor -= 'A';
|
||||
}
|
||||
else if (newcolor == '+')
|
||||
else if (newcolor == '+') // Bold
|
||||
{
|
||||
newcolor = boldcolor;
|
||||
}
|
||||
else
|
||||
else if (newcolor == '[') // Named
|
||||
{
|
||||
const byte *namestart = ch;
|
||||
while (*ch != ']' && *ch != '\0')
|
||||
{
|
||||
ch++;
|
||||
}
|
||||
FName rangename((const char *)namestart, int(ch - namestart), true);
|
||||
if (*ch != '\0')
|
||||
{
|
||||
ch++;
|
||||
}
|
||||
newcolor = V_FindFontColor (rangename);
|
||||
}
|
||||
else if (newcolor >= 'A' && newcolor < NUM_TEXT_COLORS + 'A') // Standard, uppercase
|
||||
{
|
||||
newcolor -= 'A';
|
||||
}
|
||||
else if (newcolor >= 'a' && newcolor < NUM_TEXT_COLORS + 'a') // Standard, lowercase
|
||||
{
|
||||
newcolor -= 'a';
|
||||
}
|
||||
else // Incomplete!
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -251,8 +274,18 @@ int FFont::StringWidth (const BYTE *string) const
|
|||
{
|
||||
if (*string == TEXTCOLOR_ESCAPE)
|
||||
{
|
||||
if (*(++string))
|
||||
++string;
|
||||
if (*string == '[')
|
||||
{
|
||||
while (*string != '\0' && *string != ']')
|
||||
{
|
||||
++string;
|
||||
}
|
||||
}
|
||||
else if (*string != '\0')
|
||||
{
|
||||
++string;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (*string == '\n')
|
||||
|
@ -274,10 +307,8 @@ int FFont::StringWidth (const BYTE *string) const
|
|||
//
|
||||
// Break long lines of text into multiple lines no longer than maxwidth pixels
|
||||
//
|
||||
static void breakit (brokenlines_t *line, const byte *start, const byte *string, bool keepspace, char linecolor)
|
||||
static void breakit (FBrokenLines *line, const byte *start, const byte *string, bool keepspace, FString &linecolor)
|
||||
{
|
||||
int extra;
|
||||
|
||||
// Leave out trailing white space
|
||||
if (!keepspace)
|
||||
{
|
||||
|
@ -285,34 +316,23 @@ static void breakit (brokenlines_t *line, const byte *start, const byte *string,
|
|||
string--;
|
||||
}
|
||||
|
||||
if (linecolor == 0)
|
||||
if (!linecolor.IsEmpty())
|
||||
{
|
||||
extra = 0;
|
||||
line->Text = TEXTCOLOR_ESCAPE;
|
||||
line->Text += linecolor;
|
||||
}
|
||||
else
|
||||
{
|
||||
extra = 2;
|
||||
}
|
||||
|
||||
line->string = new char[string - start + extra + 1];
|
||||
if (linecolor)
|
||||
{
|
||||
line->string[0] = TEXTCOLOR_ESCAPE;
|
||||
line->string[1] = linecolor;
|
||||
}
|
||||
strncpy (line->string + extra, (char *)start, string - start);
|
||||
line->string[string - start + extra] = 0;
|
||||
line->width = screen->Font->StringWidth (line->string);
|
||||
line->Text.AppendCStrPart ((const char *)start, string - start);
|
||||
line->Width = screen->Font->StringWidth (line->Text);
|
||||
}
|
||||
|
||||
brokenlines_t *V_BreakLines (int maxwidth, const byte *string, bool keepspace)
|
||||
FBrokenLines *V_BreakLines (int maxwidth, const byte *string, bool keepspace)
|
||||
{
|
||||
brokenlines_t lines[128]; // Support up to 128 lines (should be plenty)
|
||||
FBrokenLines lines[128]; // Support up to 128 lines (should be plenty)
|
||||
|
||||
const byte *space = NULL, *start = string;
|
||||
int i, c, w, nw;
|
||||
char lastcolor = 0, linecolor = 0;
|
||||
BOOL lastWasSpace = false;
|
||||
FString lastcolor, linecolor;
|
||||
bool lastWasSpace = false;
|
||||
int kerning = screen->Font->GetDefaultKerning ();
|
||||
|
||||
i = w = 0;
|
||||
|
@ -323,7 +343,23 @@ brokenlines_t *V_BreakLines (int maxwidth, const byte *string, bool keepspace)
|
|||
{
|
||||
if (*string)
|
||||
{
|
||||
lastcolor = *string++;
|
||||
if (*string == '[')
|
||||
{
|
||||
const byte *start = string;
|
||||
while (*string != ']' && *string != '\0')
|
||||
{
|
||||
string++;
|
||||
}
|
||||
if (*string != '\0')
|
||||
{
|
||||
string++;
|
||||
}
|
||||
lastcolor = FString((const char *)start, string - start);
|
||||
}
|
||||
else
|
||||
{
|
||||
lastcolor = *string++;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -348,11 +384,12 @@ brokenlines_t *V_BreakLines (int maxwidth, const byte *string, bool keepspace)
|
|||
if (!space)
|
||||
space = string - 1;
|
||||
|
||||
lines[i].nlterminated = (c == '\n');
|
||||
lines[i].NLTerminated = (c == '\n');
|
||||
breakit (&lines[i], start, space, keepspace, linecolor);
|
||||
if (c == '\n')
|
||||
{
|
||||
linecolor = lastcolor = 0;
|
||||
// Why did I do it like this? Why? Oh why?
|
||||
linecolor = lastcolor = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -388,7 +425,7 @@ brokenlines_t *V_BreakLines (int maxwidth, const byte *string, bool keepspace)
|
|||
{
|
||||
if (keepspace || !isspace (*s))
|
||||
{
|
||||
lines[i].nlterminated = (*s == '\n');
|
||||
lines[i].NLTerminated = (*s == '\n');
|
||||
s++;
|
||||
breakit (&lines[i++], start, string, keepspace, linecolor);
|
||||
break;
|
||||
|
@ -397,30 +434,22 @@ brokenlines_t *V_BreakLines (int maxwidth, const byte *string, bool keepspace)
|
|||
}
|
||||
}
|
||||
|
||||
// Make a copy of the broken lines and return them
|
||||
FBrokenLines *broken = new FBrokenLines[i+1];
|
||||
|
||||
for (c = 0; c < i; ++c)
|
||||
{
|
||||
// Make a copy of the broken lines and return them
|
||||
brokenlines_t *broken = new brokenlines_t[i+1];
|
||||
|
||||
memcpy (broken, lines, sizeof(brokenlines_t) * i);
|
||||
broken[i].string = NULL;
|
||||
broken[i].width = -1;
|
||||
|
||||
return broken;
|
||||
broken[c] = lines[c];
|
||||
}
|
||||
broken[c].Width = -1;
|
||||
|
||||
return broken;
|
||||
}
|
||||
|
||||
void V_FreeBrokenLines (brokenlines_t *lines)
|
||||
void V_FreeBrokenLines (FBrokenLines *lines)
|
||||
{
|
||||
if (lines)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (lines[i].width != -1)
|
||||
{
|
||||
delete[] lines[i].string;
|
||||
lines[i].string = NULL;
|
||||
i++;
|
||||
}
|
||||
delete[] lines;
|
||||
}
|
||||
}
|
||||
|
|
16
src/v_text.h
16
src/v_text.h
|
@ -37,12 +37,12 @@
|
|||
#include "doomtype.h"
|
||||
#include "v_font.h"
|
||||
|
||||
struct brokenlines_t
|
||||
struct FBrokenLines
|
||||
{
|
||||
short width;
|
||||
byte nlterminated;
|
||||
byte pad;
|
||||
char *string;
|
||||
short Width;
|
||||
BYTE NLTerminated;
|
||||
BYTE Pad;
|
||||
FString Text;
|
||||
};
|
||||
|
||||
#define TEXTCOLOR_ESCAPE '\034'
|
||||
|
@ -73,9 +73,9 @@ struct brokenlines_t
|
|||
#define TEXTCOLOR_NORMAL "\034-"
|
||||
#define TEXTCOLOR_BOLD "\034+"
|
||||
|
||||
brokenlines_t *V_BreakLines (int maxwidth, const byte *str, bool keepspace=false);
|
||||
void V_FreeBrokenLines (brokenlines_t *lines);
|
||||
inline brokenlines_t *V_BreakLines (int maxwidth, const char *str, bool keepspace=false)
|
||||
FBrokenLines *V_BreakLines (int maxwidth, const byte *str, bool keepspace=false);
|
||||
void V_FreeBrokenLines (FBrokenLines *lines);
|
||||
inline FBrokenLines *V_BreakLines (int maxwidth, const char *str, bool keepspace=false)
|
||||
{ return V_BreakLines (maxwidth, (const byte *)str, keepspace); }
|
||||
|
||||
#endif //__V_TEXT_H__
|
||||
|
|
|
@ -100,6 +100,7 @@ enum
|
|||
DTA_Masked, // true(default)=use masks from texture, false=ignore masks
|
||||
DTA_HUDRules, // use fullscreen HUD rules to position and size textures
|
||||
DTA_KeepRatio, // doesn't adjust screen size for DTA_Virtual* if the aspect ratio is not 4:3
|
||||
DTA_TextLen, // for DrawText: stop after this many characters, even if \0 not hit
|
||||
};
|
||||
|
||||
enum
|
||||
|
|
|
@ -731,20 +731,20 @@ int WI_DrawName(int y,const char * levelname, bool nomove=false)
|
|||
if (!l) return 0;
|
||||
|
||||
screen->SetFont(BigFont);
|
||||
brokenlines_t * lines = V_BreakLines(320, p);
|
||||
FBrokenLines *lines = V_BreakLines(320, p);
|
||||
|
||||
if (lines)
|
||||
{
|
||||
for (i=0; lines[i].width != -1; i++)
|
||||
for (i = 0; lines[i].Width >= 0; i++)
|
||||
{
|
||||
if (!nomove)
|
||||
{
|
||||
screen->DrawText(CR_UNTRANSLATED, 160 - lines[i].width/2, y+h, lines[i].string, DTA_Clean, true, TAG_DONE);
|
||||
screen->DrawText(CR_UNTRANSLATED, 160 - lines[i].Width/2, y+h, lines[i].Text, DTA_Clean, true, TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->DrawText(CR_UNTRANSLATED, (SCREENWIDTH - lines[i].width * CleanXfac) / 2, (y+h) * CleanYfac,
|
||||
lines[i].string, DTA_CleanNoMove, true, TAG_DONE);
|
||||
screen->DrawText(CR_UNTRANSLATED, (SCREENWIDTH - lines[i].Width * CleanXfac) / 2, (y+h) * CleanYfac,
|
||||
lines[i].Text, DTA_CleanNoMove, true, TAG_DONE);
|
||||
}
|
||||
h+=lumph;
|
||||
}
|
||||
|
|
|
@ -279,6 +279,14 @@ FString &FString::operator += (char tail)
|
|||
return *this;
|
||||
}
|
||||
|
||||
FString &FString::AppendCStrPart (const char *tail, size_t tailLen)
|
||||
{
|
||||
size_t len1 = Len();
|
||||
ReallocBuffer (len1 + tailLen);
|
||||
StrCopy (Chars + len1, tail, tailLen);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void FString::Truncate (long newlen)
|
||||
{
|
||||
if (newlen >= 0 && newlen < (long)Len())
|
||||
|
|
|
@ -104,6 +104,7 @@ public:
|
|||
FString &operator += (const FString &tail);
|
||||
FString &operator += (const char *tail);
|
||||
FString &operator += (char tail);
|
||||
FString &AppendCStrPart (const char *tail, size_t tailLen);
|
||||
|
||||
FString Left (size_t numChars) const;
|
||||
FString Right (size_t numChars) const;
|
||||
|
|
Loading…
Reference in a new issue