- Fixed: The skin loader assumed that all skin textures are in Doom patch

format. Now it calls FTexture::CreateTexture to do proper checks.
- Removed the PickupSound method from FakeInventory and changed it so that
  it uses AInventory::PickupSound to store its custom pickup sound.
- Removed the PickupMessage method from FakeInventory. This can be handled
  by the standard pickup message code now that it uses the meta data for the
  message.
- Fixed: The maximum indices for StrifeTypes were inconsistent. Now the
  allowed range is 0-1000 in all situations.
- Fixed: Setting a local SNDINFO for a map deleted all skin based sounds.
- Added a crouchsprite property to the skin info.
- Fixed: Crouching sprites must be checked each frame, not just each tic.
- Added an srand call to D_DoomMain in order to randomize the values returned
  by rand which is being used to shuffle the playlist.


SVN r185 (trunk)
This commit is contained in:
Christoph Oelckers 2006-06-11 11:28:48 +00:00
parent e2179d5c2d
commit bb5a44fc90
14 changed files with 229 additions and 104 deletions

View file

@ -1,3 +1,19 @@
June 10, 2006 (Changes by Graf Zahl)
- Fixed: The skin loader assumed that all skin textures are in Doom patch
format. Now it calls FTexture::CreateTexture to do proper checks.
- Removed the PickupSound method from FakeInventory and changed it so that
it uses AInventory::PickupSound to store its custom pickup sound.
- Removed the PickupMessage method from FakeInventory. This can be handled
by the standard pickup message code now that it uses the meta data for the
message.
- Fixed: The maximum indices for StrifeTypes were inconsistent. Now the
allowed range is 0-1000 in all situations.
- Fixed: Setting a local SNDINFO for a map deleted all skin based sounds.
- Added a crouchsprite property to the skin info.
- Fixed: Crouching sprites must be checked each frame, not just each tic.
- Added an srand call to D_DoomMain in order to randomize the values returned
by rand which is being used to shuffle the playlist.
June 10, 2006
- Fixed: Information added with addkeysection and addmenukey was never freed.
- Fixed: A classic decorate FakeInventory's PickupText was never freed.

View file

@ -510,6 +510,7 @@ void D_Display (bool screenshot)
break;
R_RefreshViewBorder ();
P_CheckPlayerSprites();
R_RenderActorView (players[consoleplayer].mo);
R_DetailDouble (); // [RH] Apply detail mode expansion
// [RH] Let cameras draw onto textures that were visible this frame.
@ -1856,6 +1857,8 @@ void D_DoomMain (void)
file[PATH_MAX-1] = 0;
srand(I_MSTime());
atterm (DObject::StaticShutdown);
PClass::StaticInit ();
atterm (C_DeinitConsole);

View file

@ -313,6 +313,9 @@ inline FArchive &operator<< (FArchive &arc, player_s *&p)
return arc.SerializePointer (players, (BYTE **)&p, sizeof(*players));
}
void P_CheckPlayerSprites();
#define CROUCHSPEED (FRACUNIT/12)
#define MAX_DN_ANGLE 56 // Max looking down angle
#define MAX_UP_ANGLE 32 // Max looking up angle

View file

