diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 99b4718f5..fc5e9376c 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,27 @@ +February 5, 2008 +- Fixed: Morphed pig and chicken players made normal human *usefail sounds. +- G_DoSaveGame() now receives the filename and description from its arguments + rather than global variables, so autosaves and manual saves can be done + in close proximity to each other without overwriting the parameters for + one of them. +- Fixed potential buffer overrun in G_SaveGame() and added a check so that + you can't interfere with saves that are still pending. +- Fixed: P_LineAttack() creates temporary puffs to get damage types, but this + had the side effect of creating particles for the puff. +- Fixed: The Heretic status bar tried to use the graphic "SELECTBOX" for the + inventory selector. The correct name is "SELECTBO". +- Fixed: Using allowrespawn for a single-player map would fire off enter + scripts instead of respawn script because the player wasn't assigned the + state PST_REBORN. +- Fixed: P_CheckMissileSpawn() now passes the BlockingMobj to + P_ExplodeMissile() so that it can select the appropriate death state. +- Added the manifest to MinGW-compiled builds of updaterevision so you can + build under Vista with MinGW without needing administrative privileges. + (But I still want to know why Vista thinks it needs elevated privileges + without a manifest telling it otherwise.) +- Using four 0xFF bytes for the final note of an IMF song should signal the + end of the song. + February 4, 2008 - Applied a modified version of Karate Chris's screenshot naming patch. - Sbarinfo optimization: Creating and destroying bar textures every frame is diff --git a/src/g_game.cpp b/src/g_game.cpp index 012728bbb..f0573093b 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -95,7 +95,7 @@ void G_DoPlayDemo (void); void G_DoCompleted (void); void G_DoVictory (void); void G_DoWorldDone (void); -void G_DoSaveGame (bool okForQuicksave); +void G_DoSaveGame (bool okForQuicksave, FString filename, const char *description); void G_DoAutoSave (); FIntCVar gameskill ("skill", 2, CVAR_SERVERINFO|CVAR_LATCH); @@ -891,10 +891,14 @@ void G_Ticker () G_DoLoadGame (); break; case ga_savegame: - G_DoSaveGame (true); + G_DoSaveGame (true, savegamefile, savedescription); + gameaction = ga_nothing; + savegamefile = ""; + savedescription[0] = '\0'; break; case ga_autosave: G_DoAutoSave (); + gameaction = ga_nothing; break; case ga_playdemo: G_DoPlayDemo (); @@ -1828,8 +1832,14 @@ void G_DoLoadGame () // void G_SaveGame (const char *filename, const char *description) { + if (sendsave || gameaction == ga_savegame) + { + Printf ("A game save is still pending.\n"); + return; + } savegamefile = filename; - strcpy (savedescription, description); + strncpy (savedescription, description, sizeof(savedescription)-1); + savedescription[sizeof(savedescription)-1] = '\0'; sendsave = true; } @@ -1893,6 +1903,8 @@ extern void P_CalcHeight (player_t *); void G_DoAutoSave () { + char description[SAVESTRINGSIZE]; + FString file; // Keep up to four autosaves at a time UCVarValue num; const char *readableTime; @@ -1901,14 +1913,14 @@ void G_DoAutoSave () num.Int = (autosavenum + 1) % count; autosavenum.ForceSet (num, CVAR_Int); - savegamefile = G_BuildSaveName ("auto", num.Int); + file = G_BuildSaveName ("auto", num.Int); readableTime = myasctime (); - strcpy (savedescription, "Autosave "); - strncpy (savedescription+9, readableTime+4, 12); - savedescription[9+12] = 0; + strcpy (description, "Autosave "); + strncpy (description+9, readableTime+4, 12); + description[9+12] = 0; - G_DoSaveGame (false); + G_DoSaveGame (false, file, description); } @@ -1974,23 +1986,21 @@ static void PutSavePic (FILE *file, int width, int height) } } -void G_DoSaveGame (bool okForQuicksave) +void G_DoSaveGame (bool okForQuicksave, FString filename, const char *description) { if (demoplayback) { - savegamefile = G_BuildSaveName ("demosave.zds", -1); + filename = G_BuildSaveName ("demosave.zds", -1); } insave = true; G_SnapshotLevel (); - FILE *stdfile = fopen (savegamefile.GetChars(), "wb"); + FILE *stdfile = fopen (filename.GetChars(), "wb"); if (stdfile == NULL) { - Printf ("Could not create savegame '%s'\n", savegamefile.GetChars()); - savegamefile = ""; - gameaction = ga_nothing; + Printf ("Could not create savegame '%s'\n", filename.GetChars()); insave = false; return; } @@ -2000,7 +2010,7 @@ void G_DoSaveGame (bool okForQuicksave) M_AppendPNGText (stdfile, "Software", "ZDoom " DOTVERSIONSTR); M_AppendPNGText (stdfile, "Engine", GAMESIG); M_AppendPNGText (stdfile, "ZDoom Save Version", SAVESIG); - M_AppendPNGText (stdfile, "Title", savedescription); + M_AppendPNGText (stdfile, "Title", description); M_AppendPNGText (stdfile, "Current Map", level.mapname); PutSaveWads (stdfile); PutSaveComment (stdfile); @@ -2037,31 +2047,28 @@ void G_DoSaveGame (bool okForQuicksave) M_AppendPNGChunk (stdfile, MAKE_ID('s','n','X','t'), &next, 1); } - M_NotifyNewSave (savegamefile.GetChars(), savedescription, okForQuicksave); - gameaction = ga_nothing; - savedescription[0] = 0; + M_NotifyNewSave (filename.GetChars(), description, okForQuicksave); M_FinishPNG (stdfile); fclose (stdfile); // Check whether the file is ok. bool success = false; - stdfile = fopen (savegamefile.GetChars(), "rb"); + stdfile = fopen (filename.GetChars(), "rb"); if (stdfile != NULL) { - PNGHandle * pngh = M_VerifyPNG(stdfile); + PNGHandle *pngh = M_VerifyPNG(stdfile); if (pngh != NULL) { - success=true; + success = true; delete pngh; } fclose(stdfile); } - if (success) Printf ("%s\n", GStrings("GGSAVED")); + if (success) Printf ("%s (%s)\n", GStrings("GGSAVED"), filename.GetChars()); else Printf(PRINT_HIGH, "Save failed\n"); - BackupSaveName = savegamefile; - savegamefile = ""; + BackupSaveName = filename; // We don't need the snapshot any longer. if (level.info->snapshot != NULL) diff --git a/src/g_heretic/a_chicken.cpp b/src/g_heretic/a_chicken.cpp index fb554d2ea..a9bb7bd24 100644 --- a/src/g_heretic/a_chicken.cpp +++ b/src/g_heretic/a_chicken.cpp @@ -168,6 +168,11 @@ IMPLEMENT_ACTOR (AChickenPlayer, Heretic, -1, 0) PROP_DeathSound ("chicken/death") END_DEFAULTS +AT_GAME_SET(ChickenPlayer) +{ + RUNTIME_CLASS(AChickenPlayer)->Meta.SetMetaString(APMETA_SoundClass, "chicken"); +} + void AChickenPlayer::MorphPlayerThink () { if (health > 0) diff --git a/src/g_heretic/heretic_sbar.cpp b/src/g_heretic/heretic_sbar.cpp index 34ab68ea3..d2b02d6e1 100644 --- a/src/g_heretic/heretic_sbar.cpp +++ b/src/g_heretic/heretic_sbar.cpp @@ -92,7 +92,7 @@ public: static const char *hereticLumpNames[NUM_HERETICSB_IMAGES] = { "LTFACE", "RTFACE", "BARBACK", "INVBAR", "CHAIN", - NULL, "LIFEGEM2", "LTFCTOP", "RTFCTOP", "SELECTBOX", + NULL, "LIFEGEM2", "LTFCTOP", "RTFCTOP", "SELECTBO", "INVGEML1", "INVGEML2", "INVGEMR1", "INVGEMR2", "BLACKSQ", "ARMCLEAR", "CHAINBACK","GOD1", "GOD2", "USEARTIA", "USEARTIB", "USEARTIC", "USEARTID", "YKEYICON", "GKEYICON", diff --git a/src/g_hexen/a_pig.cpp b/src/g_hexen/a_pig.cpp index 43b6e004c..e3b4d8b55 100644 --- a/src/g_hexen/a_pig.cpp +++ b/src/g_hexen/a_pig.cpp @@ -156,6 +156,11 @@ IMPLEMENT_ACTOR (APigPlayer, Hexen, -1, 0) PROP_DeathSound ("PigDeath") END_DEFAULTS +AT_GAME_SET(PigPlayer) +{ + RUNTIME_CLASS(APigPlayer)->Meta.SetMetaString(APMETA_SoundClass, "pig"); +} + void APigPlayer::MorphPlayerThink () { if (player->morphTics&15) diff --git a/src/m_misc.cpp b/src/m_misc.cpp index d9d9a9034..7c4328279 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -600,11 +600,11 @@ static bool FindFreeName (FString &fullname, const char *extension) switch (gameinfo.gametype) { - case GAME_Doom: gamename = "Doom"; break; - case GAME_Heretic: gamename = "Heretic"; break; - case GAME_Hexen: gamename = "Hexen"; break; - case GAME_Strife: gamename = "Strife"; break; - default: break; + case GAME_Doom: gamename = "Doom_"; break; + case GAME_Heretic: gamename = "Heretic_"; break; + case GAME_Hexen: gamename = "Hexen_"; break; + case GAME_Strife: gamename = "Strife_"; break; + default: gamename = ""; break; } time_t now; @@ -615,18 +615,18 @@ static bool FindFreeName (FString &fullname, const char *extension) if (tm == NULL) { - lbmname.Format ("%sScreenshot_%s_%04d.%s", fullname.GetChars(), gamename, i, extension); + lbmname.Format ("%sScreenshot_%s%04d.%s", fullname.GetChars(), gamename, i, extension); } else if (i == 0) { - lbmname.Format ("%sScreenshot_%s_%04d%02d%02d_%02d%02d%02d.%s", fullname.GetChars(), gamename, + lbmname.Format ("%sScreenshot_%s%04d%02d%02d_%02d%02d%02d.%s", fullname.GetChars(), gamename, tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, extension); } else { - lbmname.Format ("%sScreenshot_%s_%04d%02d%02d_%02d%02d%02d_%02d.%s", fullname.GetChars(), gamename, + lbmname.Format ("%sScreenshot_%s%04d%02d%02d_%02d%02d%02d_%02d.%s", fullname.GetChars(), gamename, tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, i, extension); diff --git a/src/oplsynth/opl_mus_player.cpp b/src/oplsynth/opl_mus_player.cpp index 83a9e5e18..a1b28a94a 100644 --- a/src/oplsynth/opl_mus_player.cpp +++ b/src/oplsynth/opl_mus_player.cpp @@ -411,6 +411,10 @@ int OPLmusicBlock::PlayTick () while (delay == 0 && score + 4 - scoredata <= ScoreLen) { + if (*(DWORD *)score == 0xFFFFFFFF) + { // This is a special value that means to end the song. + return 0; + } reg = score[0]; data = score[1]; delay = LittleShort(((WORD *)score)[1]); diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 99450f7b0..58b2f2a67 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -1512,6 +1512,7 @@ const char *FBehavior::LookupString (DWORD index) const void FBehavior::StaticStartTypedScripts (WORD type, AActor *activator, bool always, int arg1, bool runNow) { + DPrintf("Starting all scripts of type %d\n", type); for (unsigned int i = 0; i < StaticModules.Size(); ++i) { StaticModules[i]->StartTypedScripts (type, activator, always, arg1, runNow); diff --git a/src/p_local.h b/src/p_local.h index 4d752b79c..4d9811493 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -96,7 +96,7 @@ void P_ThrustMobj (AActor *mo, angle_t angle, fixed_t move); int P_FaceMobj (AActor *source, AActor *target, angle_t *delta); bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax); -AActor *P_SpawnPuff (const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, bool hit=false); +AActor *P_SpawnPuff (const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, bool hit=false, bool temporary=false); void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AActor *originator); void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator); void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator); diff --git a/src/p_map.cpp b/src/p_map.cpp index de15b24fa..3869ad005 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -2929,7 +2929,7 @@ void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, { // Since the puff is the damage inflictor we need it here // regardless of whether it is displayed or not. - puff = P_SpawnPuff (pufftype, hitx, hity, hitz, angle - ANG180, 2, true); + puff = P_SpawnPuff (pufftype, hitx, hity, hitz, angle - ANG180, 2, true, true); killPuff = true; } P_DamageMobj (trace.Actor, puff ? puff : t1, t1, damage, damageType, flags); @@ -2940,7 +2940,7 @@ void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, if (puff == NULL) { // Spawn puff just to get a mass for the splash - puff = P_SpawnPuff (pufftype, hitx, hity, hitz, angle - ANG180, 2, true); + puff = P_SpawnPuff (pufftype, hitx, hity, hitz, angle - ANG180, 2, true, true); killPuff = true; } SpawnDeepSplash (t1, trace, puff, vx, vy, vz); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index f06233104..4304b54d0 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3506,22 +3506,22 @@ void P_SpawnPlayer (mapthing2_t *mthing, bool tempplayer) p->cls = PlayerClasses[p->CurrentPlayerClass].Type; } - if (( dmflags2 & DF2_SAME_SPAWN_SPOT ) && - ( p->playerstate == PST_REBORN ) && - ( deathmatch == false ) && - ( gameaction != ga_worlddone ) && - ( p->mo != NULL )) - { - spawn_x = p->mo->x; - spawn_y = p->mo->y; - spawn_angle = p->mo->angle; - } - else - { - spawn_x = mthing->x << FRACBITS; - spawn_y = mthing->y << FRACBITS; - spawn_angle = ANG45 * (mthing->angle/45); - } + if (( dmflags2 & DF2_SAME_SPAWN_SPOT ) && + ( p->playerstate == PST_REBORN ) && + ( deathmatch == false ) && + ( gameaction != ga_worlddone ) && + ( p->mo != NULL )) + { + spawn_x = p->mo->x; + spawn_y = p->mo->y; + spawn_angle = p->mo->angle; + } + else + { + spawn_x = mthing->x << FRACBITS; + spawn_y = mthing->y << FRACBITS; + spawn_angle = ANG45 * (mthing->angle/45); + } mobj = static_cast (Spawn (p->cls, spawn_x, spawn_y, ONFLOORZ, NO_REPLACE)); @@ -3985,7 +3985,7 @@ void P_SpawnMapThing (mapthing2_t *mthing, int position) // P_SpawnPuff // -AActor *P_SpawnPuff (const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, bool hitthing) +AActor *P_SpawnPuff (const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, bool hitthing, bool temporary) { AActor *puff; @@ -4008,7 +4008,7 @@ AActor *P_SpawnPuff (const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, an puff->SetState (puff->MeleeState); } - if (cl_pufftype && updown != 3 && (puff->flags4 & MF4_ALLOWPARTICLES)) + if (cl_pufftype && updown != 3 && !temporary && (puff->flags4 & MF4_ALLOWPARTICLES)) { P_DrawSplash2 (32, x, y, z, dir, updown, 1); puff->renderflags |= RF_INVISIBLE; @@ -4399,7 +4399,7 @@ bool P_CheckMissileSpawn (AActor* th) } else { - P_ExplodeMissile (th, NULL, NULL); + P_ExplodeMissile (th, NULL, BlockingMobj); } return false; } diff --git a/src/p_user.cpp b/src/p_user.cpp index c4d089048..4f8c02bd4 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1813,7 +1813,7 @@ void P_DeathThink (player_t *player) if (level.time >= player->respawn_time || ((player->cmd.ucmd.buttons & BT_USE) && !player->isbot)) { player->cls = NULL; // Force a new class if the player is using a random class - player->playerstate = multiplayer ? PST_REBORN : PST_ENTER; + player->playerstate = (multiplayer || (level.flags & LEVEL_ALLOWRESPAWN)) ? PST_REBORN : PST_ENTER; if (player->mo->special1 > 2) { player->mo->special1 = 0; diff --git a/src/tarray.h b/src/tarray.h index e0d5bbcf7..d34e05333 100644 --- a/src/tarray.h +++ b/src/tarray.h @@ -294,7 +294,7 @@ class TDeletingArray : public TArray public: ~TDeletingArray () { - for (unsigned int i = 0; i < Size(); ++i) + for (unsigned int i = 0; i < TArray::Size(); ++i) { delete (*this)[i]; } diff --git a/tools/updaterevision/Makefile b/tools/updaterevision/Makefile index 48baf61d9..aa7a6086f 100644 --- a/tools/updaterevision/Makefile +++ b/tools/updaterevision/Makefile @@ -1,31 +1,35 @@ -ifeq (Windows_NT,$(OS)) - WIN=1 - WINCMD=1 -endif -ifeq (msys,$(OSTYPE)) - WIN=1 - WINCMD=0 -endif +ifeq (Windows_NT,$(OS)) + WIN=1 + WINCMD=1 +endif +ifeq (msys,$(OSTYPE)) + WIN=1 + WINCMD=0 +endif CC = gcc CFLAGS = -Os -Wall -fomit-frame-pointer LDFLAGS = -s +OBJS = updaterevision.o + ifeq (1,$(WIN)) EXE = updaterevision.exe + OBJS += trustinfo.o else EXE = updaterevision endif CCDV = @../../ccdv -OBJS = updaterevision.o - all: $(EXE) $(EXE): $(OBJS) $(CCDV) $(CC) -o $(EXE) $(OBJS) $(CFLAGS) $(LDFLAGS) +%.o : %.rc + $(CCDV) windres -o $@ -i $< + .PHONY: clean clean: diff --git a/wadsrc/sndinfo.txt b/wadsrc/sndinfo.txt index 614699159..20873783a 100644 --- a/wadsrc/sndinfo.txt +++ b/wadsrc/sndinfo.txt @@ -513,6 +513,8 @@ $playersounddup player male *land *grunt $playersound player male *jump plrjmp $playersound player male *burndeath hedat1 +$playeralias chicken male *usefail chicken/peck + chicken/sight chicpai chicken/pain chicpai chicken/death chicdth @@ -844,6 +846,7 @@ $playeralias mage male *usefail PlayerMageFailedUse $playeralias mage male *puzzfail PuzzleFailMage $playersound mage male *jump mgjump +$playeralias pig male *usefail PigActive1 $alias world/drip Ambient10 $alias world/watersplash WaterSplash