SVN r314 (trunk)

This commit is contained in:
Randy Heit 2006-08-31 00:16:12 +00:00
parent 2fb55622e7
commit 603e905c42
35 changed files with 365 additions and 199 deletions

View file

@ -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

View file

@ -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,
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)

View file

@ -110,7 +110,7 @@ public:
fixed_t SideMove1, SideMove2;
int ScoreIcon;
int SpawnMask;
int MorphWeapon; // actually a name
FNameNoInit MorphWeapon;
int GetMaxHealth() const;
};

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -69,7 +69,7 @@ public:
virtual void ScreenSizeChanged ();
protected:
brokenlines_t *Lines;
FBrokenLines *Lines;
int Width, Height, NumLines;
float Left, Top;
bool CenterX;

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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 ();
}

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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;
}

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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])

View file

@ -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;
}
}
}

View file

@ -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);

View file

@ -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" )

View file

@ -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

View file

@ -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)
{

View file

@ -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__

View file

@ -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;
@ -322,9 +342,25 @@ brokenlines_t *V_BreakLines (int maxwidth, const byte *string, bool keepspace)
if (c == TEXTCOLOR_ESCAPE)
{
if (*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
brokenlines_t *broken = new brokenlines_t[i+1];
FBrokenLines *broken = new FBrokenLines[i+1];
memcpy (broken, lines, sizeof(brokenlines_t) * i);
broken[i].string = NULL;
broken[i].width = -1;
for (c = 0; c < i; ++c)
{
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;
}
}

View file

@ -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__

View file

@ -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

View file

@ -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;
}

View file

@ -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())

View file

@ -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;