@ -105,16 +105,6 @@ class AFakeInventory : public AInventory
public:
bool Respawnable;
const char *PickupMessage ()
{
const char *text = GetClass()->Meta.GetMetaString (AIMETA_PickupMessage);
if (text == 0)
{
return Super::PickupMessage();
}
return text;
}
bool ShouldRespawn ()
{
return Respawnable && Super::ShouldRespawn();
@ -137,18 +127,6 @@ public:
{
// The special was already executed by TryPickup, so do nothing here
}
void PlayPickupSound (AActor *toucher)
{
if (AttackSound != 0)
{
S_SoundID (toucher, CHAN_PICKUP, AttackSound, 1, ATTN_NORM);
}
else
{
Super::PlayPickupSound (toucher);
}
}
};
IMPLEMENT_STATELESS_ACTOR (AFakeInventory, Any, -1, 0)
PROP_Flags (MF_SPECIAL)
@ -855,7 +833,7 @@ static void ParseInsideDecoration (FActorInfo *info, AActor *defaults,
else if (def == DEF_Pickup && SC_Compare ("PickupSound"))
{
SC_MustGetString ();
inv->AttackSound = S_FindSound (sc_String);
inv->PickupSound = S_FindSound (sc_String);
}
else if (def == DEF_Pickup && SC_Compare ("PickupMessage"))
{

View file

@ -1905,6 +1905,7 @@ static void PutSavePic (FILE *file, int width, int height)
// Take a snapshot of the player's view
pic->Lock ();
P_CheckPlayerSprites();
R_RenderViewToCanvas (players[consoleplayer].mo, pic, 0, 0, width, height);
screen->GetFlashedPalette (palette);
M_CreatePNG (file, pic, palette);

View file

@ -65,7 +65,7 @@ TArray<FStrifeDialogueNode *> StrifeDialogues;
// to their index in the mobjinfo table. This table indexes all
// the Strife actor types in the order Strife had them and is
// initialized as part of the actor's setup in infodefaults.cpp.
const PClass *StrifeTypes[999];
const PClass *StrifeTypes[1001];
static menu_t ConversationMenu;
static TArray<menuitem_t> ConversationItems;
@ -99,7 +99,7 @@ static bool ConversationFaceTalker;
static const PClass *GetStrifeType (int typenum)
{
if (typenum > 0 && typenum < 344)
if (typenum > 0 && typenum < 1001)
{
return StrifeTypes[typenum];
}

View file

@ -54,7 +54,7 @@ extern TArray<FStrifeDialogueNode *> StrifeDialogues;
// to their index in the mobjinfo table. This table indexes all
// the Strife actor types in the order Strife had them and is
// initialized as part of the actor's setup in infodefaults.cpp.
extern const PClass *StrifeTypes[999];
extern const PClass *StrifeTypes[1001];
void P_LoadStrifeConversations (const char *mapname);
void P_FreeStrifeConversations ();

View file

@ -254,20 +254,6 @@ void APlayerPawn::BeginPlay ()
void APlayerPawn::Tick()
{
int crouchspriteno;
// FIXME: Handle skins
if (sprite == SpawnState->sprite.index && crouchsprite > 0)
{
crouchspriteno = crouchsprite;
}
else
{
// no sprite -> squash the existing one
crouchspriteno = 0;
}
if (player != NULL && player->mo == this && player->morphTics == 0 && player->playerstate != PST_DEAD)
{
height = FixedMul(GetDefault()->height, player->crouchfactor);
@ -277,30 +263,10 @@ void APlayerPawn::Tick()
if (health > 0) height = GetDefault()->height;
}
Super::Tick();
// Here's the place where crouching sprites should be handled
if (player != NULL && player->crouchfactor<FRACUNIT*3/4)
{
if (crouchsprite != 0)
{
sprite = crouchsprite;
yscale = GetDefault()->yscale;
}
else if (player->playerstate != PST_DEAD)
{
yscale = player->crouchfactor < FRACUNIT*3/4 ? GetDefault()->yscale/2 : GetDefault()->yscale;
}
}
else
{
if (sprite == crouchsprite)
{
sprite = SpawnState->sprite.index;
}
yscale = GetDefault()->yscale;
}
}
//===========================================================================
//
// APlayerPawn :: AddInventory
@ -630,6 +596,80 @@ void APlayerPawn::SpecialInvulnerabilityHandling (EInvulState setting, fixed_t *
if (setting == INVUL_GetAlpha && pAlpha!=NULL) *pAlpha=FIXED_MAX; // indicates no change
}
//===========================================================================
//
// P_CheckPlayerSprites
//
// Here's the place where crouching sprites are handled
// This must be called each frame before rendering
//
//===========================================================================
void P_CheckPlayerSprites()
{
for(int i=0; i<MAXPLAYERS; i++)
{
player_t * player = &players[i];
APlayerPawn * mo = player->mo;
if (playeringame[i] && mo != NULL)
{
int crouchspriteno;
int defyscale = mo->GetDefault()->yscale;
if (player->userinfo.skin != 0)
{
defyscale = skins[player->userinfo.skin].scale;
}
// FIXME: Handle skins
if (player->crouchfactor < FRACUNIT*3/4)
{
if (mo->sprite == mo->SpawnState->sprite.index || mo->sprite == mo->crouchsprite)
{
crouchspriteno = mo->crouchsprite;
}
else if (mo->sprite == skins[player->userinfo.skin].sprite ||
mo->sprite == skins[player->userinfo.skin].crouchsprite)
{
crouchspriteno = skins[player->userinfo.skin].crouchsprite;
}
else
{
// no sprite -> squash the existing one
crouchspriteno = -1;
}
if (crouchspriteno > 0)
{
mo->sprite = crouchspriteno;
mo->yscale = defyscale;
}
else if (player->playerstate != PST_DEAD)
{
mo->yscale = player->crouchfactor < FRACUNIT*3/4 ? defyscale/2 : defyscale;
}
}
else
{
if (mo->sprite == mo->crouchsprite)
{
mo->sprite = mo->SpawnState->sprite.index;
}
else if (mo->sprite == skins[player->userinfo.skin].crouchsprite)
{
mo->sprite = skins[player->userinfo.skin].sprite;
}
mo->yscale = defyscale;
}
}
}
}
/*
==================
=

View file

@ -842,6 +842,7 @@ public:
byte scale;
byte game;
int sprite;
int crouchsprite;
int namespc; // namespace for this skin
};

View file

@ -418,7 +418,7 @@ void R_InitSkins (void)
spritedef_t temp;
int sndlumps[NUMSKINSOUNDS];
char key[65];
DWORD intname;
DWORD intname, crouchname;
size_t i;
int j, k, base;
int lastlump;
@ -447,6 +447,7 @@ void R_InitSkins (void)
SC_OpenLumpNum (base, "S_SKIN");
intname = 0;
crouchname = 0;
// Data is stored as "key = data".
while (SC_GetString ())
@ -478,6 +479,12 @@ void R_InitSkins (void)
sc_String[j] = toupper (sc_String[j]);
intname = *((DWORD *)sc_String);
}
else if (0 == stricmp (key, "crouchsprite"))
{
for (j = 3; j >= 0; j--)
sc_String[j] = toupper (sc_String[j]);
crouchname = *((DWORD *)sc_String);
}
else if (0 == stricmp (key, "face"))
{
for (j = 2; j >= 0; j--)
@ -559,42 +566,60 @@ void R_InitSkins (void)
intname = *(DWORD *)name;
}
memset (sprtemp, 0xFFFF, sizeof(sprtemp));
for (k = 0; k < MAX_SPRITE_FRAMES; ++k)
{
sprtemp[k].Flip = 0;
}
maxframe = -1;
int basens = Wads.GetLumpNamespace(base);
for (k = base + 1; Wads.GetLumpNamespace(k) == basens; k++)
for(int spr = 0; spr<2; spr++)
{
char lname[9];
Wads.GetLumpName (lname, k);
if (*(DWORD *)lname == intname)
memset (sprtemp, 0xFFFF, sizeof(sprtemp));
for (k = 0; k < MAX_SPRITE_FRAMES; ++k)
{
int picnum = TexMan.AddTexture (new FPatchTexture (k, FTexture::TEX_SkinSprite));
R_InstallSpriteLump (picnum, lname[4] - 'A', lname[5], false);
if (lname[6])
R_InstallSpriteLump (picnum, lname[6] - 'A', lname[7], true);
sprtemp[k].Flip = 0;
}
}
maxframe = -1;
if (maxframe <= 0)
{
Printf (PRINT_BOLD, "Skin %s (#%d) has no frames. Removing.\n", skins[i].name, i);
if (i < numskins-1)
memmove (&skins[i], &skins[i+1], sizeof(skins[0])*(numskins-i-1));
i--;
continue;
}
if (spr == 1)
{
if (crouchname !=0 && crouchname != intname)
{
intname = crouchname;
}
else
{
skins[i].crouchsprite = -1;
break;
}
}
Wads.GetLumpName (temp.name, base+1);
temp.name[4] = 0;
skins[i].sprite = (int)sprites.Push (temp);
R_InstallSprite (skins[i].sprite);
for (k = base + 1; Wads.GetLumpNamespace(k) == basens; k++)
{
char lname[9];
Wads.GetLumpName (lname, k);
if (*(DWORD *)lname == intname)
{
int picnum = TexMan.CreateTexture(k, FTexture::TEX_SkinSprite);
R_InstallSpriteLump (picnum, lname[4] - 'A', lname[5], false);
if (lname[6])
R_InstallSpriteLump (picnum, lname[6] - 'A', lname[7], true);
}
}
if (spr == 0 && maxframe <= 0)
{
Printf (PRINT_BOLD, "Skin %s (#%d) has no frames. Removing.\n", skins[i].name, i);
if (i < numskins-1)
memmove (&skins[i], &skins[i+1], sizeof(skins[0])*(numskins-i-1));
i--;
continue;
}
Wads.GetLumpName (temp.name, base+1);
temp.name[4] = 0;
int sprno = (int)sprites.Push (temp);
if (spr==0) skins[i].sprite = sprno;
else skins[i].crouchsprite = sprno;
R_InstallSprite (sprno);
}
// Register any sounds this skin provides
aliasid = 0;
@ -605,12 +630,12 @@ void R_InitSkins (void)
if (j == 0 || sndlumps[j] != sndlumps[j-1])
{
aliasid = S_AddPlayerSound (skins[i].name, skins[i].gender,
playersoundrefs[j], sndlumps[j]);
playersoundrefs[j], sndlumps[j], true);
}
else
{
S_AddPlayerSoundExisting (skins[i].name, skins[i].gender,
playersoundrefs[j], aliasid);
playersoundrefs[j], aliasid, true);
}
}
}

View file

@ -142,6 +142,16 @@ struct FMusicVolume
char MusicName[1];
};
// This is used to recreate the skin sounds after reloading SNDINFO due to a changed local one.
struct FSavedPlayerSoundInfo
{
const char * pclass;
int gender;
int refid;
int lumpnum;
bool alias;
};
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
void S_StartNamedSound (AActor *ent, fixed_t *pt, int channel,
@ -154,6 +164,8 @@ extern bool IsFloat (const char *str);
static int STACK_ARGS SortPlayerClasses (const void *a, const void *b);
static int S_DupPlayerSound (const char *pclass, int gender, int refid, int aliasref);
static void S_SavePlayerSound (const char *pclass, int gender, int refid, int lumpnum, bool alias);
static void S_RestorePlayerSounds();
static int S_AddPlayerClass (const char *name);
static int S_AddPlayerGender (int classnum, int gender);
static int S_FindPlayerClass (const char *name);
@ -203,6 +215,7 @@ static const char *SICommandStrings[] =
static TArray<FRandomSoundList> S_rnd;
static FMusicVolume *MusicVolumes;
static TArray<FSavedPlayerSoundInfo> SavedPlayerSounds;
static int NumPlayerReserves;
static bool DoneReserving;
@ -484,7 +497,7 @@ int S_AddPlayerSound (const char *pclass, int gender, int refid,
lumpname ? Wads.CheckNumForName (lumpname) : -1);
}
int S_AddPlayerSound (const char *pclass, int gender, int refid, int lumpnum)
int S_AddPlayerSound (const char *pclass, int gender, int refid, int lumpnum, bool fromskin)
{
char fakename[MAX_SNDNAME+1];
size_t len;
@ -501,6 +514,9 @@ int S_AddPlayerSound (const char *pclass, int gender, int refid, int lumpnum)
int soundlist = S_AddPlayerGender (classnum, gender);
PlayerSounds[soundlist + S_sfx[refid].link] = id;
if (fromskin) S_SavePlayerSound(pclass, gender, refid, lumpnum, false);
return id;
}
@ -512,12 +528,15 @@ int S_AddPlayerSound (const char *pclass, int gender, int refid, int lumpnum)
//==========================================================================
int S_AddPlayerSoundExisting (const char *pclass, int gender, int refid,
int aliasto)
int aliasto, bool fromskin)
{
int classnum = S_AddPlayerClass (pclass);
int soundlist = S_AddPlayerGender (classnum, gender);
PlayerSounds[soundlist + S_sfx[refid].link] = aliasto;
if (fromskin) S_SavePlayerSound(pclass, gender, refid, aliasto, true);
return aliasto;
}
@ -618,7 +637,7 @@ void S_ParseSndInfo ()
break;
}
}
S_RestorePlayerSounds();
S_HashSounds ();
S_sfx.ShrinkToFit ();
@ -873,10 +892,11 @@ static void S_AddSNDINFO (int lump)
// $playeralias <player class> <gender> <logical name> <logical name of existing sound>
char pclass[MAX_SNDNAME+1];
int gender, refid;
int soundnum;
S_ParsePlayerSoundCommon (pclass, gender, refid);
S_AddPlayerSoundExisting (pclass, gender, refid,
S_FindSoundTentative (sc_String));
soundnum = S_FindSoundTentative (sc_String);
S_AddPlayerSoundExisting (pclass, gender, refid, soundnum);
}
break;
@ -1296,6 +1316,44 @@ static int S_LookupPlayerSound (int classidx, int gender, int refid)
return sndnum;
}
//==========================================================================
//
// S_SavePlayerSound / S_RestorePlayerSounds
//
// Restores all skin-based player sounds after changing the local SNDINFO
// which forces a reload of the global one as well
//
//==========================================================================
static void S_SavePlayerSound (const char *pclass, int gender, int refid, int lumpnum, bool alias)
{
FSavedPlayerSoundInfo spi;
spi.pclass = pclass;
spi.gender = gender;
spi.refid = refid;
spi.lumpnum = lumpnum;
spi.alias = alias;
SavedPlayerSounds.Push(spi);
}
static void S_RestorePlayerSounds()
{
for(unsigned int i = 0; i < SavedPlayerSounds.Size(); i++)
{
FSavedPlayerSoundInfo * spi = &SavedPlayerSounds[i];
if (spi->alias)
{
S_AddPlayerSoundExisting(spi->pclass, spi->gender, spi->refid, spi->lumpnum);
}
else
{
S_AddPlayerSound(spi->pclass, spi->gender, spi->refid, spi->lumpnum);
}
}
}
//==========================================================================
//
// S_AreSoundsEquivalent

View file

@ -198,8 +198,8 @@ int S_FindSoundByLump (int lump);
int S_AddSound (const char *logicalname, const char *lumpname); // Add sound by lumpname
int S_AddSoundLump (const char *logicalname, int lump); // Add sound by lump index
int S_AddPlayerSound (const char *playerclass, const int gender, int refid, const char *lumpname);
int S_AddPlayerSound (const char *playerclass, const int gender, int refid, int lumpnum);
int S_AddPlayerSoundExisting (const char *playerclass, const int gender, int refid, int aliasto);
int S_AddPlayerSound (const char *playerclass, const int gender, int refid, int lumpnum, bool fromskin=false);
int S_AddPlayerSoundExisting (const char *playerclass, const int gender, int refid, int aliasto, bool fromskin=false);
void S_ShrinkPlayerSoundLists ();
// [RH] Prints sound debug info to the screen.

View file

@ -2305,9 +2305,9 @@ static void ActorConversationID (AActor *defaults, Baggage &bag)
if (convid==-1) return;
}
if (convid<0 || convid>999)
if (convid<0 || convid>1000)
{
SC_ScriptError ("ConversationID must be in the range [0,999]");
SC_ScriptError ("ConversationID must be in the range [0,1000]");
}
else StrifeTypes[convid] = bag.Info->Class;
}

View file

@ -1522,7 +1522,7 @@ void A_JumpIf(AActor * self)
//===========================================================================
void A_KillMaster(AActor * self)
{
if (self->master)
if (self->master != NULL)
{
P_DamageMobj(self->master, self, self, self->master->health, MOD_UNKNOWN, DMG_NO_ARMOR);
}