diff --git a/src/actionspecials.h b/src/actionspecials.h index eee1c958..a1d34a54 100644 --- a/src/actionspecials.h +++ b/src/actionspecials.h @@ -146,6 +146,7 @@ DEFINE_SPECIAL(Sector_Set3DFloor, 160, -1, -1, 5) DEFINE_SPECIAL(Sector_SetContents, 161, -1, -1, 3) // [RH] Begin new specials for ZDoom +DEFINE_SPECIAL(Ceiling_CrushAndRaiseDist, 168, 3, 5, 5) DEFINE_SPECIAL(Generic_Crusher2, 169, 5, 5, 5) DEFINE_SPECIAL(Sector_SetCeilingScale2, 170, 3, 3, 3) DEFINE_SPECIAL(Sector_SetFloorScale2, 171, 3, 3, 3) diff --git a/src/d_net.cpp b/src/d_net.cpp index 3ee20b8b..0af22bf7 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2353,9 +2353,10 @@ void Net_DoCommand (int type, BYTE **stream, int player) case DEM_CROUCH: if (gamestate == GS_LEVEL && players[player].mo != NULL && - players[player].health > 0 && !(players[player].oldbuttons & BT_JUMP)) + players[player].health > 0 && !(players[player].oldbuttons & BT_JUMP) && + !P_IsPlayerTotallyFrozen(&players[player])) { - players[player].crouching = players[player].crouchdir<0? 1 : -1; + players[player].crouching = players[player].crouchdir < 0 ? 1 : -1; } break; diff --git a/src/d_player.h b/src/d_player.h index abd46359..2b9c7b2f 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -426,6 +426,8 @@ void P_CheckPlayerSprites(); #define CROUCHSPEED (FRACUNIT/12) +bool P_IsPlayerTotallyFrozen(const player_t *player); + // [GRB] Custom player classes enum { diff --git a/src/menu/menu.h b/src/menu/menu.h index 8a484b7b..55884ab8 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -671,6 +671,7 @@ void M_ActivateMenu(DMenu *menu); void M_ClearMenus (); void M_ParseMenuDefs(); void M_StartupSkillMenu(FGameStartup *gs); +int M_GetDefaultSkill(); void M_StartControlPanel (bool makeSound); void M_SetMenu(FName menu, int param = -1); void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave); diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index f413a947..25d859ea 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -1235,7 +1235,7 @@ void M_CreateMenus() //============================================================================= // -// THe skill menu must be refeshed each time it starts up +// The skill menu must be refeshed each time it starts up // //============================================================================= extern int restart; @@ -1320,8 +1320,8 @@ void M_StartupSkillMenu(FGameStartup *gs) FSkillInfo &skill = AllSkills[i]; FListMenuItem *li; // Using a different name for skills that must be confirmed makes handling this easier. - FName action = skill.MustConfirm? NAME_StartgameConfirm : NAME_Startgame; - + FName action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ? + NAME_StartgameConfirm : NAME_Startgame; FString *pItemText = NULL; if (gs->PlayerClass != NULL) { @@ -1345,7 +1345,7 @@ void M_StartupSkillMenu(FGameStartup *gs) } if (AllEpisodes[gs->Episode].mNoSkill || AllSkills.Size() == 1) { - ld->mAutoselect = firstitem + MIN(2u, AllSkills.Size()-1); + ld->mAutoselect = firstitem + M_GetDefaultSkill(); } else { @@ -1388,7 +1388,8 @@ fail: FSkillInfo &skill = AllSkills[i]; FOptionMenuItem *li; // Using a different name for skills that must be confirmed makes handling this easier. - const char *action = skill.MustConfirm? "StartgameConfirm" : "Startgame"; + const char *action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ? + "StartgameConfirm" : "Startgame"; FString *pItemText = NULL; if (gs->PlayerClass != NULL) @@ -1400,12 +1401,23 @@ fail: if (!done) { done = true; - int defskill = DefaultSkill; - if ((unsigned int)defskill >= AllSkills.Size()) - { - defskill = (AllSkills.Size() - 1) / 2; - } - od->mSelectedItem = defskill; + od->mSelectedItem = M_GetDefaultSkill(); } } } + +//============================================================================= +// +// Returns the default skill level. +// +//============================================================================= + +int M_GetDefaultSkill() +{ + int defskill = DefaultSkill; + if ((unsigned int)defskill >= AllSkills.Size()) + { + defskill = (AllSkills.Size() - 1) / 2; + } + return defskill; +} diff --git a/src/p_ceiling.cpp b/src/p_ceiling.cpp index fdac779a..426bdf50 100644 --- a/src/p_ceiling.cpp +++ b/src/p_ceiling.cpp @@ -133,6 +133,7 @@ void DCeiling::Tick () switch (m_Type) { case ceilCrushAndRaise: + case ceilCrushAndRaiseDist: m_Direction = -1; m_Speed = m_Speed1; if (!SN_IsMakingLoopingSound (m_Sector)) @@ -164,6 +165,7 @@ void DCeiling::Tick () switch (m_Type) { case ceilCrushAndRaise: + case ceilCrushAndRaiseDist: case ceilCrushRaiseAndStay: m_Speed = m_Speed2; m_Direction = 1; @@ -193,6 +195,7 @@ void DCeiling::Tick () switch (m_Type) { case ceilCrushAndRaise: + case ceilCrushAndRaiseDist: case ceilLowerAndCrush: case ceilLowerAndCrushDist: if (m_Speed1 == FRACUNIT && m_Speed2 == FRACUNIT) @@ -254,6 +257,7 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, switch (type) { case ceilCrushAndRaise: + case ceilCrushAndRaiseDist: case ceilCrushRaiseAndStay: ceiling->m_TopHeight = sec->ceilingplane.d; case ceilLowerAndCrush: @@ -263,7 +267,7 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, { targheight += 8*FRACUNIT; } - else if (type == ceilLowerAndCrushDist) + else if (type == ceilLowerAndCrushDist || type == ceilCrushAndRaiseDist) { targheight += height; } @@ -505,7 +509,7 @@ bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line, // Reactivate in-stasis ceilings...for certain types. // This restarts a crusher after it has been stopped - if (type == DCeiling::ceilCrushAndRaise) + if (type == DCeiling::ceilCrushAndRaise || type == DCeiling::ceilCrushAndRaiseDist) { P_ActivateInStasisCeiling (tag); } diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 8cbeec33..dd66fdb0 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -616,6 +616,12 @@ FUNC(LS_Ceiling_CrushAndRaiseA) return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg1), SPEED(arg2), 0, arg3, 0, 0, CRUSHTYPE(arg4)); } +FUNC(LS_Ceiling_CrushAndRaiseDist) +// Ceiling_CrushAndRaiseDist (tag, dist, speed, damage, crushtype) +{ + return EV_DoCeiling (DCeiling::ceilCrushAndRaiseDist, ln, arg0, SPEED(arg2), SPEED(arg2), arg1*FRACUNIT, arg3, 0, 0, CRUSHTYPE(arg4)); +} + FUNC(LS_Ceiling_CrushAndRaiseSilentA) // Ceiling_CrushAndRaiseSilentA (tag, dnspeed, upspeed, damage, crushtype) { @@ -3248,13 +3254,13 @@ lnSpecFunc LineSpecials[256] = /* 159 */ LS_NOP, // Sector_SetPlaneReflection in GZDoom /* 160 */ LS_NOP, // Sector_Set3DFloor in GZDoom and Vavoom /* 161 */ LS_NOP, // Sector_SetContents in GZDoom and Vavoom - /* 162 */ LS_NOP, - /* 163 */ LS_NOP, - /* 164 */ LS_NOP, - /* 165 */ LS_NOP, - /* 166 */ LS_NOP, - /* 167 */ LS_NOP, - /* 168 */ LS_NOP, + /* 162 */ LS_NOP, // Reserved Doom64 branch + /* 163 */ LS_NOP, // Reserved Doom64 branch + /* 164 */ LS_NOP, // Reserved Doom64 branch + /* 165 */ LS_NOP, // Reserved Doom64 branch + /* 166 */ LS_NOP, // Reserved Doom64 branch + /* 167 */ LS_NOP, // Reserved Doom64 branch + /* 168 */ LS_Ceiling_CrushAndRaiseDist, /* 169 */ LS_Generic_Crusher2, /* 170 */ LS_Sector_SetCeilingScale2, /* 171 */ LS_Sector_SetFloorScale2, diff --git a/src/p_spec.h b/src/p_spec.h index 96bd4c8e..b1a0048f 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -603,6 +603,7 @@ public: ceilLowerInstant, ceilRaiseInstant, ceilCrushAndRaise, + ceilCrushAndRaiseDist, ceilLowerAndCrush, ceilLowerAndCrushDist, ceilCrushRaiseAndStay, diff --git a/src/p_user.cpp b/src/p_user.cpp index 49495c19..28250f9d 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2126,9 +2126,7 @@ void P_PlayerThink (player_t *player) player->mo->flags &= ~MF_JUSTATTACKED; } - bool totallyfrozen = (player->cheats & CF_TOTALLYFROZEN || gamestate == GS_TITLELEVEL || - (( level.flags2 & LEVEL2_FROZEN ) && ( player == NULL || !( player->cheats & CF_TIMEFREEZE ))) - ); + bool totallyfrozen = P_IsPlayerTotallyFrozen(player); // [RH] Being totally frozen zeros out most input parameters. if (totallyfrozen) @@ -2723,3 +2721,10 @@ void P_EnumPlayerColorSets(FName classname, TArray *out) } } +bool P_IsPlayerTotallyFrozen(const player_t *player) +{ + return + gamestate == GS_TITLELEVEL || + player->cheats & CF_TOTALLYFROZEN || + ((level.flags2 & LEVEL2_FROZEN) && !(player->cheats & CF_TIMEFREEZE)); +} diff --git a/src/p_xlat.cpp b/src/p_xlat.cpp index e61dcd52..6023b189 100644 --- a/src/p_xlat.cpp +++ b/src/p_xlat.cpp @@ -118,11 +118,6 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld) if (linetrans != NULL && linetrans->special != 0) { ld->special = linetrans->special; - ld->args[0] = linetrans->args[0]; - ld->args[1] = linetrans->args[1]; - ld->args[2] = linetrans->args[2]; - ld->args[3] = linetrans->args[3]; - ld->args[4] = linetrans->args[4]; ld->flags = flags | ((linetrans->flags & 0x1f) << 9); if (linetrans->flags & 0x20) ld->flags |= ML_FIRSTSIDEONLY; @@ -134,30 +129,37 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld) { ld->activation = SPAC_UseThrough; } - switch (linetrans->flags & LINETRANS_TAGMASK) + // Set special arguments. + FXlatExprState state; + state.tag = tag; + state.linetype = special; + for (int t = 0; t < LINETRANS_MAXARGS; ++t) { - case LINETRANS_HAS2TAGS: // First two arguments are tags - ld->args[1] = tag; - case LINETRANS_HASTAGAT1: // First argument is a tag - ld->args[0] = tag; - break; + int arg = linetrans->args[t]; + int argop = (linetrans->flags >> (LINETRANS_TAGSHIFT + t*TAGOP_NUMBITS)) & TAGOP_MASK; - case LINETRANS_HASTAGAT2: // Second argument is a tag - ld->args[1] = tag; - break; - - case LINETRANS_HASTAGAT3: // Third argument is a tag - ld->args[2] = tag; - break; - - case LINETRANS_HASTAGAT4: // Fourth argument is a tag - ld->args[3] = tag; - break; - - case LINETRANS_HASTAGAT5: // Fifth argument is a tag - ld->args[4] = tag; - break; + switch (argop) + { + case ARGOP_Const: + ld->args[t] = arg; + break; + case ARGOP_Tag: + ld->args[t] = tag; + break; + case ARGOP_Expr: + { + int *xnode = &XlatExpressions[arg]; + state.bIsConstant = true; + XlatExprEval[*xnode](&ld->args[t], xnode, &state); + } + break; + default: + assert(0); + ld->args[t] = 0; + break; + } } + if ((ld->flags & ML_SECRET) && ld->activation & (SPAC_Use|SPAC_UseThrough)) { ld->flags &= ~ML_MONSTERSCANACTIVATE; @@ -359,3 +361,132 @@ int P_TranslateSectorSpecial (int special) return special | mask; } +static const int *Expr_Const(int *dest, const int *xnode, FXlatExprState *state) +{ + *dest = xnode[-1]; + return xnode - 2; +} + +static const int *Expr_Tag(int *dest, const int *xnode, FXlatExprState *state) +{ + *dest = state->tag; + state->bIsConstant = false; + return xnode - 1; +} + +static const int *Expr_Add(int *dest, const int *xnode, FXlatExprState *state) +{ + int op1, op2; + + xnode = XlatExprEval[xnode[-1]](&op2, xnode-1, state); + xnode = XlatExprEval[xnode[0]](&op1, xnode, state); + *dest = op1 + op2; + return xnode; +} + +static const int *Expr_Sub(int *dest, const int *xnode, FXlatExprState *state) +{ + int op1, op2; + + xnode = XlatExprEval[xnode[-1]](&op2, xnode-1, state); + xnode = XlatExprEval[xnode[0]](&op1, xnode, state); + *dest = op1 - op2; + return xnode; +} + +static const int *Expr_Mul(int *dest, const int *xnode, FXlatExprState *state) +{ + int op1, op2; + + xnode = XlatExprEval[xnode[-1]](&op2, xnode-1, state); + xnode = XlatExprEval[xnode[0]](&op1, xnode, state); + *dest = op1 * op2; + return xnode; +} + +static void Div0Check(int &op1, int &op2, const FXlatExprState *state) +{ + if (op2 == 0) + { + Printf("Xlat: Division by 0 for line type %d\n", state->linetype); + // Set some safe values + op1 = 0; + op2 = 1; + } +} + +static const int *Expr_Div(int *dest, const int *xnode, FXlatExprState *state) +{ + int op1, op2; + + xnode = XlatExprEval[xnode[-1]](&op2, xnode-1, state); + xnode = XlatExprEval[xnode[0]](&op1, xnode, state); + Div0Check(op1, op2, state); + *dest = op1 / op2; + return xnode; +} + +static const int *Expr_Mod(int *dest, const int *xnode, FXlatExprState *state) +{ + int op1, op2; + + xnode = XlatExprEval[xnode[-1]](&op2, xnode-1, state); + xnode = XlatExprEval[xnode[0]](&op1, xnode, state); + Div0Check(op1, op2, state); + *dest = op1 % op2; + return xnode; +} + +static const int *Expr_And(int *dest, const int *xnode, FXlatExprState *state) +{ + int op1, op2; + + xnode = XlatExprEval[xnode[-1]](&op2, xnode-1, state); + xnode = XlatExprEval[xnode[0]](&op1, xnode, state); + *dest = op1 & op2; + return xnode; +} + +static const int *Expr_Or(int *dest, const int *xnode, FXlatExprState *state) +{ + int op1, op2; + + xnode = XlatExprEval[xnode[-1]](&op2, xnode-1, state); + xnode = XlatExprEval[xnode[0]](&op1, xnode, state); + *dest = op1 | op2; + return xnode; +} + +static const int *Expr_Xor(int *dest, const int *xnode, FXlatExprState *state) +{ + int op1, op2; + + xnode = XlatExprEval[xnode[-1]](&op2, xnode-1, state); + xnode = XlatExprEval[xnode[0]](&op1, xnode, state); + *dest = op1 ^ op2; + return xnode; +} + +static const int *Expr_Neg(int *dest, const int *xnode, FXlatExprState *state) +{ + int op; + + xnode = XlatExprEval[xnode[-1]](&op, xnode-1, state); + *dest = -op; + return xnode; +} + +const int* (*XlatExprEval[XEXP_COUNT])(int *dest, const int *xnode, FXlatExprState *state) = +{ + Expr_Const, + Expr_Tag, + Expr_Add, + Expr_Sub, + Expr_Mul, + Expr_Div, + Expr_Mod, + Expr_And, + Expr_Or, + Expr_Xor, + Expr_Neg +}; \ No newline at end of file diff --git a/src/parsecontext.cpp b/src/parsecontext.cpp index 5b764d95..6fa36b2a 100644 --- a/src/parsecontext.cpp +++ b/src/parsecontext.cpp @@ -267,6 +267,7 @@ loop: case '-': return TokenTrans[MINUS]; case '+': return TokenTrans[PLUS]; case '*': return TokenTrans[MULTIPLY]; + case '%': return TokenTrans[MODULUS]; case '(': return TokenTrans[LPAREN]; case ')': return TokenTrans[RPAREN]; case ',': return TokenTrans[COMMA]; diff --git a/src/parsecontext.h b/src/parsecontext.h index 020fc7e0..bafeaa88 100644 --- a/src/parsecontext.h +++ b/src/parsecontext.h @@ -47,6 +47,7 @@ enum PLUS , MULTIPLY , DIVIDE , + MODULUS , NUM , FLOATVAL , LPAREN , @@ -78,6 +79,7 @@ enum prefix##PLUS, \ prefix##MULTIPLY, \ prefix##DIVIDE, \ + prefix##MODULUS, \ prefix##NUM, \ prefix##FLOATVAL, \ prefix##LPAREN, \ diff --git a/src/r_polymost.cpp b/src/r_polymost.cpp index 0075d6ca..92cec1a6 100644 --- a/src/r_polymost.cpp +++ b/src/r_polymost.cpp @@ -671,7 +671,7 @@ void drawquad(float x0, float y0, float x1, float y1, float x2, float y2, float void printnum(int x, int y, int num) { char foo[16]; mysnprintf (foo, countof(foo), "%d", num); - RenderTarget->DrawText (SmallFont, CR_WHITE, x, y, foo); + RenderTarget->DrawText (SmallFont, CR_WHITE, x, y, foo, TAG_DONE); } void drawpolymosttest() diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 5c171af0..4af92f46 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -2591,7 +2591,44 @@ CCMD (playsound) { if (argv.argc() > 1) { - S_Sound (CHAN_AUTO | CHAN_UI, argv[1], 1.f, ATTN_NONE); + FSoundID id = argv[1]; + if (id == 0) + { + Printf("'%s' is not a sound\n", argv[1]); + } + else + { + S_Sound (CHAN_AUTO | CHAN_UI, id, 1.f, ATTN_NONE); + } + } +} + +//========================================================================== +// +// CCMD loopsound +// +//========================================================================== + +CCMD (loopsound) +{ + if (players[consoleplayer].mo != NULL && !netgame && argv.argc() > 1) + { + FSoundID id = argv[1]; + if (id == 0) + { + Printf("'%s' is not a sound\n", argv[1]); + } + else + { + AActor *icon = Spawn("SpeakerIcon", players[consoleplayer].mo->x, + players[consoleplayer].mo->y, + players[consoleplayer].mo->z + 32*FRACUNIT, + ALLOW_REPLACE); + if (icon != NULL) + { + S_Sound(icon, CHAN_BODY | CHAN_LOOP, id, 1.f, ATTN_IDLE); + } + } } } diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 4a5ab95a..5af94a34 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -63,6 +63,10 @@ extern HWND Window; #include "cmdlib.h" #include "s_sound.h" +#if FMOD_VERSION > 0x42899 && FMOD_VERSION < 0x43800 +#error You are trying to compile with an unsupported version of FMOD. +#endif + // MACROS ------------------------------------------------------------------ // killough 2/21/98: optionally use varying pitched sounds @@ -173,12 +177,12 @@ static const FEnumList OutputNames[] = { "ESD", FMOD_OUTPUTTYPE_ESD }, #if FMOD_VERSION >= 0x43400 { "PulseAudio", FMOD_OUTPUTTYPE_PULSEAUDIO }, + { "Pulse", FMOD_OUTPUTTYPE_PULSEAUDIO }, #endif { "SDL", 666 }, // Mac #if FMOD_VERSION < 0x43000 - // Sound Manager support was removed sometime in the 4.29 line. { "Sound Manager", FMOD_OUTPUTTYPE_SOUNDMANAGER }, #endif { "Core Audio", FMOD_OUTPUTTYPE_COREAUDIO }, @@ -238,6 +242,9 @@ static const char *OpenStateNames[] = "Streaming" }; +const FMODSoundRenderer::spk FMODSoundRenderer::SpeakerNames4[4] = { "L", "R", "BL", "BR" }; +const FMODSoundRenderer::spk FMODSoundRenderer::SpeakerNamesMore[8] = { "L", "R", "C", "LFE", "BL", "BR", "SL", "SR" }; + // CODE -------------------------------------------------------------------- //========================================================================== @@ -348,7 +355,7 @@ public: Channel->setSpeakerMix(1, 1, 1, 1, 1, 1, 1, 1); Channel->setVolume(volume); // Ensure reverb is disabled. - FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, }; if (FMOD_OK == Channel->getReverbProperties(&reverb)) { reverb.Room = -10000; @@ -704,7 +711,11 @@ bool FMODSoundRenderer::Init() } const char *wrongver = NULL; +#if FMOD_VERSION >= 0x43800 + if (version < 0x43800) +#else if (version < 0x42000) +#endif { wrongver = "an old"; } @@ -842,7 +853,14 @@ bool FMODSoundRenderer::Init() result = Sys->setDriver(driver); } result = Sys->getDriver(&driver); +#if FMOD_VERSION >= 0x43700 + // We were built with an FMOD that only returns the control panel frequency + result = Sys->getDriverCaps(driver, &Driver_Caps, &Driver_MinFrequency, &speakermode); + Driver_MaxFrequency = Driver_MinFrequency; +#else + // We were built with an FMOD that returns a frequency range result = Sys->getDriverCaps(driver, &Driver_Caps, &Driver_MinFrequency, &Driver_MaxFrequency, &speakermode); +#endif if (result != FMOD_OK) { Printf(TEXTCOLOR_BLUE"Could not ascertain driver capabilities. Some things may be weird. (Error %d)\n", result); @@ -871,7 +889,9 @@ bool FMODSoundRenderer::Init() format = eval >= 0 ? FMOD_SOUND_FORMAT(eval) : FMOD_SOUND_FORMAT_PCM16; eval = Enum_NumForName(ResamplerNames, snd_resampler); resampler = eval >= 0 ? FMOD_DSP_RESAMPLER(eval) : FMOD_DSP_RESAMPLER_LINEAR; - samplerate = clamp(snd_samplerate, Driver_MinFrequency, Driver_MaxFrequency); + // These represented the frequency limits for hardware channels, which we never used anyway. +// samplerate = clamp(snd_samplerate, Driver_MinFrequency, Driver_MaxFrequency); + samplerate = snd_samplerate; if (samplerate == 0 || snd_samplerate == 0) { // Creative's ASIO drivers report the only supported frequency as 0! if (FMOD_OK != Sys->getSoftwareFormat(&samplerate, NULL, NULL, NULL, NULL, NULL)) @@ -922,7 +942,12 @@ bool FMODSoundRenderer::Init() initflags = FMOD_INIT_NORMAL; if (snd_hrtf) { + // These flags are the same thing, just with different names. +#ifdef FMOD_INIT_SOFTWARE_HRTF initflags |= FMOD_INIT_SOFTWARE_HRTF; +#else + initflags |= FMOD_INIT_HRTF_LOWPASS; +#endif } if (snd_profile) { @@ -1007,6 +1032,7 @@ bool FMODSoundRenderer::Init() } // Create DSP units for underwater effect +#if FMOD_VERSION < 0x43701 result = Sys->createDSPByType(FMOD_DSP_TYPE_LOWPASS, &WaterLP); if (result != FMOD_OK) { @@ -1020,6 +1046,9 @@ bool FMODSoundRenderer::Init() Printf(TEXTCOLOR_BLUE" Could not create underwater reverb unit. (Error %d)\n", result); } } +#else + result = FMOD_ERR_UNSUPPORTED; +#endif // Connect underwater DSP unit between PausableSFX and SFX groups, while // retaining the connection established by SfxGroup->addGroup(). @@ -1066,6 +1095,7 @@ bool FMODSoundRenderer::Init() WaterLP->setActive(false); WaterLP->setParameter(FMOD_DSP_LOWPASS_CUTOFF, snd_waterlp); WaterLP->setParameter(FMOD_DSP_LOWPASS_RESONANCE, 2); +#if FMOD_VERSION < 0x43701 if (WaterReverb != NULL) { FMOD::DSPConnection *dry; @@ -1090,6 +1120,7 @@ bool FMODSoundRenderer::Init() } } else +#endif { result = sfx_head->addInput(WaterLP, NULL); } @@ -1209,7 +1240,6 @@ void FMODSoundRenderer::PrintStatus() int driver; int samplerate; int numoutputchannels; - int num2d, num3d, total; unsigned int bufferlength; int numbuffers; @@ -1233,12 +1263,6 @@ void FMODSoundRenderer::PrintStatus() Printf ("Driver: "TEXTCOLOR_GREEN"%d"TEXTCOLOR_NORMAL" ("TEXTCOLOR_ORANGE"%s"TEXTCOLOR_NORMAL")\n", driver, name); DumpDriverCaps(Driver_Caps, Driver_MinFrequency, Driver_MaxFrequency); } - if (FMOD_OK == Sys->getHardwareChannels(&num2d, &num3d, &total)) - { - Printf (TEXTCOLOR_YELLOW "Hardware 2D channels: "TEXTCOLOR_GREEN"%d\n", num2d); - Printf (TEXTCOLOR_YELLOW "Hardware 3D channels: "TEXTCOLOR_GREEN"%d\n", num3d); - Printf (TEXTCOLOR_YELLOW "Total hardware channels: "TEXTCOLOR_GREEN"%d\n", total); - } if (FMOD_OK == Sys->getSoftwareFormat(&samplerate, &format, &numoutputchannels, NULL, &resampler, NULL)) { Printf (TEXTCOLOR_LIGHTBLUE "Software mixer sample rate: "TEXTCOLOR_GREEN"%d\n", samplerate); @@ -1276,15 +1300,6 @@ void FMODSoundRenderer::DumpDriverCaps(FMOD_CAPS caps, int minfrequency, int max { Printf("\n"); } - if (caps & FMOD_CAPS_REVERB_EAX2) Printf(TEXTCOLOR_OLIVE " EAX2"); - if (caps & FMOD_CAPS_REVERB_EAX3) Printf(TEXTCOLOR_OLIVE " EAX3"); - if (caps & FMOD_CAPS_REVERB_EAX4) Printf(TEXTCOLOR_OLIVE " EAX4"); - if (caps & FMOD_CAPS_REVERB_EAX5) Printf(TEXTCOLOR_OLIVE " EAX5"); - if (caps & FMOD_CAPS_REVERB_I3DL2) Printf(TEXTCOLOR_OLIVE " I3DL2"); - if (caps & (FMOD_CAPS_REVERB_EAX2 | FMOD_CAPS_REVERB_EAX3 | FMOD_CAPS_REVERB_EAX4 | FMOD_CAPS_REVERB_EAX5 | FMOD_CAPS_REVERB_I3DL2)) - { - Printf("\n"); - } if (caps & FMOD_CAPS_REVERB_LIMITED) Printf("TEXTCOLOR_OLIVE Limited reverb\n"); } @@ -1689,7 +1704,7 @@ FISoundChannel *FMODSoundRenderer::StartSound(SoundHandle sfx, float vol, int pi } if (flags & SNDF_NOREVERB) { - FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, }; if (FMOD_OK == chan->getReverbProperties(&reverb)) { reverb.Room = -10000; @@ -1809,7 +1824,7 @@ FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener * } if (flags & SNDF_NOREVERB) { - FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, }; if (FMOD_OK == chan->getReverbProperties(&reverb)) { reverb.Room = -10000; @@ -2180,7 +2195,7 @@ void FMODSoundRenderer::UpdateListener(SoundListener *listener) { DPrintf ("Reverb Environment %s\n", env->Name); const_cast(env)->Modified = false; - Sys->setReverbProperties((FMOD_REVERB_PROPERTIES *)(&env->Properties)); + SetSystemReverbProperties(&env->Properties); PrevEnvironment = env; if (!SfxReverbHooked) @@ -2567,23 +2582,60 @@ void FMODSoundRenderer::DrawWaveDebug(int mode) const int window_height = 100; int window_size; int numoutchans; - int y; + int y, yy; + const spk *labels; + int labelcount; if (FMOD_OK != Sys->getSoftwareFormat(NULL, NULL, &numoutchans, NULL, NULL, NULL)) { return; } + // Decide on which set of labels to use. + labels = (numoutchans == 4) ? SpeakerNames4 : SpeakerNamesMore; + labelcount = MIN(numoutchans, countof(SpeakerNamesMore)); + // Scale all the channel windows so one group fits completely on one row, with // 16 pixels of padding between each window. window_size = (screen->GetWidth() - 16) / numoutchans - 16; float *wavearray = (float*)alloca(MAX(SPECTRUM_SIZE,window_size)*sizeof(float)); - y = 16; - y = DrawChannelGroupOutput(SfxGroup, wavearray, window_size, window_height, y, mode); - y = DrawChannelGroupOutput(MusicGroup, wavearray, window_size, window_height, y, mode >> 2); - y = DrawSystemOutput(wavearray, window_size, window_height, y, mode >> 4); + + yy = DrawChannelGroupOutput(SfxGroup, wavearray, window_size, window_height, y, mode); + if (y != yy) + { + DrawSpeakerLabels(labels, yy-14, window_size, labelcount); + } + y = DrawChannelGroupOutput(MusicGroup, wavearray, window_size, window_height, yy, mode >> 2); + if (y != yy) + { + DrawSpeakerLabels(labels, y-14, window_size, labelcount); + } + yy = DrawSystemOutput(wavearray, window_size, window_height, y, mode >> 4); + if (y != yy) + { + DrawSpeakerLabels(labels, yy-14, window_size, labelcount); + } +} + +//========================================================================== +// +// FMODSoundRenderer :: DrawSpeakerLabels +// +//========================================================================== + +void FMODSoundRenderer::DrawSpeakerLabels(const spk *labels, int y, int width, int count) +{ + if (labels == NULL) + { + return; + } + for (int i = 0, x = 16; i < count; ++i) + { + screen->DrawText(SmallFont, CR_LIGHTBLUE, x, y, labels[i], TAG_DONE); + x += width + 16; + } } //========================================================================== @@ -2716,7 +2768,7 @@ void FMODSoundRenderer::DrawWave(float *wavearray, int x, int y, int width, int // Draw a box around the oscilloscope. screen->DrawLine(x - 1, y - 1, x + width, y - 1, -1, MAKEARGB(160, 0, 40, 200)); - screen->DrawLine(x + width + 1, y - 1, x + width, y + height, -1, MAKEARGB(160, 0, 40, 200)); + screen->DrawLine(x + width, y - 1, x + width, y + height, -1, MAKEARGB(160, 0, 40, 200)); screen->DrawLine(x + width, y + height, x - 1, y + height, -1, MAKEARGB(160, 0, 40, 200)); screen->DrawLine(x - 1, y + height, x - 1, y - 1, -1, MAKEARGB(160, 0, 40, 200)); @@ -2823,7 +2875,7 @@ void FMODSoundRenderer::DrawSpectrum(float *spectrumarray, int x, int y, int wid // Draw a border and dark background for the spectrum. screen->DrawLine(x - 1, y - 1, x + width, y - 1, -1, MAKEARGB(160, 0, 40, 200)); - screen->DrawLine(x + width + 1, y - 1, x + width, y + height, -1, MAKEARGB(160, 0, 40, 200)); + screen->DrawLine(x + width, y - 1, x + width, y + height, -1, MAKEARGB(160, 0, 40, 200)); screen->DrawLine(x + width, y + height, x - 1, y + height, -1, MAKEARGB(160, 0, 40, 200)); screen->DrawLine(x - 1, y + height, x - 1, y - 1, -1, MAKEARGB(160, 0, 40, 200)); screen->Dim(MAKERGB(0,0,0), 0.3f, x, y, width, height); @@ -2912,17 +2964,60 @@ short *FMODSoundRenderer::DecodeSample(int outlen, const void *coded, int sizeby void FMODSoundRenderer::InitCreateSoundExInfo(FMOD_CREATESOUNDEXINFO *exinfo) const { -#if FMOD_VERSION >= 0x42600 - if (ActiveFMODVersion < 0x42600) - { - // This parameter was added for 4.26.00, and trying to pass it to older - // DLLs will fail. - exinfo->cbsize = myoffsetof(FMOD_CREATESOUNDEXINFO, ignoresetfilesystem); - } - else + memset(exinfo, 0, sizeof(*exinfo)); +#if FMOD_VERSION >= 0x42600 && FMOD_VERSION < 0x43800 + if (ActiveFMODVersion < 0x42600) + { + // This parameter was added for 4.26.00, and trying to pass it to older + // DLLs will fail. + exinfo->cbsize = myoffsetof(FMOD_CREATESOUNDEXINFO, ignoresetfilesystem); + } + else #endif - { - exinfo->cbsize = sizeof(*exinfo); - } - memset((BYTE *)exinfo + sizeof(exinfo->cbsize), 0, exinfo->cbsize - sizeof(exinfo->cbsize)); + { + exinfo->cbsize = sizeof(*exinfo); + } } + +//========================================================================== +// +// FMODSoundRenderer :: SetSystemReverbProperties +// +// Set the global reverb properties. +// +//========================================================================== + +FMOD_RESULT FMODSoundRenderer::SetSystemReverbProperties(const REVERB_PROPERTIES *props) +{ +#if FMOD_VERSION < 0x43800 + return Sys->setReverbProperties((const FMOD_REVERB_PROPERTIES *)props); +#else + // The reverb format changed when hardware mixing support was dropped, because + // all EAX-only properties were removed from the structure. + FMOD_REVERB_PROPERTIES fr; + + fr.Instance = props->Instance; + fr.Environment = props->Environment; + fr.EnvDiffusion = props->EnvDiffusion; + fr.Room = props->Room; + fr.RoomHF = props->RoomHF; + fr.RoomLF = props->RoomLF; + fr.DecayTime = props->DecayTime; + fr.DecayHFRatio = props->DecayHFRatio; + fr.DecayLFRatio = props->DecayLFRatio; + fr.Reflections = props->Reflections; + fr.ReflectionsDelay = props->ReflectionsDelay; + fr.Reverb = props->Reverb; + fr.ReverbDelay = props->ReverbDelay; + fr.ModulationTime = props->ModulationTime; + fr.ModulationDepth = props->ModulationDepth; + fr.HFReference = props->HFReference; + fr.LFReference = props->LFReference; + fr.Diffusion = props->Diffusion; + fr.Density = props->Density; + fr.Flags = props->Flags; + + return Sys->setReverbProperties(&fr); +#endif +} + diff --git a/src/sound/fmodsound.h b/src/sound/fmodsound.h index 8e28d074..e00b2ed2 100644 --- a/src/sound/fmodsound.h +++ b/src/sound/fmodsound.h @@ -81,6 +81,7 @@ private: bool ReconnectSFXReverbUnit(); void InitCreateSoundExInfo(FMOD_CREATESOUNDEXINFO *exinfo) const; + FMOD_RESULT SetSystemReverbProperties(const REVERB_PROPERTIES *props); bool Init (); void Shutdown (); @@ -97,6 +98,10 @@ private: int DrawSystemSpectrum(float *wavearray, int width, int height, int y, bool skip); void DrawSpectrum(float *spectrumarray, int x, int y, int width, int height); + typedef char spk[4]; + static const spk SpeakerNames4[4], SpeakerNamesMore[8]; + void DrawSpeakerLabels(const spk *labels, int y, int width, int count); + FMOD::System *Sys; FMOD::ChannelGroup *SfxGroup, *PausableSfx; FMOD::ChannelGroup *MusicGroup; diff --git a/src/svnrevision.h b/src/svnrevision.h index a36f1d8b..2d0fe354 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 "3340" -#define ZD_SVN_REVISION_NUMBER 3340 +#define ZD_SVN_REVISION_STRING "3350" +#define ZD_SVN_REVISION_NUMBER 3350 diff --git a/src/v_text.cpp b/src/v_text.cpp index 55dbcc77..b4d1e533 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -78,11 +78,11 @@ void STACK_ARGS DCanvas::DrawChar (FFont *font, int normalcolor, int x, int y, B // // Write a string using the given font // -void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, const char *string, ...) +void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag1, va_list taglist) { - va_list tags; - DWORD tag; INTBOOL boolval; + va_list tags; + uint32 tag; int maxstrlen = INT_MAX; int w, maxwidth; @@ -117,8 +117,12 @@ void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, c maxwidth = Width; scalex = scaley = 1; - va_start (tags, string); - tag = va_arg (tags, DWORD); +#ifndef NO_VA_COPY + va_copy(tags, taglist); +#else + tags = taglist; +#endif + tag = tag1; while (tag != TAG_DONE) { @@ -203,7 +207,7 @@ void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, c height = va_arg (tags, int); break; } - tag = va_arg (tags, DWORD); + tag = va_arg (tags, uint32); } height *= scaley; @@ -233,8 +237,12 @@ void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, c if (NULL != (pic = font->GetChar (c, &w))) { - va_list taglist; - va_start (taglist, string); +#ifndef NO_VA_COPY + va_copy(tags, taglist); +#else + tags = taglist; +#endif + tag = tag1; if (forcedwidth) { w = forcedwidth; @@ -242,20 +250,35 @@ void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, c DTA_Translation, range, DTA_DestWidth, forcedwidth, DTA_DestHeight, height, - TAG_MORE, &taglist); + TAG_MORE, &tags); } else { DrawTexture (pic, cx, cy, DTA_Translation, range, - TAG_MORE, &taglist); + TAG_MORE, &tags); } - va_end (taglist); + va_end (tags); } cx += (w + kerning) * scalex; } } +void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, ...) +{ + va_list tags; + va_start(tags, tag); + DrawTextV(font, normalcolor, x, y, string, tag, tags); +} + +// A synonym so that this can still be used in files that #include Windows headers +void STACK_ARGS DCanvas::DrawTextA (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, ...) +{ + va_list tags; + va_start(tags, tag); + DrawTextV(font, normalcolor, x, y, string, tag, tags); +} + // // Find string width using this font // diff --git a/src/v_video.h b/src/v_video.h index da184cba..50a81f13 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -214,7 +214,11 @@ public: void VirtualToRealCoordsInt(int &x, int &y, int &w, int &h, int vwidth, int vheight, bool vbottom=false, bool handleaspect=true) const; // 2D Text drawing - void STACK_ARGS DrawText (FFont *font, int normalcolor, int x, int y, const char *string, ...); + void STACK_ARGS DrawText (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, ...); +#ifndef DrawText // See WinUser.h for the definition of DrawText as a macro + void STACK_ARGS DrawTextA (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, ...); +#endif + void DrawTextV (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, va_list tags); void STACK_ARGS DrawChar (FFont *font, int normalcolor, int x, int y, BYTE character, ...); struct DrawParms diff --git a/src/xlat/parse_xlat.cpp b/src/xlat/parse_xlat.cpp index 5edcde58..0b5c3623 100644 --- a/src/xlat/parse_xlat.cpp +++ b/src/xlat/parse_xlat.cpp @@ -57,6 +57,7 @@ DEFINE_TOKEN_TRANS(XLAT_) static FString LastTranslator; TAutoGrowArray SimpleLineTranslations; +TArray XlatExpressions; FBoomTranslator Boomish[MAX_BOOMISH]; int NumBoomish; TAutoGrowArray SectorTranslations; @@ -67,9 +68,16 @@ FLineFlagTrans LineFlagTranslations[16]; struct SpecialArgs { int addflags; + int argcount; int args[5]; }; +struct SpecialArg +{ + int arg; + ELineTransArgOp argop; +}; + struct ListFilter { WORD filter; @@ -101,6 +109,7 @@ struct XlatParseContext : public FParseContext XlatParseContext(void *parser, ParseFunc parse, int *tt) : FParseContext(parser, parse, tt) { + DefiningLineType = -1; } //========================================================================== @@ -145,6 +154,8 @@ struct XlatParseContext : public FParseContext } return false; } + + int DefiningLineType; }; #include "xlat_parser.c" @@ -159,6 +170,7 @@ struct XlatParseContext : public FParseContext void P_ClearTranslator() { SimpleLineTranslations.Clear(); + XlatExpressions.Clear(); NumBoomish = 0; SectorTranslations.Clear(); SectorMasks.Clear(); diff --git a/src/xlat/xlat.h b/src/xlat/xlat.h index 018a2639..c5471ac8 100644 --- a/src/xlat/xlat.h +++ b/src/xlat/xlat.h @@ -4,16 +4,37 @@ #include "doomtype.h" #include "tarray.h" +enum ELineTransArgOp +{ + ARGOP_Const, + ARGOP_Tag, + ARGOP_Expr, + + TAGOP_NUMBITS = 2, + TAGOP_MASK = (1 << TAGOP_NUMBITS) - 1 +}; + enum { - LINETRANS_HASTAGAT1 = (1<<6), // (tag, x, x, x, x) - LINETRANS_HASTAGAT2 = (2<<6), // (x, tag, x, x, x) - LINETRANS_HASTAGAT3 = (3<<6), // (x, x, tag, x, x) - LINETRANS_HASTAGAT4 = (4<<6), // (x, x, x, tag, x) - LINETRANS_HASTAGAT5 = (5<<6), // (x, x, x, x, tag) + LINETRANS_MAXARGS = 5, + LINETRANS_TAGSHIFT = 30 - LINETRANS_MAXARGS * TAGOP_NUMBITS, +}; - LINETRANS_HAS2TAGS = (7<<6), // (tag, tag, x, x, x) - LINETRANS_TAGMASK = (7<<6) +enum +{ + XEXP_Const, + XEXP_Tag, + XEXP_Add, + XEXP_Sub, + XEXP_Mul, + XEXP_Div, + XEXP_Mod, + XEXP_And, + XEXP_Or, + XEXP_Xor, + XEXP_Neg, + + XEXP_COUNT }; struct FLineTrans @@ -86,12 +107,21 @@ struct FLineFlagTrans bool ismask; }; +struct FXlatExprState +{ + int linetype; + int tag; + bool bIsConstant; +}; + extern TAutoGrowArray SimpleLineTranslations; +extern TArray XlatExpressions; extern FBoomTranslator Boomish[MAX_BOOMISH]; extern int NumBoomish; extern TAutoGrowArray SectorTranslations; extern TArray SectorMasks; extern FLineFlagTrans LineFlagTranslations[16]; +extern const int* (*XlatExprEval[XEXP_COUNT])(int *dest, const int *xnode, FXlatExprState *state); #endif diff --git a/src/xlat/xlat_parser.y b/src/xlat/xlat_parser.y index d6f71b6a..084e2516 100644 --- a/src/xlat/xlat_parser.y +++ b/src/xlat/xlat_parser.y @@ -27,7 +27,7 @@ external_declaration ::= NOP. %left XOR. %left AND. %left MINUS PLUS. -%left MULTIPLY DIVIDE. +%left MULTIPLY DIVIDE MODULUS. %left NEG. %type exp {int} @@ -35,7 +35,8 @@ exp(A) ::= NUM(B). { A = B.val; } exp(A) ::= exp(B) PLUS exp(C). { A = B + C; } exp(A) ::= exp(B) MINUS exp(C). { A = B - C; } exp(A) ::= exp(B) MULTIPLY exp(C). { A = B * C; } -exp(A) ::= exp(B) DIVIDE exp(C). { if (C != 0) A = B / C; else context->PrintError("Division by Zero"); } +exp(A) ::= exp(B) DIVIDE exp(C). { if (C != 0) A = B / C; else context->PrintError("Division by zero"); } +exp(A) ::= exp(B) MODULUS exp(C). { if (C != 0) A = B % C; else context->PrintError("Division by zero"); } exp(A) ::= exp(B) OR exp(C). { A = B | C; } exp(A) ::= exp(B) AND exp(C). { A = B & C; } exp(A) ::= exp(B) XOR exp(C). { A = B ^ C; } @@ -88,15 +89,105 @@ single_enum ::= SYM(A) EQUALS exp(B). // //========================================================================== -linetype_declaration ::= exp(linetype) EQUALS exp(flags) COMMA exp(special) LPAREN special_args(arg) RPAREN. +%type linetype_exp {int} +linetype_exp(Z) ::= exp(A). +{ + Z = static_cast(context)->DefiningLineType = A; +} + +linetype_declaration ::= linetype_exp(linetype) EQUALS exp(flags) COMMA exp(special) LPAREN special_args(arg) RPAREN. { SimpleLineTranslations.SetVal(linetype, FLineTrans(special&0xffff, flags+arg.addflags, arg.args[0], arg.args[1], arg.args[2], arg.args[3], arg.args[4])); + static_cast(context)->DefiningLineType = -1; } -linetype_declaration ::= exp EQUALS exp COMMA SYM(S) LPAREN special_args RPAREN. +linetype_declaration ::= linetype_exp EQUALS exp COMMA SYM(S) LPAREN special_args RPAREN. { Printf ("%s, line %d: %s is undefined\n", context->SourceFile, context->SourceLine, S.sym); + static_cast(context)->DefiningLineType = -1; +} + +%type exp_with_tag {int} +exp_with_tag(A) ::= NUM(B). { XlatExpressions.Push(B.val); A = XlatExpressions.Push(XEXP_Const); } +exp_with_tag(A) ::= TAG. { A = XlatExpressions.Push(XEXP_Tag); } +exp_with_tag(A) ::= exp_with_tag PLUS exp_with_tag. { A = XlatExpressions.Push(XEXP_Add); } +exp_with_tag(A) ::= exp_with_tag MINUS exp_with_tag. { A = XlatExpressions.Push(XEXP_Sub); } +exp_with_tag(A) ::= exp_with_tag MULTIPLY exp_with_tag. { A = XlatExpressions.Push(XEXP_Mul); } +exp_with_tag(A) ::= exp_with_tag DIVIDE exp_with_tag. { A = XlatExpressions.Push(XEXP_Div); } +exp_with_tag(A) ::= exp_with_tag MODULUS exp_with_tag. { A = XlatExpressions.Push(XEXP_Mod); } +exp_with_tag(A) ::= exp_with_tag OR exp_with_tag. { A = XlatExpressions.Push(XEXP_Or); } +exp_with_tag(A) ::= exp_with_tag AND exp_with_tag. { A = XlatExpressions.Push(XEXP_And); } +exp_with_tag(A) ::= exp_with_tag XOR exp_with_tag. { A = XlatExpressions.Push(XEXP_Xor); } +exp_with_tag(A) ::= MINUS exp_with_tag. [NEG] { A = XlatExpressions.Push(XEXP_Neg); } +exp_with_tag(A) ::= LPAREN exp_with_tag(B) RPAREN. { A = B; } + + +%type special_arg {SpecialArg} + +special_arg(Z) ::= exp_with_tag(A). +{ + if (XlatExpressions[A] == XEXP_Tag) + { // Store tags directly + Z.arg = 0; + Z.argop = ARGOP_Tag; + XlatExpressions.Delete(A); + } + else + { // Try and evaluate it. If it's a constant, store it and erase the + // expression. Otherwise, store the index to the expression. We make + // no attempt to simplify non-constant expressions. + FXlatExprState state; + int val; + const int *endpt; + int *xnode; + + state.linetype = static_cast(context)->DefiningLineType; + state.tag = 0; + state.bIsConstant = true; + xnode = &XlatExpressions[A]; + endpt = XlatExprEval[*xnode](&val, xnode, &state); + if (state.bIsConstant) + { + Z.arg = val; + Z.argop = ARGOP_Const; + endpt++; + assert(endpt >= &XlatExpressions[0]); + XlatExpressions.Resize((unsigned)(endpt - &XlatExpressions[0])); + } + else + { + Z.arg = A; + Z.argop = ARGOP_Expr; + } + } +} + +%type multi_special_arg {SpecialArgs} + +multi_special_arg(Z) ::= special_arg(A). +{ + Z.addflags = A.argop << LINETRANS_TAGSHIFT; + Z.argcount = 1; + Z.args[0] = A.arg; + Z.args[1] = 0; + Z.args[2] = 0; + Z.args[3] = 0; + Z.args[4] = 0; +} +multi_special_arg(Z) ::= multi_special_arg(A) COMMA special_arg(B). +{ + Z = A; + if (Z.argcount < LINETRANS_MAXARGS) + { + Z.addflags |= B.argop << (LINETRANS_TAGSHIFT + Z.argcount * TAGOP_NUMBITS); + Z.args[Z.argcount] = B.arg; + Z.argcount++; + } + else if (Z.argcount++ == LINETRANS_MAXARGS) + { + context->PrintError("Line special has too many arguments\n"); + } } %type special_args {SpecialArgs} @@ -104,223 +195,16 @@ linetype_declaration ::= exp EQUALS exp COMMA SYM(S) LPAREN special_args RPAREN. special_args(Z) ::= . /* empty */ { Z.addflags = 0; + Z.argcount = 0; Z.args[0] = 0; Z.args[1] = 0; Z.args[2] = 0; Z.args[3] = 0; Z.args[4] = 0; } -special_args(Z) ::= TAG. +special_args(Z) ::= multi_special_arg(A). { - Z.addflags = LINETRANS_HASTAGAT1; - Z.args[0] = 0; - Z.args[1] = 0; - Z.args[2] = 0; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= TAG COMMA exp(B). -{ - Z.addflags = LINETRANS_HASTAGAT1; - Z.args[0] = 0; - Z.args[1] = B; - Z.args[2] = 0; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= TAG COMMA exp(B) COMMA exp(C). -{ - Z.addflags = LINETRANS_HASTAGAT1; - Z.args[0] = 0; - Z.args[1] = B; - Z.args[2] = C; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= TAG COMMA exp(B) COMMA exp(C) COMMA exp(D). -{ - Z.addflags = LINETRANS_HASTAGAT1; - Z.args[0] = 0; - Z.args[1] = B; - Z.args[2] = C; - Z.args[3] = D; - Z.args[4] = 0; -} -special_args(Z) ::= TAG COMMA exp(B) COMMA exp(C) COMMA exp(D) COMMA exp(E). -{ - Z.addflags = LINETRANS_HASTAGAT1; - Z.args[0] = 0; - Z.args[1] = B; - Z.args[2] = C; - Z.args[3] = D; - Z.args[4] = E; -} -special_args(Z) ::= TAG COMMA TAG. -{ - Z.addflags = LINETRANS_HAS2TAGS; - Z.args[0] = Z.args[1] = 0; - Z.args[2] = 0; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= TAG COMMA TAG COMMA exp(C). -{ - Z.addflags = LINETRANS_HAS2TAGS; - Z.args[0] = Z.args[1] = 0; - Z.args[2] = C; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= TAG COMMA TAG COMMA exp(C) COMMA exp(D). -{ - Z.addflags = LINETRANS_HAS2TAGS; - Z.args[0] = Z.args[1] = 0; - Z.args[2] = C; - Z.args[3] = D; - Z.args[4] = 0; -} -special_args(Z) ::= TAG COMMA TAG COMMA exp(C) COMMA exp(D) COMMA exp(E). -{ - Z.addflags = LINETRANS_HAS2TAGS; - Z.args[0] = Z.args[1] = 0; - Z.args[2] = C; - Z.args[3] = D; - Z.args[4] = E; -} -special_args(Z) ::= exp(A). -{ - Z.addflags = 0; - Z.args[0] = A; - Z.args[1] = 0; - Z.args[2] = 0; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA exp(B). -{ - Z.addflags = 0; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = 0; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA exp(B) COMMA exp(C). -{ - Z.addflags = 0; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = C; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA exp(B) COMMA exp(C) COMMA exp(D). -{ - Z.addflags = 0; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = C; - Z.args[3] = D; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA exp(B) COMMA exp(C) COMMA exp(D) COMMA exp(E). -{ - Z.addflags = 0; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = C; - Z.args[3] = D; - Z.args[4] = E; -} -special_args(Z) ::= exp(A) COMMA TAG. -{ - Z.addflags = LINETRANS_HASTAGAT2; - Z.args[0] = A; - Z.args[1] = 0; - Z.args[2] = 0; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA TAG COMMA exp(C). -{ - Z.addflags = LINETRANS_HASTAGAT2; - Z.args[0] = A; - Z.args[1] = 0; - Z.args[2] = C; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA TAG COMMA exp(C) COMMA exp(D). -{ - Z.addflags = LINETRANS_HASTAGAT2; - Z.args[0] = A; - Z.args[1] = 0; - Z.args[2] = C; - Z.args[3] = D; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA TAG COMMA exp(C) COMMA exp(D) COMMA exp(E). -{ - Z.addflags = LINETRANS_HASTAGAT2; - Z.args[0] = A; - Z.args[1] = 0; - Z.args[2] = C; - Z.args[3] = D; - Z.args[4] = E; -} -special_args(Z) ::= exp(A) COMMA exp(B) COMMA TAG. -{ - Z.addflags = LINETRANS_HASTAGAT3; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = 0; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA exp(B) COMMA TAG COMMA exp(D). -{ - Z.addflags = LINETRANS_HASTAGAT3; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = 0; - Z.args[3] = D; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA exp(B) COMMA TAG COMMA exp(D) COMMA exp(E). -{ - Z.addflags = LINETRANS_HASTAGAT3; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = 0; - Z.args[3] = D; - Z.args[4] = E; -} -special_args(Z) ::= exp(A) COMMA exp(B) COMMA exp(C) COMMA TAG. -{ - Z.addflags = LINETRANS_HASTAGAT4; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = C; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA exp(B) COMMA exp(C) COMMA TAG COMMA exp(E). -{ - Z.addflags = LINETRANS_HASTAGAT4; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = C; - Z.args[3] = 0; - Z.args[4] = E; -} -special_args(Z) ::= exp(A) COMMA exp(B) COMMA exp(C) COMMA exp(D) COMMA TAG. -{ - Z.addflags = LINETRANS_HASTAGAT5; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = C; - Z.args[3] = D; - Z.args[4] = 0; + Z = A; } //========================================================================== @@ -463,7 +347,7 @@ list_val(A) ::= exp(B) COLON exp(C). maxlinespecial_def ::= MAXLINESPECIAL EQUALS exp(mx) SEMICOLON. { // Just kill all specials higher than the max. - // If the translator wants to redefine some later, just let it.s + // If the translator wants to redefine some later, just let it. SimpleLineTranslations.Resize(mx+1); } diff --git a/wadsrc/static/actors/shared/sharedmisc.txt b/wadsrc/static/actors/shared/sharedmisc.txt index 33aa2559..6a71025d 100644 --- a/wadsrc/static/actors/shared/sharedmisc.txt +++ b/wadsrc/static/actors/shared/sharedmisc.txt @@ -68,7 +68,7 @@ ACTOR MapSpotGravity : MapSpot 9013 -NOGRAVITY } -// Point Pushers --------------------------------------------------- +// Point Pushers ----------------------------------------------------------- ACTOR PointPusher 5001 { @@ -110,7 +110,7 @@ ACTOR Gibs : RealGibs 24 ClearFlags } -// Needed for loading Build maps --------------------------------------- +// Needed for loading Build maps ------------------------------------------- ACTOR CustomSprite 9988 native { @@ -124,7 +124,7 @@ ACTOR CustomSprite 9988 native } } -// SwitchableDecoration: Activate and Deactivate change state --------------- +// SwitchableDecoration: Activate and Deactivate change state -------------- ACTOR SwitchableDecoration native { @@ -135,7 +135,7 @@ ACTOR SwitchingDecoration : SwitchableDecoration native { } -// Random spawner ----------------------------------------------------------- +// Random spawner ---------------------------------------------------------- ACTOR RandomSpawner native { @@ -145,14 +145,14 @@ ACTOR RandomSpawner native +THRUACTORS } -// Fast projectiles ----------------------------------------------------------- +// Fast projectiles -------------------------------------------------------- ACTOR FastProjectile native { Projectile } -// Sector flag setter ----------------------------------------------------------- +// Sector flag setter ------------------------------------------------------ ACTOR SectorFlagSetter 9041 native { @@ -161,3 +161,16 @@ ACTOR SectorFlagSetter 9041 native +DONTSPLASH RenderStyle None } + +// Marker for sounds ------------------------------------------------------- + +ACTOR SpeakerIcon : Unknown +{ + States + { + Spawn: + SPKR A -1 BRIGHT + Stop + } + Scale 0.125 +} diff --git a/wadsrc/static/sprites/spkra0.png b/wadsrc/static/sprites/spkra0.png new file mode 100644 index 00000000..9af2d4d8 Binary files /dev/null and b/wadsrc/static/sprites/spkra0.png differ diff --git a/wadsrc/static/xlat/base.txt b/wadsrc/static/xlat/base.txt index 1b41fc56..92e8abda 100644 --- a/wadsrc/static/xlat/base.txt +++ b/wadsrc/static/xlat/base.txt @@ -48,7 +48,7 @@ include "xlat/defines.i" 46 = SHOOT|REP|MONST, Door_Open (tag, D_SLOW) 47 = SHOOT, Plat_RaiseAndStayTx0 (tag, P_SLOW/2) 48 = 0, Scroll_Texture_Left (SCROLL_UNIT) - 49 = USE, Ceiling_CrushAndRaiseA (tag, C_SLOW, C_SLOW, 10) + 49 = USE, Ceiling_CrushAndRaiseDist (tag, 8, C_SLOW, 10) 50 = USE, Door_Close (tag, D_SLOW) 51 = USE, Exit_Secret (0) 52 = WALK, Exit_Normal (0) diff --git a/wadsrc/static/xlat/heretic.txt b/wadsrc/static/xlat/heretic.txt index 2ed3748b..8fe344f5 100644 --- a/wadsrc/static/xlat/heretic.txt +++ b/wadsrc/static/xlat/heretic.txt @@ -4,6 +4,7 @@ include "xlat/base.txt" 8 = WALK, Stairs_BuildUpDoom (tag, F_SLOW, 8) 10 = WALK, Plat_DownWaitUpStayLip (tag, P_FAST, PLATWAIT, 0) 36 = WALK, Floor_LowerToHighest (tag, F_FAST, 136, 1) + 49 = USE, Ceiling_LowerAndCrush (tag, C_SLOW, 0, 2) 88 = WALK|REP, Plat_DownWaitUpStayLip (tag, P_FAST, PLATWAIT, 0) 99 = 0, Scroll_Texture_Right (SCROLL_UNIT) 100 = WALK|REP, Door_Raise (tag, D_SLOW*3, VDOORWAIT) diff --git a/wadsrc/static/xlat/strife.txt b/wadsrc/static/xlat/strife.txt index 3d06cd7c..f0320f04 100644 --- a/wadsrc/static/xlat/strife.txt +++ b/wadsrc/static/xlat/strife.txt @@ -244,7 +244,7 @@ RetailOnly = 121 189 = USE, ACS_LockedExecute (0, 0, 189, tag, 13) 41 = USE, Ceiling_LowerToFloor (tag, C_SLOW) 71 = USE, Floor_LowerToHighest (tag, F_FAST, 128) - 49 = USE, Ceiling_CrushAndRaiseA (tag, C_SLOW, C_SLOW, 10) + 49 = USE, Ceiling_CrushAndRaiseDist (tag, 8, C_SLOW, 0, 2) 50 = USE, Door_Close (tag, D_SLOW) 51 = USE, Teleport_EndGame (0) 55 = USE, Floor_RaiseAndCrush (tag, F_SLOW, 10, 2)