diff --git a/docs/rh-log.txt b/docs/rh-log.txt index defe86fa..e10bcb43 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,17 @@ +October 29, 2009 +- Fixed: Sprites and decals that are drawn with addition must fade to black. +- Make TranslateToStartSpot() set the new sector references for a polyobj's + walls so that P_CheckSwitchRange() will work with them. +- Fixed: An unspecified save_dir will now save to the program directory on + Windows. (Other operating systems already use the user's home directory + instead.) +- Fixed: S_EvictAllChannels() must replace the channel's start time with its + position when evicting sounds, because restarting the sound system causes + the DSP clock to restart at 0, so start times that were recorded before + the reset are no longer applicable after the reset. +- Fixed: S_StopChannel() always set the channel's actor to NULL, eliminating + origin information when resetting the sound system. + October 28, 2009 - Added Gez's patch for IWAD detection of Blasphemer and Action Doom 2. - Fixed: 0 damage projectiles did not call P_DamageMobj. diff --git a/src/g_game.cpp b/src/g_game.cpp index c617f980..613b147b 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1851,14 +1851,11 @@ FString G_BuildSaveName (const char *prefix, int slot) { leader = save_dir; } + if (leader.IsEmpty()) + { #ifdef unix - if (leader.IsEmpty()) - { leader = "~/" GAME_DIR; - } #elif defined(__APPLE__) - if (leader.IsEmpty()) - { char cpath[PATH_MAX]; FSRef folder; @@ -1867,8 +1864,10 @@ FString G_BuildSaveName (const char *prefix, int slot) { leader << cpath << "/" GAME_DIR "/Savegames/"; } - } +#else + leader = progdir; #endif + } } size_t len = leader.Len(); if (leader[0] != '\0' && leader[len-1] != '\\' && leader[len-1] != '/') diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 980025d9..919c11be 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2545,6 +2545,10 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) S_Sound (corpsehit, CHAN_BODY, "vile/raise", 1, ATTN_IDLE); info = corpsehit->GetDefault (); + if (corpsehit->state == corpsehit->FindState(NAME_GenericCrush)) + { + corpsehit->Translation = info->Translation; // Clean up bloodcolor translation from crushed corpses + } if (ib_compatflags & BCOMPATF_VILEGHOSTS) { corpsehit->height <<= 2; @@ -2563,7 +2567,6 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) corpsehit->RenderStyle = STYLE_Translucent; } } - corpsehit->Translation = info->Translation; // Clean up bloodcolor translation from crushed corpses } else { diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 9b982426..7ecf4998 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1018,7 +1018,7 @@ bool AActor::Grind(bool items) if (state == NULL // Only use the default crushed state if: && !(flags & MF_NOBLOOD) // 1. the monster bleeeds, && (i_compatflags & COMPATF_CORPSEGIBS) // 2. the compat setting is on, - && player != NULL) // 3. and the thing isn't a player. + && player == NULL) // 3. and the thing isn't a player. { isgeneric = true; state = FindState(NAME_GenericCrush); diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 82d91489..56ecd517 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -293,7 +293,10 @@ bool P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType) } if (activationType == SPAC_Use) { - if (!P_CheckSwitchRange(mo, line, side)) return false; + if (!P_CheckSwitchRange(mo, line, side)) + { + return false; + } } if ((lineActivation & activationType) == 0) @@ -392,7 +395,6 @@ bool P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType) // void P_PlayerInSpecialSector (player_t *player, sector_t * sector) { - if (sector == NULL) { // Falling, not all the way down yet? diff --git a/src/p_switch.cpp b/src/p_switch.cpp index 4e312a16..9865b65c 100644 --- a/src/p_switch.cpp +++ b/src/p_switch.cpp @@ -466,7 +466,8 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno) { // Activated from an empty side -> always succeed side_t *side = line->sidedef[sideno]; - if (side == NULL) return true; + if (side == NULL) + return true; fixed_t checktop; fixed_t checkbot; @@ -474,7 +475,8 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno) FLineOpening open; // 3DMIDTEX forces CHECKSWITCHRANGE because otherwise it might cause problems. - if (!(line->flags & (ML_3DMIDTEX|ML_CHECKSWITCHRANGE))) return true; + if (!(line->flags & (ML_3DMIDTEX|ML_CHECKSWITCHRANGE))) + return true; // calculate the point where the user would touch the wall. divline_t dll, dlu; @@ -488,11 +490,25 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno) dlu.dy = finesine[user->angle >> ANGLETOFINESHIFT]; inter = P_InterceptVector(&dll, &dlu); - checkx = dll.x + FixedMul(dll.dx, inter); - checky = dll.y + FixedMul(dll.dy, inter); - // one sided line - if (line->sidedef[1] == NULL) + // Polyobjects must test the containing sector, not the one they originate from. + if (line->sidedef[0]->Flags & WALLF_POLYOBJ) + { + // Get a check point slightly inside the polyobject so that this still works + // if the polyobject lies directly on a sector boundary + checkx = dll.x + FixedMul(dll.dx, inter + (FRACUNIT/100)); + checky = dll.y + FixedMul(dll.dy, inter + (FRACUNIT/100)); + front = P_PointInSector(checkx, checky); + } + else + { + checkx = dll.x + FixedMul(dll.dx, inter); + checky = dll.y + FixedMul(dll.dy, inter); + } + + + // one sided line or polyobject + if (line->sidedef[1] == NULL || (line->sidedef[0]->Flags & WALLF_POLYOBJ)) { onesided: fixed_t sectorc = front->ceilingplane.ZatPoint(checkx, checky); @@ -502,7 +518,8 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno) // Now get the information from the line. P_LineOpening(open, NULL, line, checkx, checky, user->x, user->y); - if (open.range <= 0) goto onesided; + if (open.range <= 0) + goto onesided; if ((TryFindSwitch (side, side_t::top)) != -1) { @@ -516,7 +533,8 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno) { // 3DMIDTEX lines will force a mid texture check if no switch is found on this line // to keep compatibility with Eternity's implementation. - if (!P_GetMidTexturePosition(line, sideno, &checktop, &checkbot)) return false; + if (!P_GetMidTexturePosition(line, sideno, &checktop, &checkbot)) + return false; return user->z < checktop || user->z + user->height > checkbot; } else diff --git a/src/po_man.cpp b/src/po_man.cpp index ebafff46..37faf119 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -1545,6 +1545,7 @@ static void TranslateToStartSpot (int tag, int originX, int originY) validcount++; for (i = 0; i < po->numsegs; i++, tempSeg++, tempPt++) { + (*tempSeg)->sidedef->Flags |= WALLF_POLYOBJ; if ((*tempSeg)->linedef->validcount != validcount) { (*tempSeg)->linedef->bbox[BOXTOP] -= deltaY; @@ -1565,16 +1566,17 @@ static void TranslateToStartSpot (int tag, int originX, int originY) (*tempSeg)->v1->x -= deltaX; (*tempSeg)->v1->y -= deltaY; } - avg.x += (*tempSeg)->v1->x>>FRACBITS; - avg.y += (*tempSeg)->v1->y>>FRACBITS; + avg.x += (*tempSeg)->v1->x >> FRACBITS; + avg.y += (*tempSeg)->v1->y >> FRACBITS; // the original Pts are based off the startSpot Pt, and are // unique to each seg, not each linedef tempPt->x = (*tempSeg)->v1->x-po->startSpot[0]; tempPt->y = (*tempSeg)->v1->y-po->startSpot[1]; } + // Put polyobj in its subsector. avg.x /= po->numsegs; avg.y /= po->numsegs; - sub = R_PointInSubsector (avg.x<poly != NULL) { I_Error ("PO_TranslateToStartSpot: Multiple polyobjs in a single subsector.\n"); diff --git a/src/r_defs.h b/src/r_defs.h index ca58e3b5..b15d5b45 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -801,6 +801,7 @@ enum WALLF_SMOOTHLIGHTING = 8, // Similar to autocontrast but applies to all angles. WALLF_CLIP_MIDTEX = 16, // Like the line counterpart, but only for this side. WALLF_WRAP_MIDTEX = 32, // Like the line counterpart, but only for this side. + WALLF_POLYOBJ = 64, // This wall belongs to a polyobject. }; struct side_t diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 139167c5..a22b28c6 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -2432,14 +2432,21 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, // Prepare lighting calclighting = false; + FDynamicColormap *usecolormap = basecolormap; + + // Decals that are added to the scene must fade to black. + if (decal->RenderStyle == LegacyRenderStyles[STYLE_Add] && usecolormap->Fade != 0) + { + usecolormap = GetSpecialLights(usecolormap->Color, 0, usecolormap->Desaturate); + } rw_light = rw_lightleft + (x1 - WallSX1) * rw_lightstep; if (fixedlightlev >= 0) - dc_colormap = basecolormap->Maps + fixedlightlev; + dc_colormap = usecolormap->Maps + fixedlightlev; else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; else if (!foggy && (decal->RenderFlags & RF_FULLBRIGHT)) - dc_colormap = basecolormap->Maps; + dc_colormap = usecolormap->Maps; else calclighting = true; @@ -2486,7 +2493,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, { if (calclighting) { // calculate lighting - dc_colormap = basecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT); + dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT); } WallSpriteColumn (R_DrawMaskedColumn); @@ -2497,7 +2504,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, { if (calclighting) { // calculate lighting - dc_colormap = basecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT); + dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT); } rt_initcols(); for (int zz = 4; zz; --zz) @@ -2512,7 +2519,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, { if (calclighting) { // calculate lighting - dc_colormap = basecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT); + dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT); } WallSpriteColumn (R_DrawMaskedColumn); diff --git a/src/r_things.cpp b/src/r_things.cpp index 5f88793e..c03c162b 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -1432,6 +1432,12 @@ void R_ProjectSprite (AActor *thing, int fakeside) FDynamicColormap *mybasecolormap = basecolormap; + // Sprites that are added to the scene must fade to black. + if (vis->RenderStyle == LegacyRenderStyles[STYLE_Add] && mybasecolormap->Fade != 0) + { + mybasecolormap = GetSpecialLights(mybasecolormap->Color, 0, mybasecolormap->Desaturate); + } + if (vis->RenderStyle.Flags & STYLEF_FadeToBlack) { if (invertcolormap) diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 09956592..e294b6ef 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -1741,6 +1741,11 @@ void S_EvictAllChannels() chan->ChanFlags |= CHAN_EVICTED; if (chan->SysChannel != NULL) { + if (!(chan->ChanFlags & CHAN_ABSTIME)) + { + chan->StartTime.AsOne = GSnd ? GSnd->GetPosition(chan) : 0; + chan->ChanFlags |= CHAN_ABSTIME; + } S_StopChannel(chan); } // assert(chan->NextChan == next); @@ -2016,13 +2021,11 @@ void S_StopChannel(FSoundChan *chan) if (!(chan->ChanFlags & CHAN_EVICTED)) { chan->ChanFlags |= CHAN_FORGETTABLE; + if (chan->SourceType == SOURCE_Actor) + { + chan->Actor = NULL; + } } - - if (chan->SourceType == SOURCE_Actor) - { - chan->Actor = NULL; - } - GSnd->StopChannel(chan); } else diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 2fc37322..2a1ad2b9 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -1541,7 +1541,7 @@ FISoundChannel *FMODSoundRenderer::StartSound(SoundHandle sfx, float vol, int pi chan->setFrequency(freq); } chan->setVolume(vol); - if (!HandleChannelDelay(chan, reuse_chan, !!(flags & SNDF_ABSTIME), freq)) + if (!HandleChannelDelay(chan, reuse_chan, flags & (SNDF_ABSTIME | SNDF_LOOP), freq)) { chan->stop(); return NULL; @@ -1648,7 +1648,7 @@ FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener * chan->set3DAttributes((FMOD_VECTOR *)&pos[0], (FMOD_VECTOR *)&vel[0]); chan->set3DSpread(snd_3dspread); } - if (!HandleChannelDelay(chan, reuse_chan, !!(flags & SNDF_ABSTIME), freq)) + if (!HandleChannelDelay(chan, reuse_chan, flags & (SNDF_ABSTIME | SNDF_LOOP), freq)) { chan->stop(); return NULL; @@ -1685,7 +1685,7 @@ FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener * // //========================================================================== -bool FMODSoundRenderer::HandleChannelDelay(FMOD::Channel *chan, FISoundChannel *reuse_chan, bool abstime, float freq) const +bool FMODSoundRenderer::HandleChannelDelay(FMOD::Channel *chan, FISoundChannel *reuse_chan, int flags, float freq) const { if (reuse_chan != NULL) { // Sound is being restarted, so seek it to the position @@ -1695,7 +1695,7 @@ bool FMODSoundRenderer::HandleChannelDelay(FMOD::Channel *chan, FISoundChannel * // If abstime is set, the sound is being restored, and // the channel's start time is actually its seek position. - if (abstime) + if (flags & SNDF_ABSTIME) { unsigned int seekpos = reuse_chan->StartTime.Lo; if (seekpos > 0) diff --git a/src/sound/fmodsound.h b/src/sound/fmodsound.h index 2fe49736..5febda3e 100644 --- a/src/sound/fmodsound.h +++ b/src/sound/fmodsound.h @@ -69,7 +69,7 @@ private: static FMOD_RESULT F_CALLBACK ChannelCallback(FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type, void *data1, void *data2); static float F_CALLBACK RolloffCallback(FMOD_CHANNEL *channel, float distance); - bool HandleChannelDelay(FMOD::Channel *chan, FISoundChannel *reuse_chan, bool abstime, float freq) const; + bool HandleChannelDelay(FMOD::Channel *chan, FISoundChannel *reuse_chan, int flags, float freq) const; FISoundChannel *CommonChannelSetup(FMOD::Channel *chan, FISoundChannel *reuse_chan) const; FMOD_MODE SetChanHeadSettings(SoundListener *listener, FMOD::Channel *chan, const FVector3 &pos, bool areasound, FMOD_MODE oldmode) const; diff --git a/src/svnrevision.h b/src/svnrevision.h index 8f5d64c5..85d26755 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "1947" -#define ZD_SVN_REVISION_NUMBER 1947 +#define ZD_SVN_REVISION_STRING "1954" +#define ZD_SVN_REVISION_NUMBER 1954