diff --git a/docs/rh-log.txt b/docs/rh-log.txt index f778dc3e..733aef90 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,67 @@ +December 25, 2009 (Changes by Graf Zahl) +- Fixed: Decals could spread to walls which had a decal-less texture or + were flagged not to have decals. +- Fixed: DBaseDecal/DImpactDecal::CloneSelf never checked the return value + from their StickToWall call and left unplaced decals behind if that happened. +- Reintroduced Doom.exe's player_t::usedown variable so that respawning a + player does not immediately activate switches. oldbuttons was not usable + for this. This also required that CopyPlayer preserves this info. +- Fixed: When restarting the music there was a NULL pointer check missing + so it crashed when the game was started wi +- Fixed: If the Use key is used to respawn the player it must be cleared + so that it doesn't trigger any subsequent actions after respawning. +- Fixed: Resurrecting a monster did not restore flags5 and flags6. +- Fixed: Projectiles which killed a non-monster were unable to determine + what precisely they hit because MF_CORPSE is only valid for monsters. + A new flag, MF6_KILLED that gets set for all objects that die, was added + for this case. +- Added a generic A_Weave function that exposes all possible options of + A_BishopMissileWeave and A_CStaffMissileSlither. These 2 functions are + no longer needed from DECORATE and therefore deprecated. + +December 24, 2009 +- The options menu no longer scales up so quickly, so it can fit wider text + onscreen. In addition, it now uses the whole height available to it. Also, + at lower resolutions, items on the compatibility options menu now cut off + the beginning of the option label rather than the option setting, making + this menu useable where previously it was not. +- Added a channel parameter to the sector overload of SN_StopSequence() so + it can be properly paired with calls to SN_StartSequence(). +- Fixed: P_CheckPlayerSprites() ignored the MF4_NOSKIN flag. It now also sets + the X scale, so switching skins while morphed does not produce weird + stretching upon unmorphing. +- Fixed: Calling S_ChangeMusic() with the same song but a different looping + flag now restarts the song so that the new looping setting can be applied. + (This was easier than modifying every music handler to support modifying + loop changes on the fly, which seems like overkill.) +- Fixed: savepatchsize was declared incorrectly in d_dehacked.cpp:DoInclude(). +- Changed AFastProjectile::Effect() so that it sets the spawned trail to face + same direction as the projectile. + +December 24, 2009 (Changes by Graf Zahl) +- fixed: The UDMF blockfloaters flag was misnamed. Changed to match the spec. + +December 23, 2009 (Changes by Graf Zahl) +- made the initial weave index for A_BishopMissileWeave and A_CStaffMissileSlither + a configurable actor property. +- added a menu item for snd_channels. + +December 20, 2009 (Changes by Graf Zahl) +- Fixed: The Dehacked parser could read past the end of the file if the last + element was improperly defined. + +December 19, 2009 +- Extended MF3_SKYEXPLODE to apply to horizon walls as well. + +December 19, 2009 (Changes by Graf Zahl) +- Fixed: It was not possible to set the ammo type of a weapon explicitly to + 'none'. + +December 18, 2009 +- A_FreezeDeath() now removes fuzz effects. +- In mus2midi.cpp, added range checking to MUS_SYSEVENT and MUS_CTRLCHANGE, + and masking for note-off keys, note-on velocities, and program changes. + December 18, 2009 (Changes by Graf Zahl) - added all known maps requiring inverted sprite sorting to compatibility.txt. - added compatibility option to invert sprite sorting. Apparently Doom.exe diff --git a/src/actor.h b/src/actor.h index c0a6e19e..0390a7c9 100644 --- a/src/actor.h +++ b/src/actor.h @@ -319,6 +319,7 @@ enum MF6_LINEDONE = 0x00008000, // From MBF: Object has already run a line effect MF6_NOTRIGGER = 0x00010000, // actor cannot trigger any line actions MF6_SHATTERING = 0x00020000, // marks an ice corpse for forced shattering + MF6_KILLED = 0x00040000, // Something that was killed (but not necessarily a corpse) // --- mobj.renderflags --- @@ -765,7 +766,6 @@ public: DWORD flags6; // Shit! Where did all the flags go? int special1; // Special info int special2; // Special info - int weaveindex; // Separated from special2 because it's used by globally accessible functions. int health; BYTE movedir; // 0-7 SBYTE visdir; @@ -783,6 +783,8 @@ public: TObjPtr LastLookActor; // Actor last looked for (if TIDtoHate != 0) fixed_t SpawnPoint[3]; // For nightmare respawn WORD SpawnAngle; + BYTE WeaveIndexXY; // Separated from special2 because it's used by globally accessible functions. + BYTE WeaveIndexZ; int skillrespawncount; int TIDtoHate; // TID of things to hate (0 if none) FNameNoInit Species; // For monster families diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index a8a15451..c90eabe9 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -2205,8 +2205,8 @@ static int PatchStrings (int dummy) static int DoInclude (int dummy) { char *data; - int savedversion, savepversion; - char *savepatchfile, *savepatchpt, *savepatchname, savepatchsize; + int savedversion, savepversion, savepatchsize; + char *savepatchfile, *savepatchpt, *savepatchname; if (including) { diff --git a/src/d_player.h b/src/d_player.h index b23d0616..3c9ad954 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -276,6 +276,7 @@ public: bool centering; BYTE turnticks; bool attackdown; + bool usedown; DWORD oldbuttons; int health; // only used between levels, mo->health // is used during levels diff --git a/src/g_game.cpp b/src/g_game.cpp index 2f3a62c0..dc576c2f 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1316,7 +1316,7 @@ void G_PlayerReborn (int player) p->skill = b_skill; //Added by MC: - p->oldbuttons = ~0, p->attackdown = true; // don't do anything immediately + p->oldbuttons = ~0, p->attackdown = true; p->usedown = true; // don't do anything immediately p->original_oldbuttons = ~0; p->playerstate = PST_LIVE; diff --git a/src/g_hexen/a_bishop.cpp b/src/g_hexen/a_bishop.cpp index df998a8a..68b5ce9d 100644 --- a/src/g_hexen/a_bishop.cpp +++ b/src/g_hexen/a_bishop.cpp @@ -72,27 +72,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack2) DEFINE_ACTION_FUNCTION(AActor, A_BishopMissileWeave) { - fixed_t newX, newY; - int weaveXY, weaveZ; - int angle; - - // for compatibility this needs to set the value itself if it was never done by the projectile itself - if (self->weaveindex == -1) self->weaveindex = 16; - - // since these values are now user configurable we have to do a proper range check to avoid array overflows. - weaveXY = (self->weaveindex >> 16) & 63; - weaveZ = (self->weaveindex & 63); - angle = (self->angle + ANG90) >> ANGLETOFINESHIFT; - newX = self->x - FixedMul (finecosine[angle], FloatBobOffsets[weaveXY]<<1); - newY = self->y - FixedMul (finesine[angle], FloatBobOffsets[weaveXY]<<1); - weaveXY = (weaveXY + 2) & 63; - newX += FixedMul (finecosine[angle], FloatBobOffsets[weaveXY]<<1); - newY += FixedMul (finesine[angle], FloatBobOffsets[weaveXY]<<1); - P_TryMove (self, newX, newY, true); - self->z -= FloatBobOffsets[weaveZ]; - weaveZ = (weaveZ + 2) & 63; - self->z += FloatBobOffsets[weaveZ]; - self->weaveindex = weaveZ + (weaveXY<<16); + A_Weave(self, 2, 2, 2*FRACUNIT, FRACUNIT); } //============================================================================ diff --git a/src/g_hexen/a_clericstaff.cpp b/src/g_hexen/a_clericstaff.cpp index b2a50487..829e4512 100644 --- a/src/g_hexen/a_clericstaff.cpp +++ b/src/g_hexen/a_clericstaff.cpp @@ -135,12 +135,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffAttack) mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->angle-(ANG45/15)); if (mo) { - mo->weaveindex = 32; + mo->WeaveIndexXY = 32; } mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->angle+(ANG45/15)); if (mo) { - mo->weaveindex = 0; + mo->WeaveIndexXY = 0; } S_Sound (self, CHAN_WEAPON, "ClericCStaffFire", 1, ATTN_NORM); } @@ -153,22 +153,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffAttack) DEFINE_ACTION_FUNCTION(AActor, A_CStaffMissileSlither) { - fixed_t newX, newY; - int weaveXY; - int angle; - - if (self->weaveindex == -1) self->weaveindex = 0; - - // since these values are now user configurable we have to do a proper range check to avoid array overflows. - weaveXY = self->weaveindex & 63; - angle = (self->angle+ANG90)>>ANGLETOFINESHIFT; - newX = self->x-FixedMul(finecosine[angle], FloatBobOffsets[weaveXY]); - newY = self->y-FixedMul(finesine[angle], FloatBobOffsets[weaveXY]); - weaveXY = (weaveXY+3)&63; - newX += FixedMul(finecosine[angle], FloatBobOffsets[weaveXY]); - newY += FixedMul(finesine[angle], FloatBobOffsets[weaveXY]); - P_TryMove (self, newX, newY, true); - self->weaveindex = weaveXY; + A_Weave(self, 3, 0, FRACUNIT, 0); } //============================================================================ diff --git a/src/g_hexen/a_hexenspecialdecs.cpp b/src/g_hexen/a_hexenspecialdecs.cpp index a3fee855..60302c68 100644 --- a/src/g_hexen/a_hexenspecialdecs.cpp +++ b/src/g_hexen/a_hexenspecialdecs.cpp @@ -348,6 +348,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BellReset2) { self->flags |= MF_SHOOTABLE; self->flags &= ~MF_CORPSE; + self->flags6 &= ~MF6_KILLED; self->health = 5; } diff --git a/src/g_shared/a_decals.cpp b/src/g_shared/a_decals.cpp index 51a30e08..d992bec9 100644 --- a/src/g_shared/a_decals.cpp +++ b/src/g_shared/a_decals.cpp @@ -298,6 +298,13 @@ FTextureID DBaseDecal::StickToWall (side_t *wall, fixed_t x, fixed_t y, F3DFloor else return FNullTextureID(); CalcFracPos (wall, x, y); + FTexture *texture = TexMan[tex]; + + if (texture == NULL || texture->bNoDecals) + { + return FNullTextureID(); + } + return tex; } @@ -546,11 +553,18 @@ DBaseDecal *DBaseDecal::CloneSelf (const FDecalTemplate *tpl, fixed_t ix, fixed_ DBaseDecal *decal = new DBaseDecal(iz); if (decal != NULL) { - decal->StickToWall (wall, ix, iy, ffloor); - tpl->ApplyToDecal (decal, wall); - decal->AlphaColor = AlphaColor; - decal->RenderFlags = (decal->RenderFlags & RF_DECALMASK) | - (this->RenderFlags & ~RF_DECALMASK); + if (decal->StickToWall (wall, ix, iy, ffloor).isValid()) + { + tpl->ApplyToDecal (decal, wall); + decal->AlphaColor = AlphaColor; + decal->RenderFlags = (decal->RenderFlags & RF_DECALMASK) | + (this->RenderFlags & ~RF_DECALMASK); + } + else + { + decal->Destroy(); + return NULL; + } } return decal; } @@ -652,16 +666,12 @@ DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, fixed_t x, } DImpactDecal::CheckMax(); decal = new DImpactDecal (z); - - FTextureID stickypic = decal->StickToWall (wall, x, y, ffloor); - FTexture *tex = TexMan[stickypic]; - - if (tex != NULL && tex->bNoDecals) + if (decal == NULL) { return NULL; } - if (decal == NULL) + if (!decal->StickToWall (wall, x, y, ffloor).isValid()) { return NULL; } @@ -685,15 +695,27 @@ DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, fixed_t x, DBaseDecal *DImpactDecal::CloneSelf (const FDecalTemplate *tpl, fixed_t ix, fixed_t iy, fixed_t iz, side_t *wall, F3DFloor * ffloor) const { + if (wall->Flags & WALLF_NOAUTODECALS) + { + return NULL; + } + DImpactDecal::CheckMax(); DImpactDecal *decal = new DImpactDecal(iz); if (decal != NULL) { - decal->StickToWall (wall, ix, iy, ffloor); - tpl->ApplyToDecal (decal, wall); - decal->AlphaColor = AlphaColor; - decal->RenderFlags = (decal->RenderFlags & RF_DECALMASK) | - (this->RenderFlags & ~RF_DECALMASK); + if (decal->StickToWall (wall, ix, iy, ffloor).isValid()) + { + tpl->ApplyToDecal (decal, wall); + decal->AlphaColor = AlphaColor; + decal->RenderFlags = (decal->RenderFlags & RF_DECALMASK) | + (this->RenderFlags & ~RF_DECALMASK); + } + else + { + decal->Destroy(); + return NULL; + } } return decal; } diff --git a/src/g_shared/a_fastprojectile.cpp b/src/g_shared/a_fastprojectile.cpp index fe97e6a5..5829fc16 100644 --- a/src/g_shared/a_fastprojectile.cpp +++ b/src/g_shared/a_fastprojectile.cpp @@ -125,7 +125,14 @@ void AFastProjectile::Effect() } const PClass *trail = PClass::FindClass(name); - Spawn (trail, x, y, hitz, ALLOW_REPLACE); + if (trail != NULL) + { + AActor *act = Spawn (trail, x, y, hitz, ALLOW_REPLACE); + if (act != NULL) + { + act->angle = this->angle; + } + } } } } diff --git a/src/m_menu.cpp b/src/m_menu.cpp index d16a964d..3535cf48 100644 --- a/src/m_menu.cpp +++ b/src/m_menu.cpp @@ -2120,6 +2120,26 @@ static void M_PlayerSetupTicker (void) } } + +static void M_DrawPlayerSlider (int x, int y, int cur) +{ + const int range = 255; + + x = (x - 160) * CleanXfac + screen->GetWidth() / 2; + y = (y - 100) * CleanYfac + screen->GetHeight() / 2; + + screen->DrawText (ConFont, CR_WHITE, x, y, + "\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12", + DTA_CellX, 8 * CleanXfac, + DTA_CellY, 8 * CleanYfac, + TAG_DONE); + screen->DrawText (ConFont, CR_ORANGE, x + (5 + (int)((cur * 78) / range)) * CleanXfac, y, + "\x13", + DTA_CellX, 8 * CleanXfac, + DTA_CellY, 8 * CleanYfac, + TAG_DONE); +} + static void M_PlayerSetupDrawer () { int x, xo, yo; @@ -2251,9 +2271,9 @@ static void M_PlayerSetupDrawer () x = SmallFont->StringWidth ("Green") + 8 + PSetupDef.x; color = players[consoleplayer].userinfo.color; - M_DrawSlider (x, PSetupDef.y + LINEHEIGHT*2+yo, 0.0f, 255.0f, float(RPART(color)), -1); - M_DrawSlider (x, PSetupDef.y + LINEHEIGHT*3+yo, 0.0f, 255.0f, float(GPART(color)), -1); - M_DrawSlider (x, PSetupDef.y + LINEHEIGHT*4+yo, 0.0f, 255.0f, float(BPART(color)), -1); + M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*2+yo, RPART(color)); + M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*3+yo, GPART(color)); + M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*4+yo, BPART(color)); // [GRB] Draw class setting int pclass = players[consoleplayer].userinfo.PlayerClass; @@ -3443,7 +3463,13 @@ void M_Drawer () screen->DrawText(SmallFont, CR_UNTRANSLATED, 160, y + fontheight + 1, GStrings["TXT_NO"], DTA_Clean, true, TAG_DONE); if (skullAnimCounter < 6) { - M_DrawConText(CR_RED, 150, y + (fontheight + 1) * messageSelection, "\xd"); + screen->DrawText(ConFont, CR_RED, + (150 - 160) * CleanXfac + screen->GetWidth() / 2, + (y + (fontheight + 1) * messageSelection - 100) * CleanYfac + screen->GetHeight() / 2, + "\xd", + DTA_CellX, 8 * CleanXfac, + DTA_CellY, 8 * CleanYfac, + TAG_DONE); } } } diff --git a/src/m_menu.h b/src/m_menu.h index ce7ba99e..997cf0e7 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -84,9 +84,6 @@ void M_DeactivateMenuInput (); void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave); -// Draw a slider. Set fracdigits negative to not display the current value numerically. -void M_DrawSlider (int x, int y, double min, double max, double cur, int fracdigits=1); - // // MENU TYPEDEFS // diff --git a/src/m_options.cpp b/src/m_options.cpp index fa597878..89efec7c 100644 --- a/src/m_options.cpp +++ b/src/m_options.cpp @@ -87,15 +87,17 @@ #include "m_menu.h" extern FButtonStatus MenuButtons[NUM_MKEYS]; -void StartGLMenu (void); -EXTERN_CVAR(Int, vid_renderer) + EXTERN_CVAR(Bool, nomonsterinterpolation) EXTERN_CVAR(Int, showendoom) EXTERN_CVAR(Bool, hud_althud) EXTERN_CVAR(Int, compatmode) EXTERN_CVAR (Bool, vid_vsync) EXTERN_CVAR(Bool, displaynametags) +EXTERN_CVAR (Int, snd_channels) +void StartGLMenu (void); +EXTERN_CVAR(Int, vid_renderer) static value_t Renderers[] = { { 0.0, "Software" }, { 1.0, "OpenGL" }, @@ -104,7 +106,6 @@ EXTERN_CVAR (Float, vid_brightness) EXTERN_CVAR (Float, vid_contrast) extern bool gl_disabled; - // // defaulted values // @@ -1266,6 +1267,7 @@ static menuitem_t SoundItems[] = { discrete, "Underwater reverb", {&snd_waterreverb}, {2.0}, {0.0}, {0.0}, {OnOff} }, { slider, "Underwater cutoff", {&snd_waterlp}, {0.0}, {2000.0},{50.0}, {NULL} }, { discrete, "Randomize pitches", {&snd_pitched}, {2.0}, {0.0}, {0.0}, {OnOff} }, + { slider, "Sound channels", {&snd_channels}, {8.0}, {256.0}, {8.0}, {NULL} }, { redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} }, { more, "Restart sound", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)MakeSoundChanges} }, { redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} }, @@ -1513,11 +1515,9 @@ void M_DrawConText (int color, int x, int y, const char *str) { int len = (int)strlen(str); - x = (x - 160) * CleanXfac + screen->GetWidth() / 2; - y = (y - 100) * CleanYfac + screen->GetHeight() / 2; screen->DrawText (ConFont, color, x, y, str, - DTA_CellX, 8 * CleanXfac, - DTA_CellY, 8 * CleanYfac, + DTA_CellX, 8 * CleanXfac_1, + DTA_CellY, 8 * CleanYfac_1, TAG_DONE); } @@ -1577,7 +1577,8 @@ bool M_StartOptionsMenu (void) return true; } -void M_DrawSlider (int x, int y, double min, double max, double cur,int fracdigits) +// Draw a slider. Set fracdigits negative to not display the current value numerically. +static void M_DrawSlider (int x, int y, double min, double max, double cur,int fracdigits) { double range; @@ -1591,7 +1592,7 @@ void M_DrawSlider (int x, int y, double min, double max, double cur,int fracdigi { char textbuf[16]; mysnprintf(textbuf, countof(textbuf), "%.*f", fracdigits, cur); - screen->DrawText(SmallFont, CR_DARKGRAY, x + 12*8 + 4, y, textbuf, DTA_Clean, true, TAG_DONE); + screen->DrawText(SmallFont, CR_DARKGRAY, x + (12*8 + 4) * CleanXfac_1, y, textbuf, DTA_CleanNoMove_1, true, TAG_DONE); } } @@ -1662,6 +1663,7 @@ void M_OptDrawer () DWORD overlay; int labelofs; int indent; + int cursorspace; if (!CurrentMenu->DontDim) { @@ -1682,9 +1684,9 @@ void M_OptDrawer () if (BigFont && CurrentMenu->texttitle) { screen->DrawText (BigFont, gameinfo.gametype & GAME_DoomChex ? CR_RED : CR_UNTRANSLATED, - 160-BigFont->StringWidth (CurrentMenu->texttitle)/2, 10, - CurrentMenu->texttitle, DTA_Clean, true, TAG_DONE); - y = 15 + BigFont->GetHeight (); + (screen->GetWidth() - BigFont->StringWidth(CurrentMenu->texttitle) * CleanXfac_1) / 2, 10*CleanYfac_1, + CurrentMenu->texttitle, DTA_CleanNoMove_1, true, TAG_DONE); + y = 15 + BigFont->GetHeight(); } else { @@ -1693,7 +1695,7 @@ void M_OptDrawer () } if (gameinfo.gametype & GAME_Raven) { - labelofs = 2; + labelofs = 2 * CleanXfac_1; y -= 2; fontheight = 9; } @@ -1702,9 +1704,13 @@ void M_OptDrawer () labelofs = 0; fontheight = 8; } - ytop = y + CurrentMenu->scrolltop * 8; + cursorspace = 14 * CleanXfac_1; + y *= CleanYfac_1; + fontheight *= CleanYfac_1; + ytop = y + CurrentMenu->scrolltop * 8 * CleanYfac_1; + int lastrow = screen->GetHeight() - SmallFont->GetHeight() * CleanYfac_1; - for (i = 0; i < CurrentMenu->numitems && y <= 200 - SmallFont->GetHeight(); i++, y += fontheight) + for (i = 0; i < CurrentMenu->numitems && y <= lastrow; i++, y += fontheight) { if (i == CurrentMenu->scrolltop) { @@ -1715,15 +1721,30 @@ void M_OptDrawer () overlay = 0; if (item->type == discrete && item->c.discretecenter == 1) { - indent = 160; + indent = screen->GetWidth() / 2; } else if (item->type == joymore) { - indent = 4; + indent = 4 * CleanXfac_1; } else { indent = CurrentMenu->indent; + if (indent > 280) + { // kludge for the compatibility options with their extremely long labels + if (indent + 40 <= CleanWidth_1) + { + indent = (screen->GetWidth() - ((indent + 40) * CleanXfac_1)) / 2 + indent * CleanXfac_1; + } + else + { + indent = screen->GetWidth() - 40 * CleanXfac_1; + } + } + else + { + indent = (indent - 160) * CleanXfac_1 + screen->GetWidth() / 2; + } } if (item->type != screenres) @@ -1746,7 +1767,7 @@ void M_OptDrawer () label = somestring; } } - width = SmallFont->StringWidth(label); + width = SmallFont->StringWidth(label) * CleanXfac_1; switch (item->type) { case more: @@ -1756,34 +1777,34 @@ void M_OptDrawer () break; case joymore: - x = 20; + x = 20 * CleanXfac_1; color = MoreColor; break; case numberedmore: case rsafemore: case rightmore: - x = indent + 14; + x = indent + cursorspace; color = item->type != rightmore ? CR_GREEN : MoreColor; break; case redtext: - x = 160 - width / 2; + x = screen->GetWidth() / 2 - width / 2; color = LabelColor; break; case whitetext: - x = 160 - width / 2; + x = screen->GetWidth() / 2 - width / 2; color = CR_GOLD;//ValueColor; break; case listelement: - x = indent + 14; + x = indent + cursorspace; color = LabelColor; break; case colorpicker: - x = indent + 14; + x = indent + cursorspace; color = MoreColor; break; @@ -1800,7 +1821,7 @@ void M_OptDrawer () ? CR_YELLOW : LabelColor; break; } - screen->DrawText (SmallFont, color, x, y, label, DTA_Clean, true, DTA_ColorOverlay, overlay, TAG_DONE); + screen->DrawText (SmallFont, color, x, y, label, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE); switch (item->type) { @@ -1810,8 +1831,8 @@ void M_OptDrawer () char tbuf[16]; mysnprintf (tbuf, countof(tbuf), "%d.", item->b.position); - x = indent - SmallFont->StringWidth (tbuf); - screen->DrawText (SmallFont, CR_GREY, x, y, tbuf, DTA_Clean, true, TAG_DONE); + x = indent - SmallFont->StringWidth (tbuf) * CleanXfac_1; + screen->DrawText (SmallFont, CR_GREY, x, y, tbuf, DTA_CleanNoMove_1, true, TAG_DONE); } break; @@ -1827,14 +1848,14 @@ void M_OptDrawer () if (v == vals) { - screen->DrawText (SmallFont, ValueColor, indent + 14, y, "Unknown", - DTA_Clean, true, TAG_DONE); + screen->DrawText (SmallFont, ValueColor, indent + cursorspace, y, "Unknown", + DTA_CleanNoMove_1, true, TAG_DONE); } else { screen->DrawText (SmallFont, item->type == cdiscrete ? v : ValueColor, - indent + 14, y, item->e.values[v].name, - DTA_Clean, true, TAG_DONE); + indent + cursorspace, y, item->e.values[v].name, + DTA_CleanNoMove_1, true, TAG_DONE); } } @@ -1884,15 +1905,15 @@ void M_OptDrawer () if (v == vals) { - screen->DrawText (SmallFont, ValueColor, indent + 14, y, "Unknown", - DTA_Clean, true, DTA_ColorOverlay, overlay, TAG_DONE); + screen->DrawText (SmallFont, ValueColor, indent + cursorspace, y, "Unknown", + DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE); } else { screen->DrawText (SmallFont, item->type == cdiscrete ? v : ValueColor, - indent + 14, y, + indent + cursorspace, y, item->type != discretes ? item->e.values[v].name : item->e.valuestrings[v].name.GetChars(), - DTA_Clean, true, DTA_ColorOverlay, overlay, TAG_DONE); + DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE); } } @@ -1904,18 +1925,18 @@ void M_OptDrawer () value = item->a.cvar->GetGenericRep (CVAR_String); v = M_FindCurVal(value.String, item->e.enumvalues, (int)item->b.numvalues); - screen->DrawText(SmallFont, ValueColor, indent + 14, y, v, DTA_Clean, true, TAG_DONE); + screen->DrawText(SmallFont, ValueColor, indent + cursorspace, y, v, DTA_CleanNoMove_1, true, TAG_DONE); } break; case nochoice: - screen->DrawText (SmallFont, CR_GOLD, indent + 14, y, - (item->e.values[(int)item->b.min]).name, DTA_Clean, true, TAG_DONE); + screen->DrawText (SmallFont, CR_GOLD, indent + cursorspace, y, + (item->e.values[(int)item->b.min]).name, DTA_CleanNoMove_1, true, TAG_DONE); break; case joy_sens: value.Float = SELECTED_JOYSTICK->GetSensitivity(); - M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, value.Float, 1); + M_DrawSlider (indent + cursorspace, y + labelofs, item->b.min, item->c.max, value.Float, 1); break; case joy_slider: @@ -1928,29 +1949,29 @@ void M_OptDrawer () assert(item->e.joyslidernum == 1); value.Float = SELECTED_JOYSTICK->GetAxisDeadZone(item->a.joyselection); } - M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, fabs(value.Float), 3); + M_DrawSlider (indent + cursorspace, y + labelofs, item->b.min, item->c.max, fabs(value.Float), 3); break; case joy_inverter: assert(item->e.joyslidernum == 0); value.Float = SELECTED_JOYSTICK->GetAxisScale(item->a.joyselection); - screen->DrawText(SmallFont, ValueColor, indent + 14, y, + screen->DrawText(SmallFont, ValueColor, indent + cursorspace, y, (value.Float < 0) ? "Yes" : "No", - DTA_Clean, true, TAG_DONE); + DTA_CleanNoMove_1, true, TAG_DONE); break; case slider: value = item->a.cvar->GetGenericRep (CVAR_Float); - M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, value.Float, 1); + M_DrawSlider (indent + cursorspace, y + labelofs, item->b.min, item->c.max, value.Float, 1); break; case absslider: value = item->a.cvar->GetGenericRep (CVAR_Float); - M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, fabs(value.Float), 1); + M_DrawSlider (indent + cursorspace, y + labelofs, item->b.min, item->c.max, fabs(value.Float), 1); break; case intslider: - M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, item->a.fval, 0); + M_DrawSlider (indent + cursorspace, y + labelofs, item->b.min, item->c.max, item->a.fval, 0); break; case control: @@ -1960,12 +1981,12 @@ void M_OptDrawer () C_NameKeys (description, item->b.key1, item->c.key2); if (description[0]) { - M_DrawConText(CR_WHITE, indent + 14, y-1+labelofs, description); + M_DrawConText(CR_WHITE, indent + cursorspace, y-1+labelofs, description); } else { - screen->DrawText(SmallFont, CR_BLACK, indent + 14, y + labelofs, "---", - DTA_Clean, true, TAG_DONE); + screen->DrawText(SmallFont, CR_BLACK, indent + cursorspace, y + labelofs, "---", + DTA_CleanNoMove_1, true, TAG_DONE); } } break; @@ -1973,9 +1994,9 @@ void M_OptDrawer () case colorpicker: { int box_x, box_y; - box_x = (indent - 35 - 160) * CleanXfac + screen->GetWidth()/2; - box_y = (y - ((gameinfo.gametype & GAME_Raven) ? 99 : 100)) * CleanYfac + screen->GetHeight()/2; - screen->Clear (box_x, box_y, box_x + 32*CleanXfac, box_y + (fontheight-1)*CleanYfac, + box_x = indent - 35 * CleanXfac_1; + box_y = (gameinfo.gametype & GAME_Raven) ? y - CleanYfac_1 : y; + screen->Clear (box_x, box_y, box_x + 32*CleanXfac_1, box_y + fontheight-CleanYfac_1, item->a.colorcvar->GetIndex(), 0); } break; @@ -1984,12 +2005,12 @@ void M_OptDrawer () { int box_x, box_y; int x1, p; - const int w = fontheight*CleanXfac; - const int h = fontheight*CleanYfac; + const int w = fontheight; + const int h = fontheight; - box_y = (y - 98) * CleanYfac + screen->GetHeight()/2; + box_y = y - 2 * CleanYfac_1; p = 0; - box_x = (indent - 32 - 160) * CleanXfac + screen->GetWidth()/2; + box_x = indent - 32 * CleanXfac_1; for (x1 = 0, p = int(item->b.min * 16); x1 < 16; ++p, ++x1) { screen->Clear (box_x, box_y, box_x + w, box_y + h, p, 0); @@ -2044,7 +2065,7 @@ void M_OptDrawer () } screen->DrawText (SmallFont, ValueColor, - indent + 14, y, str, DTA_Clean, true, TAG_DONE); + indent + cursorspace, y, str, DTA_CleanNoMove_1, true, TAG_DONE); } break; @@ -2056,12 +2077,13 @@ void M_OptDrawer () i == CurrentItem && (skullAnimCounter < 6 || menuactive == MENU_WaitKey)) { - M_DrawConText(CR_RED, indent + 3, y-1+labelofs, "\xd"); + M_DrawConText(CR_RED, indent + 3 * CleanXfac_1, y-CleanYfac_1+labelofs, "\xd"); } } else { char *str = NULL; + int colwidth = screen->GetWidth() / 3; for (x = 0; x < 3; x++) { @@ -2078,13 +2100,13 @@ void M_OptDrawer () else color = CR_BRICK; //LabelColor; - screen->DrawText (SmallFont, color, 104 * x + 20, y, str, DTA_Clean, true, TAG_DONE); + screen->DrawText (SmallFont, color, colwidth * x + 20 * CleanXfac_1, y, str, DTA_CleanNoMove_1, true, TAG_DONE); } } if (i == CurrentItem && ((item->a.selmode != -1 && (skullAnimCounter < 6 || menuactive == MENU_WaitKey)) || testingmode)) { - M_DrawConText(CR_RED, item->a.selmode * 104 + 8, y-1 + labelofs, "\xd"); + M_DrawConText(CR_RED, item->a.selmode * colwidth + 8 * CleanXfac_1, y - CleanYfac_1 + labelofs, "\xd"); } } } @@ -2095,11 +2117,11 @@ void M_OptDrawer () if (CanScrollUp) { - M_DrawConText(CR_ORANGE, 3, ytop + labelofs, "\x1a"); + M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, ytop + labelofs, "\x1a"); } if (CanScrollDown) { - M_DrawConText(CR_ORANGE, 3, y - 8 + labelofs, "\x1b"); + M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, y - 8*CleanYfac_1 + labelofs, "\x1b"); } if (flagsvar) @@ -2122,8 +2144,8 @@ void M_OptDrawer () } } screen->DrawText (SmallFont, ValueColor, - 160 - (SmallFont->StringWidth (flagsblah) >> 1), 0, flagsblah, - DTA_Clean, true, TAG_DONE); + (screen->GetWidth() - SmallFont->StringWidth (flagsblah) * CleanXfac_1) / 2, 0, flagsblah, + DTA_CleanNoMove_1, true, TAG_DONE); } } @@ -2276,31 +2298,33 @@ void M_OptButtonHandler(EMenuKey key, bool repeat) } if (CurrentItem < 0) { - int maxitems, rowheight; + int ytop, maxitems, rowheight; // Figure out how many lines of text fit on the menu if (CurrentMenu->y != 0) { - maxitems = CurrentMenu->y; + ytop = CurrentMenu->y; } else if (BigFont && CurrentMenu->texttitle) { - maxitems = 15 + BigFont->GetHeight (); + ytop = 15 + BigFont->GetHeight (); } else { - maxitems = 15; + ytop = 15; } if (!(gameinfo.gametype & GAME_DoomChex)) { - maxitems -= 2; + ytop -= 2; rowheight = 9; } else { rowheight = 8; } - maxitems = (200 - SmallFont->GetHeight () - maxitems) / rowheight + 1; + ytop *= CleanYfac_1; + rowheight *= CleanYfac_1; + maxitems = (screen->GetHeight() - SmallFont->GetHeight() - ytop) / rowheight + 1; CurrentMenu->scrollpos = MAX (0,CurrentMenu->numitems - maxitems + CurrentMenu->scrolltop); CurrentItem = CurrentMenu->numitems - 1; @@ -3008,16 +3032,16 @@ static void ColorPickerDrawer () DWORD oldColor = DWORD(*ColorPickerItems[0].a.colorcvar) | 0xFF000000; int x = screen->GetWidth()*2/3; - int y = (15 + BigFont->GetHeight() + SmallFont->GetHeight()*5 - 90) * CleanYfac + screen->GetHeight()/2; + int y = (15 + BigFont->GetHeight() + SmallFont->GetHeight()*5 - 10) * CleanYfac_1; - screen->Clear (x, y, x + 48*CleanXfac, y + 48*CleanYfac, -1, oldColor); - screen->Clear (x + 48*CleanXfac, y, x + 48*2*CleanXfac, y + 48*CleanYfac, -1, newColor); + screen->Clear (x, y, x + 48*CleanXfac_1, y + 48*CleanYfac_1, -1, oldColor); + screen->Clear (x + 48*CleanXfac_1, y, x + 48*2*CleanXfac_1, y + 48*CleanYfac_1, -1, newColor); - y += 49*CleanYfac; - screen->DrawText (SmallFont, CR_GRAY, x+(24-SmallFont->StringWidth("Old")/2)*CleanXfac, y, - "Old", DTA_CleanNoMove, true, TAG_DONE); - screen->DrawText (SmallFont, CR_WHITE, x+(48+24-SmallFont->StringWidth("New")/2)*CleanXfac, y, - "New", DTA_CleanNoMove, true, TAG_DONE); + y += 49*CleanYfac_1; + screen->DrawText (SmallFont, CR_GRAY, x+(24-SmallFont->StringWidth("Old")/2)*CleanXfac_1, y, + "Old", DTA_CleanNoMove_1, true, TAG_DONE); + screen->DrawText (SmallFont, CR_WHITE, x+(48+24-SmallFont->StringWidth("New")/2)*CleanXfac_1, y, + "New", DTA_CleanNoMove_1, true, TAG_DONE); } static void SetColorPickerSliders () @@ -3118,11 +3142,12 @@ static void DrawJoystickConfigMenuHeader() { FString joyname = SELECTED_JOYSTICK->GetName(); screen->DrawText(BigFont, gameinfo.gametype & GAME_DoomChex ? CR_RED : CR_UNTRANSLATED, - 160-BigFont->StringWidth(CurrentMenu->texttitle)/2, 5, - CurrentMenu->texttitle, DTA_Clean, true, TAG_DONE); + (screen->GetWidth() - BigFont->StringWidth(CurrentMenu->texttitle) * CleanXfac_1) / 2, + 5 * CleanYfac_1, + CurrentMenu->texttitle, DTA_CleanNoMove_1, true, TAG_DONE); screen->DrawText(SmallFont, gameinfo.gametype & GAME_DoomChex ? CR_RED : CR_UNTRANSLATED, - 160-SmallFont->StringWidth(joyname)/2, 8 + BigFont->GetHeight(), - joyname, DTA_Clean, true, TAG_DONE); + (screen->GetWidth() - SmallFont->StringWidth(joyname) * CleanXfac_1) / 2, (8 + BigFont->GetHeight()) * CleanYfac_1, + joyname, DTA_CleanNoMove_1, true, TAG_DONE); } static void UpdateJoystickConfigMenu(IJoystickConfig *joy) diff --git a/src/p_ceiling.cpp b/src/p_ceiling.cpp index 12f957b4..4dd072a0 100644 --- a/src/p_ceiling.cpp +++ b/src/p_ceiling.cpp @@ -112,7 +112,7 @@ void DCeiling::Tick () m_Sector->SetTexture(sector_t::ceiling, m_Texture); // fall through default: - SN_StopSequence (m_Sector); + SN_StopSequence (m_Sector, CHAN_CEILING); Destroy (); break; } @@ -145,7 +145,7 @@ void DCeiling::Tick () m_Sector->SetTexture(sector_t::ceiling, m_Texture); // fall through default: - SN_StopSequence (m_Sector); + SN_StopSequence (m_Sector, CHAN_CEILING); Destroy (); break; } @@ -500,7 +500,7 @@ bool EV_CeilingCrushStop (int tag) { if (scan->m_Tag == tag && scan->m_Direction != 0) { - SN_StopSequence (scan->m_Sector); + SN_StopSequence (scan->m_Sector, CHAN_CEILING); scan->m_OldDirection = scan->m_Direction; scan->m_Direction = 0; // in-stasis; rtn = true; diff --git a/src/p_doors.cpp b/src/p_doors.cpp index c77ded90..78fb9e57 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -133,7 +133,7 @@ void DDoor::Tick () if (res == pastdest) { - SN_StopSequence (m_Sector); + SN_StopSequence (m_Sector, CHAN_CEILING); switch (m_Type) { case doorRaise: @@ -179,7 +179,7 @@ void DDoor::Tick () if (res == pastdest) { - SN_StopSequence (m_Sector); + SN_StopSequence (m_Sector, CHAN_CEILING); switch (m_Type) { case doorRaise: diff --git a/src/p_enemy.h b/src/p_enemy.h index a7386ccf..ce5703e7 100644 --- a/src/p_enemy.h +++ b/src/p_enemy.h @@ -54,6 +54,7 @@ void P_NewChaseDir (AActor *actor); AInventory *P_DropItem (AActor *source, const PClass *type, int special, int chance); void P_TossItem (AActor *item); bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params); +void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdist); DECLARE_ACTION(A_Look) DECLARE_ACTION(A_Wander) diff --git a/src/p_floor.cpp b/src/p_floor.cpp index 0b9a634e..984a0f06 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -126,7 +126,7 @@ void DFloor::Tick () if (res == pastdest) { - SN_StopSequence (m_Sector); + SN_StopSequence (m_Sector, CHAN_FLOOR); if (m_Type == buildStair) m_Type = waitStair; @@ -530,7 +530,7 @@ bool EV_FloorCrushStop (int tag) if (sec->floordata && sec->floordata->IsKindOf (RUNTIME_CLASS(DFloor)) && barrier_cast(sec->floordata)->m_Type == DFloor::floorRaiseAndCrush) { - SN_StopSequence (sec); + SN_StopSequence (sec, CHAN_FLOOR); sec->floordata->Destroy (); sec->floordata = NULL; } @@ -959,7 +959,7 @@ void DElevator::Tick () if (res == pastdest) // if destination height acheived { // make floor stop sound - SN_StopSequence (m_Sector); + SN_StopSequence (m_Sector, CHAN_FLOOR); m_Sector->floordata = NULL; //jff 2/22/98 m_Sector->ceilingdata = NULL; //jff 2/22/98 diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 3b1521f8..075d978b 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -396,6 +396,8 @@ void AActor::Die (AActor *source, AActor *inflictor) // be revived by an Arch-Vile. Batman Doom needs this. flags |= MF_CORPSE; } + flags6 |= MF6_KILLED; + // [RH] Allow the death height to be overridden using metadata. fixed_t metaheight = 0; if (DamageType == NAME_Fire) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index c0f8af6e..496bd758 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -312,13 +312,34 @@ void AActor::Serialize (FArchive &arc) { arc << DamageFactor; } - if (SaveVersion >= 2036) + if (SaveVersion > 2036) { - arc << weaveindex; + arc << WeaveIndexXY << WeaveIndexZ; } else { - weaveindex = special2; + int index; + + if (SaveVersion < 2036) + { + index = special2; + } + else + { + arc << index; + } + // A_BishopMissileWeave and A_CStaffMissileSlither stored the weaveXY + // value in different parts of the index. + if (this->IsKindOf(PClass::FindClass("BishopFX"))) + { + WeaveIndexXY = index >> 16; + WeaveIndexZ = index; + } + else + { + WeaveIndexXY = index; + WeaveIndexZ = 0; + } } // Skip past uservar array in old savegames diff --git a/src/p_pillar.cpp b/src/p_pillar.cpp index f20dc1ef..1d2d5ba8 100644 --- a/src/p_pillar.cpp +++ b/src/p_pillar.cpp @@ -98,7 +98,7 @@ void DPillar::Tick () if (r == pastdest && s == pastdest) { - SN_StopSequence (m_Sector); + SN_StopSequence (m_Sector, CHAN_FLOOR); Destroy (); } else diff --git a/src/p_plats.cpp b/src/p_plats.cpp index 962447e4..87d9e673 100644 --- a/src/p_plats.cpp +++ b/src/p_plats.cpp @@ -82,7 +82,7 @@ void DPlat::Tick () } else if (res == pastdest) { - SN_StopSequence (m_Sector); + SN_StopSequence (m_Sector, CHAN_FLOOR); if (m_Type != platToggle) { m_Count = m_Wait; @@ -121,7 +121,7 @@ void DPlat::Tick () if (res == pastdest) { - SN_StopSequence (m_Sector); + SN_StopSequence (m_Sector, CHAN_FLOOR); // if not an instant toggle, start waiting if (m_Type != platToggle) //jff 3/14/98 toggle up down { // is silent, instant, no waiting diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index dd97f075..ed60a8dc 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -244,6 +244,8 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name) // needs to come from the save for bots. userinfo_t uibackup = dst->userinfo; int chasecam = dst->cheats & CF_CHASECAM; // Remember the chasecam setting + bool attackdown = dst->attackdown; + bool usedown = dst->usedown; *dst = *src; dst->cheats |= chasecam; @@ -270,6 +272,9 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name) { dst->mo->player = dst; } + // These 2 variables may not be overwritten. + dst->attackdown = attackdown; + dst->usedown = usedown; } static void SpawnExtraPlayers () diff --git a/src/p_things.cpp b/src/p_things.cpp index 0b166cdc..109b2d69 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -466,6 +466,8 @@ bool P_Thing_Raise(AActor *thing) thing->flags2 = info->flags2; thing->flags3 = info->flags3; thing->flags4 = info->flags4; + thing->flags5 = info->flags5; + thing->flags6 = info->flags6; thing->health = info->health; thing->target = NULL; thing->lastenemy = NULL; diff --git a/src/p_user.cpp b/src/p_user.cpp index 82914b1f..9146b2bb 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -222,6 +222,7 @@ player_t::player_t() centering(0), turnticks(0), attackdown(0), + usedown(0), oldbuttons(0), health(0), inventorytics(0), @@ -1399,10 +1400,12 @@ void P_CheckPlayerSprites() { int crouchspriteno; fixed_t defscaleY = mo->GetDefault()->scaleY; + fixed_t defscaleX = mo->GetDefault()->scaleX; - if (player->userinfo.skin != 0) + if (player->userinfo.skin != 0 && !(player->mo->flags4 & MF4_NOSKIN)) { defscaleY = skins[player->userinfo.skin].ScaleY; + defscaleX = skins[player->userinfo.skin].ScaleX; } // Set the crouch sprite @@ -1413,8 +1416,9 @@ void P_CheckPlayerSprites() { crouchspriteno = mo->crouchsprite; } - else if (mo->sprite == skins[player->userinfo.skin].sprite || - mo->sprite == skins[player->userinfo.skin].crouchsprite) + else if (!(player->mo->flags4 & MF4_NOSKIN) && + (mo->sprite == skins[player->userinfo.skin].sprite || + mo->sprite == skins[player->userinfo.skin].crouchsprite)) { crouchspriteno = skins[player->userinfo.skin].crouchsprite; } @@ -1446,6 +1450,7 @@ void P_CheckPlayerSprites() } mo->scaleY = defscaleY; } + mo->scaleX = defscaleX; } } } @@ -2283,10 +2288,15 @@ void P_PlayerThink (player_t *player) } } // check for use - if ((cmd->ucmd.buttons & BT_USE) && !(player->oldbuttons & BT_USE)) + if ((cmd->ucmd.buttons & BT_USE) && !player->usedown) { + player->usedown = true; P_UseLines (player); } + else + { + player->usedown = false; + } // Morph counter if (player->morphTics) { diff --git a/src/s_sndseq.cpp b/src/s_sndseq.cpp index ecfed124..93474ae1 100644 --- a/src/s_sndseq.cpp +++ b/src/s_sndseq.cpp @@ -849,7 +849,7 @@ DSeqNode *SN_StartSequence (sector_t *sector, int chan, int sequence, seqtype_t { if (!nostop) { - SN_StopSequence (sector); + SN_StopSequence (sector, chan); } if (TwiddleSeqNum (sequence, type)) { @@ -963,9 +963,23 @@ void SN_StopSequence (AActor *actor) SN_DoStop (actor); } -void SN_StopSequence (sector_t *sector) +void SN_StopSequence (sector_t *sector, int chan) { - SN_DoStop (sector); + DSeqNode *node; + + for (node = DSeqNode::FirstSequence(); node; ) + { + DSeqNode *next = node->NextSequence(); + if (node->Source() == sector) + { + assert(node->IsKindOf(RUNTIME_CLASS(DSeqSectorNode))); + if ((static_cast(node)->Channel & 7) == chan) + { + node->StopAndDestroy (); + } + } + node = next; + } } void SN_StopSequence (FPolyObj *poly) diff --git a/src/s_sndseq.h b/src/s_sndseq.h index e5401007..434dccb6 100644 --- a/src/s_sndseq.h +++ b/src/s_sndseq.h @@ -86,7 +86,7 @@ DSeqNode *SN_StartSequence (sector_t *sec, int chan, FName seqname, int modenum) DSeqNode *SN_StartSequence (FPolyObj *poly, int sequence, seqtype_t type, int modenum, bool nostop=false); DSeqNode *SN_StartSequence (FPolyObj *poly, const char *name, int modenum); void SN_StopSequence (AActor *mobj); -void SN_StopSequence (sector_t *sector); +void SN_StopSequence (sector_t *sector, int chan); void SN_StopSequence (FPolyObj *poly); void SN_UpdateActiveSequences (void); ptrdiff_t SN_GetSequenceOffset (int sequence, SDWORD *sequencePtr); diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 4fbef6ae..8e5284f4 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -2306,7 +2306,10 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force) } } - if (!mus_playing.name.IsEmpty() && stricmp (mus_playing.name, musicname) == 0) + if (!mus_playing.name.IsEmpty() && + mus_playing.handle != NULL && + stricmp (mus_playing.name, musicname) == 0 && + mus_playing.handle->m_Looping == looping) { if (order != mus_playing.baseorder) { diff --git a/src/svnrevision.h b/src/svnrevision.h index 25357a8d..19d440f6 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 "2037" -#define ZD_SVN_REVISION_NUMBER 2037 +#define ZD_SVN_REVISION_STRING "2047" +#define ZD_SVN_REVISION_NUMBER 2047 diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 1c00e7ae..2c3d3fe6 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -3019,6 +3019,58 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Quake) P_StartQuake(self, 0, intensity, duration, damrad, tremrad, sound); } +//=========================================================================== +// +// A_Weave +// +//=========================================================================== + +void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdist) +{ + fixed_t newX, newY; + int weaveXY, weaveZ; + int angle; + fixed_t dist; + + weaveXY = self->WeaveIndexXY & 63; + weaveZ = self->WeaveIndexZ & 63; + angle = (self->angle + ANG90) >> ANGLETOFINESHIFT; + + if (xydist != 0 && xyspeed != 0) + { + dist = FixedMul(FloatBobOffsets[weaveXY], xydist); + newX = self->x - FixedMul (finecosine[angle], dist); + newY = self->y - FixedMul (finesine[angle], dist); + weaveXY = (weaveXY + xyspeed) & 63; + dist = FixedMul(FloatBobOffsets[weaveXY], xydist); + newX += FixedMul (finecosine[angle], dist); + newY += FixedMul (finesine[angle], dist); + P_TryMove (self, newX, newY, true); + self->WeaveIndexXY = weaveXY; + } + + if (zdist != 0 && zspeed != 0) + { + self->z -= FixedMul(FloatBobOffsets[weaveZ], zdist); + weaveZ = (weaveZ + zspeed) & 63; + self->z += FixedMul(FloatBobOffsets[weaveZ], zdist); + self->WeaveIndexZ = weaveZ; + } +} + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Weave) +{ + ACTION_PARAM_START(4); + ACTION_PARAM_INT(xspeed, 0); + ACTION_PARAM_INT(yspeed, 1); + ACTION_PARAM_FIXED(xdist, 2); + ACTION_PARAM_FIXED(ydist, 3); + A_Weave(self, xspeed, yspeed, xdist, ydist); +} + + + + //=========================================================================== // // A_LineEffect diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index e8b17088..cd2537db 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -905,10 +905,19 @@ DEFINE_PROPERTY(bouncecount, I, Actor) //========================================================================== // //========================================================================== -DEFINE_PROPERTY(weaveindex, I, Actor) +DEFINE_PROPERTY(weaveindexXY, I, Actor) { PROP_INT_PARM(id, 0); - defaults->weaveindex = id; + defaults->WeaveIndexXY = id; +} + +//========================================================================== +// +//========================================================================== +DEFINE_PROPERTY(weaveindexZ, I, Actor) +{ + PROP_INT_PARM(id, 0); + defaults->WeaveIndexZ = id; } //========================================================================== diff --git a/src/v_draw.cpp b/src/v_draw.cpp index e6ff521c..e46a99d1 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -59,6 +59,9 @@ int CleanXfac, CleanYfac; // [RH] Effective screen sizes that the above scale values give you int CleanWidth, CleanHeight; +// Above minus 1 (or 1, if they are already 1) +int CleanXfac_1, CleanYfac_1, CleanWidth_1, CleanHeight_1; + CVAR (Bool, hud_scale, false, CVAR_ARCHIVE); // For routines that take RGB colors, cache the previous lookup in case there @@ -425,6 +428,15 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag } break; + case DTA_CleanNoMove_1: + boolval = va_arg(tags, INTBOOL); + if (boolval) + { + parms->destwidth = parms->texwidth * CleanXfac_1; + parms->destheight = parms->texheight * CleanYfac_1; + } + break; + case DTA_320x200: boolval = va_arg(tags, INTBOOL); if (boolval) diff --git a/src/v_text.cpp b/src/v_text.cpp index 2c758d5f..be386e99 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -156,13 +156,23 @@ void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, c ptrval = va_arg (tags, void*); break; + case DTA_CleanNoMove_1: + boolval = va_arg (tags, INTBOOL); + if (boolval) + { + scalex = CleanXfac_1; + scaley = CleanYfac_1; + maxwidth = Width - (Width % scalex); + } + break; + case DTA_CleanNoMove: boolval = va_arg (tags, INTBOOL); if (boolval) { scalex = CleanXfac; scaley = CleanYfac; - maxwidth = Width - (Width % CleanYfac); + maxwidth = Width - (Width % scalex); } break; diff --git a/src/v_video.cpp b/src/v_video.cpp index d8187eb9..fa1f090d 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1398,6 +1398,11 @@ bool V_DoModeSetup (int width, int height, int bits) assert(CleanWidth >= 320); assert(CleanHeight >= 200); + CleanXfac_1 = MAX(CleanXfac - 1, 1); + CleanYfac_1 = MAX(CleanYfac - 1, 1); + CleanWidth_1 = width / CleanXfac_1; + CleanHeight_1 = height / CleanYfac_1; + DisplayWidth = width; DisplayHeight = height; DisplayBits = bits; diff --git a/src/v_video.h b/src/v_video.h index e722c62d..6beaeea7 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -42,6 +42,7 @@ #include "c_cvars.h" extern int CleanWidth, CleanHeight, CleanXfac, CleanYfac; +extern int CleanWidth_1, CleanHeight_1, CleanXfac_1, CleanYfac_1; extern int DisplayWidth, DisplayHeight, DisplayBits; bool V_DoModeSetup (int width, int height, int bits); @@ -79,6 +80,7 @@ enum DTA_320x200, // bool: scale texture size and position to fit on a virtual 320x200 screen DTA_Bottom320x200, // bool: same as DTA_320x200 but centers virtual screen on bottom for 1280x1024 targets DTA_CleanNoMove, // bool: like DTA_Clean but does not reposition output position + DTA_CleanNoMove_1, // bool: like DTA_CleanNoMove, but uses Clean[XY]fac_1 instead DTA_FlipX, // bool: flip image horizontally //FIXME: Does not work with DTA_Window(Left|Right) DTA_ShadowColor, // color of shadow DTA_ShadowAlpha, // alpha of shadow diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 71c0790d..90a592c3 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -19,7 +19,8 @@ ACTOR Actor native //: Thinker Gravity 1 DamageFactor 1.0 PushFactor 0.25 - WeaveIndex -1 + WeaveIndexXY 0 + WeaveIndexZ 16 // Variables for the expression evaluator // NOTE: fixed_t and angle_t are only used here to ensure proper conversion @@ -221,6 +222,7 @@ ACTOR Actor native //: Thinker action native A_PlayerSkinCheck(state label); action native A_BasicAttack(int meleedamage, sound meleesound, class missiletype, float missileheight); action native A_ThrowGrenade(class itemtype, float zheight = 0, float xyvel = 0, float zvel = 0, bool useammo = true); + action native A_Weave(int xspeed, int yspeed, float xdist, float ydist); action native A_Recoil(float xyvel); action native A_JumpIfInTargetInventory(class itemtype, int amount, state label);