diff --git a/docs/rh-log.txt b/docs/rh-log.txt index e409bc6be..ae1d4a3b0 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -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. diff --git a/src/d_main.cpp b/src/d_main.cpp index e8addb39e..130d95f57 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -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); diff --git a/src/d_player.h b/src/d_player.h index db7c262f5..a588b1a3a 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -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 diff --git a/src/decorations.cpp b/src/decorations.cpp index 92ff95050..9bbdd1197 100644 --- a/src/decorations.cpp +++ b/src/decorations.cpp @@ -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")) { diff --git a/src/g_game.cpp b/src/g_game.cpp index 7fcf95e1b..aea91129c 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -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); diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 6e1c64b46..c61e53d2a 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -65,7 +65,7 @@ TArray 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 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]; } diff --git a/src/p_conversation.h b/src/p_conversation.h index 5705cb22f..e57284d8b 100644 --- a/src/p_conversation.h +++ b/src/p_conversation.h @@ -54,7 +54,7 @@ extern TArray 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 (); diff --git a/src/p_user.cpp b/src/p_user.cpp index d614a1227..21f8f8fe5 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -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->crouchfactoryscale; - } - 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; imo; + + 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; + } + } + } +} + /* ================== = diff --git a/src/r_defs.h b/src/r_defs.h index 8794cc62e..e40f6493f 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -842,6 +842,7 @@ public: byte scale; byte game; int sprite; + int crouchsprite; int namespc; // namespace for this skin }; diff --git a/src/r_things.cpp b/src/r_things.cpp index 00ec1a24f..431acc4f7 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -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); } } } diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index ff88ecfd9..0f6ca34b1 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -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 S_rnd; static FMusicVolume *MusicVolumes; +static TArray 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 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 diff --git a/src/s_sound.h b/src/s_sound.h index 9ced0705c..ccc68379f 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -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. diff --git a/src/thingdef.cpp b/src/thingdef.cpp index 33f848ca6..dc72263fe 100644 --- a/src/thingdef.cpp +++ b/src/thingdef.cpp @@ -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; } diff --git a/src/thingdef_codeptr.cpp b/src/thingdef_codeptr.cpp index 3c4bb1f97..37802c719 100644 --- a/src/thingdef_codeptr.cpp +++ b/src/thingdef_codeptr.cpp @@ -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); }