diff --git a/Makefile.linux b/Makefile.linux index 3ac87287d..3280acc9e 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -19,10 +19,10 @@ DEBUGOBJ ?= debugobj CPPSRCS = $(wildcard $(addsuffix *.cpp,$(SRCDIRS))) CSRCS = $(wildcard $(addsuffix *.c,$(SRCDIRS))) ifndef NOASM -ASRCS = $(wildcard src/*.nas) -CFLAGS += -DUSEASM=1 + ASRCS = $(wildcard src/*.nas) + CFLAGS += -DUSEASM=1 else -CFLAGS += -DNOASM + CFLAGS += -DNOASM endif SRCS = $(CSRCS) $(CPPSRCS) $(ASRCS) CPPOBJFILES = $(notdir $(patsubst %.cpp,%.o,$(CPPSRCS))) @@ -54,27 +54,30 @@ RESTART?=1 # rule pattern for dependencies define DEPBUILD_PATTERN _dep_: _src_ - $(CXX) _src_ -MM $(CXXFLAGS) -MT "$$(patsubst %.d,%.o,_dep_) _dep_" -MF _dep_ + $(CXX) _src_ -MM $(CXXFLAGS) -MT "$$(patsubst %.d,%.o,_dep_) _dep_" -MF _dep_ endef # rule pattern for assembly files define ASMBUILD_PATTERN _obj_: _src_ - $(NASM) -o _obj_ $(NASMFLAGS) _src_ + $(NASM) -o _obj_ $(NASMFLAGS) _src_ endef define CBUILD_PATTERN _obj_: _src_ - $(CC) -c $(CFLAGS) -o _obj_ -c _src_ + $(CC) -c $(CFLAGS) -o _obj_ -c _src_ endef all: $(ZDOOMBIN) zdoom.wad -$(ZDOOMBIN): $(OBJDIR) deps $(OBJS) - $(CXX) $(LDFLAGS) $(OBJDIR)/autostart.o \ - $(filter-out %/autostart.o %/autozend.o,$(OBJS)) $(OBJDIR)/autozend.o -o $(ZDOOMBIN) +$(ZDOOMBIN): $(OBJDIR) $(if $(RESTART),deps) $(OBJS) +ifndef RESTART + $(CXX) $(LDFLAGS) $(OBJDIR)/autostart.o \ + $(filter-out %/autostart.o %/autozend.o,$(OBJS)) \ + $(OBJDIR)/autozend.o -o $(ZDOOMBIN) +endif -#include any of the dep files that already exist +# include any of the dep files that already exist $(foreach dep,$(DEPS),$(if $(wildcard $(dep)),$(eval include $(dep)))) # textually substitute in the _dep_ and the _src_ it depends on to create rules @@ -92,30 +95,32 @@ $(foreach src,$(CSRCS), $(eval $(subst _src_,$(src),$(subst \ _obj_,$(OBJDIR)/$(patsubst %.c,%.o,$(notdir $$$(src))),$(CBUILD_PATTERN))))) $(OBJDIR)/%.o: - $(CXX) -c $(CXXFLAGS) -o $@ -c $< + $(CXX) -c $(CXXFLAGS) -o $@ -c $< # start a new instance of make after dependency files have been made deps: $(DEPS) - $(if $(RESTART),@make -f $(firstword $(MAKEFILE_LIST)) RESTART=) +ifdef RESTART + @make -f $(firstword $(MAKEFILE_LIST)) RESTART= +endif $(OBJDIR): - mkdir $(OBJDIR) + mkdir $(OBJDIR) zdoom.wad: - make -C wadsrc/ -f Makefile + make -C wadsrc/ -f Makefile .PHONY : clean cleandeps cleanobjs distclean deps clean: cleanobjs - rm -f $(ZDOOMDEBUG) $(ZDOOM) $(ZDOOM).map + rm -f $(ZDOOMDEBUG) $(ZDOOM) $(ZDOOM).map # I could use a recursive delete instead, but that could be dangerous... distclean: clean cleandeps - rmdir $(RELEASEOBJ) $(DEBUGOBJ) + rmdir $(RELEASEOBJ) $(DEBUGOBJ) cleandeps: - rm -f $(RELEASEOBJ)/*.d $(DEBUGOBJ)/*.d + rm -f $(RELEASEOBJ)/*.d $(DEBUGOBJ)/*.d cleanobjs: - rm -f $(RELEASEOBJ)/*.o $(DEBUGOBJ)/*.o - \ No newline at end of file + rm -f $(RELEASEOBJ)/*.o $(DEBUGOBJ)/*.o + diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 787305967..1cc456792 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,26 @@ April 19, 2006 (Changes by Graf Zahl) +- Fixed: Hexen's ammo display in the status bar cannot be refreshed + partially because the background patch has to be drawn always to + overwrite the old display. +- Fixed: Giving a health item to a non-player caused a crash. +- Added a compatibility option to limit deh.MaxHealth to the health bonus. + Originally this value wasn't used for health packs. Doing this was a bug + in Boom but since there's quite a few maps out there which require + Boom's altered behavior it has to be compatibility optioned. +- Fixed: The health bonus's max health must be defined by deh.MaxHealth, + not deh.MaxSoulsphere. To achieve this deh.MaxHealth's handling had to + be altered because it has to default to 100. +- Fixed: ZDBSP created incorrect side references with compressed sidedefs + and both sidedefs of a linedef being the same. This only affects the + external tool because the internal node builder is run after uncompressing + the sidedefs. +- Added Jim's latest makefile.linux. +- Added a consistency check to the PNAMES loader because one crash log + indicated that it crashed due to a corrupt PNAMES lump. +- Brought back the sector based sound target handling as a compatibility + option. This radical change just broke far too many maps that depend + on the original behavior. Strife's special AI functions are excluded + though because they work better with the new method. - Fixed: Hexen had no default sound sequence for doors and passed a NULL pointer to SN_StartSequence in DoorSound. diff --git a/src/b_think.cpp b/src/b_think.cpp index f59ba922f..a43606fc9 100644 --- a/src/b_think.cpp +++ b/src/b_think.cpp @@ -363,7 +363,7 @@ void DCajunMaster::WhatToGet (AActor *actor, AActor *item) } else if ((typeis (Megasphere) || typeis (Soulsphere) || typeis (HealthBonus)) && actor->health >= deh.MaxSoulsphere) return; - else if (item->IsKindOf (RUNTIME_CLASS(AHealth)) && actor->health >= MAXHEALTH) + else if (item->IsKindOf (RUNTIME_CLASS(AHealth)) && actor->health >= deh.MaxHealth /*MAXHEALTH*/) return; if ((b->dest == NULL || diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 08b86a3ef..04cbcadc3 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -129,7 +129,7 @@ DehInfo deh = { 100, // .StartHealth 50, // .StartBullets - 100, // .MaxHealth + -1, // .MaxHealth 200, // .MaxArmor 1, // .GreenAC 2, // .BlueAC @@ -1640,7 +1640,7 @@ static int PatchMisc (int dummy) AHealth *health; health = static_cast (GetDefaultByName ("HealthBonus")); - health->MaxAmount = deh.MaxSoulsphere; + if (deh.MaxHealth != -1) health->MaxAmount = deh.MaxHealth; // 0xDD means "enable infighting" if (infighting == 0xDD) @@ -2531,6 +2531,10 @@ void FinishDehPatch () DPrintf ("%s replaces %s\n", subclass->Name, type->Name); } + + // Since deh.MaxHealth was used incorrectly this can only be set + // after finishing with the DEH stuff. + if (deh.MaxHealth == -1) deh.MaxHealth = 100; } void HandleNoSector() diff --git a/src/d_main.cpp b/src/d_main.cpp index fec5f05ba..28a52f36a 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -390,6 +390,8 @@ CVAR (Flag, compat_notossdrops, compatflags, COMPATF_NOTOSSDROPS); CVAR (Flag, compat_useblocking, compatflags, COMPATF_USEBLOCKING); CVAR (Flag, compat_nodoorlight, compatflags, COMPATF_NODOORLIGHT); CVAR (Flag, compat_ravenscroll, compatflags, COMPATF_RAVENSCROLL); +CVAR (Flag, compat_soundtarget, compatflags, COMPATF_SOUNDTARGET); +CVAR (Flag, compat_dehhealth, compatflags, COMPATF_DEHHEALTH); //========================================================================== // diff --git a/src/doomdef.h b/src/doomdef.h index 2f454cb7f..731a36ae5 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -262,6 +262,8 @@ enum COMPATF_USEBLOCKING = 1 << 8, // Any special line can block a use line COMPATF_NODOORLIGHT = 1 << 9, // Don't do the BOOM local door light effect COMPATF_RAVENSCROLL = 1 << 10, // Raven's scrollers use their original carrying speed + COMPATF_SOUNDTARGET = 1 << 11, // Use sector based sound target code. + COMPATF_DEHHEALTH = 1 << 12, // Limit deh.MaxHealth to the health bonus (as in Doom2.exe) }; // phares 3/20/98: diff --git a/src/g_hexen/hexen_sbar.cpp b/src/g_hexen/hexen_sbar.cpp index f4811e854..bd569d552 100644 --- a/src/g_hexen/hexen_sbar.cpp +++ b/src/g_hexen/hexen_sbar.cpp @@ -197,8 +197,6 @@ public: Mana1Refresh = 0; Mana2Refresh = 0; AmmoRefresh = 0; - Ammo1Refresh = 0; - Ammo2Refresh = 0; } ~FHexenStatusBar () @@ -509,51 +507,40 @@ private: void DrawMainAltAmmo (AAmmo *ammo1, AAmmo *ammo2, int ammocount1, int ammocount2) { - if (AmmoRefresh) - { - Ammo1Refresh = MAX(AmmoRefresh, Ammo1Refresh); - Ammo2Refresh = MAX(AmmoRefresh, Ammo2Refresh); - AmmoRefresh--; - DrawImage (Images[imgAMMOBACK], 77, 2); - } if (ammo1 != oldammo1 || ammocount1 != oldammocount1) { - Ammo1Refresh = screen->GetPageCount (); + AmmoRefresh = screen->GetPageCount (); oldammo1 = ammo1; oldammocount1 = ammocount1; } if (ammo2 != oldammo2 || ammocount2 != oldammocount2) { - Ammo2Refresh = screen->GetPageCount (); + AmmoRefresh = screen->GetPageCount (); oldammo2 = ammo2; oldammocount2 = ammocount2; } - if (ammo2 != NULL) - { // Draw both ammos - if (Ammo1Refresh) - { - Ammo1Refresh--; + + if (AmmoRefresh) + { + AmmoRefresh--; + DrawImage (Images[imgAMMOBACK], 77, 2); + if (ammo2 != NULL) + { // Draw both ammos + AmmoRefresh--; screen->DrawTexture (TexMan[ammo1->Icon], 89+ST_X, 10+ST_Y, DTA_CenterOffset, true, DTA_320x200, true, TAG_DONE); DrSmallNumber (ammo1->Amount, 86, 20); - } - if (Ammo2Refresh) - { - Ammo2Refresh--; + screen->DrawTexture (TexMan[ammo2->Icon], 113+ST_X, 10+ST_Y, DTA_CenterOffset, true, DTA_320x200, true, TAG_DONE); DrSmallNumber (ammo2->Amount, 110, 20); } - } - else - { // Draw one ammo - if (Ammo1Refresh) - { - Ammo1Refresh--; + else + { // Draw one ammo screen->DrawTexture (TexMan[ammo1->Icon], 100+ST_X, 10+ST_Y, DTA_CenterOffset, true, DTA_320x200, true, @@ -1150,8 +1137,6 @@ private: char Mana1Refresh; char Mana2Refresh; char AmmoRefresh; - char Ammo1Refresh; - char Ammo2Refresh; FManaBar ManaVial1Pic; FManaBar ManaVial2Pic; diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index dad016903..3197b69d8 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -183,7 +183,7 @@ bool P_GiveBody (AActor *actor, int num) if (player != NULL) { - max = MAXHEALTH + player->stamina; + max = ((compatflags&COMPATF_DEHHEALTH)? 100 : deh.MaxHealth) + player->stamina; if (player->morphTics) { max = MAXMORPHHEALTH; @@ -1728,31 +1728,43 @@ bool AHealth::TryPickup (AActor *other) player_t *player = other->player; int max = MaxAmount; - if (max == 0) + if (player != NULL) { - max = MAXHEALTH + (player != NULL ? player->stamina : 0); - if (player->morphTics) + if (max == 0) { - max = MAXMORPHHEALTH; + max = ((compatflags&COMPATF_DEHHEALTH)? 100 : deh.MaxHealth) + player->stamina; + if (player->morphTics) + { + max = MAXMORPHHEALTH; + } } + if (player->health >= max) + { + // You should be able to pick up the Doom health bonus even if + // you are already full on health. + if (ItemFlags & IF_ALWAYSPICKUP) + { + GoAwayAndDie (); + return true; + } + return false; + } + player->health += Amount; + if (player->health > max) + { + player->health = max; + } + player->mo->health = player->health; } - if (player->health >= max) + else { - // You should be able to pick up the Doom health bonus even if - // you are already full on health. - if (ItemFlags & IF_ALWAYSPICKUP) + if (P_GiveBody(other, Amount) || ItemFlags & IF_ALWAYSPICKUP) { GoAwayAndDie (); return true; } return false; } - player->health += Amount; - if (player->health > max) - { - player->health = max; - } - player->mo->health = player->health; GoAwayAndDie (); return true; } diff --git a/src/g_strife/a_merchants.cpp b/src/g_strife/a_merchants.cpp index b56b8a1e6..4fa29d4b3 100644 --- a/src/g_strife/a_merchants.cpp +++ b/src/g_strife/a_merchants.cpp @@ -209,6 +209,7 @@ void A_ClearSoundTarget (AActor *self) { AActor *actor; + self->Sector->SoundTarget = NULL; for (actor = self->Sector->thinglist; actor != NULL; actor = actor->snext) { actor->LastHeard = NULL; diff --git a/src/g_strife/a_oracle.cpp b/src/g_strife/a_oracle.cpp index 806d24cb7..9ed0b9f29 100644 --- a/src/g_strife/a_oracle.cpp +++ b/src/g_strife/a_oracle.cpp @@ -64,7 +64,7 @@ void A_WakeOracleSpectre (AActor *self) if (spectre != NULL) { - spectre->LastHeard = self->LastHeard; + spectre->Sector->SoundTarget = spectre->LastHeard = self->LastHeard; spectre->target = self->target; spectre->SetState (spectre->SeeState); } diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index 3db072dd9..ade4469f7 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -686,12 +686,6 @@ void A_KlaxonBlare (AActor *self) } if (self->reactiontime == 2) { - /* - for (AActor *actor = self->Sector->thinglist; actor != NULL; actor = actor->snext) - { - actor->LastHeard = NULL; - } - */ // [RH] Unalert monsters near the alarm and not just those in the same sector as it. P_NoiseAlert (NULL, self, false); } diff --git a/src/m_menu.cpp b/src/m_menu.cpp index 8a48aab7a..aa63cff6a 100644 --- a/src/m_menu.cpp +++ b/src/m_menu.cpp @@ -181,6 +181,7 @@ static char underscore[2]; static int MenuPClass; static FSaveGameNode *quickSaveSlot; // NULL = no quicksave slot picked! +static FSaveGameNode *lastSaveSlot; // Used for highlighting the most recently used slot in the menu static int messageToPrint; // 1 = message to be printed static const char *messageString; // ...and here is the message string! static EMenuState messageLastMenuActive; @@ -796,9 +797,10 @@ void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave) SelSaveGame = node; } - if (quickSaveSlot == NULL && okForQuicksave) + if (okForQuicksave) { - quickSaveSlot = node; + if (quickSaveSlot == NULL) quickSaveSlot = node; + lastSaveSlot = node; } } @@ -1244,13 +1246,13 @@ void M_SaveGame (int choice) M_ReadSaveStrings(); SaveGames.AddHead (&NewSaveNode); TopSaveGame = static_cast(SaveGames.Head); - if (quickSaveSlot == NULL) + if (lastSaveSlot == NULL) { SelSaveGame = &NewSaveNode; } else { - SelSaveGame = quickSaveSlot; + SelSaveGame = lastSaveSlot; } M_ExtractSaveData (SelSaveGame); } @@ -2808,6 +2810,10 @@ static void M_DeleteSaveResponse (int choice) { quickSaveSlot = NULL; } + if (lastSaveSlot == SelSaveGame) + { + lastSaveSlot = NULL; + } SelSaveGame->Remove (); delete SelSaveGame; SelSaveGame = next; @@ -3120,6 +3126,7 @@ void M_Init (void) messageString = NULL; messageLastMenuActive = menuactive; quickSaveSlot = NULL; + lastSaveSlot = NULL; strcpy (NewSaveNode.Title, ""); underscore[0] = (gameinfo.gametype & (GAME_Doom|GAME_Strife)) ? '_' : '['; diff --git a/src/m_options.cpp b/src/m_options.cpp index 9df06dd6c..137895113 100644 --- a/src/m_options.cpp +++ b/src/m_options.cpp @@ -954,6 +954,8 @@ static menuitem_t CompatibilityItems[] = { { bitflag, "All special lines can block ", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_USEBLOCKING} }, { bitflag, "Disable BOOM door light effect", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_NODOORLIGHT} }, { bitflag, "Raven scrollers use original speed", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_RAVENSCROLL} }, + { bitflag, "Use original sound target handling", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_SOUNDTARGET} }, + { bitflag, "DEH health settings like Doom2.exe", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_DEHHEALTH} }, { discrete, "Interpolate monster movement", {&nomonsterinterpolation}, {2.0}, {0.0}, {0.0}, {NoYes} }, }; diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 0195da305..7f7e1c341 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -125,6 +125,7 @@ void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soun sec->validcount = validcount; sec->soundtraversed = soundblocks+1; + sec->SoundTarget = soundtarget; // [RH] Set this in the actors in the sector instead of the sector itself. for (actor = sec->thinglist; actor != NULL; actor = actor->snext) @@ -1385,7 +1386,7 @@ void A_Look (AActor *actor) } else { - targ = actor->LastHeard; + targ = (compatflags & COMPATF_SOUNDTARGET)? actor->Sector->SoundTarget : actor->LastHeard; // [RH] If the soundtarget is dead, don't chase it if (targ != NULL && targ->health <= 0) diff --git a/src/p_local.h b/src/p_local.h index 9e3bc024c..e9f0d263d 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -33,7 +33,6 @@ #define STEEPSLOPE 46341 // [RH] Minimum floorplane.c value for walking -#define MAXHEALTH (deh.MaxHealth) //100 #define MAXMORPHHEALTH 30 #define BONUSADD 6 diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index f567e7da1..71257d1c3 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -118,6 +118,7 @@ void P_SerializeWorld (FArchive &arc) << sec->gravity << sec->damage << sec->mod + << sec->SoundTarget << sec->SecActTarget << sec->FloorLight << sec->CeilingLight diff --git a/src/r_data.cpp b/src/r_data.cpp index a27d26b97..9224ae221 100644 --- a/src/r_data.cpp +++ b/src/r_data.cpp @@ -636,6 +636,23 @@ void FTextureManager::AddTexturesLump (const void *lumpdata, int lumpsize, int p pnames >> numpatches; + // Check whether the amount of names reported is correct. + if (numpatches < 0) + { + I_Error("Corrupt PNAMES lump found (negative amount of entries reported)"); + return; + } + + // Check whether the amount of names reported is correct. + int lumplength = Wads.LumpLength(patcheslump); + if (numpatches > (lumplength-4)/8) + { + Printf("PNAMES lump is shorter than required (%ld entries reported but only %d bytes (%ld entries) long\n", + numpatches, lumplength, (lumplength-4)/8); + // Truncate but continue reading. Who knows how many such lumps exist? + numpatches = (lumplength-4)/8; + } + // Catalog the patches these textures use so we know which // textures they represent. patchlookup = (FPatchLookup *)alloca (numpatches * sizeof(*patchlookup)); diff --git a/src/r_defs.h b/src/r_defs.h index cb6af375d..3ecb0dc51 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -302,6 +302,7 @@ struct sector_t short floorpic, ceilingpic; BYTE lightlevel; + AActor * SoundTarget; byte soundtraversed; // 0 = untraversed, 1,2 = sndlines -1 short special;