diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 9c064977c..ac304a52d 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,101 @@ +September 22, 2009 +- Added a technique to try and minimize input lag with vsync enabled: Two + surfaces are alternately locked for read-only access each frame, forcing + the driver to stop buffering more than one frame at a time. The input lag + on my system doesn't seem to be as bad as it once was (I can no longer + see it obviously with my naked eye), but turning antilag on "feels" + slightly more responsive. The cvar d3d_antilag turns this technique on and + off. See for more details. + +September 22, 2009 (Changes by Graf Zahl) +- Added a check to Dehacked code which tries to set the blend color. + It must set it to 0 if the alpha is 0 to avoid problems with special + colormap detection. +- Changed SPECIALCOLORMAP_MASK again so that it does not interfere with + any valid setting. It must use a value with a 0-alpha because these + are guaranteed not to be produced by the DECORATE code elsewhere. +- Fixed precision issues with AddFixedColormap's search for identical colormaps. +- Added custom colormap support to texture composition code. +- Fixed initialization of FSpecialColormap::GrayscaleToColor. This is not + a mapping from the palette but from a [0,255] grayscale ramp and used to + apply colormaps to true color images for texture composition. + +September 21, 2009 +- For hardware 2D, apply fixed colormaps when copying to video memory instead + of doing it directly during the rendering, in order to improve visual + fidelity for colormaps that aren't grayscale. +- Added support for defining the full color range of a special colormap. +- Moved the code for specialcolormap and colormapstyle in D3DFB::SetStyle() + at the end of the normally-colored block so that they get all the proper + texture format setup. +- Fixed: In letterbox modes, the clipping window needs to be adjusted down. + +September 21, 2009 (Changes by Graf Zahl) +- Fixed: When drawing with a special colormap the quad's flags weren't cleared + which could cause crashes. +- Added custom special colormaps to DECORATE. +- Cleaned up special colormap code and removed lots of dependencies on the + knowledge of the tables' contents. + +September 20, 2009 (Changes by Graf Zahl) +- Changed call to R_DrawRemainingPlayerSprites into a virtual function + of DFrameBuffer because its implementation is specific to the software + renderer and needs to be overridable. + +September 19, 2009 +- Fixed: Wall drawing handled fixed light levels improperly (but did not + completely ignore them, either). +- Separated light level fixing out of player_t's fixedcolormap parameter. + Using a fixed light level (e.g. PowerTorch) will no longer wipe out + colored lighting. +- Moved the blending rectangle drawing into a separate discrete stage, since + doing it while copying the 3D view window to the display now blends + underneath the weapon instead of on top of it. +- Consolidated the special colormaps into a single 2D table. +- Tweaked the special colormaps slightly to make the true color results more + closely match the paletted approximations. +- fb_d3d9_shaders.h was getting unwieldy, so I moved the shaders out of the + executable and into zdoom.pk3. Shaders are still precompiled so I don't need + to pull in a dependancy on D3DX. +- Added a few more shaders to accomodate drawing weapons with all the in-game + lighting models. These are accessed with the new DrawTexture tags + DTA_SpecialColormap and DTA_ColormapStyle. +- Player weapon sprites are now drawn using Direct3D and receive all the + benefits thereof. + +September 17, 2009 (Changes by Graf Zahl) +- Fixed: Unmorphing while invulnerable was blocked. +- Various cleanup changes. +- fixed Dog's class name in DEHSUPP. +- Renamed plane flags from SECF_* to PLANEF_*. +- Changed Heretic's plat raise type to use a flag to block further sector movement + instead of keeping the dead thinker around to block the sector. + +September 16, 2009 (Changes by Graf Zahl) +- Fixed: A_LookEx did not work for monsters having the MF_NOSECTOR flag. +- Fixed: The deprecated flag handler for the old bounce flags needs to clear + BOUNCE_MBF and BOUNCE_UseSeeSound, too, when clearing one of these flags. +- Fixed: When adding the AVOIDMELEE code the code was accidentally changed so that + friendly monsters could no longer acquire targets by themselves. +- Renamed WIF_BOT_MELEE to WIF_MELEEWEAPON because it's no longer a bot only flag. +- Added MBF's monster_backing feature as an actor flag: AVOIDMELEE. +- Gez's misc. bugs patch: +* Moves the dog sound out of the Doom-specific sounds in SNDINFO to address this, +* Renames the dog actor to MBFHelperDog to prevent name conflicts, +* Adds APROP_Score to CheckActorProperty, +* Completes the randomspawner update (the reason I moved the recursion counter out of + special1 was that I found some projectiles had this set to them, for example in + A_LichAttack, but I forgot to add transfer for them), +* Provides centered sprites for beta plasma balls if this is deemed deserving correction. +- Added some pieces of MBF's friendly AI. +- Cleaned up A_LookEx code and merged most of it with the base functions. + The major difference was a common piece of code that was repeated 5 times + throughout the code so I moved it into a subfunction. +- Changed P_BlockmapSearch to pass a user parameter to its callback so that + A_LookEx does not need to store its info inside the actor itself. +- fixed: The linetarget CCMD duplicated all of the info CCMD. +- fixed: PrintActorInfo crashed due to some incomplete implementation. + September 15, 2009 (Changes by Graf Zahl) - added PinkSilver's A_Respawn enhancement patch. - added RandomSpawner update from Gez's experimental build. @@ -16872,7 +16970,7 @@ November 14, 2000 into c_cvars.cpp. Virtual inline functions are not inlined and cause the function to be generated for every source file the class is used in. - Fixed bug with Transfer_CeilingLight special. I was or'ing CeilingLight - with SECF_ABSLIGHTING instead of CeilingFlags. + with PLANEF_ABSLIGHTING instead of CeilingFlags. November 11, 2000 - Slopes don't work in mirrors. :-( diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 824d764a6..91e187574 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -589,7 +589,6 @@ add_executable( zdoom WIN32 p_doors.cpp p_effect.cpp p_enemy.cpp - p_enemy_a_lookex.cpp p_floor.cpp p_interaction.cpp p_lights.cpp diff --git a/src/actor.h b/src/actor.h index deb9bfd45..b490aeade 100644 --- a/src/actor.h +++ b/src/actor.h @@ -216,7 +216,7 @@ enum MF3_NOBLOCKMONST = 0x00100000, // Can cross ML_BLOCKMONSTERS lines MF3_CRASHED = 0x00200000, // Actor entered its crash state MF3_FULLVOLDEATH = 0x00400000, // DeathSound is played full volume (for missiles) - /* = 0x00800000, */ + MF3_AVOIDMELEE = 0x00800000, // Avoids melee attacks (same as MBF's monster_backing but must be explicitly set) /* = 0x01000000, */ MF3_FOILINVUL = 0x02000000, // Actor can hurt MF2_INVULNERABLE things MF3_NOTELEOTHER = 0x04000000, // Monster is unaffected by teleport other artifact @@ -399,7 +399,7 @@ enum EBounceFlags // for them that are not present in ZDoom, so it is necessary to identify it properly. BOUNCE_MBF = 1<<12, // This in itself is not a valid mode, but replaces MBF's MF_BOUNCE flag. - BOUNCE_TypeMask = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors | BOUNCE_AutoOff | BOUNCE_HereticType, + BOUNCE_TypeMask = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors | BOUNCE_AutoOff | BOUNCE_HereticType | BOUNCE_MBF, // The three "standard" types of bounciness are: // HERETIC - Missile will only bounce off the floor once and then enter @@ -760,6 +760,7 @@ public: BYTE movedir; // 0-7 SBYTE visdir; SWORD movecount; // when 0, select a new dir + SWORD strafecount; // for MF3_AVOIDMELEE TObjPtr target; // thing being chased/attacked (or NULL) // also the originator for missiles TObjPtr lastenemy; // Last known enemy -- killough 2/15/98 @@ -810,14 +811,6 @@ public: AActor *BlockingMobj; // Actor that blocked the last move line_t *BlockingLine; // Line that blocked the last move - // [KS] These temporary-use properties are needed to allow A_LookEx to pass its parameters to - // LookFor*InBlock in P_BlockmapSearch so that friendly enemies and monsters that look for - // other monsters can find their targets properly. If there's a cleaner way of doing this, - // feel free to remove these and use that method instead. - fixed_t LookExMinDist; // Minimum sight distance - fixed_t LookExMaxDist; // Maximum sight distance - angle_t LookExFOV; // Field of Vision - // a linked list of sectors where this object appears struct msecnode_t *touching_sectorlist; // phares 3/14/98 diff --git a/src/b_bot.cpp b/src/b_bot.cpp index b03c067f7..3911264cd 100644 --- a/src/b_bot.cpp +++ b/src/b_bot.cpp @@ -136,7 +136,6 @@ void InitBotStuff() { "SkullRod", 27000000, 0, "HornRodFX1" }, { "SkullRodPowered", 27000000, 0, "HornRodFX2" }, { "PhoenixRod", 18350080, WIF_BOT_REACTION_SKILL_THING|WIF_BOT_EXPLOSIVE, "PhoenixFX1" }, - { "PhoenixRodPowered", 0, WIF_BOT_MELEE, "PhoenixFX2" }, { "Mace", 27000000, WIF_BOT_REACTION_SKILL_THING, "MaceFX2" }, { "MacePowered", 27000000, WIF_BOT_REACTION_SKILL_THING|WIF_BOT_EXPLOSIVE, "MaceFX4" }, { "FWeapHammer", 22000000, 0, "HammerMissile" }, diff --git a/src/b_func.cpp b/src/b_func.cpp index 5da2e8e2c..adaa755c2 100644 --- a/src/b_func.cpp +++ b/src/b_func.cpp @@ -175,7 +175,7 @@ void FCajunMaster::Dofire (AActor *actor, ticcmd_t *cmd) (actor->y + actor->vely) - (enemy->y + enemy->vely)); //FIRE EACH TYPE OF WEAPON DIFFERENT: Here should all the different weapons go. - if (actor->player->ReadyWeapon->WeaponFlags & WIF_BOT_MELEE) + if (actor->player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON) { if ((actor->player->ReadyWeapon->ProjectileType != NULL)) { diff --git a/src/b_move.cpp b/src/b_move.cpp index 896ce9342..332160f1a 100644 --- a/src/b_move.cpp +++ b/src/b_move.cpp @@ -342,7 +342,7 @@ void FCajunMaster::TurnToAng (AActor *actor) if(actor->player->enemy) if(!actor->player->dest) //happens when running after item in combat situations, or normal, prevents weak turns - if(actor->player->ReadyWeapon->ProjectileType == NULL && !(actor->player->ReadyWeapon->WeaponFlags & WIF_BOT_MELEE)) + if(actor->player->ReadyWeapon->ProjectileType == NULL && !(actor->player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON)) if(Check_LOS(actor, actor->player->enemy, SHOOTFOV+5*ANGLE_1)) maxturn = 3; } diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 3cddb6d52..ed27e2d27 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -778,7 +778,6 @@ CCMD(linetarget) linetarget->GetClass()->TypeName.GetChars(), linetarget->health, linetarget->SpawnHealth()); - PrintMiscActorInfo(linetarget); } else Printf("No target found\n"); } diff --git a/src/colormatcher.h b/src/colormatcher.h index ca7992d6d..04b9f7198 100644 --- a/src/colormatcher.h +++ b/src/colormatcher.h @@ -43,6 +43,11 @@ public: void SetPalette (const DWORD *palette); BYTE Pick (int r, int g, int b); + BYTE Pick (PalEntry pe) + { + return Pick(pe.r, pe.g, pe.b); + } + FColorMatcher &operator= (const FColorMatcher &other); private: diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 09fd3ba18..3c51af2b9 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -1793,7 +1793,7 @@ static int PatchMisc (int dummy) { Printf ("Bad powerup color description \"%s\" for %s\n", Line2, Line1); } - else + else if (a > 0) { static_cast(GetDefaultByType (*types[i]))->BlendColor = PalEntry( BYTE(clamp(a,0.f,1.f)*255.f), @@ -1801,6 +1801,10 @@ static int PatchMisc (int dummy) clamp(g,0,255), clamp(b,0,255)); } + else + { + static_cast(GetDefaultByType (*types[i]))->BlendColor = 0; + } } } else diff --git a/src/d_main.cpp b/src/d_main.cpp index 9ade69c8e..d86a26465 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -681,6 +681,8 @@ void D_Display () SB_state = screen->GetPageCount(); BorderNeedRefresh = screen->GetPageCount(); } + screen->DrawRemainingPlayerSprites(); + screen->DrawBlendingRect(); if (automapactive) { int saved_ST_Y = ST_Y; diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index c395681ce..e31354a6e 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -839,6 +839,6 @@ CCMD (playerinfo) Printf ("PlayerClass: %s (%d)\n", ui->PlayerClass == -1 ? "Random" : PlayerClasses[ui->PlayerClass].Type->Meta.GetMetaString (APMETA_DisplayName), ui->PlayerClass); - PrintMiscActorInfo(players[i].mo); + if (argv.argc() > 2) PrintMiscActorInfo(players[i].mo); } } diff --git a/src/d_player.h b/src/d_player.h index 7c7becbe3..fa936b552 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -303,7 +303,8 @@ public: TObjPtr poisoner; // NULL for non-player actors TObjPtr attacker; // who did damage (NULL for floors) int extralight; // so gun flashes light up areas - int fixedcolormap; // can be set to REDCOLORMAP, etc. + short fixedcolormap; // can be set to REDCOLORMAP, etc. + short fixedlightlevel; pspdef_t psprites[NUMPSPRITES]; // view sprites (gun, etc) int morphTics; // player is a chicken/pig if > 0 BYTE MorphedPlayerClass; // [MH] (for SBARINFO) class # for this player instance when morphed diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index d0e26b8ba..236646820 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -519,6 +519,9 @@ IMPLEMENT_ABSTRACT_CLASS(PSymbol); IMPLEMENT_CLASS(PSymbolConst); IMPLEMENT_CLASS(PSymbolVariable); IMPLEMENT_CLASS(PSymbolActionFunction); +IMPLEMENT_POINTY_CLASS(PSymbolVMFunction) + DECLARE_POINTER(Function) +END_POINTERS PSymbol::~PSymbol() { diff --git a/src/dobjtype.h b/src/dobjtype.h index 518f076c6..5ad13eaf6 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -13,7 +13,8 @@ enum ESymbolType { SYM_Const, SYM_Variable, - SYM_ActionFunction + SYM_ActionFunction, + SYM_VMFunction }; class PSymbol : public DObject @@ -96,6 +97,20 @@ public: // A symbol table ----------------------------------------------------------- +class VMFunction; +class PSymbolVMFunction : public PSymbol +{ + DECLARE_CLASS(PSymbolVMFunction, PSymbol); + HAS_OBJECT_POINTERS; +public: + VMFunction *Function; + + PSymbolVMFunction(FName name) : PSymbol(name, SYM_VMFunction) {} + PSymbolVMFunction() : PSymbol(NAME_None, SYM_VMFunction) {} +}; + +// A symbol table ----------------------------------------------------------- + struct PSymbolTable { PSymbolTable(); diff --git a/src/g_doom/a_bossbrain.cpp b/src/g_doom/a_bossbrain.cpp index 2fc203e1d..7764f2ecd 100644 --- a/src/g_doom/a_bossbrain.cpp +++ b/src/g_doom/a_bossbrain.cpp @@ -238,7 +238,7 @@ static void SpawnFly(AActor *self, const PClass *spawntype, FSoundID sound) { newmobj->CopyFriendliness (eye, false); } - if (newmobj->SeeState != NULL && P_LookForPlayers (newmobj, true)) + if (newmobj->SeeState != NULL && P_LookForPlayers (newmobj, true, NULL)) newmobj->SetState (newmobj->SeeState); if (!(newmobj->ObjectFlags & OF_EuthanizeMe)) diff --git a/src/g_doom/a_scriptedmarine.cpp b/src/g_doom/a_scriptedmarine.cpp index fbae607ca..9f6f54051 100644 --- a/src/g_doom/a_scriptedmarine.cpp +++ b/src/g_doom/a_scriptedmarine.cpp @@ -168,7 +168,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_Refire) { if (self->MissileState && pr_m_refire() < 160) { // Look for a new target most of the time - if (P_LookForPlayers (self, true) && P_CheckMissileRange (self)) + if (P_LookForPlayers (self, true, NULL) && P_CheckMissileRange (self)) { // Found somebody new and in range, so don't stop shooting return; } diff --git a/src/g_game.cpp b/src/g_game.cpp index 34b98c607..43587bb08 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1195,7 +1195,8 @@ void G_PlayerFinishLevel (int player, EFinishLevelType mode, bool resetinventory p->mo->RenderStyle = STYLE_Normal; p->mo->alpha = FRACUNIT; p->extralight = 0; // cancel gun flashes - p->fixedcolormap = 0; // cancel ir goggles + p->fixedcolormap = NOFIXEDCOLORMAP; // cancel ir goggles + p->fixedlightlevel = -1; p->damagecount = 0; // no palette changes p->bonuscount = 0; p->poisoncount = 0; @@ -1230,7 +1231,7 @@ void G_PlayerFinishLevel (int player, EFinishLevelType mode, bool resetinventory if (p->morphTics) { // Undo morph - P_UndoPlayerMorph (p, p, true); + P_UndoPlayerMorph (p, p, 0, true); } // Clears the entire inventory and gives back the defaults for starting a game diff --git a/src/g_heretic/a_hereticartifacts.cpp b/src/g_heretic/a_hereticartifacts.cpp index d9c08ec1a..1b7a79966 100644 --- a/src/g_heretic/a_hereticartifacts.cpp +++ b/src/g_heretic/a_hereticartifacts.cpp @@ -24,7 +24,7 @@ bool AArtiTomeOfPower::Use (bool pickup) { if (Owner->player->morphTics && (Owner->player->MorphStyle & MORPH_UNDOBYTOMEOFPOWER)) { // Attempt to undo chicken - if (!P_UndoPlayerMorph (Owner->player, Owner->player)) + if (!P_UndoPlayerMorph (Owner->player, Owner->player, MORPH_UNDOBYTOMEOFPOWER)) { // Failed if (!(Owner->player->MorphStyle & MORPH_FAILNOTELEFRAG)) { diff --git a/src/g_hexen/a_dragon.cpp b/src/g_hexen/a_dragon.cpp index 8ef10e245..0c5ea81b5 100644 --- a/src/g_hexen/a_dragon.cpp +++ b/src/g_hexen/a_dragon.cpp @@ -213,7 +213,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlight) } else { - P_LookForPlayers (self, true); + P_LookForPlayers (self, true, NULL); } } diff --git a/src/g_hexen/a_firedemon.cpp b/src/g_hexen/a_firedemon.cpp index 884a12f27..d0366fdf0 100644 --- a/src/g_hexen/a_firedemon.cpp +++ b/src/g_hexen/a_firedemon.cpp @@ -145,7 +145,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase) if(!self->target || !(self->target->flags&MF_SHOOTABLE)) { // Invalid target - P_LookForPlayers (self,true); + P_LookForPlayers (self,true, NULL); return; } diff --git a/src/g_hexen/a_magestaff.cpp b/src/g_hexen/a_magestaff.cpp index 85b51d330..76610f693 100644 --- a/src/g_hexen/a_magestaff.cpp +++ b/src/g_hexen/a_magestaff.cpp @@ -19,7 +19,7 @@ void A_DropBloodscourgePieces (AActor *); void A_MStaffAttack (AActor *actor); void A_MStaffPalette (AActor *actor); -static AActor *FrontBlockCheck (AActor *mo, int index); +static AActor *FrontBlockCheck (AActor *mo, int index, void *); static divline_t BlockCheckLine; //========================================================================== @@ -254,7 +254,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffTrack) // //============================================================================ -static AActor *FrontBlockCheck (AActor *mo, int index) +static AActor *FrontBlockCheck (AActor *mo, int index, void *) { FBlockNode *link; diff --git a/src/g_raven/a_artitele.cpp b/src/g_raven/a_artitele.cpp index 11350338e..9828f9581 100644 --- a/src/g_raven/a_artitele.cpp +++ b/src/g_raven/a_artitele.cpp @@ -45,7 +45,8 @@ bool AArtiTeleport::Use (bool pickup) bool canlaugh = true; if (Owner->player->morphTics && (Owner->player->MorphStyle & MORPH_UNDOBYCHAOSDEVICE)) { // Teleporting away will undo any morph effects (pig) - if (!P_UndoPlayerMorph (Owner->player, Owner->player) && (Owner->player->MorphStyle & MORPH_FAILNOLAUGH)) + if (!P_UndoPlayerMorph (Owner->player, Owner->player, MORPH_UNDOBYCHAOSDEVICE) + && (Owner->player->MorphStyle & MORPH_FAILNOLAUGH)) { canlaugh = false; } diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 9eb95c5e3..fa2c1e59f 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -139,14 +139,7 @@ PalEntry APowerup::GetBlend () if (EffectTics <= BLINKTHRESHOLD && !(EffectTics & 8)) return 0; - if (BlendColor == INVERSECOLOR || - BlendColor == GOLDCOLOR || - // [BC] HAX! - BlendColor == REDCOLOR || - BlendColor == GREENCOLOR || - BlendColor == BLUECOLOR) - return 0; - + if (IsSpecialColormap(BlendColor)) return 0; return BlendColor; } @@ -175,37 +168,19 @@ void APowerup::DoEffect () if (EffectTics > 0) { - int oldcolormap = Owner->player->fixedcolormap; - if (EffectTics > BLINKTHRESHOLD || (EffectTics & 8)) + int Colormap = GetSpecialColormap(BlendColor); + + if (Colormap != NOFIXEDCOLORMAP) { - if (BlendColor == INVERSECOLOR) + if (EffectTics > BLINKTHRESHOLD || (EffectTics & 8)) { - Owner->player->fixedcolormap = INVERSECOLORMAP; + Owner->player->fixedcolormap = Colormap; } - else if (BlendColor == GOLDCOLOR) + else if (Owner->player->fixedcolormap == Colormap) { - Owner->player->fixedcolormap = GOLDCOLORMAP; + // only unset if the fixed colormap comes from this item + Owner->player->fixedcolormap = NOFIXEDCOLORMAP; } - else if (BlendColor == REDCOLOR) - { - Owner->player->fixedcolormap = REDCOLORMAP; - } - else if (BlendColor == GREENCOLOR) - { - Owner->player->fixedcolormap = GREENCOLORMAP; - } - else if (BlendColor == BLUECOLOR) - { - Owner->player->fixedcolormap = BLUECOLORMAP; - } - } - else if ((BlendColor == INVERSECOLOR && Owner->player->fixedcolormap == INVERSECOLORMAP) || - (BlendColor == GOLDCOLOR && Owner->player->fixedcolormap == GOLDCOLORMAP) || - (BlendColor == REDCOLOR && Owner->player->fixedcolormap == REDCOLORMAP) || - (BlendColor == GREENCOLOR && Owner->player->fixedcolormap == GREENCOLORMAP) || - (BlendColor == BLUECOLOR && Owner->player->fixedcolormap == BLUECOLORMAP)) - { - Owner->player->fixedcolormap = 0; } } } @@ -471,7 +446,7 @@ void APowerInvulnerable::EndEffect () if (Owner->player != NULL) { - Owner->player->fixedcolormap = 0; + Owner->player->fixedcolormap = NOFIXEDCOLORMAP; } } @@ -565,7 +540,7 @@ IMPLEMENT_CLASS (APowerInvisibility) IMPLEMENT_CLASS (APowerShadow) // Invisibility flag combos -#define INVISIBILITY_FLAGS1 (MF_SHADOW | MF_STEALTH) +#define INVISIBILITY_FLAGS1 (MF_SHADOW) #define INVISIBILITY_FLAGS3 (MF3_GHOST) #define INVISIBILITY_FLAGS5 (MF5_CANTSEEK) @@ -590,24 +565,6 @@ void APowerInvisibility::InitEffect () flags5 &= ~(Owner->flags5 & INVISIBILITY_FLAGS5); Owner->flags5 |= flags5 & INVISIBILITY_FLAGS5; - // Finds out what's the normal alpha and render style for the owner. - // First assume it's what it currently is. - //OwnersNormalStyle = Owner->RenderStyle; - //OwnersNormalAlpha = Owner->alpha; - // Then look if there aren't active invis powerups and look what they're saying. - /*AInventory *item = Owner->Inventory; - while (item != NULL) - { - if (item->IsKindOf(RUNTIME_CLASS(APowerInvisibility)) && item != this) - { - OwnersNormalStyle = static_cast(item)->OwnersNormalStyle; - OwnersNormalAlpha = static_cast(item)->OwnersNormalAlpha; - item = NULL; // No need to look further - } - else item = item->Inventory; - } - Printf("Owner's normal style is found to be %i, normal alpha is found to be %i.\n", - OwnersNormalStyle, OwnersNormalAlpha>>FRACBITS);*/ DoEffect(); } } @@ -623,7 +580,7 @@ void APowerInvisibility::DoEffect () // Due to potential interference with other PowerInvisibility items // the effect has to be refreshed each tic. fixed_t ts = Strength * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT; - Owner->alpha = clamp((/*OwnersNormalAlpha*/OPAQUE - ts), 0, OPAQUE); + Owner->alpha = clamp((OPAQUE - ts), 0, OPAQUE); switch (Mode) { case (NAME_Fuzzy): @@ -639,6 +596,7 @@ void APowerInvisibility::DoEffect () Owner->RenderStyle = STYLE_Stencil; break; case (NAME_None): + case (NAME_Cumulative): case (NAME_Translucent): Owner->RenderStyle = STYLE_Translucent; break; @@ -663,8 +621,8 @@ void APowerInvisibility::EndEffect () Owner->flags3 &= ~(flags3 & INVISIBILITY_FLAGS3); Owner->flags5 &= ~(flags5 & INVISIBILITY_FLAGS5); - Owner->RenderStyle = STYLE_Normal;//OwnersNormalStyle; - Owner->alpha = OPAQUE;//OwnersNormalAlpha; + Owner->RenderStyle = STYLE_Normal; + Owner->alpha = OPAQUE; // Check whether there are other invisibility items and refresh their effect. // If this isn't done there will be one incorrectly drawn frame when this @@ -693,15 +651,15 @@ int APowerInvisibility::AlterWeaponSprite (vissprite_t *vis) // Blink if the powerup is wearing off if (changed == 0 && EffectTics < 4*32 && !(EffectTics & 8)) { - vis->RenderStyle = STYLE_Normal;//OwnersNormalStyle; - vis->alpha = OPAQUE;//OwnersNormalAlpha; + vis->RenderStyle = STYLE_Normal; + vis->alpha = OPAQUE; return 1; } else if (changed == 1) { // something else set the weapon sprite back to opaque but this item is still active. fixed_t ts = Strength * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT; - vis->alpha = clamp((/*OwnersNormalAlpha*/OPAQUE - ts), 0, OPAQUE); + vis->alpha = clamp((OPAQUE - ts), 0, OPAQUE); switch (Mode) { case (NAME_Fuzzy): @@ -728,7 +686,7 @@ int APowerInvisibility::AlterWeaponSprite (vissprite_t *vis) if ((vis->alpha < TRANSLUC25 && special1 > 0) || (vis->alpha == 0)) { vis->alpha = clamp((OPAQUE - Strength), 0, OPAQUE); - vis->colormap = InverseColormap; + vis->colormap = SpecialColormaps[INVERSECOLORMAP].Colormap; } return -1; // This item is valid so another one shouldn't reset the translucency } @@ -847,11 +805,11 @@ void APowerLightAmp::DoEffect () { if (EffectTics > BLINKTHRESHOLD || (EffectTics & 8)) { - Owner->player->fixedcolormap = 1; + Owner->player->fixedlightlevel = 1; } else { - Owner->player->fixedcolormap = 0; + Owner->player->fixedlightlevel = -1; } } } @@ -866,7 +824,7 @@ void APowerLightAmp::EndEffect () { if (Owner != NULL && Owner->player != NULL && Owner->player->fixedcolormap < NUMCOLORMAPS) { - Owner->player->fixedcolormap = 0; + Owner->player->fixedlightlevel = -1; } } @@ -911,22 +869,22 @@ void APowerTorch::DoEffect () { if (NewTorch != 0) { - if (Owner->player->fixedcolormap + NewTorchDelta > 7 - || Owner->player->fixedcolormap + NewTorchDelta < 1 - || NewTorch == Owner->player->fixedcolormap) + if (Owner->player->fixedlightlevel + NewTorchDelta > 7 + || Owner->player->fixedlightlevel + NewTorchDelta < 0 + || NewTorch == Owner->player->fixedlightlevel) { NewTorch = 0; } else { - Owner->player->fixedcolormap += NewTorchDelta; + Owner->player->fixedlightlevel += NewTorchDelta; } } else { NewTorch = (pr_torch() & 7) + 1; - NewTorchDelta = (NewTorch == Owner->player->fixedcolormap) ? - 0 : ((NewTorch > Owner->player->fixedcolormap) ? 1 : -1); + NewTorchDelta = (NewTorch == Owner->player->fixedlightlevel) ? + 0 : ((NewTorch > Owner->player->fixedlightlevel) ? 1 : -1); } } } diff --git a/src/g_shared/a_artifacts.h b/src/g_shared/a_artifacts.h index 1272de60d..93352a719 100644 --- a/src/g_shared/a_artifacts.h +++ b/src/g_shared/a_artifacts.h @@ -3,14 +3,6 @@ #include "a_pickups.h" -#define INVERSECOLOR 0x00345678 -#define GOLDCOLOR 0x009abcde - -// [BC] More hacks! -#define REDCOLOR 0x00beefee -#define GREENCOLOR 0x00beefad -#define BLUECOLOR 0x00befeed - class player_t; // A powerup is a pseudo-inventory item that applies an effect to its diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index f319f5414..f12c36aef 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -173,7 +173,7 @@ bool P_MorphPlayer (player_t *activator, player_t *p, const PClass *spawntype, i // //---------------------------------------------------------------------------- -bool P_UndoPlayerMorph (player_t *activator, player_t *player, bool force) +bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, bool force) { AWeapon *beastweap; APlayerPawn *mo; @@ -192,10 +192,13 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, bool force) return false; } - if ((pmo->flags2 & MF2_INVULNERABLE) && ((player != activator) || (!(player->MorphStyle & MORPH_WHENINVULNERABLE)))) - { // Immune when invulnerable unless this is something we initiated. - // If the WORLD is the initiator, the same player should be given - // as the activator; WORLD initiated actions should always succeed. + bool DeliberateUnmorphIsOkay = !!(player->MorphStyle & unmorphflag); + + if ((pmo->flags2 & MF2_INVULNERABLE) // If the player is invulnerable + && ((player != activator) // and either did not decide to unmorph, + || (!((player->MorphStyle & MORPH_WHENINVULNERABLE) // or the morph style does not allow it + || (DeliberateUnmorphIsOkay))))) // (but standard morph styles always allow it), + { // Then the player is immune to the unmorph. return false; } diff --git a/src/g_shared/a_morph.h b/src/g_shared/a_morph.h index 338b5f549..cfaec9ae3 100644 --- a/src/g_shared/a_morph.h +++ b/src/g_shared/a_morph.h @@ -17,7 +17,7 @@ enum MORPH_UNDOBYCHAOSDEVICE = 0x00000008, // Player unmorphs upon activating a Chaos Device MORPH_FAILNOTELEFRAG = 0x00000010, // Player stays morphed if unmorph by Tome of Power fails MORPH_FAILNOLAUGH = 0x00000020, // Player doesn't laugh if unmorph by Chaos Device fails - MORPH_WHENINVULNERABLE = 0x00000040, // Player can morph (or scripted unmorph) when invulnerable but ONLY if doing it to themselves + MORPH_WHENINVULNERABLE = 0x00000040, // Player can morph when invulnerable but ONLY if doing it to themselves MORPH_LOSEACTUALWEAPON = 0x00000080, // Player loses specified morph weapon only (not "whichever they have when unmorphing") MORPH_NEWTIDBEHAVIOUR = 0x00000100, // Actor TID is by default transferred from the old actor to the new actor MORPH_UNDOBYDEATH = 0x00000200, // Actor unmorphs when killed and (unless MORPH_UNDOBYDEATHSAVES) stays dead @@ -32,7 +32,7 @@ class AMorphedMonster; bool P_MorphPlayer (player_t *activator, player_t *player, const PClass *morphclass, int duration = 0, int style = 0, const PClass *enter_flash = NULL, const PClass *exit_flash = NULL); -bool P_UndoPlayerMorph (player_t *activator, player_t *player, bool force = false); +bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag = 0, bool force = false); bool P_MorphMonster (AActor *actor, const PClass *morphclass, int duration = 0, int style = 0, const PClass *enter_flash = NULL, const PClass *exit_flash = NULL); bool P_UndoMonsterMorph (AMorphedMonster *beast, bool force = false); diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 045e5bf92..e9d9e2003 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -1741,10 +1741,7 @@ IMPLEMENT_CLASS(AScoreItem) // // AScoreItem :: TryPickup // -// This function does nothing much. Theoretically, the player could have a -// score property which would be incremented by the score items' own score -// property (probably using the Amount property for that), but that is not -// needed for the moment. +// Adds the value (Amount) of the item to the toucher's Score property. // //=========================================================================== diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index 6ccc8cd5e..b402fcf59 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -322,6 +322,7 @@ enum WIF_NO_AUTO_SWITCH = 0x00001000, // never switch to this weapon when it's picked up WIF_STAFF2_KICKBACK = 0x00002000, // the powered-up Heretic staff has special kickback WIF_NOAUTOAIM = 0x00004000, // this weapon never uses autoaim (useful for ballistic projectiles) + WIF_MELEEWEAPON = 0x00008000, // melee weapon. Used by bots and monster AI. WIF_CHEATNOTWEAPON = 0x08000000, // Give cheat considers this not a weapon (used by Sigil) @@ -329,7 +330,6 @@ enum WIF_BOT_REACTION_SKILL_THING = 1<<31, // I don't understand this WIF_BOT_EXPLOSIVE = 1<<30, // weapon fires an explosive - WIF_BOT_MELEE = 1<<29, // melee weapon WIF_BOT_BFG = 1<<28, // this is a BFG }; @@ -477,7 +477,7 @@ public: // A score item is picked up without being added to the inventory. -// Contrarily to FakeInventory, it does nothing. +// It differs from FakeInventory by doing nothing more than increasing the player's score. class AScoreItem : public AInventory { DECLARE_CLASS (AScoreItem, AInventory) diff --git a/src/g_shared/a_randomspawner.cpp b/src/g_shared/a_randomspawner.cpp index b4b9176ae..a5ffa9251 100644 --- a/src/g_shared/a_randomspawner.cpp +++ b/src/g_shared/a_randomspawner.cpp @@ -111,6 +111,8 @@ class ARandomSpawner : public AActor newmobj->args[2] = args[2]; newmobj->args[3] = args[3]; newmobj->args[4] = args[4]; + newmobj->special1 = special1; + newmobj->special2 = special2; newmobj->SpawnFlags = SpawnFlags; newmobj->HandleSpawnFlags(); newmobj->tid = tid; diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index 29b3295e0..d1509c649 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -74,14 +74,14 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag ffloor->bottom.plane = &sec2->floorplane; ffloor->bottom.texture = &sec2->planes[sector_t::floor].Texture; ffloor->bottom.texheight = &sec2->planes[sector_t::floor].TexZ; - ffloor->bottom.isceiling = false; + ffloor->bottom.isceiling = sector_t::floor; } else { ffloor->bottom.plane = &sec2->ceilingplane; ffloor->bottom.texture = &sec2->planes[sector_t::ceiling].Texture; ffloor->bottom.texheight = &sec2->planes[sector_t::ceiling].TexZ; - ffloor->bottom.isceiling = true; + ffloor->bottom.isceiling = sector_t::ceiling; } if (!(flags&FF_FIX)) @@ -90,7 +90,7 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag ffloor->top.texture = &sec2->planes[sector_t::ceiling].Texture; ffloor->top.texheight = &sec2->planes[sector_t::ceiling].TexZ; ffloor->toplightlevel = &sec2->lightlevel; - ffloor->top.isceiling = true; + ffloor->top.isceiling = sector_t::ceiling; } else // FF_FIX is a special case to patch rendering holes { @@ -98,7 +98,7 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag ffloor->top.texture = &sec2->planes[sector_t::floor].Texture; ffloor->top.texheight = &sec2->planes[sector_t::floor].TexZ; ffloor->toplightlevel = &sec->lightlevel; - ffloor->top.isceiling = false; + ffloor->top.isceiling = sector_t::floor; ffloor->top.model = sec; } @@ -117,12 +117,14 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag // fortunately this plane won't be rendered - otherwise this wouldn't work... ffloor->bottom.plane=&sec->floorplane; ffloor->bottom.model=sec; + ffloor->bottom.isceiling = sector_t::floor; } } ffloor->flags = flags; ffloor->master = master; ffloor->alpha = transluc; + ffloor->top.vindex = ffloor->bottom.vindex = -1; // The engine cannot handle sloped translucent floors. Sorry if (ffloor->top.plane->a || ffloor->top.plane->b || ffloor->bottom.plane->a || ffloor->bottom.plane->b) diff --git a/src/p_3dfloors.h b/src/p_3dfloors.h index 6ae29e3c3..dfaf5a5eb 100644 --- a/src/p_3dfloors.h +++ b/src/p_3dfloors.h @@ -73,7 +73,8 @@ struct F3DFloor const FTextureID * texture; const fixed_t * texheight; sector_t * model; - bool isceiling; + int isceiling; + int vindex; }; planeref bottom; diff --git a/src/p_acs.cpp b/src/p_acs.cpp index e45f92752..3f24ad0ed 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -2684,6 +2684,7 @@ int DLevelScript::CheckActorProperty (int tid, int property, int value) case APROP_Gravity: case APROP_SpawnHealth: case APROP_JumpZ: + case APROP_Score: return (GetActorProperty(tid, property) == value); // Boolean values need to compare to a binary version of value diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 8cf3273e1..b9e9b9517 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -381,7 +381,7 @@ static void LoadSectors (sectortype *bsec) sec->SetXOffset(sector_t::floor, (bsec->floorxpanning << FRACBITS) + (32 << FRACBITS)); sec->SetYOffset(sector_t::floor, bsec->floorypanning << FRACBITS); sec->SetPlaneLight(sector_t::floor, SHADE2LIGHT (bsec->floorshade)); - sec->ChangeFlags(sector_t::floor, 0, SECF_ABSLIGHTING); + sec->ChangeFlags(sector_t::floor, 0, PLANEF_ABSLIGHTING); sec->SetPlaneTexZ(sector_t::ceiling, -(LittleLong(bsec->ceilingz) << 8)); sec->ceilingplane.d = sec->GetPlaneTexZ(sector_t::ceiling); @@ -399,7 +399,7 @@ static void LoadSectors (sectortype *bsec) sec->SetXOffset(sector_t::ceiling, (bsec->ceilingxpanning << FRACBITS) + (32 << FRACBITS)); sec->SetYOffset(sector_t::ceiling, bsec->ceilingypanning << FRACBITS); sec->SetPlaneLight(sector_t::ceiling, SHADE2LIGHT (bsec->ceilingshade)); - sec->ChangeFlags(sector_t::ceiling, 0, SECF_ABSLIGHTING); + sec->ChangeFlags(sector_t::ceiling, 0, PLANEF_ABSLIGHTING); sec->lightlevel = (sec->GetPlaneLight(sector_t::floor) + sec->GetPlaneLight(sector_t::ceiling)) / 2; diff --git a/src/p_ceiling.cpp b/src/p_ceiling.cpp index 4da11fd04..12f957b47 100644 --- a/src/p_ceiling.cpp +++ b/src/p_ceiling.cpp @@ -232,7 +232,7 @@ bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line, sec = §ors[secnum]; manual_ceiling: // if ceiling already moving, don't start a second function on it - if (sec->ceilingdata) + if (sec->PlaneMoving(sector_t::ceiling)) { if (!manual) continue; diff --git a/src/p_doors.cpp b/src/p_doors.cpp index 090065fb4..c77ded90d 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -394,7 +394,7 @@ bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, secnum = int(sec-sectors); // if door already has a thinker, use it - if (sec->ceilingdata) + if (sec->PlaneMoving(sector_t::ceiling)) { if (sec->ceilingdata->IsKindOf (RUNTIME_CLASS(DDoor))) { @@ -447,7 +447,7 @@ bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, { sec = §ors[secnum]; // if the ceiling already moving, don't start the door action - if (sec->ceilingdata) + if (sec->PlaneMoving(sector_t::ceiling)) continue; if (new DDoor (sec, type, speed, delay, lightTag)) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index a321955a2..7e3bb0b26 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -62,8 +62,10 @@ static FRandom pr_look2 ("LookyLooky"); static FRandom pr_look3 ("IGotHooky"); static FRandom pr_slook ("SlooK"); static FRandom pr_dropoff ("Dropoff"); +static FRandom pr_defect ("Defect"); static FRandom pr_skiptarget("SkipTarget"); +static FRandom pr_enemystrafe("EnemyStrafe"); // movement interpolation is fine for objects that are moved by their own // velocity. But for monsters it is problematic. @@ -219,20 +221,20 @@ void P_NoiseAlert (AActor *target, AActor *emmiter, bool splash) bool AActor::CheckMeleeRange () { - AActor *pl; + AActor *pl = target; + fixed_t dist; - if (!target) + if (!pl) return false; - pl = target; dist = P_AproxDistance (pl->x - x, pl->y - y); if (dist >= meleerange + pl->radius) return false; // [RH] If moving toward goal, then we've reached it. - if (target == goal) + if (pl == goal) return true; // [RH] Don't melee things too far above or below actor. @@ -243,6 +245,10 @@ bool AActor::CheckMeleeRange () if (pl->z + pl->height < z) return false; } + + // killough 7/18/98: friendly monsters don't attack other friends + if (IsFriend(pl)) + return false; if (!P_CheckSight (this, pl, 0)) return false; @@ -279,6 +285,12 @@ bool P_CheckMeleeRange2 (AActor *actor) { // Attacker is higher return false; } + else if (actor->IsFriend(mo)) + { + // killough 7/18/98: friendly monsters don't attack other friends + return false; + } + if (!P_CheckSight(actor, mo)) { return false; @@ -303,12 +315,34 @@ bool P_CheckMissileRange (AActor *actor) { // the target just hit the enemy, so fight back! actor->flags &= ~MF_JUSTHIT; - return true; + + // killough 7/18/98: no friendly fire at corpses + // killough 11/98: prevent too much infighting among friends + // Cleaned up and made readable + if (!(actor->flags & MF_FRIENDLY)) return true; + if (actor->target->health <= 0) return false; + if (!actor->IsFriend(actor->target)) return true; + if (actor->target->player != NULL) + { + return (pr_defect() >128); + } + else + { + return !(actor->target->flags & MF_JUSTHIT) && pr_defect() >128; + } } if (actor->reactiontime) return false; // do not attack yet - + + // killough 7/18/98: friendly monsters don't attack other friendly + // monsters or players (except when attacked, and then only once) + if (actor->IsFriend(actor->target)) + return false; + + if (actor->flags & MF_FRIENDLY && P_HitFriend(actor)) + return false; + // OPTIMIZE: get this from a global checksight // [RH] What? dist = P_AproxDistance (actor->x-actor->target->x, @@ -357,7 +391,7 @@ bool P_HitFriend(AActor * self) if (self->flags&MF_FRIENDLY && self->target != NULL) { angle_t angle = R_PointToAngle2 (self->x, self->y, self->target->x, self->target->y); - fixed_t dist = P_AproxDistance (self->x-self->target->x, self->y-self->target->y); + fixed_t dist = P_AproxDistance (self->x - self->target->x, self->y - self->target->y); P_AimLineAttack (self, angle, dist, &linetarget, 0, true); if (linetarget != NULL && linetarget != self->target) { @@ -739,6 +773,8 @@ void P_NewChaseDir(AActor * actor) fixed_t deltax; fixed_t deltay; + actor->strafecount = 0; + if ((actor->flags5&MF5_CHASEGOAL || actor->goal == actor->target) && actor->goal!=NULL) { deltax = actor->goal->x - actor->x; @@ -831,7 +867,56 @@ void P_NewChaseDir(AActor * actor) return; } } + +#if 0 + // Move away from friends when too close, except + // in certain situations (e.g. a crowded lift) + + // MBF code for friends. Cannot be done in ZDoom but left here as a reminder for later implementation. + + if (actor->flags & target->flags & MF_FRIEND && + distfriend << FRACBITS > dist && + !P_IsOnLift(target) && !P_IsUnderDamage(actor)) + deltax = -deltax, deltay = -deltay; + else +#endif + + // MBF's monster_backing option. Made an actor flag instead. Also cleaned the code up to make it readable. + // Todo: implement the movement logic + AActor *target = actor->target; + if (target->health > 0 && !actor->IsFriend(target)) + { // Live enemy target + + if (actor->flags3 & MF3_AVOIDMELEE) + { + bool ismeleeattacker = false; + fixed_t dist = P_AproxDistance(actor->x-target->x, actor->y-target->y); + if (target->player == NULL) + { + ismeleeattacker = (target->MissileState == NULL && dist < (target->meleerange + target->radius)*2); + } + else if (target->player->ReadyWeapon != NULL) + { + // melee range of player weapon is a parameter of the action function and cannot be checked here. + // Add a new weapon property? + ismeleeattacker = (target->player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON && dist < MELEERANGE*3); + } + if (ismeleeattacker) + { + actor->strafecount = pr_enemystrafe() & 15; + deltax = -deltax, deltay = -deltay; + } + } + } + P_DoNewChaseDir(actor, deltax, deltay); + + // If strafing, set movecount to strafecount so that old Doom + // logic still works the same, except in the strafing part + + if (actor->strafecount) + actor->movecount = actor->strafecount; + } @@ -996,6 +1081,58 @@ void P_RandomChaseDir (AActor *actor) actor->movedir = DI_NODIR; // cannot move } +//--------------------------------------------------------------------------- +// +// P_IsVisible +// +// killough 9/9/98: whether a target is visible to a monster +// Extended to handle all A_LookEx related checking, too. +// +//--------------------------------------------------------------------------- + +bool P_IsVisible(AActor *lookee, AActor *other, INTBOOL allaround, FLookExParams *params) +{ + fixed_t maxdist; + fixed_t mindist; + angle_t fov; + + if (params != NULL) + { + maxdist = params->maxdist; + mindist = params->mindist; + fov = params->fov; + } + else + { + mindist = maxdist = 0; + fov = allaround? 0 : ANGLE_180; + } + + fixed_t dist = P_AproxDistance (other->x - lookee->x, other->y - lookee->y); + + if (maxdist && dist > maxdist) + return false; // [KS] too far + + if (mindist && dist < mindist) + return false; // [KS] too close + + if (fov && fov < ANGLE_MAX) + { + angle_t an = R_PointToAngle2 (lookee->x, lookee->y, other->x, other->y) - lookee->angle; + + if (an > (fov / 2) && an < (ANGLE_MAX - (fov / 2))) + { + // if real close, react anyway + // [KS] but respect minimum distance rules + if (mindist || dist > MELEERANGE) + return false; // outside of fov + } + } + + // P_CheckSight is by far the most expensive operation in here so let's do it last. + return P_CheckSight(lookee, other, 2); +} + //--------------------------------------------------------------------------- // // FUNC P_LookForMonsters @@ -1061,8 +1198,9 @@ bool P_LookForMonsters (AActor *actor) // //============================================================================ -AActor *LookForTIDinBlock (AActor *lookee, int index) +AActor *LookForTIDInBlock (AActor *lookee, int index, void *extparams) { + FLookExParams *params = (FLookExParams *)extparams; FBlockNode *block; AActor *link; AActor *other; @@ -1104,25 +1242,8 @@ AActor *LookForTIDinBlock (AActor *lookee, int index) if (!(lookee->flags3 & MF3_NOSIGHTCHECK)) { - if (!P_CheckSight (lookee, other, 2)) + if (!P_IsVisible(lookee, other, true, params)) continue; // out of sight - /* - if (!allaround) - { - angle_t an = R_PointToAngle2 (actor->x, actor->y, - other->x, other->y) - - actor->angle; - - if (an > ANG90 && an < ANG270) - { - fixed_t dist = P_AproxDistance (other->x - actor->x, - other->y - actor->y); - // if real close, react anyway - if (dist > MELEERANGE) - continue; // behind back - } - } - */ } return other; @@ -1138,12 +1259,13 @@ AActor *LookForTIDinBlock (AActor *lookee, int index) // //============================================================================ -bool P_LookForTID (AActor *actor, INTBOOL allaround) +bool P_LookForTID (AActor *actor, INTBOOL allaround, FLookExParams *params) { AActor *other; bool reachedend = false; + bool chasegoal = params? (!(params->flags & LOF_DONTCHASEGOAL)) : true; - other = P_BlockmapSearch (actor, 0, LookForTIDinBlock); + other = P_BlockmapSearch (actor, 0, LookForTIDInBlock, params); if (other != NULL) { @@ -1198,24 +1320,8 @@ bool P_LookForTID (AActor *actor, INTBOOL allaround) if (!(actor->flags3 & MF3_NOSIGHTCHECK)) { - if (!P_CheckSight (actor, other, 2)) + if (!P_IsVisible (actor, other, !!allaround, params)) continue; // out of sight - - if (!allaround) - { - angle_t an = R_PointToAngle2 (actor->x, actor->y, - other->x, other->y) - - actor->angle; - - if (an > ANG90 && an < ANG270) - { - fixed_t dist = P_AproxDistance (other->x - actor->x, - other->y - actor->y); - // if real close, react anyway - if (dist > MELEERANGE) - continue; // behind back - } - } } // [RH] Need to be sure the reactiontime is 0 if the monster is @@ -1231,7 +1337,7 @@ bool P_LookForTID (AActor *actor, INTBOOL allaround) if (actor->target == NULL) { // [RH] use goal as target - if (actor->goal != NULL) + if (actor->goal != NULL && chasegoal) { actor->target = actor->goal; return true; @@ -1256,18 +1362,19 @@ bool P_LookForTID (AActor *actor, INTBOOL allaround) //============================================================================ // -// LookForTIDinBlock +// LookForEnemiesinBlock // // Finds a non-friendly monster in a mapblock. It can also use targets of // friendlies in this mapblock to find non-friendlies in other mapblocks. // //============================================================================ -AActor *LookForEnemiesInBlock (AActor *lookee, int index) +AActor *LookForEnemiesInBlock (AActor *lookee, int index, void *extparam) { FBlockNode *block; AActor *link; AActor *other; + FLookExParams *params = (FLookExParams *)extparam; for (block = blocklinks[index]; block != NULL; block = block->NextActor) { @@ -1330,25 +1437,11 @@ AActor *LookForEnemiesInBlock (AActor *lookee, int index) } } - if (other == NULL || !P_CheckSight (lookee, other, 2)) + // [KS] Hey, shouldn't there be a check for MF3_NOSIGHTCHECK here? + + if (other == NULL || !P_IsVisible (lookee, other, true, params)) continue; // out of sight - /* - if (!allaround) - { - angle_t an = R_PointToAngle2 (actor->x, actor->y, - other->x, other->y) - - actor->angle; - - if (an > ANG90 && an < ANG270) - { - fixed_t dist = P_AproxDistance (other->x - actor->x, - other->y - actor->y); - // if real close, react anyway - if (dist > MELEERANGE) - continue; // behind back - } - } - */ + return other; } @@ -1363,11 +1456,11 @@ AActor *LookForEnemiesInBlock (AActor *lookee, int index) // //============================================================================ -bool P_LookForEnemies (AActor *actor, INTBOOL allaround) +bool P_LookForEnemies (AActor *actor, INTBOOL allaround, FLookExParams *params) { AActor *other; - other = P_BlockmapSearch (actor, 10, LookForEnemiesInBlock); + other = P_BlockmapSearch (actor, 10, LookForEnemiesInBlock, params); if (other != NULL) { @@ -1415,18 +1508,17 @@ bool P_LookForEnemies (AActor *actor, INTBOOL allaround) ================ */ -bool P_LookForPlayers (AActor *actor, INTBOOL allaround) +bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params) { int c; int stop; int pnum; player_t* player; - angle_t an; - fixed_t dist; + bool chasegoal = params? (!(params->flags & LOF_DONTCHASEGOAL)) : true; if (actor->TIDtoHate != 0) { - if (P_LookForTID (actor, allaround)) + if (P_LookForTID (actor, allaround, params)) { return true; } @@ -1437,10 +1529,43 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround) } else if (actor->flags & MF_FRIENDLY) { - if (!deathmatch) // [SP] If you don't see any enemies in deathmatch, look for players. - return P_LookForEnemies (actor, allaround); - else if ( P_LookForEnemies (actor, allaround) ) - return true; + bool result = P_LookForEnemies (actor, allaround, params); + +#ifdef MBF_FRIENDS + if (!result && (actor->flags & MF_FRIEND_MBF)) + { // killough 9/9/98: friendly monsters go about players differently + + // Go back to a player, no matter whether it's visible or not + for (int anyone=0; anyone<=1; anyone++) + { + for (int c=0; cIsFriend(players[c].mo) && + (anyone || P_IsVisible(actor, players[c].mo, allaround))) + { + actor->target = players[c].mo; + + // killough 12/98: + // get out of refiring loop, to avoid hitting player accidentally + + if (actor->MissileState != NULL) + { + actor->SetStateNF(actor->SeeState); + actor->flags &= ~MF_JUSTHIT; + } + + return true; + } + } + } + } +#endif + // [SP] If you don't see any enemies in deathmatch, look for players (but only when friend to a specific player.) + if (actor->FriendPlayer == 0) return result; + if (result || !deathmatch) return true; + + } // [SP] if false, and in deathmatch, intentional fall-through if (!(gameinfo.gametype & (GAME_DoomStrifeChex)) && @@ -1478,7 +1603,8 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround) if (actor->target == NULL) { // [RH] use goal as target - if (actor->goal != NULL) + // [KS] ...unless we're ignoring goals and we don't already have one + if (actor->goal != NULL && chasegoal) { actor->target = actor->goal; return true; @@ -1512,7 +1638,7 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround) if (player->health <= 0) continue; // dead - if (!P_CheckSight (actor, player->mo, 2)) + if (!P_IsVisible (actor, player->mo, allaround, params)) continue; // out of sight // [SP] Deathmatch fixes - if we have MF_FRIENDLY we're definitely in deathmatch @@ -1525,23 +1651,6 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround) continue; // This is my master. } - if (!allaround) - { - an = R_PointToAngle2 (actor->x, - actor->y, - player->mo->x, - player->mo->y) - - actor->angle; - - if (an > ANG90 && an < ANG270) - { - dist = P_AproxDistance (player->mo->x - actor->x, - player->mo->y - actor->y); - // if real close, react anyway - if (dist > MELEERANGE) - continue; // behind back - } - } if ((player->mo->flags & MF_SHADOW && !(i_compatflags & COMPATF_INVISIBILITY)) || player->mo->flags3 & MF3_GHOST) { @@ -1630,7 +1739,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look) { // If we find a valid target here, the wandering logic should *not* // be activated! It would cause the seestate to be set twice. - if (P_LookForPlayers (self, self->flags4 & MF4_LOOKALLAROUND)) + if (P_LookForPlayers (self, self->flags4 & MF4_LOOKALLAROUND, NULL)) goto seeyou; // Let the self wander around aimlessly looking for a fight @@ -1657,7 +1766,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look) } } - if (!P_LookForPlayers (self, self->flags4 & MF4_LOOKALLAROUND)) + if (!P_LookForPlayers (self, self->flags4 & MF4_LOOKALLAROUND, NULL)) return; // go into chase state @@ -1687,6 +1796,193 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look) } +//========================================================================== +// +// A_LookEx (int flags, fixed minseedist, fixed maxseedist, fixed maxheardist, fixed fov, state wakestate) +// [KS] Borrowed the A_Look code to make a parameterized version. +// +//========================================================================== + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LookEx) +{ + ACTION_PARAM_START(6); + ACTION_PARAM_INT(flags, 0); + ACTION_PARAM_FIXED(minseedist, 1); + ACTION_PARAM_FIXED(maxseedist, 2); + ACTION_PARAM_FIXED(maxheardist, 3); + ACTION_PARAM_ANGLE(fov, 4); + ACTION_PARAM_STATE(seestate, 5); + + AActor *targ = NULL; // Shuts up gcc + fixed_t dist; + FLookExParams params = {fov, minseedist, maxseedist, maxheardist, flags, seestate }; + + if (self->flags5 & MF5_INCONVERSATION) + return; + + // [RH] Set goal now if appropriate + if (self->special == Thing_SetGoal && self->args[0] == 0) + { + NActorIterator iterator (NAME_PatrolPoint, self->args[1]); + self->special = 0; + self->goal = iterator.Next (); + self->reactiontime = self->args[2] * TICRATE + level.maptime; + if (self->args[3] == 0) self->flags5 &=~ MF5_CHASEGOAL; + else self->flags5 |= MF5_CHASEGOAL; + } + + self->threshold = 0; // any shot will wake up + + if (self->TIDtoHate != 0) + { + targ = self->target; + } + else + { + if (!(flags & LOF_NOSOUNDCHECK)) + { + targ = (self->flags & MF_NOSECTOR)? self->Sector->SoundTarget : self->LastHeard; + if (targ != NULL) + { + // [RH] If the soundtarget is dead, don't chase it + if (targ->health <= 0) + { + targ = NULL; + } + else + { + dist = P_AproxDistance (targ->x - self->x, + targ->y - self->y); + + // [KS] If the target is too far away, don't respond to the sound. + if (maxheardist && dist > maxheardist) + { + targ = NULL; + self->LastHeard = NULL; + } + } + } + } + + if (targ && targ->player && (targ->player->cheats & CF_NOTARGET)) + { + return; + } + } + + // [RH] Andy Baker's stealth monsters + if (self->flags & MF_STEALTH) + { + self->visdir = -1; + } + + if (targ && (targ->flags & MF_SHOOTABLE)) + { + if (self->IsFriend (targ)) // be a little more precise! + { + if (!(self->flags4 & MF4_STANDSTILL)) + { + if (!(flags & LOF_NOSIGHTCHECK)) + { + // If we find a valid target here, the wandering logic should *not* + // be activated! If would cause the seestate to be set twice. + if (P_LookForPlayers(self, true, ¶ms)) + goto seeyou; + } + + // Let the self wander around aimlessly looking for a fight + if (!(self->flags & MF_INCHASE)) + { + if (seestate) + { + self->SetState (seestate); + } + else + { + if (self->SeeState != NULL) + { + self->SetState (self->SeeState); + } + else + { + CALL_ACTION(A_Wander, self); + } + } + } + } + } + else + { + self->target = targ; //We already have a target? + + // [KS] The target can become ourselves in rare circumstances (like + // if we committed suicide), so if that's the case, just ignore it. + if (self->target == self) self->target = NULL; + + if (self->target != NULL) + { + if (self->flags & MF_AMBUSH) + { + dist = P_AproxDistance (self->target->x - self->x, + self->target->y - self->y); + if (P_CheckSight (self, self->target, 2) && + (!minseedist || dist > minseedist) && + (!maxseedist || dist < maxseedist)) + { + goto seeyou; + } + } + else + goto seeyou; + } + } + } + + if (!(flags & LOF_NOSIGHTCHECK)) + { + if (!P_LookForPlayers(self, true, ¶ms)) + return; + } + else + { + return; + } + + // go into chase state + seeyou: + // [RH] Don't start chasing after a goal if it isn't time yet. + if (self->target == self->goal) + { + if (self->reactiontime > level.maptime) + self->target = NULL; + } + else if (self->SeeSound && !(flags & LOF_NOSEESOUND)) + { + if (flags & LOF_FULLVOLSEESOUND) + { // full volume + S_Sound (self, CHAN_VOICE, self->SeeSound, 1, ATTN_NONE); + } + else + { + S_Sound (self, CHAN_VOICE, self->SeeSound, 1, ATTN_NORM); + } + } + + if (self->target && !(self->flags & MF_INCHASE)) + { + if (seestate) + { + self->SetState (seestate); + } + else + { + self->SetState (self->SeeState); + } + } +} + +// [KS] *** End additions by me *** + //========================================================================== // // A_Wander @@ -1770,7 +2066,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look2) } else { - if (!P_LookForPlayers (self, self->flags4 & MF4_LOOKALLAROUND)) + if (!P_LookForPlayers (self, self->flags4 & MF4_LOOKALLAROUND, NULL)) goto nosee; self->SetState (self->SeeState); self->flags4 |= MF4_INCOMBAT; @@ -1856,7 +2152,11 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi } // turn towards movement direction if not there yet - if (actor->movedir < 8) + if (actor->strafecount) + { + A_FaceTarget(actor); + } + else if (actor->movedir < 8) { actor->angle &= (angle_t)(7<<29); delta = actor->angle - (actor->movedir << 29); @@ -1916,7 +2216,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi // hurt our old one temporarily. actor->threshold = 0; } - if (P_LookForPlayers (actor, true) && actor->target != actor->goal) + if (P_LookForPlayers (actor, true, NULL) && actor->target != actor->goal) { // got a new target actor->flags &= ~MF_INCHASE; return; @@ -2088,7 +2388,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi lookForBetter = true; } AActor * oldtarget = actor->target; - gotNew = P_LookForPlayers (actor, true); + gotNew = P_LookForPlayers (actor, true, NULL); if (lookForBetter) { actor->flags3 |= MF3_NOSIGHTCHECK; @@ -2104,6 +2404,9 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi // chase towards player // + if (actor->strafecount) + actor->strafecount--; + // class bosses don't do this when strafing if ((!fastchase || !actor->FastChaseStrafeCount) && !dontmove) { diff --git a/src/p_enemy.h b/src/p_enemy.h index 73fe06e3d..b26360631 100644 --- a/src/p_enemy.h +++ b/src/p_enemy.h @@ -25,6 +25,25 @@ enum dirtype_t extern fixed_t xspeed[8], yspeed[8]; +enum LO_Flags +{ + LOF_NOSIGHTCHECK = 1, + LOF_NOSOUNDCHECK = 2, + LOF_DONTCHASEGOAL = 4, + LOF_NOSEESOUND = 8, + LOF_FULLVOLSEESOUND = 16, +}; + +struct FLookExParams +{ + angle_t fov; + fixed_t mindist; + fixed_t maxdist; + fixed_t maxheardist; + int flags; + FState *seestate; +}; + void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soundblocks); bool P_HitFriend (AActor *self); void P_NoiseAlert (AActor *target, AActor *emmiter, bool splash=false); @@ -32,9 +51,9 @@ bool P_CheckMeleeRange2 (AActor *actor); bool P_Move (AActor *actor); bool P_TryWalk (AActor *actor); void P_NewChaseDir (AActor *actor); -bool P_LookForPlayers (AActor *actor, INTBOOL allaround); 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); DECLARE_ACTION(A_Look) DECLARE_ACTION(A_Wander) diff --git a/src/p_enemy_a_lookex.cpp b/src/p_enemy_a_lookex.cpp deleted file mode 100644 index 4c68fcbf2..000000000 --- a/src/p_enemy_a_lookex.cpp +++ /dev/null @@ -1,904 +0,0 @@ -#include - -#include "templates.h" -#include "m_random.h" -#include "i_system.h" -#include "doomdef.h" -#include "p_local.h" -#include "p_lnspec.h" -#include "s_sound.h" -#include "g_game.h" -#include "doomstat.h" -#include "r_state.h" -#include "c_cvars.h" -#include "p_enemy.h" -#include "a_sharedglobal.h" -#include "a_action.h" -#include "thingdef/thingdef.h" -#include "g_level.h" - -#include "gi.h" - -bool P_LookForMonsters (AActor *actor); - -static FRandom pr_look2 ("LookyLookyEx"); -static FRandom pr_look3 ("IGotHookyEx"); -static FRandom pr_lookforplayers ("LookForPlayersEx"); -static FRandom pr_skiptarget("SkipTargetEx"); - - -// [KS] *** Start additions by me - p_enemy.cpp *** - -// LookForTIDinBlockEx -// LookForEnemiesInBlockEx -// P_NewLookTID (copied from P_LookForTID) -// P_NewLookPlayers (copied from P_LookForPlayers) -// Takes FOV and sight distances into account when acquiring a target. -// TODO: Not sure if using actor properties to pass parameters around indirectly is such a good idea. If there's a cleaner method, do it that way instead. -// ~Kate S. Last updated on 12/23/2007 - -AActor *LookForTIDinBlockEx (AActor *lookee, int index) -{ - FBlockNode *block; - AActor *link; - AActor *other; - fixed_t dist; - angle_t an; - - for (block = blocklinks[index]; block != NULL; block = block->NextActor) - { - link = block->Me; - - if (!(link->flags & MF_SHOOTABLE)) - continue; // not shootable (observer or dead) - - if (link == lookee) - continue; - - if (link->health <= 0) - continue; // dead - - if (link->flags2 & MF2_DORMANT) - continue; // don't target dormant things - - if (link->tid == lookee->TIDtoHate) - { - other = link; - } - else if (link->target != NULL && link->target->tid == lookee->TIDtoHate) - { - other = link->target; - if (!(other->flags & MF_SHOOTABLE) || - other->health <= 0 || - (other->flags2 & MF2_DORMANT)) - { - continue; - } - } - else - { - continue; - } - - if (!(lookee->flags3 & MF3_NOSIGHTCHECK)) - { - if (!P_CheckSight (lookee, other, 2)) - continue; // out of sight - - dist = P_AproxDistance (other->x - lookee->x, - other->y - lookee->y); - - if (lookee->LookExMaxDist && dist > lookee->LookExMaxDist) - continue; // [KS] too far - - if (lookee->LookExMinDist && dist < lookee->LookExMinDist) - continue; // [KS] too close - - if (lookee->LookExFOV && lookee->LookExFOV < ANGLE_MAX) - { - an = R_PointToAngle2 (lookee->x, - lookee->y, - other->x, - other->y) - - lookee->angle; - - if (an > (lookee->LookExFOV / 2) && an < (ANGLE_MAX - (lookee->LookExFOV / 2))) - { - // if real close, react anyway - // [KS] but respect minimum distance rules - if (lookee->LookExMinDist || dist > MELEERANGE) - continue; // outside of fov - } - } - else - { - if(!(lookee->flags4 & MF4_LOOKALLAROUND) || (lookee->LookExFOV >= ANGLE_MAX)) // Just in case angle_t doesn't clamp stuff, because I can't be too sure. - { - an = R_PointToAngle2 (lookee->x, - lookee->y, - other->x, - other->y) - - lookee->angle; - - if (an > ANG90 && an < ANG270) - { - // if real close, react anyway - // [KS] but respect minimum distance rules - if (lookee->LookExMinDist || dist > MELEERANGE) - continue; // behind back - } - } - } - } - - return other; - } - return NULL; -} - -AActor *LookForEnemiesInBlockEx (AActor *lookee, int index) -{ - FBlockNode *block; - AActor *link; - AActor *other; - fixed_t dist; - angle_t an; - - for (block = blocklinks[index]; block != NULL; block = block->NextActor) - { - link = block->Me; - - if (!(link->flags & MF_SHOOTABLE)) - continue; // not shootable (observer or dead) - - if (link == lookee) - continue; - - if (link->health <= 0) - continue; // dead - - if (link->flags2 & MF2_DORMANT) - continue; // don't target dormant things - - if (!(link->flags3 & MF3_ISMONSTER)) - continue; // don't target it if it isn't a monster (could be a barrel) - - other = NULL; - if (link->flags & MF_FRIENDLY) - { - if (deathmatch && - lookee->FriendPlayer != 0 && link->FriendPlayer != 0 && - lookee->FriendPlayer != link->FriendPlayer) - { - // This is somebody else's friend, so go after it - other = link; - } - else if (link->target != NULL && !(link->target->flags & MF_FRIENDLY)) - { - other = link->target; - if (!(other->flags & MF_SHOOTABLE) || - other->health <= 0 || - (other->flags2 & MF2_DORMANT)) - { - other = NULL;; - } - } - } - else - { - other = link; - } - - // [MBF] If the monster is already engaged in a one-on-one attack - // with a healthy friend, don't attack around 60% the time. - - // [GrafZahl] This prevents friendlies from attacking all the same - // target. - - if (other) - { - AActor *targ = other->target; - if (targ && targ->target == other && pr_skiptarget() > 100 && lookee->IsFriend (targ) && - targ->health*2 >= targ->SpawnHealth()) - { - continue; - } - } - - // [KS] Hey, shouldn't there be a check for MF3_NOSIGHTCHECK here? - - if (other == NULL || !P_CheckSight (lookee, other, 2)) - continue; // out of sight - - dist = P_AproxDistance (other->x - lookee->x, - other->y - lookee->y); - - if (lookee->LookExMaxDist && dist > lookee->LookExMaxDist) - continue; // [KS] too far - - if (lookee->LookExMinDist && dist < lookee->LookExMinDist) - continue; // [KS] too close - - if (lookee->LookExFOV && lookee->LookExFOV < ANGLE_MAX) - { - an = R_PointToAngle2 (lookee->x, - lookee->y, - other->x, - other->y) - - lookee->angle; - - if (an > (lookee->LookExFOV / 2) && an < (ANGLE_MAX - (lookee->LookExFOV / 2))) - { - // if real close, react anyway - // [KS] but respect minimum distance rules - if (lookee->LookExMinDist || dist > MELEERANGE) - continue; // outside of fov - } - } - else - { - if(!(lookee->flags4 & MF4_LOOKALLAROUND) || (lookee->LookExFOV >= ANGLE_MAX)) // Just in case angle_t doesn't clamp stuff, because I can't be too sure. - { - an = R_PointToAngle2 (lookee->x, - lookee->y, - other->x, - other->y) - - lookee->angle; - - if (an > ANG90 && an < ANG270) - { - // if real close, react anyway - // [KS] but respect minimum distance rules - if (lookee->LookExMinDist || dist > MELEERANGE) - continue; // behind back - } - } - } - - return other; - } - return NULL; -} - -bool P_NewLookTID (AActor *actor, angle_t fov, fixed_t mindist, fixed_t maxdist, bool chasegoal) -{ - AActor *other; - - actor->LookExMinDist = mindist; - actor->LookExMaxDist = maxdist; - actor->LookExFOV = fov; - other = P_BlockmapSearch (actor, 0, LookForTIDinBlockEx); - - bool reachedend = false; - fixed_t dist; - angle_t an; - - if (other != NULL) - { - if (!(actor->flags3 & MF3_NOSIGHTCHECK)) - { - dist = P_AproxDistance (other->x - actor->x, - other->y - actor->y); - - if (maxdist && dist > maxdist) - { - other = NULL; // [KS] too far - goto endcheck; - } - - if (mindist && dist < mindist) - { - other = NULL; // [KS] too close - goto endcheck; - } - - if (fov && fov < ANGLE_MAX) - { - an = R_PointToAngle2 (actor->x, - actor->y, - other->x, - other->y) - - actor->angle; - - if (an > (fov / 2) && an < (ANGLE_MAX - (fov / 2))) - { - // if real close, react anyway - // [KS] but respect minimum distance rules - if (mindist || dist > MELEERANGE) - { - other = NULL; // outside of fov - goto endcheck; - } - } - } - else - { - if(!((actor->flags4 & MF4_LOOKALLAROUND) || (fov >= ANGLE_MAX))) // Just in case angle_t doesn't clamp stuff, because I can't be too sure. - { - an = R_PointToAngle2 (actor->x, - actor->y, - other->x, - other->y) - - actor->angle; - - if (an > ANG90 && an < ANG270) - { - // if real close, react anyway - // [KS] but respect minimum distance rules - if (mindist || dist > MELEERANGE) - { - other = NULL; // behind back - goto endcheck; - } - } - } - } - } - } - - endcheck: - - if (other != NULL) - { - if (actor->goal && actor->target == actor->goal) - actor->reactiontime = 0; - - actor->target = other; - actor->LastLookActor = other; - return true; - } - - // The actor's TID could change because of death or because of - // Thing_ChangeTID. If it's not what we expect, then don't use - // it as a base for the iterator. - if (actor->LastLookActor != NULL && - actor->LastLookActor->tid != actor->TIDtoHate) - { - actor->LastLookActor = NULL; - } - - FActorIterator iterator (actor->TIDtoHate, actor->LastLookActor); - int c = (pr_look3() & 31) + 7; // Look for between 7 and 38 hatees at a time - while ((other = iterator.Next()) != actor->LastLookActor) - { - if (other == NULL) - { - if (reachedend) - { - // we have cycled through the entire list at least once - // so let's abort because even if we continue nothing can - // be found. - break; - } - reachedend = true; - continue; - } - - if (!(other->flags & MF_SHOOTABLE)) - continue; // not shootable (observer or dead) - - if (other == actor) - continue; // don't hate self - - if (other->health <= 0) - continue; // dead - - if (other->flags2 & MF2_DORMANT) - continue; // don't target dormant things - - if (--c == 0) - break; - - if (!(actor->flags3 & MF3_NOSIGHTCHECK)) - { - if (!P_CheckSight (actor, other, 2)) - continue; // out of sight - - dist = P_AproxDistance (other->x - actor->x, - other->y - actor->y); - - if (maxdist && dist > maxdist) - continue; // [KS] too far - - if (mindist && dist < mindist) - continue; // [KS] too close - - if (fov && fov < ANGLE_MAX) - { - an = R_PointToAngle2 (actor->x, - actor->y, - other->x, - other->y) - - actor->angle; - - if (an > (fov / 2) && an < (ANGLE_MAX - (fov / 2))) - { - // if real close, react anyway - // [KS] but respect minimum distance rules - if (mindist || dist > MELEERANGE) - continue; // outside of fov - } - } - else - { - if(!((actor->flags4 & MF4_LOOKALLAROUND) || (fov >= ANGLE_MAX))) // Just in case angle_t doesn't clamp stuff, because I can't be too sure. - { - an = R_PointToAngle2 (actor->x, - actor->y, - other->x, - other->y) - - actor->angle; - - if (an > ANG90 && an < ANG270) - { - // if real close, react anyway - // [KS] but respect minimum distance rules - if (mindist || dist > MELEERANGE) - continue; // behind back - } - } - } - } - - // [RH] Need to be sure the reactiontime is 0 if the monster is - // leaving its goal to go after something else. - if (actor->goal && actor->target == actor->goal) - actor->reactiontime = 0; - - actor->target = other; - actor->LastLookActor = other; - return true; - } - actor->LastLookActor = other; - if (actor->target == NULL) - { - // [RH] use goal as target - if (actor->goal != NULL && chasegoal) - { - actor->target = actor->goal; - return true; - } - // Use last known enemy if no hatee sighted -- killough 2/15/98: - if (actor->lastenemy != NULL && actor->lastenemy->health > 0) - { - if (!actor->IsFriend(actor->lastenemy)) - { - actor->target = actor->lastenemy; - actor->lastenemy = NULL; - return true; - } - else - { - actor->lastenemy = NULL; - } - } - } - return false; -} - -bool P_NewLookEnemies (AActor *actor, angle_t fov, fixed_t mindist, fixed_t maxdist, bool chasegoal) -{ - AActor *other; - - actor->LookExMinDist = mindist; - actor->LookExMaxDist = maxdist; - actor->LookExFOV = fov; - other = P_BlockmapSearch (actor, 10, LookForEnemiesInBlockEx); - - if (other != NULL) - { - if (actor->goal && actor->target == actor->goal) - actor->reactiontime = 0; - - actor->target = other; -// actor->LastLook.Actor = other; - return true; - } - - if (actor->target == NULL) - { - // [RH] use goal as target - if (actor->goal != NULL) - { - actor->target = actor->goal; - return true; - } - // Use last known enemy if no hatee sighted -- killough 2/15/98: - if (actor->lastenemy != NULL && actor->lastenemy->health > 0) - { - if (!actor->IsFriend(actor->lastenemy)) - { - actor->target = actor->lastenemy; - actor->lastenemy = NULL; - return true; - } - else - { - actor->lastenemy = NULL; - } - } - } - return false; -} - -bool P_NewLookPlayers (AActor *actor, angle_t fov, fixed_t mindist, fixed_t maxdist, bool chasegoal) -{ - int c; - int stop; - int pnum; - player_t* player; - angle_t an; - fixed_t dist; - - if (actor->TIDtoHate != 0) - { - if (P_NewLookTID (actor, fov, mindist, maxdist, chasegoal)) - { - return true; - } - if (!(actor->flags3 & MF3_HUNTPLAYERS)) - { - return false; - } - } - else if (actor->flags & MF_FRIENDLY) - { - if (!deathmatch) // [SP] If you don't see any enemies in deathmatch, look for players. - return P_NewLookEnemies (actor, fov, mindist, maxdist, chasegoal); - else if ( P_NewLookEnemies (actor, fov, mindist, maxdist, chasegoal) ) - return true; - } // [SP] if false, and in deathmatch, intentional fall-through - - if (!(gameinfo.gametype & (GAME_DoomStrifeChex)) && - !multiplayer && - players[0].health <= 0) - { // Single player game and player is dead; look for monsters - return P_LookForMonsters (actor); - } - - c = 0; - if (actor->TIDtoHate != 0) - { - pnum = pr_look2() & (MAXPLAYERS-1); - } - else - { - pnum = actor->LastLookPlayerNumber; - } - stop = (pnum - 1) & (MAXPLAYERS-1); - - for (;;) - { - pnum = (pnum + 1) & (MAXPLAYERS-1); - if (!playeringame[pnum]) - continue; - - if (actor->TIDtoHate == 0) - { - actor->LastLookPlayerNumber = pnum; - } - - if (++c == MAXPLAYERS-1 || pnum == stop) - { - // done looking - if (actor->target == NULL) - { - // [RH] use goal as target - // [KS] ...unless we're ignoring goals and we don't already have one - if (actor->goal != NULL && chasegoal) - { - actor->target = actor->goal; - return true; - } - // Use last known enemy if no players sighted -- killough 2/15/98: - if (actor->lastenemy != NULL && actor->lastenemy->health > 0) - { - if (!actor->IsFriend(actor->lastenemy)) - { - actor->target = actor->lastenemy; - actor->lastenemy = NULL; - return true; - } - else - { - actor->lastenemy = NULL; - } - } - } - return actor->target == actor->goal && actor->goal != NULL; - } - - player = &players[pnum]; - - if (!(player->mo->flags & MF_SHOOTABLE)) - continue; // not shootable (observer or dead) - - if (player->cheats & CF_NOTARGET) - continue; // no target - - if (player->health <= 0) - continue; // dead - - if (!P_CheckSight (actor, player->mo, 2)) - continue; // out of sight - - dist = P_AproxDistance (player->mo->x - actor->x, - player->mo->y - actor->y); - - if (maxdist && dist > maxdist) - continue; // [KS] too far - - if (mindist && dist < mindist) - continue; // [KS] too close - - // [SP] Deathmatch fixes - if we have MF_FRIENDLY we're definitely in deathmatch - // We're going to ignore our master, but go after his enemies. - if ( actor->flags & MF_FRIENDLY ) - { - if ( actor->FriendPlayer == 0 ) - continue; // I have no friends, I will ignore players. - if ( actor->FriendPlayer == player->mo->FriendPlayer ) - continue; // This is my master. - } - - if (fov) - { - an = R_PointToAngle2 (actor->x, - actor->y, - player->mo->x, - player->mo->y) - - actor->angle; - - if (an > (fov / 2) && an < (ANGLE_MAX - (fov / 2))) - { - // if real close, react anyway - // [KS] but respect minimum distance rules - if (mindist || dist > MELEERANGE) - continue; // outside of fov - } - } - else - { - if(!((actor->flags4 & MF4_LOOKALLAROUND) || (fov >= ANGLE_MAX))) - { - an = R_PointToAngle2 (actor->x, - actor->y, - player->mo->x, - player->mo->y) - - actor->angle; - - if (an > ANG90 && an < ANG270) - { - // if real close, react anyway - // [KS] but respect minimum distance rules - if (mindist || dist > MELEERANGE) - continue; // behind back - } - } - } - if ((player->mo->flags & MF_SHADOW && !(i_compatflags & COMPATF_INVISIBILITY)) || - player->mo->flags3 & MF3_GHOST) - { - if ((P_AproxDistance (player->mo->x - actor->x, - player->mo->y - actor->y) > 2*MELEERANGE) - && P_AproxDistance (player->mo->velx, player->mo->vely) - < 5*FRACUNIT) - { // Player is sneaking - can't detect - return false; - } - if (pr_lookforplayers() < 225) - { // Player isn't sneaking, but still didn't detect - return false; - } - } - - // [RH] Need to be sure the reactiontime is 0 if the monster is - // leaving its goal to go after a player. - if (actor->goal && actor->target == actor->goal) - actor->reactiontime = 0; - - actor->target = player->mo; - return true; - } -} - -// -// ACTION ROUTINES -// - -// -// A_Look -// Stay in state until a player is sighted. -// [RH] Will also leave state to move to goal. -// -// A_LookEx (int flags, fixed minseedist, fixed maxseedist, fixed maxheardist, fixed fov, state wakestate) -// [KS] Borrowed the A_Look code to make a parameterized version. -// - -enum LO_Flags -{ - LOF_NOSIGHTCHECK = 1, - LOF_NOSOUNDCHECK = 2, - LOF_DONTCHASEGOAL = 4, - LOF_NOSEESOUND = 8, - LOF_FULLVOLSEESOUND = 16, -}; - -DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LookEx) -{ - ACTION_PARAM_START(6); - ACTION_PARAM_INT(flags, 0); - ACTION_PARAM_FIXED(minseedist, 1); - ACTION_PARAM_FIXED(maxseedist, 2); - ACTION_PARAM_FIXED(maxheardist, 3); - ACTION_PARAM_ANGLE(fov, 4); - ACTION_PARAM_STATE(seestate, 5); - - AActor *targ = NULL; // Shuts up gcc - fixed_t dist; - - if (self->flags5 & MF5_INCONVERSATION) - return; - - // [RH] Set goal now if appropriate - if (self->special == Thing_SetGoal && self->args[0] == 0) - { - NActorIterator iterator (NAME_PatrolPoint, self->args[1]); - self->special = 0; - self->goal = iterator.Next (); - self->reactiontime = self->args[2] * TICRATE + level.maptime; - if (self->args[3] == 0) self->flags5 &=~ MF5_CHASEGOAL; - else self->flags5 |= MF5_CHASEGOAL; - } - - self->threshold = 0; // any shot will wake up - - if (self->TIDtoHate != 0) - { - targ = self->target; - } - else - { - if (!(flags & LOF_NOSOUNDCHECK)) - { - targ = self->LastHeard; - if (targ != NULL) - { - // [RH] If the soundtarget is dead, don't chase it - if (targ->health <= 0) - { - targ = NULL; - } - else - { - dist = P_AproxDistance (targ->x - self->x, - targ->y - self->y); - - // [KS] If the target is too far away, don't respond to the sound. - if (maxheardist && dist > maxheardist) - { - targ = NULL; - self->LastHeard = NULL; - } - } - } - } - - if (targ && targ->player && (targ->player->cheats & CF_NOTARGET)) - { - return; - } - } - - // [RH] Andy Baker's stealth monsters - if (self->flags & MF_STEALTH) - { - self->visdir = -1; - } - - if (targ && (targ->flags & MF_SHOOTABLE)) - { - if (self->IsFriend (targ)) // be a little more precise! - { - if (!(self->flags4 & MF4_STANDSTILL)) - { - if (!(flags & LOF_NOSIGHTCHECK)) - { - // If we find a valid target here, the wandering logic should *not* - // be activated! If would cause the seestate to be set twice. - if (P_NewLookPlayers(self, fov, minseedist, maxseedist, !(flags & LOF_DONTCHASEGOAL))) - goto seeyou; - } - - // Let the self wander around aimlessly looking for a fight - if (!(self->flags & MF_INCHASE)) - { - if (seestate) - { - self->SetState (seestate); - } - else - { - if (self->SeeState != NULL) - { - self->SetState (self->SeeState); - } - else - { - CALL_ACTION(A_Wander, self); - } - } - } - } - } - else - { - self->target = targ; //We already have a target? - - // [KS] The target can become ourselves in rare circumstances (like - // if we committed suicide), so if that's the case, just ignore it. - if (self->target == self) self->target = NULL; - - if (self->target != NULL) - { - if (self->flags & MF_AMBUSH) - { - dist = P_AproxDistance (self->target->x - self->x, - self->target->y - self->y); - if (P_CheckSight (self, self->target, 2) && - (!minseedist || dist > minseedist) && - (!maxseedist || dist < maxseedist)) - { - goto seeyou; - } - } - else - goto seeyou; - } - } - } - - if (!(flags & LOF_NOSIGHTCHECK)) - { - if (!P_NewLookPlayers(self, fov, minseedist, maxseedist, !(flags & LOF_DONTCHASEGOAL))) - return; - } - else - { - return; - } - - // go into chase state - seeyou: - // [RH] Don't start chasing after a goal if it isn't time yet. - if (self->target == self->goal) - { - if (self->reactiontime > level.maptime) - self->target = NULL; - } - else if (self->SeeSound && !(flags & LOF_NOSEESOUND)) - { - if (flags & LOF_FULLVOLSEESOUND) - { // full volume - S_Sound (self, CHAN_VOICE, self->SeeSound, 1, ATTN_NONE); - } - else - { - S_Sound (self, CHAN_VOICE, self->SeeSound, 1, ATTN_NORM); - } - } - - if (self->target && !(self->flags & MF_INCHASE)) - { - if (seestate) - { - self->SetState (seestate); - } - else - { - self->SetState (self->SeeState); - } - } -} - -// [KS] *** End additions by me *** diff --git a/src/p_floor.cpp b/src/p_floor.cpp index bd489d525..7ab77b026 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -377,7 +377,7 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, manual_floor: // ALREADY MOVING? IF SO, KEEP GOING... - if (sec->floordata) + if (sec->PlaneMoving(sector_t::floor)) { if (manual) continue; @@ -748,7 +748,7 @@ manual_stair: // ALREADY MOVING? IF SO, KEEP GOING... //jff 2/26/98 add special lockout condition to wait for entire //staircase to build before retriggering - if (sec->floordata || sec->stairlock) + if (sec->PlaneMoving(sector_t::floor) || sec->stairlock) { if (!manual) continue; @@ -800,7 +800,7 @@ manual_stair: // if sector's floor already moving, look for another //jff 2/26/98 special lockout condition for retriggering - if (tsec->floordata || tsec->stairlock) + if (tsec->PlaneMoving(sector_t::floor) || tsec->stairlock) { prev = sec; sec = tsec; @@ -833,7 +833,7 @@ manual_stair: // if sector's floor already moving, look for another //jff 2/26/98 special lockout condition for retriggering - if (tsec->floordata || tsec->stairlock) + if (tsec->PlaneMoving(sector_t::floor) || tsec->stairlock) continue; ok = true; @@ -917,7 +917,7 @@ bool EV_DoDonut (int tag, fixed_t pillarspeed, fixed_t slimespeed) s1 = §ors[secnum]; // s1 is pillar's sector // ALREADY MOVING? IF SO, KEEP GOING... - if (s1->floordata) + if (s1->PlaneMoving(sector_t::floor)) continue; rtn = true; @@ -925,7 +925,7 @@ bool EV_DoDonut (int tag, fixed_t pillarspeed, fixed_t slimespeed) if (!s2) // note lowest numbered line around continue; // pillar must be two-sided - if (s2->floordata) + if (s2->PlaneMoving(sector_t::floor)) continue; for (i = 0; i < s2->linecount; i++) @@ -1007,7 +1007,7 @@ bool EV_DoElevator (line_t *line, DElevator::EElevator elevtype, sec = §ors[secnum]; // If either floor or ceiling is already activated, skip it - if (sec->floordata || sec->ceilingdata) //jff 2/22/98 + if (sec->PlaneMoving(sector_t::floor) || sec->ceilingdata) //jff 2/22/98 continue; // create and initialize new elevator thinker @@ -1225,7 +1225,8 @@ bool EV_StartWaggle (int tag, int height, int speed, int offset, while ((sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0) { sector = §ors[sectorIndex]; - if ((!ceiling && sector->floordata) || (ceiling && sector->ceilingdata)) + if ((!ceiling && sector->PlaneMoving(sector_t::floor)) || + (ceiling && sector->PlaneMoving(sector_t::ceiling))) { // Already busy with another thinker continue; } diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 03d489b8d..b508d8f55 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -882,6 +882,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage int painchance = 0; FState * woundstate = NULL; PainChanceList * pc = NULL; + bool justhit = false; if (target == NULL || !((target->flags & MF_SHOOTABLE) || (target->flags6 & MF6_VULNERABLE))) { // Shouldn't happen @@ -893,12 +894,6 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage { if (inflictor == NULL || !(inflictor->flags4 & MF4_SPECTRAL)) { - /* - if (target->MissileState != NULL) - { - target->SetState (target->MissileState); - } - */ return; } } @@ -1285,7 +1280,7 @@ dopain: { if (pr_lightning() < 96) { - target->flags |= MF_JUSTHIT; // fight back! + justhit = true; FState * painstate = target->FindState(NAME_Pain, mod); if (painstate != NULL) target->SetState (painstate); } @@ -1300,7 +1295,7 @@ dopain: } else { - target->flags |= MF_JUSTHIT; // fight back! + justhit = true; FState * painstate = target->FindState(NAME_Pain, mod); if (painstate != NULL) target->SetState (painstate); if (mod == NAME_PoisonCloud) @@ -1345,6 +1340,11 @@ dopain: } } } + + // killough 11/98: Don't attack a friend, unless hit by that friend. + if (justhit && (target->target == source || !target->target || !target->IsFriend(target->target))) + target->flags |= MF_JUSTHIT; // fight back! + } bool AActor::OkayToSwitchTarget (AActor *other) diff --git a/src/p_linkedsectors.cpp b/src/p_linkedsectors.cpp index 4fa4a699d..b932eb0aa 100644 --- a/src/p_linkedsectors.cpp +++ b/src/p_linkedsectors.cpp @@ -300,7 +300,8 @@ bool P_AddSectorLinks(sector_t *control, int tag, INTBOOL ceiling, int movetype) int param = movetype; // can't be done if the control sector is moving. - if ((ceiling && control->ceilingdata) || (!ceiling && control->floordata)) return false; + if ((ceiling && control->PlaneMoving(sector_t::ceiling)) || + (!ceiling && control->PlaneMoving(sector_t::floor))) return false; // Make sure we have only valid combinations movetype &= LINK_FLAGMASK; diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 8615ffcac..d5caabeb9 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2532,7 +2532,10 @@ FUNC(LS_SetPlayerProperty) if (power != 4) { APowerup *item = static_cast(it->GiveInventoryType (*powers[power])); - if (item != NULL && power == 0) item->BlendColor = INVERSECOLOR; + if (item != NULL && power == 0 && arg1 == 1) + { + item->BlendColor = MakeSpecialColormap(INVERSECOLORMAP); + } } else if (it->player - players == consoleplayer) { @@ -2568,7 +2571,11 @@ FUNC(LS_SetPlayerProperty) { // Give power if (power != 4) { - players[i].mo->GiveInventoryType (*powers[power]); + APowerup *item = static_cast(players[i].mo->GiveInventoryType (*powers[power])); + if (item != NULL && power == 0 && arg1 == 1) + { + item->BlendColor = MakeSpecialColormap(INVERSECOLORMAP); + } } else if (i == consoleplayer) { diff --git a/src/p_local.h b/src/p_local.h index 1ac7687e3..71a662fb7 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -320,7 +320,7 @@ public: #define PT_ADDLINES 1 #define PT_ADDTHINGS 2 -AActor *P_BlockmapSearch (AActor *origin, int distance, AActor *(*func)(AActor *, int)); +AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, int, void *), void *params = NULL); AActor *P_RoughMonsterSearch (AActor *mo, int distance); // diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 2d8e8a515..d4ea1bdf9 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -40,7 +40,7 @@ #include "r_state.h" #include "templates.h" -static AActor *RoughBlockCheck (AActor *mo, int index); +static AActor *RoughBlockCheck (AActor *mo, int index, void *); //========================================================================== @@ -1278,7 +1278,7 @@ AActor *P_RoughMonsterSearch (AActor *mo, int distance) return P_BlockmapSearch (mo, distance, RoughBlockCheck); } -AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, int)) +AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, int, void *), void *params) { int blockX; int blockY; @@ -1297,7 +1297,7 @@ AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, in if (startX >= 0 && startX < bmapwidth && startY >= 0 && startY < bmapheight) { - if ( (target = check (mo, startY*bmapwidth+startX)) ) + if ( (target = check (mo, startY*bmapwidth+startX, params)) ) { // found a target right away return target; } @@ -1334,7 +1334,7 @@ AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, in // Trace the first block section (along the top) for (; blockIndex <= firstStop; blockIndex++) { - if ( (target = check (mo, blockIndex)) ) + if ( (target = check (mo, blockIndex, params)) ) { return target; } @@ -1342,7 +1342,7 @@ AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, in // Trace the second block section (right edge) for (blockIndex--; blockIndex <= secondStop; blockIndex += bmapwidth) { - if ( (target = check (mo, blockIndex)) ) + if ( (target = check (mo, blockIndex, params)) ) { return target; } @@ -1350,7 +1350,7 @@ AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, in // Trace the third block section (bottom edge) for (blockIndex -= bmapwidth; blockIndex >= thirdStop; blockIndex--) { - if ( (target = check (mo, blockIndex)) ) + if ( (target = check (mo, blockIndex, params)) ) { return target; } @@ -1358,7 +1358,7 @@ AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, in // Trace the final block section (left edge) for (blockIndex++; blockIndex > finalStop; blockIndex -= bmapwidth) { - if ( (target = check (mo, blockIndex)) ) + if ( (target = check (mo, blockIndex, params)) ) { return target; } @@ -1373,7 +1373,7 @@ AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, in // //=========================================================================== -static AActor *RoughBlockCheck (AActor *mo, int index) +static AActor *RoughBlockCheck (AActor *mo, int index, void *) { FBlockNode *link; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 670672ec7..b070adef1 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -240,6 +240,7 @@ void AActor::Serialize (FArchive &arc) << movedir << visdir << movecount + << strafecount << target << lastenemy << LastHeard @@ -3898,7 +3899,8 @@ APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer) p->MorphStyle = 0; p->MorphExitFlash = NULL; p->extralight = 0; - p->fixedcolormap = 0; + p->fixedcolormap = NOFIXEDCOLORMAP; + p->fixedlightlevel = -1; p->viewheight = mobj->ViewHeight; p->inconsistant = 0; p->attacker = NULL; @@ -5475,10 +5477,7 @@ void PrintMiscActorInfo(AActor * query) static const char * renderstyles[]= {"None", "Normal", "Fuzzy", "SoulTrans", "OptFuzzy", "Stencil", "Translucent", "Add", "Shaded", "TranslucentStencil"}; - /* - Printf("%s %x has the following flags:\n\tflags1: %x", - query->GetNameTag().GetChars(), query, query->flags); - */ + Printf("%s has the following flags:\n\tflags: %x", query->GetTag(), query->flags); for (flagi = 0; flagi < 31; flagi++) if (query->flags & 1<flags2); @@ -5496,25 +5495,20 @@ void PrintMiscActorInfo(AActor * query) Printf("\n\tflags6: %x", query->flags6); for (flagi = 0; flagi < 31; flagi++) if (query->flags6 & 1<bouncefactor), + Printf("\nIts bounce style and factors are %x and f:%f, w:%f; its bounce flags are:\n\tflagsb: %x", + query->BounceFlags, FIXED2FLOAT(query->bouncefactor), FIXED2FLOAT(query->wallbouncefactor), query->BounceFlags); - for (flagi = 0; flagi < 31; flagi++) - if (query->BounceFlags & 1<BounceFlags & 1<alpha), query->renderflags); - /* - for (flagi = 0; flagi < 31; flagi++) - if (query->renderflags & 1<renderflags & 1<special]->name, query->args[0], query->args[1], - query->args[2], query->args[3], query->args[4], - query->special1, query->special2); + (query->special ? LineSpecialsInfo[query->special]->name : "None"), + query->args[0], query->args[1], query->args[2], query->args[3], + query->args[4], query->special1, query->special2); Printf("\nIts coordinates are x: %f, y: %f, z:%f, floor:%f, ceiling:%f.", FIXED2FLOAT(query->x), FIXED2FLOAT(query->y), FIXED2FLOAT(query->z), FIXED2FLOAT(query->floorz), FIXED2FLOAT(query->ceilingz)); diff --git a/src/p_pillar.cpp b/src/p_pillar.cpp index a9135cefb..f20dc1ef4 100644 --- a/src/p_pillar.cpp +++ b/src/p_pillar.cpp @@ -205,7 +205,7 @@ bool EV_DoPillar (DPillar::EPillar type, int tag, fixed_t speed, fixed_t height, { sector_t *sec = §ors[secnum]; - if (sec->floordata || sec->ceilingdata) + if (sec->PlaneMoving(sector_t::floor) || sec->PlaneMoving(sector_t::ceiling)) continue; fixed_t flor, ceil; diff --git a/src/p_plats.cpp b/src/p_plats.cpp index 9d64e1145..962447e49 100644 --- a/src/p_plats.cpp +++ b/src/p_plats.cpp @@ -91,7 +91,10 @@ void DPlat::Tick () switch (m_Type) { case platRaiseAndStayLockout: - break; + // Instead of keeping the dead thinker like Heretic did let's + // better use a flag to avoid problems elsewhere. For example, + // keeping the thinker would make tagwait wait indefinitely. + m_Sector->planes[sector_t::floor].Flags |= PLANEF_BLOCKED; case platRaiseAndStay: case platDownByValue: case platDownWaitUpStay: @@ -236,7 +239,7 @@ bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height, sec = §ors[secnum]; manual_plat: - if (sec->floordata) + if (sec->PlaneMoving(sector_t::floor)) { if (!manual) continue; diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index dd98faa25..0e3c88b78 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -761,3 +761,12 @@ void sector_t::ClosestPoint(fixed_t fx, fixed_t fy, fixed_t &ox, fixed_t &oy) co ox = fixed_t(bestx); oy = fixed_t(besty); } + + +bool sector_t::PlaneMoving(int pos) +{ + if (pos == floor) + return (floordata != NULL || (planes[floor].Flags & PLANEF_BLOCKED)); + else + return (ceilingdata != NULL || (planes[ceiling].Flags & PLANEF_BLOCKED)); +} diff --git a/src/p_spec.cpp b/src/p_spec.cpp index c7e792908..88dec732e 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -692,12 +692,12 @@ DLightTransfer::DLightTransfer (sector_t *srcSec, int target, bool copyFloor) if (copyFloor) { for (secnum = -1; (secnum = P_FindSectorFromTag (target, secnum)) >= 0; ) - sectors[secnum].ChangeFlags(sector_t::floor, 0, SECF_ABSLIGHTING); + sectors[secnum].ChangeFlags(sector_t::floor, 0, PLANEF_ABSLIGHTING); } else { for (secnum = -1; (secnum = P_FindSectorFromTag (target, secnum)) >= 0; ) - sectors[secnum].ChangeFlags(sector_t::ceiling, 0, SECF_ABSLIGHTING); + sectors[secnum].ChangeFlags(sector_t::ceiling, 0, PLANEF_ABSLIGHTING); } ChangeStatNum (STAT_LIGHTTRANSFER); } diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index b9c41b724..79b64a1de 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1125,13 +1125,13 @@ struct UDMFParser continue; case NAME_Lightfloorabsolute: - if (CheckBool(key)) sec->ChangeFlags(sector_t::floor, 0, SECF_ABSLIGHTING); - else sec->ChangeFlags(sector_t::floor, SECF_ABSLIGHTING, 0); + if (CheckBool(key)) sec->ChangeFlags(sector_t::floor, 0, PLANEF_ABSLIGHTING); + else sec->ChangeFlags(sector_t::floor, PLANEF_ABSLIGHTING, 0); continue; case NAME_Lightceilingabsolute: - if (CheckBool(key)) sec->ChangeFlags(sector_t::ceiling, 0, SECF_ABSLIGHTING); - else sec->ChangeFlags(sector_t::ceiling, SECF_ABSLIGHTING, 0); + if (CheckBool(key)) sec->ChangeFlags(sector_t::ceiling, 0, PLANEF_ABSLIGHTING); + else sec->ChangeFlags(sector_t::ceiling, PLANEF_ABSLIGHTING, 0); continue; case NAME_Gravity: diff --git a/src/p_user.cpp b/src/p_user.cpp index 703b37867..014d837d4 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2508,9 +2508,27 @@ void player_t::Serialize (FArchive &arc) << poisoncount << poisoner << attacker - << extralight - << fixedcolormap - << morphTics + << extralight; + if (SaveVersion < 1858) + { + int fixedmap; + arc << fixedmap; + fixedcolormap = NOFIXEDCOLORMAP; + fixedlightlev = -1; + if (fixedmap >= NUMCOLORMAPS) + { + fixedcolormap = fixedmap - NUMCOLORMAPS; + } + else if (fixedmap > 0) + { + fixedlightlev = fixedmap; + } + } + else + { + arc << fixedcolormap << fixedlightlev; + } + arc << morphTics << MorphedPlayerClass << MorphStyle << MorphExitFlash @@ -2532,7 +2550,7 @@ void player_t::Serialize (FArchive &arc) << ConversationPC << ConversationNPCAngle << ConversationFaceTalker; - + for (i = 0; i < MAXPLAYERS; i++) arc << frags[i]; for (i = 0; i < NUMPSPRITES; i++) diff --git a/src/r_blend.h b/src/r_blend.h index fbc478c12..132d09507 100644 --- a/src/r_blend.h +++ b/src/r_blend.h @@ -114,10 +114,10 @@ union FRenderStyle BYTE DestAlpha; // Of ERenderAlpha type BYTE Flags; }; - DWORD AsDWORD; + uint32 AsDWORD; inline FRenderStyle &operator= (ERenderStyle legacy); - operator DWORD() const { return AsDWORD; } + operator uint32() const { return AsDWORD; } bool operator==(const FRenderStyle &o) const { return AsDWORD == o.AsDWORD; } void CheckFuzz(); bool IsVisible(fixed_t alpha) const throw(); diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index bf09603e3..a1f6f6098 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -270,7 +270,7 @@ void R_ClearClipSegs (short left, short right) int GetFloorLight (const sector_t *sec) { - if (sec->GetFlags(sector_t::floor) & SECF_ABSLIGHTING) + if (sec->GetFlags(sector_t::floor) & PLANEF_ABSLIGHTING) { return sec->GetPlaneLight(sector_t::floor); } @@ -282,7 +282,7 @@ int GetFloorLight (const sector_t *sec) int GetCeilingLight (const sector_t *sec) { - if (sec->GetFlags(sector_t::ceiling) & SECF_ABSLIGHTING) + if (sec->GetFlags(sector_t::ceiling) & PLANEF_ABSLIGHTING) { return sec->GetPlaneLight(sector_t::ceiling); } diff --git a/src/r_defs.h b/src/r_defs.h index cf287de20..88f4e98a8 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -299,7 +299,8 @@ inline FArchive &operator<< (FArchive &arc, secplane_t &plane) // Ceiling/floor flags enum { - SECF_ABSLIGHTING = 1 // floor/ceiling light is absolute, not relative + PLANEF_ABSLIGHTING = 1, // floor/ceiling light is absolute, not relative + PLANEF_BLOCKED = 2 // can not be moved anymore. }; // Internal sector flags @@ -605,6 +606,8 @@ struct sector_t return lightlevel; } + bool PlaneMoving(int pos); + // Member variables fixed_t CenterFloor () const { return floorplane.ZatPoint (soundorg[0], soundorg[1]); } diff --git a/src/r_draw.cpp b/src/r_draw.cpp index c9bb8fbec..12cf3c51f 100644 --- a/src/r_draw.cpp +++ b/src/r_draw.cpp @@ -2205,7 +2205,7 @@ ESPSResult R_SetPatchStyle (FRenderStyle style, fixed_t alpha, int translation, hcolfunc_post4 = rt_shaded4cols; dc_color = fixedcolormap ? fixedcolormap[APART(color)] : basecolormap->Maps[APART(color)]; dc_colormap = (basecolormap = &ShadeFakeColormap[16-alpha])->Maps; - if (fixedlightlev && !fixedcolormap) + if (fixedlightlev >= 0 && fixedcolormap == NULL) { dc_colormap += fixedlightlev; } diff --git a/src/r_main.cpp b/src/r_main.cpp index d20ec9670..e5caada3d 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -140,6 +140,7 @@ int validcount = 1; // increment every time a check is made FDynamicColormap*basecolormap; // [RH] colormap currently drawing with int fixedlightlev; lighttable_t *fixedcolormap; +FSpecialColormap *realfixedcolormap; float WallTMapScale; float WallTMapScale2; @@ -1158,46 +1159,36 @@ void R_SetupFrame (AActor *actor) } } + realfixedcolormap = NULL; fixedcolormap = NULL; - fixedlightlev = 0; + fixedlightlev = -1; - if (player != NULL && camera == player->mo && player->fixedcolormap) + if (player != NULL && camera == player->mo) { - if (player->fixedcolormap < NUMCOLORMAPS) + if (player->fixedcolormap >= 0 && player->fixedcolormap < (int)SpecialColormaps.Size()) { - fixedlightlev = player->fixedcolormap*256; - fixedcolormap = NormalLight.Maps; + realfixedcolormap = &SpecialColormaps[player->fixedcolormap]; + if (RenderTarget == screen && (DFrameBuffer *)screen->Accel2D) + { + // Render everything fullbright. The copy to video memory will + // apply the special colormap, so it won't be restricted to the + // palette. + fixedcolormap = realcolormaps; + } + else + { + fixedcolormap = SpecialColormaps[player->fixedcolormap].Colormap; + } } - else switch (player->fixedcolormap) + else if (player->fixedlightlevel >= 0 && player->fixedlightlevel < NUMCOLORMAPS) { - case INVERSECOLORMAP: - fixedcolormap = InverseColormap; - break; - - case REDCOLORMAP: - fixedcolormap = RedColormap; - break; - - case GREENCOLORMAP: - fixedcolormap = GreenColormap; - break; - - case BLUECOLORMAP: - fixedcolormap = BlueColormap; - break; - - case GOLDCOLORMAP: - fixedcolormap = GoldColormap; - break; - - default: - break; + fixedlightlev = player->fixedlightlevel * 256; } } // [RH] Inverse light for shooting the Sigil - else if (extralight == INT_MIN) + if (fixedcolormap == NULL && extralight == INT_MIN) { - fixedcolormap = InverseColormap; + fixedcolormap = SpecialColormaps[INVERSECOLORMAP].Colormap; extralight = 0; } diff --git a/src/r_main.h b/src/r_main.h index 0952219fe..e633404e1 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -30,6 +30,7 @@ #include "d_player.h" #include "r_data.h" #include "r_state.h" +#include "v_palette.h" // @@ -88,12 +89,6 @@ extern bool r_dontmaplines; // 16 discrete light levels. The terminology I use is borrowed from Build. // -#define INVERSECOLORMAP 32 -#define GOLDCOLORMAP 33 -#define REDCOLORMAP 34 -#define GREENCOLORMAP 35 -#define BLUECOLORMAP 36 - // The size of a single colormap, in bits #define COLORMAPSHIFT 8 @@ -126,6 +121,7 @@ extern int extralight, r_actualextralight; extern bool foggy; extern int fixedlightlev; extern lighttable_t* fixedcolormap; +extern FSpecialColormap*realfixedcolormap; // diff --git a/src/r_plane.cpp b/src/r_plane.cpp index b2dc9ac40..69af40223 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -1407,7 +1407,7 @@ void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool masked) planeheight = abs (FixedMul (pl->height.d, -pl->height.ic) - viewz); GlobVis = FixedDiv (r_FloorVisibility, planeheight); - if (fixedlightlev) + if (fixedlightlev >= 0) ds_colormap = basecolormap->Maps + fixedlightlev, plane_shade = false; else if (fixedcolormap) ds_colormap = fixedcolormap, plane_shade = false; @@ -1545,7 +1545,7 @@ void R_DrawTiltedPlane (visplane_t *pl, fixed_t alpha, bool masked) if (pl->height.c > 0) planelightfloat = -planelightfloat; - if (fixedlightlev) + if (fixedlightlev >= 0) ds_colormap = basecolormap->Maps + fixedlightlev, plane_shade = false; else if (fixedcolormap) ds_colormap = fixedcolormap, plane_shade = false; diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 7fb5800c9..e58d042ab 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -154,7 +154,7 @@ CVAR(Bool, r_fogboundary, true, 0) inline bool IsFogBoundary (sector_t *front, sector_t *back) { - return r_fogboundary && !fixedcolormap && front->ColorMap->Fade && + return r_fogboundary && fixedcolormap == NULL && front->ColorMap->Fade && front->ColorMap->Fade != back->ColorMap->Fade && (front->GetTexture(sector_t::ceiling) != skyflatnum || back->GetTexture(sector_t::ceiling) != skyflatnum); } @@ -179,7 +179,7 @@ static void BlastMaskedColumn (void (*blastfunc)(const BYTE *pixels, const FText if (maskedtexturecol[dc_x] != FIXED_MAX) { // calculate lighting - if (!fixedcolormap) + if (fixedcolormap == NULL && fixedlightlev < 0) { dc_colormap = basecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT); } @@ -298,9 +298,9 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) } } - if (fixedlightlev) + if (fixedlightlev >= 0) dc_colormap = basecolormap->Maps + fixedlightlev; - else if (fixedcolormap) + else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; if (!(curline->linedef->flags & ML_WRAP_MIDTEX) && @@ -453,7 +453,8 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t x = x1; //while ((umost[x] > dmost[x]) && (x <= x2)) x++; - if (fixedcolormap) + bool fixed = (fixedcolormap != NULL || fixedlightlev >= 0); + if (fixed) { palookupoffse[0] = dc_colormap; palookupoffse[1] = dc_colormap; @@ -470,7 +471,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t assert (y1ve[0] < viewheight); assert (y2ve[0] <= viewheight); - if (!fixedcolormap) + if (!fixed) { // calculate lighting dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); } @@ -505,7 +506,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t continue; } - if (!fixedcolormap) + if (!fixed) { for (z = 0; z < 4; ++z) { @@ -563,7 +564,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t assert (y1ve[0] < viewheight); assert (y2ve[0] <= viewheight); - if (!fixedcolormap) + if (!fixed) { // calculate lighting dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); } @@ -700,7 +701,8 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixe x = startx = x1; p = x + dc_destorg; - if (fixedcolormap) + bool fixed = (fixedcolormap != NULL || fixedlightlev >= 0); + if (fixed) { palookupoffse[0] = dc_colormap; palookupoffse[1] = dc_colormap; @@ -715,7 +717,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixe y2ve[0] = dwal[x];//min(dwal[x],dmost[x]); if (y2ve[0] <= y1ve[0]) continue; - if (!fixedcolormap) + if (!fixed) { // calculate lighting dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); } @@ -748,7 +750,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixe continue; } - if (!fixedcolormap) + if (!fixed) { for (z = 0; z < 4; ++z) { @@ -804,7 +806,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixe y2ve[0] = dwal[x]; if (y2ve[0] <= y1ve[0]) continue; - if (!fixedcolormap) + if (!fixed) { // calculate lighting dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); } @@ -872,7 +874,8 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, x = startx = x1; p = x + dc_destorg; - if (fixedcolormap) + bool fixed = (fixedcolormap != NULL || fixedlightlev >= 0); + if (fixed) { palookupoffse[0] = dc_colormap; palookupoffse[1] = dc_colormap; @@ -887,7 +890,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, y2ve[0] = dwal[x];//min(dwal[x],dmost[x]); if (y2ve[0] <= y1ve[0]) continue; - if (!fixedcolormap) + if (!fixed) { // calculate lighting dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); } @@ -920,7 +923,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, continue; } - if (!fixedcolormap) + if (!fixed) { for (z = 0; z < 4; ++z) { @@ -979,7 +982,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, y2ve[0] = dwal[x]; if (y2ve[0] <= y1ve[0]) continue; - if (!fixedcolormap) + if (!fixed) { // calculate lighting dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); } @@ -1016,9 +1019,9 @@ void R_RenderSegLoop () fixed_t xscale, yscale; fixed_t xoffset = rw_offset; - if (fixedlightlev) + if (fixedlightlev >= 0) dc_colormap = basecolormap->Maps + fixedlightlev; - else if (fixedcolormap) + else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; // clip wall to the floor and ceiling @@ -1087,7 +1090,7 @@ void R_RenderSegLoop () { rw_offset = rw_offset_mid; } - if (fixedlightlev || fixedcolormap || !frontsector->ExtraLights) + if (fixedcolormap != NULL || !frontsector->ExtraLights) { wallscan (x1, x2-1, walltop, wallbottom, swall, lwall, yscale); } @@ -1126,7 +1129,7 @@ void R_RenderSegLoop () { rw_offset = rw_offset_top; } - if (fixedlightlev || fixedcolormap || !frontsector->ExtraLights) + if (fixedcolormap != NULL || !frontsector->ExtraLights) { wallscan (x1, x2-1, walltop, wallupper, swall, lwall, yscale); } @@ -1168,7 +1171,7 @@ void R_RenderSegLoop () { rw_offset = rw_offset_bottom; } - if (fixedlightlev || fixedcolormap || !frontsector->ExtraLights) + if (fixedcolormap != NULL || !frontsector->ExtraLights) { wallscan (x1, x2-1, walllower, wallbottom, swall, lwall, yscale); } @@ -1434,7 +1437,7 @@ void R_NewWall (bool needlights) PrepWall (swall, lwall, sidedef->TexelLength * lwallscale); - if (!fixedcolormap) + if (fixedcolormap == NULL && fixedlightlev < 0) { wallshade = LIGHT2SHADE(curline->sidedef->GetLightLevel(foggy, frontsector->lightlevel) + r_actualextralight); @@ -2421,9 +2424,9 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, bool calclighting = false; rw_light = rw_lightleft + (x1 - WallSX1) * rw_lightstep; - if (fixedlightlev) + if (fixedlightlev >= 0) dc_colormap = basecolormap->Maps + fixedlightlev; - else if (fixedcolormap) + else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; else if (!foggy && (decal->RenderFlags & RF_FULLBRIGHT)) dc_colormap = basecolormap->Maps; diff --git a/src/r_things.cpp b/src/r_things.cpp index ffc9ed3dd..3e9b8b0b3 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -50,6 +50,7 @@ #include "r_plane.h" #include "r_segs.h" #include "v_palette.h" +#include "r_translate.h" extern fixed_t globaluclip, globaldclip; @@ -74,6 +75,10 @@ fixed_t pspritexiscale; fixed_t sky1scale; // [RH] Sky 1 scale factor fixed_t sky2scale; // [RH] Sky 2 scale factor +vissprite_t *VisPSprites[NUMPSPRITES]; +int VisPSpritesX1[NUMPSPRITES]; +FDynamicColormap *VisPSpritesBaseColormap[NUMPSPRITES]; + static int spriteshade; TArray ParticlesInSubsec; @@ -1430,50 +1435,40 @@ void R_ProjectSprite (AActor *thing, int fakeside) if (vis->RenderStyle.Flags & STYLEF_FadeToBlack) { if (invertcolormap) - { - // Fade to white + { // Fade to white mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(255,255,255), mybasecolormap->Desaturate); invertcolormap = false; } else - { - // Fade to black + { // Fade to black mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(0,0,0), mybasecolormap->Desaturate); } } // get light level - if (fixedlightlev) - { - if (invertcolormap) - { - mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate); - } - vis->colormap = mybasecolormap->Maps + fixedlightlev; - } - else if (fixedcolormap) - { - // fixed map + if (fixedcolormap != NULL) + { // fixed map vis->colormap = fixedcolormap; } - else if (!foggy && ((thing->renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT))) - { - // full bright - if (invertcolormap) - { - mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate); - } - vis->colormap = mybasecolormap->Maps; - } else { - // diminished light if (invertcolormap) { mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate); } - vis->colormap = mybasecolormap->Maps + (GETPALOOKUP ( - (fixed_t)DivScale12 (r_SpriteVisibility, tz), spriteshade) << COLORMAPSHIFT); + if (fixedlightlev >= 0) + { + vis->colormap = mybasecolormap->Maps + fixedlightlev; + } + else if (!foggy && ((thing->renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT))) + { // full bright + vis->colormap = mybasecolormap->Maps; + } + else + { // diminished light + vis->colormap = mybasecolormap->Maps + (GETPALOOKUP ( + (fixed_t)DivScale12 (r_SpriteVisibility, tz), spriteshade) << COLORMAPSHIFT); + } } } @@ -1522,7 +1517,10 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, fixed_t sx, fixed_ WORD flip; FTexture* tex; vissprite_t* vis; - vissprite_t avis; + static vissprite_t avis[NUMPSPRITES]; + bool noaccel; + + assert(pspnum >= 0 && pspnum < NUMPSPRITES); // decide which patch to use if ( (unsigned)psp->state->sprite >= (unsigned)sprites.Size ()) @@ -1550,7 +1548,7 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, fixed_t sx, fixed_ tx -= tex->GetScaledLeftOffset() << FRACBITS; x1 = (centerxfrac + FixedMul (tx, pspritexscale)) >>FRACBITS; - + VisPSpritesX1[pspnum] = x1; // off the right side if (x1 > viewwidth) @@ -1564,7 +1562,7 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, fixed_t sx, fixed_ return; // store information in a vissprite - vis = &avis; + vis = &avis[pspnum]; vis->renderflags = owner->renderflags; vis->floorclip = 0; @@ -1619,6 +1617,7 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, fixed_t sx, fixed_ if (vis->x1 > x1) vis->startfrac += vis->xiscale*(vis->x1-x1); + noaccel = false; if (pspnum <= ps_flash) { vis->alpha = owner->alpha; @@ -1639,67 +1638,93 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, fixed_t sx, fixed_ if (vis->RenderStyle.Flags & STYLEF_FadeToBlack) { if (invertcolormap) - { - // Fade to white + { // Fade to white mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(255,255,255), mybasecolormap->Desaturate); invertcolormap = false; } else - { - // Fade to black + { // Fade to black mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(0,0,0), mybasecolormap->Desaturate); } } - if (fixedlightlev) - { - if (invertcolormap) - { - mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate); - } - vis->colormap = mybasecolormap->Maps + fixedlightlev; - } - else if (fixedcolormap) - { - // fixed color - vis->colormap = fixedcolormap; - } - else if (!foggy && psp->state->GetFullbright()) - { - // full bright - if (invertcolormap) - { - mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate); - } - vis->colormap = mybasecolormap->Maps; // [RH] use basecolormap + if (realfixedcolormap != NULL) + { // fixed color + vis->colormap = realfixedcolormap->Colormap; } else { - // local light if (invertcolormap) { mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate); } - vis->colormap = mybasecolormap->Maps + (GETPALOOKUP (0, spriteshade) << COLORMAPSHIFT); + if (fixedlightlev >= 0) + { + vis->colormap = mybasecolormap->Maps + fixedlightlev; + } + else if (!foggy && psp->state->GetFullbright()) + { // full bright + vis->colormap = mybasecolormap->Maps; // [RH] use basecolormap + } + else + { // local light + vis->colormap = mybasecolormap->Maps + (GETPALOOKUP (0, spriteshade) << COLORMAPSHIFT); + } } if (camera->Inventory != NULL) { + lighttable_t *oldcolormap = vis->colormap; camera->Inventory->AlterWeaponSprite (vis); + if (vis->colormap != oldcolormap) + { + // The colormap has changed. Is it one we can easily identify? + // If not, then don't bother trying to identify it for + // hardware accelerated drawing. + if (vis->colormap < SpecialColormaps[0].Colormap || + vis->colormap >= SpecialColormaps[SpecialColormaps.Size()].Colormap) + { + noaccel = true; + } + // Has the basecolormap changed? If so, we can't hardware accelerate it, + // since we don't know what it is anymore. + else if (vis->colormap < mybasecolormap->Maps || + vis->colormap >= mybasecolormap->Maps + NUMCOLORMAPS*256) + { + noaccel = true; + } + } } + VisPSpritesBaseColormap[pspnum] = mybasecolormap; } else { + VisPSpritesBaseColormap[pspnum] = basecolormap; vis->RenderStyle = STYLE_Normal; } - + + // Check for hardware-assisted 2D. If it's available, and this sprite is not + // fuzzy, don't draw it until after the switch to 2D mode. + if (!noaccel && RenderTarget == screen && (DFrameBuffer *)screen->Accel2D) + { + FRenderStyle style = vis->RenderStyle; + style.CheckFuzz(); + if (style.BlendOp != STYLEOP_Fuzz) + { + VisPSprites[pspnum] = vis; + return; + } + } R_DrawVisSprite (vis); } +//========================================================================== // // R_DrawPlayerSprites // +//========================================================================== + void R_DrawPlayerSprites (void) { int i; @@ -1708,7 +1733,7 @@ void R_DrawPlayerSprites (void) sector_t* sec; static sector_t tempsec; int floorlight, ceilinglight; - + if (!r_drawplayersprites || !camera->player || (players[consoleplayer].cheats & CF_CHASECAM)) @@ -1766,6 +1791,78 @@ void R_DrawPlayerSprites (void) } } +//========================================================================== +// +// R_DrawRemainingPlayerSprites +// +// Called from D_Display to draw sprites that were not drawn by +// R_DrawPlayerSprites(). +// +//========================================================================== + +void R_DrawRemainingPlayerSprites() +{ + for (int i = 0; i < NUMPSPRITES; ++i) + { + vissprite_t *vis; + + vis = VisPSprites[i]; + VisPSprites[i] = NULL; + + if (vis != NULL) + { + FDynamicColormap *colormap = VisPSpritesBaseColormap[i]; + bool flip = vis->xiscale < 0; + FSpecialColormap *special = NULL; + PalEntry overlay = 0; + FColormapStyle colormapstyle; + bool usecolormapstyle = false; + + if (vis->colormap >= SpecialColormaps[0].Colormap && + vis->colormap < SpecialColormaps[SpecialColormaps.Size()].Colormap) + { + // Yuck! There needs to be a better way to store colormaps in the vissprite... :( + ptrdiff_t specialmap = (vis->colormap - SpecialColormaps[0].Colormap) / sizeof(FSpecialColormap); + special = &SpecialColormaps[specialmap]; + } + else if (colormap->Color == PalEntry(255,255,255) && + colormap->Desaturate == 0) + { + overlay = colormap->Fade; + overlay.a = BYTE(((vis->colormap - colormap->Maps) >> 8) * 255 / NUMCOLORMAPS); + } + else + { + usecolormapstyle = true; + colormapstyle.Color = colormap->Color; + colormapstyle.Fade = colormap->Fade; + colormapstyle.Desaturate = colormap->Desaturate; + colormapstyle.FadeLevel = ((vis->colormap - colormap->Maps) >> 8) / float(NUMCOLORMAPS); + } + screen->DrawTexture(vis->pic, + viewwindowx + VisPSpritesX1[i], + viewwindowy + viewheight/2 - MulScale32(vis->texturemid, vis->yscale) - 1, + DTA_DestWidth, FixedMul(vis->pic->GetWidth(), vis->xscale), + DTA_DestHeight, FixedMul(vis->pic->GetHeight(), vis->yscale), + DTA_Translation, TranslationToTable(vis->Translation), + DTA_FlipX, flip, + DTA_TopOffset, 0, + DTA_LeftOffset, 0, + DTA_ClipLeft, viewwindowx, + DTA_ClipTop, viewwindowy, + DTA_ClipRight, viewwindowx + viewwidth, + DTA_ClipBottom, viewwindowy + viewheight, + DTA_Alpha, vis->alpha, + DTA_RenderStyle, vis->RenderStyle, + DTA_FillColor, vis->FillColor, + DTA_SpecialColormap, special, + DTA_ColorOverlay, overlay, + DTA_ColormapStyle, usecolormapstyle ? &colormapstyle : NULL, + TAG_DONE); + } + } +} + @@ -2423,7 +2520,7 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade, vis->floorclip = 0; vis->heightsec = heightsec; - if (fixedlightlev) + if (fixedlightlev >= 0) { vis->colormap = map + fixedlightlev; } diff --git a/src/r_things.h b/src/r_things.h index a3614c063..9ae796ce9 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -102,6 +102,7 @@ void R_InitSprites (); void R_DeinitSprites (); void R_ClearSprites (); void R_DrawMasked (); +void R_DrawRemainingPlayerSprites (); void R_ClipVisSprite (vissprite_t *vis, int xl, int xh); diff --git a/src/tarray.h b/src/tarray.h index 72bbc5e61..92a6552e4 100644 --- a/src/tarray.h +++ b/src/tarray.h @@ -120,12 +120,12 @@ public: } } // Return a reference to an element - T &operator[] (unsigned int index) const + T &operator[] (size_t index) const { return Array[index]; } // Returns the value of an element - TT operator() (unsigned int index) const + TT operator() (size_t index) const { return Array[index]; } diff --git a/src/textures/bitmap.cpp b/src/textures/bitmap.cpp index c985e1494..913aa507e 100644 --- a/src/textures/bitmap.cpp +++ b/src/textures/bitmap.cpp @@ -35,6 +35,7 @@ #include "bitmap.h" #include "templates.h" #include "r_translate.h" +#include "v_palette.h" //=========================================================================== @@ -70,86 +71,6 @@ void iCopyColors(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *in } break; - case BLEND_INVERSEMAP: - // Doom's inverted invulnerability map - for(i=0;i(255 - TSrc::Gray(pin),0,255); - - TBlend::OpC(pout[TDest::RED], gray, a, inf); - TBlend::OpC(pout[TDest::GREEN], gray, a, inf); - TBlend::OpC(pout[TDest::BLUE], gray, a, inf); - TBlend::OpA(pout[TDest::ALPHA], a, inf); - } - pout+=4; - pin+=step; - } - break; - - case BLEND_GOLDMAP: - // Heretic's golden invulnerability map - for(i=0;i(gray+(gray>>1),0,255); - g=clamp(gray-(gray>>2),0,255); - - TBlend::OpC(pout[TDest::RED], r, a, inf); - TBlend::OpC(pout[TDest::GREEN], g, a, inf); - TBlend::OpC(pout[TDest::BLUE], 0, a, inf); - TBlend::OpA(pout[TDest::ALPHA], a, inf); - } - pout+=4; - pin+=step; - } - break; - - case BLEND_REDMAP: - // Skulltag's red Doomsphere map - for(i=0;i(gray+(gray>>1),0,255); - - TBlend::OpC(pout[TDest::RED], r, a, inf); - TBlend::OpC(pout[TDest::GREEN], 0, a, inf); - TBlend::OpC(pout[TDest::BLUE], 0, a, inf); - TBlend::OpA(pout[TDest::ALPHA], a, inf); - } - pout+=4; - pin+=step; - } - break; - - case BLEND_GREENMAP: - // Skulltag's Guardsphere map - for(i=0;i(gray+(gray>>1),0,255); - - TBlend::OpC(pout[TDest::RED], r, a, inf); - TBlend::OpC(pout[TDest::GREEN], r, a, inf); - TBlend::OpC(pout[TDest::BLUE], gray, a, inf); - TBlend::OpA(pout[TDest::ALPHA], a, inf); - } - pout+=4; - pin+=step; - } - break; - case BLEND_ICEMAP: // Create the ice translation table, based on Hexen's. // Since this is done in True Color the purplish tint is fully preserved - even in Doom! @@ -171,7 +92,28 @@ void iCopyColors(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *in break; default: - if (inf->blend >= BLEND_DESATURATE1 && inf->blend<=BLEND_DESATURATE31) + + if (inf->blend >= BLEND_SPECIALCOLORMAP1) + { + FSpecialColormap *cm = &SpecialColormaps[inf->blend - BLEND_SPECIALCOLORMAP1]; + for(i=0;i(255 - TSrc::Gray(pin),0,255); + + PalEntry pe = cm->GrayscaleToColor[gray]; + TBlend::OpC(pout[TDest::RED], pe.r , a, inf); + TBlend::OpC(pout[TDest::GREEN], pe.g, a, inf); + TBlend::OpC(pout[TDest::BLUE], pe.b, a, inf); + TBlend::OpA(pout[TDest::ALPHA], a, inf); + } + pout+=4; + pin+=step; + } + } + else if (inf->blend >= BLEND_DESATURATE1 && inf->blend<=BLEND_DESATURATE31) { // Desaturated light settings. fac=inf->blend-BLEND_DESATURATE1+1; diff --git a/src/textures/bitmap.h b/src/textures/bitmap.h index 5d9b58a6f..04bd580cd 100644 --- a/src/textures/bitmap.h +++ b/src/textures/bitmap.h @@ -262,13 +262,10 @@ enum ColorType enum EBlend { BLEND_NONE = 0, - BLEND_INVERSEMAP = 1, - BLEND_GOLDMAP = 2, - BLEND_REDMAP = 3, - BLEND_GREENMAP = 4, - BLEND_ICEMAP = 5, - BLEND_DESATURATE1 = 6, - BLEND_DESATURATE31 = 36, + BLEND_ICEMAP = 1, + BLEND_DESATURATE1 = 2, + BLEND_DESATURATE31 = 32, + BLEND_SPECIALCOLORMAP1 = 33, BLEND_MODULATE = -1, BLEND_OVERLAY = -2, }; diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index 2079f2448..4b9bd5e1b 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -423,27 +423,19 @@ const BYTE *FMultiPatchTexture::GetColumn (unsigned int column, const Span **spa BYTE *GetBlendMap(PalEntry blend, BYTE *blendwork) { - switch (blend.a==0 ? blend.r : -1) + switch (blend.a==0 ? int(blend) : -1) { - case BLEND_INVERSEMAP: - return InverseColormap; - - case BLEND_GOLDMAP: - return GoldColormap; - - case BLEND_REDMAP: - return RedColormap; - - case BLEND_GREENMAP: - return GreenColormap; - case BLEND_ICEMAP: return TranslationToTable(TRANSLATION(TRANSLATION_Standard, 7))->Remap; default: - if (blend.r >= BLEND_DESATURATE1 && blend.r <= BLEND_DESATURATE31) + if (blend >= BLEND_SPECIALCOLORMAP1) { - return DesaturateColormap[blend.r - BLEND_DESATURATE1]; + return SpecialColormaps[blend - BLEND_SPECIALCOLORMAP1].Colormap; + } + else if (blend >= BLEND_DESATURATE1 && blend <= BLEND_DESATURATE31) + { + return DesaturateColormap[blend - BLEND_DESATURATE1]; } else { @@ -1044,22 +1036,29 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part) } else if (sc.Compare("Translation")) { + int match; + bComplex = true; if (part.Translation != NULL) delete part.Translation; part.Translation = NULL; part.Blend = 0; - static const char *maps[] = { "inverse", "gold", "red", "green", "ice", "desaturate", NULL }; + static const char *maps[] = { "inverse", "gold", "red", "green", "blue", NULL }; sc.MustGetString(); - int match = sc.MatchString(maps); + + match = sc.MatchString(maps); if (match >= 0) { - part.Blend.r = 1 + match; - if (part.Blend.r == BLEND_DESATURATE1) - { - sc.MustGetStringName(","); - sc.MustGetNumber(); - part.Blend.r += clamp(sc.Number-1, 0, 30); - } + part.Blend = BLEND_SPECIALCOLORMAP1 + match; + } + else if (sc.Compare("ICE")) + { + part.Blend = BLEND_ICEMAP; + } + else if (sc.Compare("DESATURATE")) + { + sc.MustGetStringName(","); + sc.MustGetNumber(); + part.Blend = BLEND_DESATURATE1 + clamp(sc.Number-1, 0, 30); } else { @@ -1075,6 +1074,36 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part) } } + else if (sc.Compare("Colormap")) + { + float r1,g1,b1; + float r2,g2,b2; + + sc.MustGetFloat(); + r1 = (float)sc.Float; + sc.MustGetStringName(","); + sc.MustGetFloat(); + g1 = (float)sc.Float; + sc.MustGetStringName(","); + sc.MustGetFloat(); + b1 = (float)sc.Float; + if (!sc.CheckString(",")) + { + part.Blend = AddSpecialColormap(0,0,0, r1, g1, b1); + } + else + { + sc.MustGetFloat(); + r2 = (float)sc.Float; + sc.MustGetStringName(","); + sc.MustGetFloat(); + g2 = (float)sc.Float; + sc.MustGetStringName(","); + sc.MustGetFloat(); + b2 = (float)sc.Float; + part.Blend = AddSpecialColormap(r1, g1, b1, r2, g2, b2); + } + } else if (sc.Compare("Blend")) { bComplex = true; @@ -1101,10 +1130,14 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part) sc.MustGetStringName(","); part.Blend = MAKERGB(r, g, b); } + // Blend.a may never be 0 here. if (sc.CheckString(",")) { sc.MustGetFloat(); - part.Blend.a = clamp(int(sc.Float*255), 1, 254); + if (sc.Float > 0.f) + part.Blend.a = clamp(int(sc.Float*255), 1, 254); + else + part.Blend = 0; } else part.Blend.a = 255; } diff --git a/src/textures/tgatexture.cpp b/src/textures/tgatexture.cpp index 595cef522..41bbb11b8 100644 --- a/src/textures/tgatexture.cpp +++ b/src/textures/tgatexture.cpp @@ -354,12 +354,14 @@ void FTGATexture::MakeTexture () int step_x = (hdr.bpp>>3); int Pitch = Width * step_x; + /* if (hdr.img_desc&32) { ptr += (Width-1) * step_x; step_x =- step_x; } - if (!(hdr.img_desc&64)) + */ + if (!(hdr.img_desc&32)) { ptr += (Height-1) * Pitch; Pitch = -Pitch; @@ -557,12 +559,14 @@ int FTGATexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int w, int h, i int step_x = (hdr.bpp>>3); int Pitch = Width * step_x; + /* if (hdr.img_desc&32) { ptr += (Width-1) * step_x; step_x =- step_x; } - if (!(hdr.img_desc&64)) + */ + if (!(hdr.img_desc&32)) { ptr += (Height-1) * Pitch; Pitch = -Pitch; diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index b23852365..8b0ed1a41 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -141,6 +141,7 @@ static FFlagDef ActorFlags[]= DEFINE_FLAG(MF3, NOTARGET, AActor, flags3), DEFINE_FLAG(MF3, DONTGIB, AActor, flags3), DEFINE_FLAG(MF3, NOBLOCKMONST, AActor, flags3), + DEFINE_FLAG(MF3, AVOIDMELEE, AActor, flags3), DEFINE_FLAG(MF3, FULLVOLDEATH, AActor, flags3), DEFINE_FLAG(MF3, FOILINVUL, AActor, flags3), DEFINE_FLAG(MF3, NOTELEOTHER, AActor, flags3), @@ -239,6 +240,7 @@ static FFlagDef ActorFlags[]= DEFINE_FLAG2(BOUNCE_Quiet, NOBOUNCESOUND, AActor, BounceFlags), DEFINE_FLAG2(BOUNCE_AllActors, BOUNCEONACTORS, AActor, BounceFlags), DEFINE_FLAG2(BOUNCE_ExplodeOnWater, EXPLODEONWATER, AActor, BounceFlags), + DEFINE_FLAG2(BOUNCE_MBF, MBFBOUNCER, AActor, BounceFlags), // Deprecated flags. Handling must be performed in HandleDeprecatedFlags DEFINE_DEPRECATED_FLAG(FIREDAMAGE), @@ -295,7 +297,7 @@ static FFlagDef WeaponFlags[] = DEFINE_FLAG(WIF, POWERED_UP, AWeapon, WeaponFlags), DEFINE_FLAG(WIF, STAFF2_KICKBACK, AWeapon, WeaponFlags), DEFINE_FLAG(WIF_BOT, EXPLOSIVE, AWeapon, WeaponFlags), - DEFINE_FLAG2(WIF_BOT_MELEE, MELEEWEAPON, AWeapon, WeaponFlags), + DEFINE_FLAG(WIF, MELEEWEAPON, AWeapon, WeaponFlags), DEFINE_FLAG(WIF_BOT, BFG, AWeapon, WeaponFlags), DEFINE_FLAG(WIF, CHEATNOTWEAPON, AWeapon, WeaponFlags), DEFINE_FLAG(WIF, NO_AUTO_SWITCH, AWeapon, WeaponFlags), diff --git a/src/thingdef/thingdef_parse.cpp b/src/thingdef/thingdef_parse.cpp index 160555f46..eb68a6d27 100644 --- a/src/thingdef/thingdef_parse.cpp +++ b/src/thingdef/thingdef_parse.cpp @@ -617,6 +617,10 @@ static bool ParsePropertyParams(FScanner &sc, FPropertyInfo *prop, AActor *defau case 'M': // special case. An expression-aware parser will not need this. conv.i = ParseMorphStyle(sc); break; + + case 'N': // special case. An expression-aware parser will not need this. + conv.i = ParseThingActivation(sc); + break; case 'L': // Either a number or a list of strings if (sc.CheckNumber()) diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index f04c6ba8c..92e259f0c 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -130,15 +130,15 @@ void HandleDeprecatedFlags(AActor *defaults, FActorInfo *info, bool set, int ind break; // the bounce flags will set the compatibility bounce modes to remain compatible case DEPF_HERETICBOUNCE: - defaults->BounceFlags &= ~BOUNCE_TypeMask; + defaults->BounceFlags &= ~(BOUNCE_TypeMask|BOUNCE_UseSeeSound); if (set) defaults->BounceFlags |= BOUNCE_HereticCompat; break; case DEPF_HEXENBOUNCE: - defaults->BounceFlags &= ~BOUNCE_TypeMask; + defaults->BounceFlags &= ~(BOUNCE_TypeMask|BOUNCE_UseSeeSound); if (set) defaults->BounceFlags |= BOUNCE_HexenCompat; break; case DEPF_DOOMBOUNCE: - defaults->BounceFlags &= ~BOUNCE_TypeMask; + defaults->BounceFlags &= ~(BOUNCE_TypeMask|BOUNCE_UseSeeSound); if (set) defaults->BounceFlags |= BOUNCE_DoomCompat; break; case DEPF_PICKUPFLASH: @@ -1556,7 +1556,8 @@ DEFINE_CLASS_PROPERTY(weapon, S, WeaponPiece) //========================================================================== DEFINE_CLASS_PROPERTY_PREFIX(powerup, color, C_f, Inventory) { - PROP_INT_PARM(i, 0); + static const char *specialcolormapnames[] = { + "INVERSEMAP", "GOLDMAP", "REDMAP", "GREENMAP", "BLUEMAP", NULL }; int alpha; PalEntry * pBlendColor; @@ -1582,30 +1583,11 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, color, C_f, Inventory) { PROP_STRING_PARM(name, 1); - if (!stricmp(name, "INVERSEMAP")) + // We must check the old special colormap names for compatibility + int v = MatchString(name, specialcolormapnames); + if (v >= 0) { - *pBlendColor = INVERSECOLOR; - return; - } - else if (!stricmp(name, "GOLDMAP")) - { - *pBlendColor = GOLDCOLOR; - return; - } - // [BC] Yay, more hacks. - else if (!stricmp(name, "REDMAP" )) - { - *pBlendColor = REDCOLOR; - return; - } - else if (!stricmp(name, "GREENMAP" )) - { - *pBlendColor = GREENCOLOR; - return; - } - else if (!stricmp(name, "BLUEMAP")) - { - *pBlendColor = BLUECOLOR; + *pBlendColor = MakeSpecialColormap(v); return; } @@ -1619,10 +1601,54 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, color, C_f, Inventory) else alpha = 255/3; alpha=clamp(alpha, 0, 255); - if (alpha!=0) *pBlendColor = MAKEARGB(alpha, 0, 0, 0) | color; + if (alpha != 0) *pBlendColor = MAKEARGB(alpha, 0, 0, 0) | color; else *pBlendColor = 0; } +//========================================================================== +// +//========================================================================== +DEFINE_CLASS_PROPERTY_PREFIX(powerup, colormap, FFFfff, Inventory) +{ + PalEntry * pBlendColor; + + if (info->Class->IsDescendantOf(RUNTIME_CLASS(APowerup))) + { + pBlendColor = &((APowerup*)defaults)->BlendColor; + } + else if (info->Class->IsDescendantOf(RUNTIME_CLASS(APowerupGiver))) + { + pBlendColor = &((APowerupGiver*)defaults)->BlendColor; + } + else + { + I_Error("\"powerup.colormap\" requires an actor of type \"Powerup\"\n"); + return; + } + + if (PROP_PARM_COUNT == 3) + { + PROP_FLOAT_PARM(r, 0); + PROP_FLOAT_PARM(g, 1); + PROP_FLOAT_PARM(b, 2); + *pBlendColor = MakeSpecialColormap(AddSpecialColormap(0, 0, 0, r, g, b)); + } + else if (PROP_PARM_COUNT == 6) + { + PROP_FLOAT_PARM(r1, 0); + PROP_FLOAT_PARM(g1, 1); + PROP_FLOAT_PARM(b1, 2); + PROP_FLOAT_PARM(r2, 3); + PROP_FLOAT_PARM(g2, 4); + PROP_FLOAT_PARM(b2, 5); + *pBlendColor = MakeSpecialColormap(AddSpecialColormap(r1, g1, b1, r2, g2, b2)); + } + else + { + I_Error("\"power.colormap\" must have either 3 or 6 parameters\n"); + } +} + //========================================================================== // //========================================================================== diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 659a2f502..05cd73c5c 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -341,6 +341,8 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, int x, int y, DWORD tag, va_l parms->style.BlendOp = 255; // Dummy "not set" value parms->masked = true; parms->bilinear = false; + parms->specialcolormap = NULL; + parms->colormapstyle = NULL; parms->x = x << FRACBITS; parms->y = y << FRACBITS; @@ -580,6 +582,14 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, int x, int y, DWORD tag, va_l case DTA_RenderStyle: parms->style.AsDWORD = va_arg (tags, DWORD); break; + + case DTA_SpecialColormap: + parms->specialcolormap = va_arg (tags, FSpecialColormap *); + break; + + case DTA_ColormapStyle: + parms->colormapstyle = va_arg (tags, FColormapStyle *); + break; } tag = va_arg (tags, DWORD); } diff --git a/src/v_palette.cpp b/src/v_palette.cpp index 921093433..b9279779d 100644 --- a/src/v_palette.cpp +++ b/src/v_palette.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #ifdef _WIN32 #include #else @@ -61,15 +62,34 @@ extern "C" { FDynamicColormap NormalLight; } FPalette GPalette; -BYTE InverseColormap[256]; -BYTE GoldColormap[256]; -// [BC] New Skulltag colormaps. -BYTE RedColormap[256]; -BYTE GreenColormap[256]; -BYTE BlueColormap[256]; +TArray SpecialColormaps; BYTE DesaturateColormap[31][256]; -static void FreeSpecialLights();; +struct FSpecialColormapParameters +{ + float Start[3], End[3]; +}; + +static FSpecialColormapParameters SpecialColormapParms[] = +{ + // Doom invulnerability is an inverted grayscale. + // Strife uses it when firing the Sigil + { { 1, 1, 1 }, { 0, 0, 0 } }, + + // Heretic invulnerability is a golden shade. + { { 0, 0, 0 }, { 1.5, 0.75, 0 }, }, + + // [BC] Build the Doomsphere colormap. It is red! + { { 0, 0, 0 }, { 1.5, 0, 0 } }, + + // [BC] Build the Guardsphere colormap. It's a greenish-white kind of thing. + { { 0, 0, 0 }, { 1.25, 1.5, 1 } }, + + // Build a blue colormap. + {{ 0, 0, 0 }, { 0, 0, 1.5 } }, +}; + +static void FreeSpecialLights(); FColorMatcher ColorMatcher; @@ -341,10 +361,72 @@ static bool FixBuildPalette (BYTE *opal, int lump, bool blood) return true; } +int AddSpecialColormap(float r1, float g1, float b1, float r2, float g2, float b2) +{ + // Clamp these in range for the hardware shader. + r1 = clamp(r1, 0.0f, 2.0f); + g1 = clamp(g1, 0.0f, 2.0f); + b1 = clamp(b1, 0.0f, 2.0f); + r2 = clamp(r2, 0.0f, 2.0f); + g2 = clamp(g2, 0.0f, 2.0f); + b2 = clamp(b2, 0.0f, 2.0f); + + for(unsigned i=0; iColorizeStart[0] = float(r1); + cm->ColorizeStart[1] = float(g1); + cm->ColorizeStart[2] = float(b1); + cm->ColorizeEnd[0] = float(r2); + cm->ColorizeEnd[1] = float(g2); + cm->ColorizeEnd[2] = float(b2); + + r2 -= r1; + g2 -= g1; + b2 -= b1; + r1 *= 255; + g1 *= 255; + b1 *= 255; + + for (int c = 0; c < 256; c++) + { + double intensity = (GPalette.BaseColors[c].r * 77 + + GPalette.BaseColors[c].g * 143 + + GPalette.BaseColors[c].b * 37) / 256.0; + + PalEntry pe = PalEntry( MIN(255, int(r1 + intensity*r2)), + MIN(255, int(g1 + intensity*g2)), + MIN(255, int(b1 + intensity*b2))); + + cm->Colormap[c] = ColorMatcher.Pick(pe); + } + + // This table is used by the texture composition code + for(int i = 0;i < 256; i++) + { + cm->GrayscaleToColor[i] = PalEntry( MIN(255, int(r1 + i*r2)), + MIN(255, int(g1 + i*g2)), + MIN(255, int(b1 + i*b2))); + } + return SpecialColormaps.Size() - 1; +} + void InitPalette () { BYTE pal[768]; - BYTE *shade; int c; bool usingBuild = false; int lump; @@ -384,76 +466,22 @@ void InitPalette () NormalLight.Fade = 0; // NormalLight.Maps is set by R_InitColormaps() - // build special maps (e.g. invulnerability) - int intensity; + // build default special maps (e.g. invulnerability) + SpecialColormaps.Clear(); - // Doom invulnerability is an inverted grayscale. - // Strife uses it when firing the Sigil - shade = InverseColormap; - - for (c = 0; c < 256; c++) + for (int i = 0; i < countof(SpecialColormapParms); ++i) { - intensity = (65535 - - (GPalette.BaseColors[c].r * 77 + - GPalette.BaseColors[c].g * 143 + - GPalette.BaseColors[c].b * 37)) >> 8; - shade[c] = ColorMatcher.Pick (intensity, intensity, intensity); + AddSpecialColormap(SpecialColormapParms[i].Start[0], SpecialColormapParms[i].Start[1], + SpecialColormapParms[i].Start[2], SpecialColormapParms[i].End[0], + SpecialColormapParms[i].End[1], SpecialColormapParms[i].End[2]); } - - // Heretic invulnerability is a golden shade. - shade = GoldColormap; - - for (c = 0; c < 256; c++) - { - intensity = GPalette.BaseColors[c].r * 77 + - GPalette.BaseColors[c].g * 143 + - GPalette.BaseColors[c].b * 37; - shade[c] = ColorMatcher.Pick ( - MIN (255, (intensity+intensity/2)>>8), intensity>>8, 0); - } - - // [BC] Build the Doomsphere colormap. It is red! - shade = RedColormap; - for (c = 0; c < 256; c++) - { - intensity = ((GPalette.BaseColors[c].r * 77 + - GPalette.BaseColors[c].g * 143 + - GPalette.BaseColors[c].b * 37)); - shade[c] = ColorMatcher.Pick ( - MIN( 255, ( intensity + ( intensity / 2 )) >> 8 ), 0, 0 ); - } - - // [BC] Build the Guardsphere colormap. It's a greenish-white kind of thing. - shade = GreenColormap; - for (c = 0; c < 256; c++) - { - intensity = GPalette.BaseColors[c].r * 77 + - GPalette.BaseColors[c].g * 143 + - GPalette.BaseColors[c].b * 37; - shade[c] = ColorMatcher.Pick ( - MIN( 255, ( intensity + ( intensity / 2 )) >> 8 ), - MIN( 255, ( intensity + ( intensity / 2 )) >> 8 ), - intensity>>8 ); - } - - // Build a blue colormap. - shade = BlueColormap; - for (c = 0; c < 256; c++) - { - intensity = ((GPalette.BaseColors[c].r * 77 + - GPalette.BaseColors[c].g * 143 + - GPalette.BaseColors[c].b * 37)); - shade[c] = ColorMatcher.Pick (0, 0, - MIN( 255, ( intensity + ( intensity / 2 )) >> 8 )); - } - // desaturated colormaps for(int m = 0; m < 31; m++) { - shade = DesaturateColormap[m]; + BYTE *shade = DesaturateColormap[m]; for (c = 0; c < 256; c++) { - intensity = (GPalette.BaseColors[c].r * 77 + + int intensity = (GPalette.BaseColors[c].r * 77 + GPalette.BaseColors[c].g * 143 + GPalette.BaseColors[c].b * 37) / 255; diff --git a/src/v_palette.h b/src/v_palette.h index e723ba5c2..453365d53 100644 --- a/src/v_palette.h +++ b/src/v_palette.h @@ -79,18 +79,60 @@ struct FDynamicColormap FDynamicColormap *Next; }; -extern BYTE InverseColormap[256]; -extern BYTE GoldColormap[256]; -// [BC] New Skulltag colormaps. -extern BYTE RedColormap[256]; -extern BYTE GreenColormap[256]; -extern BYTE BlueColormap[256]; +// For hardware-accelerated weapon sprites in colored sectors +struct FColormapStyle +{ + PalEntry Color; + PalEntry Fade; + int Desaturate; + float FadeLevel; +}; + +enum +{ + NOFIXEDCOLORMAP = -1, + INVERSECOLORMAP, // the inverse map is used explicitly in a few places. +}; + + +struct FSpecialColormap +{ + float ColorizeStart[3]; + float ColorizeEnd[3]; + BYTE Colormap[256]; + PalEntry GrayscaleToColor[256]; +}; + +extern TArray SpecialColormaps; + +// some utility functions to store special colormaps in powerup blends +#define SPECIALCOLORMAP_MASK 0x00b60000 + +inline int MakeSpecialColormap(int index) +{ + assert(index >= 0 && index < 65536); + return index | SPECIALCOLORMAP_MASK; +} + +inline bool IsSpecialColormap(int map) +{ + return (map & 0xFFFF0000) == SPECIALCOLORMAP_MASK; +} + +inline int GetSpecialColormap(int blend) +{ + return IsSpecialColormap(blend) ? blend & 0xFFFF : NOFIXEDCOLORMAP; +} + +int AddSpecialColormap(float r1, float g1, float b1, float r2, float g2, float b2); + + + extern BYTE DesaturateColormap[31][256]; extern FPalette GPalette; extern "C" { extern FDynamicColormap NormalLight; } - // The color overlay to use for depleted items #define DIM_OVERLAY MAKEARGB(170,0,0,0) @@ -110,7 +152,7 @@ void V_SetBlend (int blendr, int blendg, int blendb, int blenda); // V_ForceBlend() // // Normally, V_SetBlend() does nothing if the new blend is the -// same as the old. This function will performing the blending +// same as the old. This function will perform the blending // even if the blend hasn't changed. void V_ForceBlend (int blendr, int blendg, int blendb, int blenda); diff --git a/src/v_video.cpp b/src/v_video.cpp index 304a8ee44..acd481f68 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1099,6 +1099,20 @@ bool DFrameBuffer::Begin2D (bool copy3d) return false; } +//========================================================================== +// +// DFrameBuffer :: DrawBlendingRect +// +// In hardware 2D modes, the blending rect needs to be drawn separately +// from transferring the 3D scene to video memory, because the weapon +// sprite is drawn on top of that. +// +//========================================================================== + +void DFrameBuffer::DrawBlendingRect() +{ +} + //========================================================================== // // DFrameBuffer :: CreateTexture @@ -1244,6 +1258,17 @@ void DFrameBuffer::WriteSavePic (player_t *player, FILE *file, int width, int he delete pic; } +//=========================================================================== +// +// +// +//=========================================================================== + +void DFrameBuffer::DrawRemainingPlayerSprites() +{ + R_DrawRemainingPlayerSprites(); +} + FNativePalette::~FNativePalette() diff --git a/src/v_video.h b/src/v_video.h index 84a59db50..98bf420de 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -101,6 +101,8 @@ enum DTA_RenderStyle, // same as render style for actors DTA_ColorOverlay, // DWORD: ARGB to overlay on top of image; limited to black for software DTA_BilinearFilter, // bool: apply bilinear filtering to the image + DTA_SpecialColormap,// pointer to FSpecialColormapParameters (likely to be forever hardware-only) + DTA_ColormapStyle, // pointer to FColormapStyle (hardware-only) // For DrawText calls: DTA_TextLen, // stop after this many characters, even if \0 not hit @@ -225,6 +227,8 @@ public: INTBOOL masked; INTBOOL bilinear; FRenderStyle style; + struct FSpecialColormap *specialcolormap; + struct FColormapStyle *colormapstyle; }; protected: @@ -344,17 +348,24 @@ public: // renders view to a savegame picture virtual void WriteSavePic (player_t *player, FILE *file, int width, int height); + // draws player sprites with hardware acceleration (only useful for software rendering) + virtual void DrawRemainingPlayerSprites(); + bool Accel2D; // If true, 2D drawing can be accelerated. // Begin 2D drawing operations. This is like Update, but it doesn't end // the scene, and it doesn't present the image yet. If you are going to // be covering the entire screen with 2D elements, then pass false to - // avoid copying the software bufferer to the screen. + // avoid copying the software buffer to the screen. // Returns true if hardware-accelerated 2D has been entered, false if not. virtual bool Begin2D(bool copy3d); // DrawTexture calls after Begin2D use native textures. + // Draws the blending rectangle over the viewwindow if in hardware- + // accelerated 2D mode. + virtual void DrawBlendingRect(); + // Create a native texture from a game texture. virtual FNativeTexture *CreateTexture(FTexture *gametex, bool wrapping); diff --git a/src/version.h b/src/version.h index 283bfd413..8896eb713 100644 --- a/src/version.h +++ b/src/version.h @@ -75,7 +75,7 @@ // SAVESIG should match SAVEVER. // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 1823 +#define MINSAVEVER 1848 #if SVN_REVISION_NUMBER < MINSAVEVER // Never write a savegame with a version lower than what we need diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index 6eb7da66f..562abf13d 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -61,13 +61,14 @@ #include "v_pfx.h" #include "stats.h" #include "doomerrors.h" -#include "r_draw.h" +#include "r_main.h" #include "r_translate.h" #include "f_wipe.h" #include "st_stuff.h" #include "win32iface.h" #include "doomstat.h" #include "v_palette.h" +#include "w_wad.h" // MACROS ------------------------------------------------------------------ @@ -168,6 +169,7 @@ enum BQF_WrapUV = 16, BQF_InvertSource = 32, BQF_DisableAlphaTest= 64, + BQF_Desaturated = 128, }; // Shaders for a buffered quad @@ -176,7 +178,9 @@ enum BQS_PalTex, BQS_Plain, BQS_RedToAlpha, - BQS_ColorOnly + BQS_ColorOnly, + BQS_SpecialColormap, + BQS_InGameColormap, }; // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- @@ -207,7 +211,33 @@ extern cycle_t BlitCycles; // PRIVATE DATA DEFINITIONS ------------------------------------------------ -#include "fb_d3d9_shaders.h" +const char *const D3DFB::ShaderNames[D3DFB::NUM_SHADERS] = +{ + "NormalColor.pso", + "NormalColorPal.pso", + "NormalColorInv.pso", + "NormalColorPalInv.pso", + + "RedToAlpha.pso", + "RedToAlphaInv.pso", + + "VertexColor.pso", + + "SpecialColormap.pso", + "SpecialColorMapPal.pso", + + "InGameColormap.pso", + "InGameColormapDesat.pso", + "InGameColormapInv.pso", + "InGameColormapInvDesat.pso", + "InGameColormapPal.pso", + "InGameColormapPalDesat.pso", + "InGameColormapPalInv.pso", + "InGameColormapPalInvDesat.pso", + + "BurnWipe.pso", + "GammaCorrection.pso", +}; // PUBLIC DATA DEFINITIONS ------------------------------------------------- @@ -216,11 +246,18 @@ CUSTOM_CVAR(Bool, vid_hw2d, true, CVAR_NOINITCALL) BorderNeedRefresh = SB_state = screen->GetPageCount(); } +CVAR(Bool, d3d_antilag, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Int, d3d_showpacks, 0, 0) CVAR(Bool, vid_hwaalines, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // CODE -------------------------------------------------------------------- +//========================================================================== +// +// D3DFB - Constructor +// +//========================================================================== + D3DFB::D3DFB (int width, int height, bool fullscreen) : BaseWinFB (width, height) { @@ -236,15 +273,12 @@ D3DFB::D3DFB (int width, int height, bool fullscreen) ScreenshotSurface = NULL; FinalWipeScreen = NULL; PaletteTexture = NULL; - PalTexShader = NULL; - InvPalTexShader = NULL; - PalTexBilinearShader = NULL; - PlainShader = NULL; - InvPlainShader = NULL; - RedToAlphaShader = NULL; - ColorOnlyShader = NULL; - GammaFixerShader = NULL; - BurnShader = NULL; + for (int i = 0; i < NUM_SHADERS; ++i) + { + Shaders[i] = NULL; + } + BlockSurface[0] = NULL; + BlockSurface[1] = NULL; FBFormat = D3DFMT_UNKNOWN; PalFormat = D3DFMT_UNKNOWN; VSync = vid_vsync; @@ -350,6 +384,12 @@ D3DFB::D3DFB (int width, int height, bool fullscreen) } } +//========================================================================== +// +// D3DFB - Destructor +// +//========================================================================== + D3DFB::~D3DFB () { ReleaseResources(); @@ -357,8 +397,15 @@ D3DFB::~D3DFB () delete[] QuadExtra; } +//========================================================================== +// +// D3DFB :: SetInitialState +// // Called after initial device creation and reset, when everything is set // to D3D's defaults. +// +//========================================================================== + void D3DFB::SetInitialState() { AlphaBlendEnabled = FALSE; @@ -398,9 +445,9 @@ void D3DFB::SetInitialState() D3DDevice->SetGammaRamp(0, 0, &ramp); } - // Used by the inverse color shaders - float ones[4] = { 1, 1, 1, 1 }; - D3DDevice->SetPixelShaderConstantF(6, ones, 1); + // This constant is used for grayscaling weights (.xyz) and color inversion (.w) + float weights[4] = { 77/256.f, 143/256.f, 37/256.f, 1 }; + D3DDevice->SetPixelShaderConstantF(PSCONST_Weights, weights, 1); // D3DRS_ALPHATESTENABLE defaults to FALSE // D3DRS_ALPHAREF defaults to 0 @@ -410,6 +457,12 @@ void D3DFB::SetInitialState() CurBorderColor = 0; } +//========================================================================== +// +// D3DFB :: FillPresentParameters +// +//========================================================================== + void D3DFB::FillPresentParameters (D3DPRESENT_PARAMETERS *pp, bool fullscreen, bool vsync) { memset (pp, 0, sizeof(*pp)); @@ -427,7 +480,13 @@ void D3DFB::FillPresentParameters (D3DPRESENT_PARAMETERS *pp, bool fullscreen, b } } -bool D3DFB::CreateResources () +//========================================================================== +// +// D3DFB :: CreateResources +// +//========================================================================== + +bool D3DFB::CreateResources() { Packs = NULL; if (!Windowed) @@ -444,56 +503,28 @@ bool D3DFB::CreateResources () LOG2 ("Resize window to %dx%d\n", sizew, sizeh); VidResizing = true; // Make sure the window has a border in windowed mode - SetWindowLong (Window, GWL_STYLE, WS_VISIBLE|WS_OVERLAPPEDWINDOW); - if (GetWindowLong (Window, GWL_EXSTYLE) & WS_EX_TOPMOST) + SetWindowLong(Window, GWL_STYLE, WS_VISIBLE|WS_OVERLAPPEDWINDOW); + if (GetWindowLong(Window, GWL_EXSTYLE) & WS_EX_TOPMOST) { // Direct3D 9 will apparently add WS_EX_TOPMOST to fullscreen windows, // and removing it is a little tricky. Using SetWindowLongPtr to clear it // will not do the trick, but sending the window behind everything will. - SetWindowPos (Window, HWND_BOTTOM, 0, 0, sizew, sizeh, + SetWindowPos(Window, HWND_BOTTOM, 0, 0, sizew, sizeh, SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOMOVE); - SetWindowPos (Window, HWND_TOP, 0, 0, 0, 0, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE); + SetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE); } else { - SetWindowPos (Window, NULL, 0, 0, sizew, sizeh, + SetWindowPos(Window, NULL, 0, 0, sizew, sizeh, SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER); } - I_RestoreWindowedPos (); + I_RestoreWindowedPos(); VidResizing = false; } - SM14 = false; - if (FAILED(D3DDevice->CreatePixelShader (PalTexShader20Def, &PalTexShader)) && - (SM14 = true, FAILED(D3DDevice->CreatePixelShader (PalTexShader14Def, &PalTexShader)))) + if (!LoadShaders()) { return false; } - if (FAILED(D3DDevice->CreatePixelShader (InvPalTexShader20Def, &InvPalTexShader)) && - (SM14 = true, FAILED(D3DDevice->CreatePixelShader (InvPalTexShader14Def, &InvPalTexShader)))) - { - return false; - } - if (FAILED(D3DDevice->CreatePixelShader (PlainShaderDef, &PlainShader)) || - FAILED(D3DDevice->CreatePixelShader (InvPlainShaderDef, &InvPlainShader)) || - FAILED(D3DDevice->CreatePixelShader (RedToAlphaDef, &RedToAlphaShader)) || - FAILED(D3DDevice->CreatePixelShader (ColorOnlyDef, &ColorOnlyShader))) - { - return false; - } - if (FAILED(D3DDevice->CreatePixelShader (GammaFixerDef, &GammaFixerShader))) - { -// Cannot print during screen creation. -// Printf ("Using Shader Model 1.4: Windowed mode gamma will not work.\n"); - GammaFixerShader = NULL; - } - if (FAILED(D3DDevice->CreatePixelShader(PalTexBilinearDef, &PalTexBilinearShader))) - { - PalTexBilinearShader = PalTexShader; - } - if (FAILED(D3DDevice->CreatePixelShader (BurnShaderDef, &BurnShader))) - { - BurnShader = NULL; - } if (!CreateFBTexture() || !CreatePaletteTexture()) { @@ -503,9 +534,66 @@ bool D3DFB::CreateResources () { return false; } + CreateBlockSurfaces(); return true; } +//========================================================================== +// +// D3DFB :: LoadShaders +// +// Returns true if all required shaders were loaded. (Gamma and burn wipe +// are the only ones not considered "required".) +// +//========================================================================== + +bool D3DFB::LoadShaders() +{ + static const char *const models[] = { "30/", "20/", "14/" }; + FString shaderdir, shaderpath; + int model, i, lump; + + // We determine the best available model simply by trying them all in + // order of decreasing preference. + for (model = 0; model < countof(models); ++model) + { + shaderdir = "shaders/d3d/sm"; + shaderdir += models[model]; + for (i = 0; i < NUM_SHADERS; ++i) + { + shaderpath = shaderdir; + shaderpath += ShaderNames[i]; + lump = Wads.CheckNumForFullName(shaderpath); + if (lump >= 0) + { + FMemLump data = Wads.ReadLump(lump); + if (FAILED(D3DDevice->CreatePixelShader((DWORD *)data.GetMem(), &Shaders[i])) && + i != SHADER_GammaCorrection && i != SHADER_BurnWipe) + { + break; + } + } + } + if (i == NUM_SHADERS) + { // Success! + SM14 = (model == countof(models) - 1); + return true; + } + // Failure. Release whatever managed to load (which is probably nothing.) + for (i = 0; i < NUM_SHADERS; ++i) + { + SAFE_RELEASE( Shaders[i] ); + } + } + return false; +} + +//========================================================================== +// +// D3DFB :: ReleaseResources +// +//========================================================================== + void D3DFB::ReleaseResources () { I_SaveWindowedPos (); @@ -515,22 +603,10 @@ void D3DFB::ReleaseResources () SAFE_RELEASE( ScreenshotSurface ); SAFE_RELEASE( ScreenshotTexture ); SAFE_RELEASE( PaletteTexture ); - if (PalTexBilinearShader != NULL) + for (int i = 0; i < NUM_SHADERS; ++i) { - if (PalTexBilinearShader != PalTexShader) - { - PalTexBilinearShader->Release(); - } - PalTexBilinearShader = NULL; + SAFE_RELEASE( Shaders[i] ); } - SAFE_RELEASE( PalTexShader ); - SAFE_RELEASE( InvPalTexShader ); - SAFE_RELEASE( PlainShader ); - SAFE_RELEASE( InvPlainShader ); - SAFE_RELEASE( RedToAlphaShader ); - SAFE_RELEASE( ColorOnlyShader ); - SAFE_RELEASE( GammaFixerShader ); - SAFE_RELEASE( BurnShader ); if (ScreenWipe != NULL) { delete ScreenWipe; @@ -545,7 +621,14 @@ void D3DFB::ReleaseResources () GatheringWipeScreen = false; } +//========================================================================== +// +// D3DFB :: ReleaseDefaultPoolItems +// // Free resources created with D3DPOOL_DEFAULT. +// +//========================================================================== + void D3DFB::ReleaseDefaultPoolItems() { SAFE_RELEASE( FBTexture ); @@ -561,8 +644,16 @@ void D3DFB::ReleaseDefaultPoolItems() SAFE_RELEASE( InitialWipeScreen ); SAFE_RELEASE( VertexBuffer ); SAFE_RELEASE( IndexBuffer ); + SAFE_RELEASE( BlockSurface[0] ); + SAFE_RELEASE( BlockSurface[1] ); } +//========================================================================== +// +// D3DFB :: Reset +// +//========================================================================== + bool D3DFB::Reset () { D3DPRESENT_PARAMETERS d3dpp; @@ -589,10 +680,35 @@ bool D3DFB::Reset () { return false; } + CreateBlockSurfaces(); SetInitialState(); return true; } +//========================================================================== +// +// D3DFB :: CreateBlockSurfaces +// +// Create blocking surfaces for antilag. It's okay if these can't be +// created; antilag just won't work. +// +//========================================================================== + +void D3DFB::CreateBlockSurfaces() +{ + BlockNum = 0; + if (SUCCEEDED(D3DDevice->CreateOffscreenPlainSurface(16, 16, D3DFMT_A8R8G8B8, + D3DPOOL_DEFAULT, &BlockSurface[0], 0))) + { + if (FAILED(D3DDevice->CreateOffscreenPlainSurface(16, 16, D3DFMT_A8R8G8B8, + D3DPOOL_DEFAULT, &BlockSurface[1], 0))) + { + BlockSurface[0]->Release(); + BlockSurface[0] = NULL; + } + } +} + //========================================================================== // // D3DFB :: KillNativePals @@ -836,10 +952,7 @@ void D3DFB::Update () DrawRateStuff(); DrawPackedTextures(d3d_showpacks); EndBatch(); // Make sure all batched primitives are drawn. - DoWindowedGamma(); - D3DDevice->EndScene(); - D3DDevice->Present(NULL, NULL, NULL, NULL); - InScene = false; + Flip(); } In2D = 0; return; @@ -881,7 +994,7 @@ void D3DFB::Update () } psgamma[2] = psgamma[1] = psgamma[0] = igamma; psgamma[3] = 1; - D3DDevice->SetPixelShaderConstantF(7, psgamma, 1); + D3DDevice->SetPixelShaderConstantF(PSCONST_Gamma, psgamma, 1); } if (NeedPalUpdate) @@ -902,10 +1015,7 @@ void D3DFB::Update () Draw3DPart(In2D <= 1); if (In2D == 0) { - DoWindowedGamma(); - D3DDevice->EndScene(); - D3DDevice->Present(NULL, NULL, NULL, NULL); - InScene = false; + Flip(); } BlitCycles.Unclock(); @@ -915,6 +1025,30 @@ void D3DFB::Update () UpdatePending = false; } +void D3DFB::Flip() +{ + assert(InScene); + + DoWindowedGamma(); + D3DDevice->EndScene(); + + // Attempt to counter input lag. + if (d3d_antilag && BlockSurface[0] != NULL) + { + D3DLOCKED_RECT lr; + volatile int dummy; + D3DDevice->ColorFill(BlockSurface[BlockNum], NULL, D3DCOLOR_ARGB(0xFF,0,0x20,0x50)); + BlockNum ^= 1; + if (!FAILED((BlockSurface[BlockNum]->LockRect(&lr, NULL, D3DLOCK_READONLY)))) + { + dummy = *(int *)lr.pBits; + BlockSurface[BlockNum]->UnlockRect(); + } + } + D3DDevice->Present(NULL, NULL, NULL, NULL); + InScene = false; +} + bool D3DFB::PaintToWindow () { HRESULT hr; @@ -971,7 +1105,7 @@ void D3DFB::Draw3DPart(bool copy3d) D3DDevice->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, vid_hwaalines); assert(OldRenderTarget == NULL); if (TempRenderTexture != NULL && - ((Windowed && GammaFixerShader && TempRenderTexture != FinalWipeScreen) || GatheringWipeScreen || PixelDoubling)) + ((Windowed && Shaders[SHADER_GammaCorrection] && TempRenderTexture != FinalWipeScreen) || GatheringWipeScreen || PixelDoubling)) { IDirect3DSurface9 *targetsurf; if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &targetsurf))) @@ -989,17 +1123,40 @@ void D3DFB::Draw3DPart(bool copy3d) SetTexture (0, FBTexture); SetPaletteTexture(PaletteTexture, 256, BorderColor); - SetPixelShader(PalTexShader); D3DDevice->SetFVF (D3DFVF_FBVERTEX); memset(Constant, 0, sizeof(Constant)); SetAlphaBlend(D3DBLENDOP(0)); EnableAlphaTest(FALSE); + SetPixelShader(Shaders[SHADER_NormalColorPal]); if (copy3d) { FBVERTEX verts[4]; - CalcFullscreenCoords(verts, Accel2D, false, FlashColor0, FlashColor1); + D3DCOLOR color0, color1; + if (Accel2D) + { + if (realfixedcolormap == NULL) + { + color0 = 0; + color1 = 0xFFFFFFF; + } + else + { + color0 = D3DCOLOR_COLORVALUE(realfixedcolormap->ColorizeStart[0]/2, + realfixedcolormap->ColorizeStart[1]/2, realfixedcolormap->ColorizeStart[2]/2, 0); + color1 = D3DCOLOR_COLORVALUE(realfixedcolormap->ColorizeEnd[0]/2, + realfixedcolormap->ColorizeEnd[1]/2, realfixedcolormap->ColorizeEnd[2]/2, 1); + SetPixelShader(Shaders[SHADER_SpecialColormapPal]); + } + } + else + { + color0 = FlashColor0; + color1 = FlashColor1; + } + CalcFullscreenCoords(verts, Accel2D, false, color0, color1); D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX)); } + SetPixelShader(Shaders[SHADER_NormalColorPal]); } //========================================================================== @@ -1039,7 +1196,7 @@ void D3DFB::DoWindowedGamma() D3DDevice->SetRenderTarget(0, OldRenderTarget); D3DDevice->SetFVF(D3DFVF_FBVERTEX); SetTexture(0, TempRenderTexture); - SetPixelShader((Windowed && GammaFixerShader != NULL) ? GammaFixerShader : PlainShader); + SetPixelShader(Shaders[(Windowed && Shaders[SHADER_GammaCorrection]) ? SHADER_GammaCorrection : SHADER_NormalColor]); SetAlphaBlend(D3DBLENDOP(0)); EnableAlphaTest(FALSE); D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX)); @@ -2148,6 +2305,23 @@ bool D3DFB::Begin2D(bool copy3d) return true; } +//========================================================================== +// +// D3DFB :: DrawBlendingRect +// +// Call after Begin2D to blend the 3D view. +// +//========================================================================== + +void D3DFB::DrawBlendingRect() +{ + if (!In2D || !Accel2D) + { + return; + } + Dim(FlashColor, FlashAmount / 256.f, viewwindowx, viewwindowy, viewwidth, viewheight); +} + //========================================================================== // // D3DFB :: CreateTexture @@ -2278,7 +2452,7 @@ void D3DFB::EndLineBatch() VertexBuffer->Unlock(); if (VertexPos > 0) { - SetPixelShader(ColorOnlyShader); + SetPixelShader(Shaders[SHADER_VertexColor]); SetAlphaBlend(D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); D3DDevice->SetStreamSource(0, VertexBuffer, 0, sizeof(FBVERTEX)); D3DDevice->DrawPrimitive(D3DPT_LINELIST, 0, VertexPos / 2); @@ -2357,7 +2531,7 @@ void D3DFB::DrawPixel(int x, int y, int palcolor, uint32 color) float(x), float(y), 0, 1, color }; EndBatch(); // Draw out any batched operations. - SetPixelShader(ColorOnlyShader); + SetPixelShader(Shaders[SHADER_VertexColor]); SetAlphaBlend(D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); D3DDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 1, &pt, sizeof(FBVERTEX)); } @@ -2454,7 +2628,10 @@ void STACK_ARGS D3DFB::DrawTextureV (FTexture *img, int x, int y, uint32 tags_fi EndQuadBatch(); BeginQuadBatch(); } - RECT scissor = { parms.lclip, parms.uclip, parms.rclip, parms.dclip }; + RECT scissor = { + parms.lclip, parms.uclip + LBOffsetI, + parms.rclip, parms.dclip + LBOffsetI + }; D3DDevice->SetScissorRect(&scissor); D3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); } @@ -2845,26 +3022,38 @@ void D3DFB::EndQuadBatch() // Set the pixel shader if (quad->ShaderNum == BQS_PalTex) { - if (!(quad->Flags & BQF_Bilinear)) - { - SetPixelShader((quad->Flags & BQF_InvertSource) ? InvPalTexShader : PalTexShader); - } - else - { - SetPixelShader(PalTexBilinearShader); - } + SetPixelShader(Shaders[(quad->Flags & BQF_InvertSource) ? + SHADER_NormalColorPalInv : SHADER_NormalColorPal]); } else if (quad->ShaderNum == BQS_Plain) { - SetPixelShader((quad->Flags & BQF_InvertSource) ? InvPlainShader : PlainShader); + SetPixelShader(Shaders[(quad->Flags & BQF_InvertSource) ? + SHADER_NormalColorInv : SHADER_NormalColor]); } else if (quad->ShaderNum == BQS_RedToAlpha) { - SetPixelShader(RedToAlphaShader); + SetPixelShader(Shaders[(quad->Flags & BQF_InvertSource) ? + SHADER_RedToAlphaInv : SHADER_RedToAlpha]); } else if (quad->ShaderNum == BQS_ColorOnly) { - SetPixelShader(ColorOnlyShader); + SetPixelShader(Shaders[SHADER_VertexColor]); + } + else if (quad->ShaderNum == BQS_SpecialColormap) + { + int select; + + select = !!(quad->Flags & BQF_Paletted); + SetPixelShader(Shaders[SHADER_SpecialColormap + select]); + } + else if (quad->ShaderNum == BQS_InGameColormap) + { + int select; + + select = !!(quad->Flags & BQF_Desaturated); + select |= !!(quad->Flags & BQF_InvertSource) << 1; + select |= !!(quad->Flags & BQF_Paletted) << 2; + SetPixelShader(Shaders[SHADER_InGameColormap + select]); } // Set the texture clamp addressing mode @@ -2961,6 +3150,7 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR & stencilling = false; quad.Palette = NULL; + quad.Flags = 0; switch (style.BlendOp) { @@ -3047,10 +3237,42 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR & { quad.Flags |= BQF_InvertSource; } + + if (parms.specialcolormap != NULL) + { // Emulate an invulnerability or similar colormap. + float *start, *end; + start = parms.specialcolormap->ColorizeStart; + end = parms.specialcolormap->ColorizeEnd; + if (quad.Flags & BQF_InvertSource) + { + quad.Flags &= ~BQF_InvertSource; + swap(start, end); + } + quad.ShaderNum = BQS_SpecialColormap; + color0 = D3DCOLOR_RGBA(DWORD(start[0]/2*255), DWORD(start[1]/2*255), DWORD(start[2]/2*255), color0 >> 24); + color1 = D3DCOLOR_RGBA(DWORD(end[0]/2*255), DWORD(end[1]/2*255), DWORD(end[2]/2*255), color1 >> 24); + } + else if (parms.colormapstyle != NULL) + { // Emulate the fading from an in-game colormap (colorized, faded, and desaturated) + if (parms.colormapstyle->Desaturate != 0) + { + quad.Flags |= BQF_Desaturated; + } + quad.ShaderNum = BQS_InGameColormap; + color0 = D3DCOLOR_ARGB(parms.colormapstyle->Desaturate, + parms.colormapstyle->Color.r, + parms.colormapstyle->Color.g, + parms.colormapstyle->Color.b); + double fadelevel = parms.colormapstyle->FadeLevel; + color1 = D3DCOLOR_ARGB(DWORD((1 - fadelevel) * 255), + DWORD(parms.colormapstyle->Fade.r * fadelevel), + DWORD(parms.colormapstyle->Fade.g * fadelevel), + DWORD(parms.colormapstyle->Fade.b * fadelevel)); + } } // For unmasked images, force the alpha from the image data to be ignored. - if (!parms.masked) + if (!parms.masked && quad.ShaderNum != BQS_InGameColormap) { color0 = (color0 & D3DCOLOR_RGBA(255, 255, 255, 0)) | D3DCOLOR_COLORVALUE(0, 0, 0, alpha); color1 &= D3DCOLOR_RGBA(255, 255, 255, 0); @@ -3187,7 +3409,7 @@ void D3DFB::SetPaletteTexture(IDirect3DTexture9 *texture, int count, D3DCOLOR bo if (SM14) { // Shader Model 1.4 only uses 256-color palettes. - SetConstant(2, 1.f, 0.5f / 256.f, 0, 0); + SetConstant(PSCONST_PaletteMod, 1.f, 0.5f / 256.f, 0, 0); if (border_color != 0 && CurBorderColor != border_color) { CurBorderColor = border_color; @@ -3208,13 +3430,14 @@ void D3DFB::SetPaletteTexture(IDirect3DTexture9 *texture, int count, D3DCOLOR bo // The constant register c2 is used to hold the multiplier in the // x part and the adder in the y part. float fcount = 1 / float(count); - SetConstant(2, pc * fcount, pal * fcount, 0, 0); + SetConstant(PSCONST_PaletteMod, pc * fcount, pal * fcount, 0, 0); } SetTexture(1, texture); } void D3DFB::SetPalTexBilinearConstants(PackingTexture *tex) { +#if 0 float con[8]; // Don't bother doing anything if the constants won't be used. @@ -3233,4 +3456,5 @@ void D3DFB::SetPalTexBilinearConstants(PackingTexture *tex) con[7] = con[3]; D3DDevice->SetPixelShaderConstantF(3, con, 2); +#endif } diff --git a/src/win32/fb_d3d9_shaders.h b/src/win32/fb_d3d9_shaders.h deleted file mode 100644 index 2e7292614..000000000 --- a/src/win32/fb_d3d9_shaders.h +++ /dev/null @@ -1,665 +0,0 @@ -#define HLSL_SOURCE_CODE 0 -#define SHADER_ASSEMBLY_CODE 0 - -// A paletted texture shader ------------------------------------------------ - -#if HLSL_SOURCE_CODE -sampler2D Image : register(s0); -sampler1D Palette : register(s1); -float4 PaletteMod : register(c2); - -float4 main (float2 texCoord : TEXCOORD0, float4 Flash : COLOR0, float4 InvFlash : COLOR1) : COLOR -{ - float index = tex2D (Image, texCoord).x; - index = index * PaletteMod.x + PaletteMod.y; - float4 rgb = tex1D (Palette, index); - return Flash + rgb * InvFlash; -} -#elif SHADER_ASSEMBLY_CODE -// -// Generated by Microsoft (R) D3DX9 Shader Compiler 9.15.779.0000 -// -// fxc paltex.ps /Tps_1_4 /LD /VnPalTexShader14Def /Fhpaltex.h -// -// -// Parameters: -// -// sampler2D Image; -// sampler1D Palette; -// float4 PaletteMod; -// -// -// Registers: -// -// Name Reg Size -// ------------ ----- ---- -// PaletteMod c2 1 -// Image s0 1 -// Palette s1 1 -// - - ps_1_4 - texld r0, t0 - mad r0.xy, r0.x, c2.x, c2.y - phase - texld r1, r0 - mad r0, r1, v1, v0 - -// approximately 4 instruction slots used (2 texture, 2 arithmetic) -#endif - -const DWORD PalTexShader14Def[] = -{ - 0xffff0104, 0x0039fffe, 0x42415443, 0x0000001c, 0x000000ab, 0xffff0104, - 0x00000003, 0x0000001c, 0x00000100, 0x000000a4, 0x00000058, 0x00000003, - 0x00000001, 0x00000060, 0x00000000, 0x00000070, 0x00010003, 0x00000001, - 0x00000078, 0x00000000, 0x00000088, 0x00020002, 0x00020001, 0x00000094, - 0x00000000, 0x67616d49, 0xabab0065, 0x000c0004, 0x00010001, 0x00000001, - 0x00000000, 0x656c6150, 0x00657474, 0x000b0004, 0x00010001, 0x00000001, - 0x00000000, 0x656c6150, 0x4d657474, 0xab00646f, 0x00030001, 0x00040001, - 0x00000001, 0x00000000, 0x315f7370, 0x4d00345f, 0x6f726369, 0x74666f73, - 0x29522820, 0x44334420, 0x53203958, 0x65646168, 0x6f432072, 0x6c69706d, - 0x39207265, 0x2e35312e, 0x2e393737, 0x30303030, 0xababab00, 0x00000042, - 0x800f0000, 0xb0e40000, 0x00000004, 0x80030000, 0x80000000, 0xa0000002, - 0xa0550002, 0x0000fffd, 0x00000042, 0x800f0001, 0x80e40000, 0x00000004, - 0x800f0000, 0x80e40001, 0x90e40001, 0x90e40000, 0x0000ffff -}; - -#if SHADER_ASSEMBLY_CODE - ps_2_0 - dcl t0.xy - dcl v0 - dcl v1 - dcl_2d s0 - dcl_2d s1 - texld r0, t0, s0 - mad r0.xy, r0.x, c2.x, c2.y - texld r0, r0, s1 - mov r1, v1 - mad r0, r0, r1, v0 - mov oC0, r0 - -// approximately 6 instruction slots used (2 texture, 4 arithmetic) -#endif - -const DWORD PalTexShader20Def[] = -{ - 0xffff0200, 0x0039fffe, 0x42415443, 0x0000001c, 0x000000ab, 0xffff0200, - 0x00000003, 0x0000001c, 0x00000100, 0x000000a4, 0x00000058, 0x00000003, - 0x00000001, 0x00000060, 0x00000000, 0x00000070, 0x00010003, 0x00000001, - 0x00000078, 0x00000000, 0x00000088, 0x00020002, 0x00020001, 0x00000094, - 0x00000000, 0x67616d49, 0xabab0065, 0x000c0004, 0x00010001, 0x00000001, - 0x00000000, 0x656c6150, 0x00657474, 0x000b0004, 0x00010001, 0x00000001, - 0x00000000, 0x656c6150, 0x4d657474, 0xab00646f, 0x00030001, 0x00040001, - 0x00000001, 0x00000000, 0x325f7370, 0x4d00305f, 0x6f726369, 0x74666f73, - 0x29522820, 0x44334420, 0x53203958, 0x65646168, 0x6f432072, 0x6c69706d, - 0x39207265, 0x2e35312e, 0x2e393737, 0x30303030, 0xababab00, 0x0200001f, - 0x80000000, 0xb0030000, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, - 0x80000000, 0x900f0001, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, - 0x90000000, 0xa00f0801, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, - 0x04000004, 0x80030000, 0x80000000, 0xa0000002, 0xa0550002, 0x03000042, - 0x800f0000, 0x80e40000, 0xa0e40801, 0x02000001, 0x800f0001, 0x90e40001, - 0x04000004, 0x800f0000, 0x80e40000, 0x80e40001, 0x90e40000, 0x02000001, - 0x800f0800, 0x80e40000, 0x0000ffff -}; - -// An inverted paletted texture shader -------------------------------------- - -#if HLSL_SOURCE_CODE -sampler2D Image : register(s0); -sampler1D Palette : register(s1); -float4 PaletteMod : register(c2); -float4 White : register(c6); // Preloaded with (1,1,1,0) - -float4 main (float2 texCoord : TEXCOORD0, float4 Flash : COLOR0, float4 InvFlash : COLOR1) : COLOR -{ - float index = tex2D (Image, texCoord).x; - index = index * PaletteMod.x + PaletteMod.y; - float4 rgb = tex1D (Palette, index); - rgb.xyz = White.xyz - rgb.xyz; - return Flash + rgb * InvFlash; -} -#elif SHADER_ASSEMBLY_CODE -// -// Generated by Microsoft (R) D3DX9 Shader Compiler 9.15.779.0000 -// -// fxc paltex.ps /Tps_1_4 /LD /VnInvPalTexShader14Def /Fhinvpaltex.h -// -// -// Parameters: -// -// sampler2D Image; -// sampler1D Palette; -// float4 PaletteMod; -// float4 White; -// -// -// Registers: -// -// Name Reg Size -// ------------ ----- ---- -// PaletteMod c2 1 -// White c6 1 -// Image s0 1 -// Palette s1 1 -// - - ps_1_4 - texld r0, t0 - mad r0.xy, r0.x, c2.x, c2.y - phase - texld r1, r0 - add r1.xyz, -r1, c6 - mad r0, r1, v1, v0 - -// approximately 5 instruction slots used (2 texture, 3 arithmetic) -#endif - -const DWORD InvPalTexShader14Def[] = -{ - 0xffff0104, 0x003ffffe, 0x42415443, 0x0000001c, 0x000000c5, 0xffff0104, - 0x00000004, 0x0000001c, 0x00000100, 0x000000be, 0x0000006c, 0x00000003, - 0x00000001, 0x00000074, 0x00000000, 0x00000084, 0x00010003, 0x00000001, - 0x0000008c, 0x00000000, 0x0000009c, 0x00020002, 0x00020001, 0x000000a8, - 0x00000000, 0x000000b8, 0x00060002, 0x00020001, 0x000000a8, 0x00000000, - 0x67616d49, 0xabab0065, 0x000c0004, 0x00010001, 0x00000001, 0x00000000, - 0x656c6150, 0x00657474, 0x000b0004, 0x00010001, 0x00000001, 0x00000000, - 0x656c6150, 0x4d657474, 0xab00646f, 0x00030001, 0x00040001, 0x00000001, - 0x00000000, 0x74696857, 0x73700065, 0x345f315f, 0x63694d00, 0x6f736f72, - 0x28207466, 0x44202952, 0x39584433, 0x61685320, 0x20726564, 0x706d6f43, - 0x72656c69, 0x312e3920, 0x37372e35, 0x30302e39, 0xab003030, 0x00000042, - 0x800f0000, 0xb0e40000, 0x00000004, 0x80030000, 0x80000000, 0xa0000002, - 0xa0550002, 0x0000fffd, 0x00000042, 0x800f0001, 0x80e40000, 0x00000002, - 0x80070001, 0x81e40001, 0xa0e40006, 0x00000004, 0x800f0000, 0x80e40001, - 0x90e40001, 0x90e40000, 0x0000ffff -}; - -#if SHADER_ASSEMBLY_CODE - ps_2_0 - dcl t0.xy - dcl v0 - dcl v1 - dcl_2d s0 - dcl_2d s1 - texld r0, t0, s0 - mad r0.xy, r0.x, c2.x, c2.y - texld r0, r0, s1 - add r0.xyz, -r0, c6 - mov r1, v1 - mad r0, r0, r1, v0 - mov oC0, r0 - -// approximately 7 instruction slots used (2 texture, 5 arithmetic) -#endif - -const DWORD InvPalTexShader20Def[] = -{ - 0xffff0200, 0x003ffffe, 0x42415443, 0x0000001c, 0x000000c5, 0xffff0200, - 0x00000004, 0x0000001c, 0x20000100, 0x000000be, 0x0000006c, 0x00000003, - 0x00020001, 0x00000074, 0x00000000, 0x00000084, 0x00010003, 0x00060001, - 0x0000008c, 0x00000000, 0x0000009c, 0x00020002, 0x000a0001, 0x000000a8, - 0x00000000, 0x000000b8, 0x00060002, 0x001a0001, 0x000000a8, 0x00000000, - 0x67616d49, 0xabab0065, 0x000c0004, 0x00010001, 0x00000001, 0x00000000, - 0x656c6150, 0x00657474, 0x000b0004, 0x00010001, 0x00000001, 0x00000000, - 0x656c6150, 0x4d657474, 0xab00646f, 0x00030001, 0x00040001, 0x00000001, - 0x00000000, 0x74696857, 0x73700065, 0x305f325f, 0x63694d00, 0x6f736f72, - 0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, - 0x2072656c, 0x39312e39, 0x3934392e, 0x3131322e, 0xabab0031, 0x0200001f, - 0x80000000, 0xb0030000, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, - 0x80000000, 0x900f0001, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, - 0x90000000, 0xa00f0801, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, - 0x04000004, 0x80030000, 0x80000000, 0xa0000002, 0xa0550002, 0x03000042, - 0x800f0000, 0x80e40000, 0xa0e40801, 0x03000002, 0x80070000, 0x81e40000, - 0xa0e40006, 0x02000001, 0x800f0001, 0x90e40001, 0x04000004, 0x800f0000, - 0x80e40000, 0x80e40001, 0x90e40000, 0x02000001, 0x800f0800, 0x80e40000, - 0x0000ffff -}; - -// A paletted texture shader that does bilinear filtering ------------------- - -#if HLSL_SOURCE_CODE -sampler2D Image : register(s0); -sampler2D Palette : register(s1); -float4 PaletteMod : register(c2); - -//#define texture_size_x 512.0f -//#define texture_size_y 256.0f -//#define texel_size_x 1.0f / 512.0f -//#define texel_size_y 1.0f / 256.0f - -// texture_size_x, texture_size_y, 0, texel_size_x -float4 size_a : register(c3); - -// 0, texel_size_y, texel_size_y, texel_size_x -float4 size_b : register(c4); - -float4 main (float2 texCoord : TEXCOORD0, float4 Flash : COLOR0, float4 InvFlash : COLOR1) : COLOR -{ - float2 f = frac (texCoord.xy * size_a/*float2(texture_size_x, texture_size_y)*/); - - float4 t00 = tex2D(Image, texCoord); - float4 t10 = tex2D(Image, texCoord + size_a.wz/*float2(texel_size_x, 0)*/); - - t00.x = t00.x * PaletteMod.x + PaletteMod.y; - t10.x = t10.x * PaletteMod.x + PaletteMod.y; - - float4 c00 = tex2D(Palette, t00); - float4 c10 = tex2D(Palette, t10); - - float4 cA = lerp(c00, c10, f.x); - - float4 t01 = tex2D(Image, texCoord + size_b.xy/*float2(0, texel_size_y)*/); - float4 t11 = tex2D(Image, texCoord + size_b.wz/*float2(texel_size_x, texel_size_y)*/); - - t01.x = t01.x * PaletteMod.x + PaletteMod.y; - t11.x = t11.x * PaletteMod.x + PaletteMod.y; - - float4 c01 = tex2D(Palette, t01); - float4 c11 = tex2D(Palette, t11); - - float4 cB = lerp(c01, c11, f.x); - - return Flash + lerp(cA, cB, f.y) * InvFlash; -} -#elif SHADER_ASSEMBLY_CODE -// -// Generated by Microsoft (R) HLSL Shader Compiler 9.19.949.2111 -// -// fxc paltex_bilinear.ps /Tps_2_0 /VnPalTexBilinearDef /Fhpaltex_bilinear.h -// -// -// Parameters: -// -// sampler2D Image; -// sampler2D Palette; -// float4 PaletteMod; -// float4 size_a; -// float4 size_b; -// -// -// Registers: -// -// Name Reg Size -// ------------ ----- ---- -// PaletteMod c2 1 -// size_a c3 1 -// size_b c4 1 -// Image s0 1 -// Palette s1 1 -// - - ps_2_0 - dcl t0.xy - dcl v0 - dcl v1 - dcl_2d s0 - dcl_2d s1 - add r0.xy, t0, c4 - add r1.xy, t0, c4.wzyx - add r2.xy, t0, c3.wzyx - texld r0, r0, s0 - texld r1, r1, s0 - texld r2, r2, s0 - texld r3, t0, s0 - mad r0.x, r0.x, c2.x, c2.y - mad r1.x, r1.x, c2.x, c2.y - mad r2.x, r2.x, c2.x, c2.y - mad r3.x, r3.x, c2.x, c2.y - texld r0, r0, s1 - texld r1, r1, s1 - texld r2, r2, s1 - texld r3, r3, s1 - mul r4.xy, t0, c3 - frc r4.xy, r4 - lrp r5, r4.x, r1, r0 - lrp r0, r4.x, r2, r3 - lrp r1, r4.y, r5, r0 - mov r0, v1 - mad r0, r1, r0, v0 - mov oC0, r0 - -// approximately 23 instruction slots used (8 texture, 15 arithmetic) -#endif - -const DWORD PalTexBilinearDef[] = -{ - 0xffff0200, 0x0042fffe, 0x42415443, 0x0000001c, 0x000000d1, 0xffff0200, - 0x00000005, 0x0000001c, 0x20000100, 0x000000ca, 0x00000080, 0x00000003, - 0x00020001, 0x00000088, 0x00000000, 0x00000098, 0x00010003, 0x00060001, - 0x00000088, 0x00000000, 0x000000a0, 0x00020002, 0x000a0001, 0x000000ac, - 0x00000000, 0x000000bc, 0x00030002, 0x000e0001, 0x000000ac, 0x00000000, - 0x000000c3, 0x00040002, 0x00120001, 0x000000ac, 0x00000000, 0x67616d49, - 0xabab0065, 0x000c0004, 0x00010001, 0x00000001, 0x00000000, 0x656c6150, - 0x00657474, 0x656c6150, 0x4d657474, 0xab00646f, 0x00030001, 0x00040001, - 0x00000001, 0x00000000, 0x657a6973, 0x7300615f, 0x5f657a69, 0x73700062, - 0x305f325f, 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, - 0x64616853, 0x43207265, 0x69706d6f, 0x2072656c, 0x39312e39, 0x3934392e, - 0x3131322e, 0xabab0031, 0x0200001f, 0x80000000, 0xb0030000, 0x0200001f, - 0x80000000, 0x900f0000, 0x0200001f, 0x80000000, 0x900f0001, 0x0200001f, - 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, 0x03000002, - 0x80030000, 0xb0e40000, 0xa0e40004, 0x03000002, 0x80030001, 0xb0e40000, - 0xa01b0004, 0x03000002, 0x80030002, 0xb0e40000, 0xa01b0003, 0x03000042, - 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, - 0xa0e40800, 0x03000042, 0x800f0002, 0x80e40002, 0xa0e40800, 0x03000042, - 0x800f0003, 0xb0e40000, 0xa0e40800, 0x04000004, 0x80010000, 0x80000000, - 0xa0000002, 0xa0550002, 0x04000004, 0x80010001, 0x80000001, 0xa0000002, - 0xa0550002, 0x04000004, 0x80010002, 0x80000002, 0xa0000002, 0xa0550002, - 0x04000004, 0x80010003, 0x80000003, 0xa0000002, 0xa0550002, 0x03000042, - 0x800f0000, 0x80e40000, 0xa0e40801, 0x03000042, 0x800f0001, 0x80e40001, - 0xa0e40801, 0x03000042, 0x800f0002, 0x80e40002, 0xa0e40801, 0x03000042, - 0x800f0003, 0x80e40003, 0xa0e40801, 0x03000005, 0x80030004, 0xb0e40000, - 0xa0e40003, 0x02000013, 0x80030004, 0x80e40004, 0x04000012, 0x800f0005, - 0x80000004, 0x80e40001, 0x80e40000, 0x04000012, 0x800f0000, 0x80000004, - 0x80e40002, 0x80e40003, 0x04000012, 0x800f0001, 0x80550004, 0x80e40005, - 0x80e40000, 0x02000001, 0x800f0000, 0x90e40001, 0x04000004, 0x800f0000, - 0x80e40001, 0x80e40000, 0x90e40000, 0x02000001, 0x800f0800, 0x80e40000, - 0x0000ffff -}; - -// A shader that doesn't look up colors from a palette. --------------------- -// Can be used for RGB textures. - -#if HLSL_SOURCE_CODE -sampler2D Image : register(s0); - -float4 main (float2 texCoord : TEXCOORD0, float4 Flash : COLOR0, float4 InvFlash : COLOR1) : COLOR -{ - float4 index = tex2D (Image, texCoord); - return Flash + index * InvFlash; -} -#elif SHADER_ASSEMBLY_CODE -// -// Generated by Microsoft (R) D3DX9 Shader Compiler 9.15.779.0000 -// -// fxc plain.ps /Tps_1_1 /LD /VnPlainShaderDef /Fhplain.h -// -// -// Parameters: -// -// sampler2D Image; -// -// -// Registers: -// -// Name Reg Size -// ------------ ----- ---- -// Image s0 1 -// - - ps_1_1 - tex t0 - mad r0, t0, v1, v0 - -// approximately 2 instruction slots used (1 texture, 1 arithmetic) -#endif - -const DWORD PlainShaderDef[] = -{ - 0xffff0101, 0x0022fffe, 0x42415443, 0x0000001c, 0x0000004f, 0xffff0101, - 0x00000001, 0x0000001c, 0x00000100, 0x00000048, 0x00000030, 0x00000003, - 0x00000001, 0x00000038, 0x00000000, 0x67616d49, 0xabab0065, 0x000c0004, - 0x00010001, 0x00000001, 0x00000000, 0x315f7370, 0x4d00315f, 0x6f726369, - 0x74666f73, 0x29522820, 0x44334420, 0x53203958, 0x65646168, 0x6f432072, - 0x6c69706d, 0x39207265, 0x2e35312e, 0x2e393737, 0x30303030, 0xababab00, - 0x00000042, 0xb00f0000, 0x00000004, 0x800f0000, 0xb0e40000, 0x90e40001, - 0x90e40000, 0x0000ffff -}; - -// A shader that inverts the source's colors -------------------------------- - -#if HLSL_SOURCE_CODE -sampler2D Image : register(s0); -float4 White : register(c6); // Preloaded with (1,1,1,0) - -float4 main (float2 texCoord : TEXCOORD0, float4 Flash : COLOR0, float4 InvFlash : COLOR1) : COLOR -{ - float4 rgb = tex2D (Image, texCoord); - rgb.xyz = White.xyz - rgb.xyz; - return Flash + rgb * InvFlash; -} -#elif SHADER_ASSEMBLY_CODE -// -// Generated by Microsoft (R) D3DX9 Shader Compiler 9.15.779.0000 -// -// fxc plain.ps /Tps_1_1 /LD /VnInvPlainShaderDef /Fhinvplain.h -// -// -// Parameters: -// -// sampler2D Image; -// float4 White; -// -// -// Registers: -// -// Name Reg Size -// ------------ ----- ---- -// White c6 1 -// Image s0 1 -// - - ps_1_1 - tex t0 - add t0.xyz, -t0, c6 - mad r0, t0, v1, v0 - -// approximately 3 instruction slots used (1 texture, 2 arithmetic) -#endif - -const DWORD InvPlainShaderDef[] = -{ - 0xffff0101, 0x002dfffe, 0x42415443, 0x0000001c, 0x0000007b, 0xffff0101, - 0x00000002, 0x0000001c, 0x00000100, 0x00000074, 0x00000044, 0x00000003, - 0x00000001, 0x0000004c, 0x00000000, 0x0000005c, 0x00060002, 0x00020001, - 0x00000064, 0x00000000, 0x67616d49, 0xabab0065, 0x000c0004, 0x00010001, - 0x00000001, 0x00000000, 0x74696857, 0xabab0065, 0x00030001, 0x00040001, - 0x00000001, 0x00000000, 0x315f7370, 0x4d00315f, 0x6f726369, 0x74666f73, - 0x29522820, 0x44334420, 0x53203958, 0x65646168, 0x6f432072, 0x6c69706d, - 0x39207265, 0x2e35312e, 0x2e393737, 0x30303030, 0xababab00, 0x00000042, - 0xb00f0000, 0x00000002, 0xb0070000, 0xb1e40000, 0xa0e40006, 0x00000004, - 0x800f0000, 0xb0e40000, 0x90e40001, 0x90e40000, 0x0000ffff -}; - -// A shader that copies the red component to the alpha component ------------ - -#if HLSL_SOURCE_CODE -sampler2D Image : register(s0); - -float4 main (float2 texCoord : TEXCOORD0, float4 Flash : COLOR0, float4 InvFlash : COLOR1) : COLOR -{ - float4 color = tex2D (Image, texCoord); - color.a = color.r; - return Flash + color * InvFlash; -} -#elif SHADER_ASSEMBLY_CODE -// -// Generated by Microsoft (R) D3DX9 Shader Compiler 9.15.779.0000 -// -// fxc redtoalpha.ps /Tps_1_4 /LD /VnRedToAlphaDef /Fhredtoalpha.h -// -// -// Parameters: -// -// sampler2D Image; -// -// -// Registers: -// -// Name Reg Size -// ------------ ----- ---- -// Image s0 1 -// - - ps_1_4 - texld r0, t0 - mad r1.xyz, r0, v1, v0 - + mad r1.w, r0.x, v1.w, v0.w - mov r0, r1 - -// approximately 3 instruction slots used (1 texture, 2 arithmetic) -#endif - -const DWORD RedToAlphaDef[] = -{ - 0xffff0104, 0x0022fffe, 0x42415443, 0x0000001c, 0x0000004f, 0xffff0104, - 0x00000001, 0x0000001c, 0x00000100, 0x00000048, 0x00000030, 0x00000003, - 0x00000001, 0x00000038, 0x00000000, 0x67616d49, 0xabab0065, 0x000c0004, - 0x00010001, 0x00000001, 0x00000000, 0x315f7370, 0x4d00345f, 0x6f726369, - 0x74666f73, 0x29522820, 0x44334420, 0x53203958, 0x65646168, 0x6f432072, - 0x6c69706d, 0x39207265, 0x2e35312e, 0x2e393737, 0x30303030, 0xababab00, - 0x00000042, 0x800f0000, 0xb0e40000, 0x00000004, 0x80070001, 0x80e40000, - 0x90e40001, 0x90e40000, 0x40000004, 0x80080001, 0x80000000, 0x90ff0001, - 0x90ff0000, 0x00000001, 0x800f0000, 0x80e40001, 0x0000ffff -}; - -// A shader that just returns the first color component from the vertex ----- - -#if HLSL_SOURCE_CODE -float4 main (float4 color : COLOR0) : COLOR -{ - return color; -} -#elif SHADER_ASSEMBLY_CODE -// -// Generated by Microsoft (R) D3DX9 Shader Compiler 9.15.779.0000 -// -// fxc coloronlyshader.ps /Tps_1_1 /LD /VnColorOnlyDef /Fhcoloronly.h -// - ps_1_1 - mov r0, v0 - -// approximately 1 instruction slot used -#endif - -const DWORD ColorOnlyDef[] = -{ - 0xffff0101, 0x0017fffe, 0x42415443, 0x0000001c, 0x00000023, 0xffff0101, - 0x00000000, 0x00000000, 0x00000100, 0x0000001c, 0x315f7370, 0x4d00315f, - 0x6f726369, 0x74666f73, 0x29522820, 0x44334420, 0x53203958, 0x65646168, - 0x6f432072, 0x6c69706d, 0x39207265, 0x2e35312e, 0x2e393737, 0x30303030, - 0xababab00, 0x00000001, 0x800f0000, 0x90e40000, 0x0000ffff -}; - -// A shader that just corrects gamma for windowed mode ---------------------- - -#if HLSL_SOURCE_CODE -sampler2D Image : register(s0); -float4 Gamma : register(c7); - -float4 main (float2 texCoord : TEXCOORD0) : COLOR -{ - float4 color = tex2D (Image, texCoord); - color.xyz = pow(color.xyz, Gamma.xyz); - return color; -} -#elif SHADER_ASSEMBLY_CODE -// -// Generated by Microsoft (R) HLSL Shader Compiler 9.19.949.2111 -// -// fxc gammafixer.ps /Tps_2_0 /VnGammaFixerDef /Fhgammafixer.h -// -// -// Parameters: -// -// float4 Gamma; -// sampler2D Image; -// -// -// Registers: -// -// Name Reg Size -// ------------ ----- ---- -// Gamma c7 1 -// Image s0 1 -// - - ps_2_0 - dcl t0.xy - dcl_2d s0 - texld r0, t0, s0 - log r1.x, r0.x - log r1.y, r0.y - log r1.z, r0.z - mul r1.xyz, r1, c7 - exp r0.x, r1.x - exp r0.y, r1.y - exp r0.z, r1.z - mov oC0, r0 - -// approximately 9 instruction slots used (1 texture, 8 arithmetic) -#endif - -const DWORD GammaFixerDef[] = -{ - 0xffff0200, 0x002cfffe, 0x42415443, 0x0000001c, 0x0000007b, 0xffff0200, - 0x00000002, 0x0000001c, 0x20000100, 0x00000074, 0x00000044, 0x00070002, - 0x001e0001, 0x0000004c, 0x00000000, 0x0000005c, 0x00000003, 0x00020001, - 0x00000064, 0x00000000, 0x6d6d6147, 0xabab0061, 0x00030001, 0x00040001, - 0x00000001, 0x00000000, 0x67616d49, 0xabab0065, 0x000c0004, 0x00010001, - 0x00000001, 0x00000000, 0x325f7370, 0x4d00305f, 0x6f726369, 0x74666f73, - 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, - 0x2e392072, 0x392e3931, 0x322e3934, 0x00313131, 0x0200001f, 0x80000000, - 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x03000042, 0x800f0000, - 0xb0e40000, 0xa0e40800, 0x0200000f, 0x80010001, 0x80000000, 0x0200000f, - 0x80020001, 0x80550000, 0x0200000f, 0x80040001, 0x80aa0000, 0x03000005, - 0x80070001, 0x80e40001, 0xa0e40007, 0x0200000e, 0x80010000, 0x80000001, - 0x0200000e, 0x80020000, 0x80550001, 0x0200000e, 0x80040000, 0x80aa0001, - 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff -}; - -// The shader used by the burn effect screen wipe --------------------------- - -#if HLSL_SOURCE_CODE -sampler2D NewScreen : register(s0); -sampler2D Burn : register(s1); - -float4 main (float2 coord[2] : TEXCOORD0) : COLOR -{ - float4 color = tex2D(NewScreen, coord[0]); - float4 alpha = tex2D(Burn, coord[1]); - color.a = alpha.r * 2; - return color; -} -#elif SHADER_ASSEMBLY_CODE -// -// Generated by Microsoft (R) D3DX9 Shader Compiler 9.15.779.0000 -// -// fxc burn.ps /Tps_1_4 /VnBurnShaderDef /Fhburn.h /LD -// -// -// Parameters: -// -// sampler2D Burn; -// sampler2D NewScreen; -// -// -// Registers: -// -// Name Reg Size -// ------------ ----- ---- -// NewScreen s0 1 -// Burn s1 1 -// - - ps_1_4 - texld r0, t0 - texld r1, t1 - add r0.w, r1.x, r1.x - + mov r0.xyz, r0 - -// approximately 3 instruction slots used (2 texture, 1 arithmetic) -#endif - -const DWORD BurnShaderDef[] = -{ - 0xffff0104, 0x0029fffe, 0x42415443, 0x0000001c, 0x0000006d, 0xffff0104, - 0x00000002, 0x0000001c, 0x00000100, 0x00000066, 0x00000044, 0x00010003, - 0x00000001, 0x0000004c, 0x00000000, 0x0000005c, 0x00000003, 0x00000001, - 0x0000004c, 0x00000000, 0x6e727542, 0xababab00, 0x000c0004, 0x00010001, - 0x00000001, 0x00000000, 0x5377654e, 0x65657263, 0x7370006e, 0x345f315f, - 0x63694d00, 0x6f736f72, 0x28207466, 0x44202952, 0x39584433, 0x61685320, - 0x20726564, 0x706d6f43, 0x72656c69, 0x312e3920, 0x37372e35, 0x30302e39, - 0xab003030, 0x00000042, 0x800f0000, 0xb0e40000, 0x00000042, 0x800f0001, - 0xb0e40001, 0x00000002, 0x80080000, 0x80000001, 0x80000001, 0x40000001, - 0x80070000, 0x80e40000, 0x0000ffff -}; diff --git a/src/win32/fb_d3d9_wipe.cpp b/src/win32/fb_d3d9_wipe.cpp index a6adab9ee..699407b85 100644 --- a/src/win32/fb_d3d9_wipe.cpp +++ b/src/win32/fb_d3d9_wipe.cpp @@ -164,7 +164,7 @@ bool D3DFB::WipeStartScreen(int type) // Create another texture to copy the final wipe screen to so // we can still gamma correct the wipe. Since this is just for // gamma correction, it's okay to fail (though not desirable.) - if (PixelDoubling || (GammaFixerShader != NULL && Windowed)) + if (PixelDoubling || (Shaders[SHADER_GammaCorrection] != NULL && Windowed)) { if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &tsurf))) { @@ -384,7 +384,7 @@ bool D3DFB::Wiper_Crossfade::Run(int ticks, D3DFB *fb) fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX); fb->SetTexture(0, fb->FinalWipeScreen); fb->SetAlphaBlend(D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); - fb->SetPixelShader(fb->PlainShader); + fb->SetPixelShader(fb->Shaders[SHADER_NormalColor]); fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX)); return Clock >= 32; @@ -442,7 +442,7 @@ bool D3DFB::Wiper_Melt::Run(int ticks, D3DFB *fb) fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX); fb->SetTexture(0, fb->FinalWipeScreen); fb->SetAlphaBlend(D3DBLENDOP(0)); - fb->SetPixelShader(fb->PlainShader); + fb->SetPixelShader(fb->Shaders[SHADER_NormalColor]); fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX)); int i, dy; @@ -504,7 +504,7 @@ D3DFB::Wiper_Burn::Wiper_Burn(D3DFB *fb) Density = 4; BurnTime = 0; memset(BurnArray, 0, sizeof(BurnArray)); - if (fb->BurnShader == NULL || FAILED(fb->D3DDevice->CreateTexture(WIDTH, HEIGHT, 1, + if (fb->Shaders[SHADER_BurnWipe] == NULL || FAILED(fb->D3DDevice->CreateTexture(WIDTH, HEIGHT, 1, D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &BurnTexture, NULL))) { BurnTexture = NULL; @@ -593,7 +593,7 @@ bool D3DFB::Wiper_Burn::Run(int ticks, D3DFB *fb) fb->SetTexture(0, fb->FinalWipeScreen); fb->SetTexture(1, BurnTexture); fb->SetAlphaBlend(D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); - fb->SetPixelShader(fb->BurnShader); + fb->SetPixelShader(fb->Shaders[SHADER_BurnWipe]); fb->D3DDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); if (fb->SM14) { diff --git a/src/win32/win32iface.h b/src/win32/win32iface.h index 2c6440c2c..e4c21a015 100644 --- a/src/win32/win32iface.h +++ b/src/win32/win32iface.h @@ -226,6 +226,7 @@ public: bool Lock (bool buffered); void Unlock (); void Update (); + void Flip (); PalEntry *GetPalette (); void GetFlashedPalette (PalEntry palette[256]); void UpdatePalette (); @@ -244,6 +245,7 @@ public: void ReleaseScreenshotBuffer(); void SetBlendingRect (int x1, int y1, int x2, int y2); bool Begin2D (bool copy3d); + void DrawBlendingRect (); FNativeTexture *CreateTexture (FTexture *gametex, bool wrapping); FNativePalette *CreatePalette (FRemapTable *remap); void STACK_ARGS DrawTextureV (FTexture *img, int x, int y, uint32 tag, va_list tags); @@ -290,9 +292,48 @@ private: PackingTexture *Texture; }; + enum + { + PSCONST_PaletteMod = 2, + PSCONST_Weights = 6, + PSCONST_Gamma = 7, + }; + enum + { + SHADER_NormalColor, + SHADER_NormalColorPal, + SHADER_NormalColorInv, + SHADER_NormalColorPalInv, + + SHADER_RedToAlpha, + SHADER_RedToAlphaInv, + + SHADER_VertexColor, + + SHADER_SpecialColormap, + SHADER_SpecialColormapPal, + + SHADER_InGameColormap, + SHADER_InGameColormapDesat, + SHADER_InGameColormapInv, + SHADER_InGameColormapInvDesat, + SHADER_InGameColormapPal, + SHADER_InGameColormapPalDesat, + SHADER_InGameColormapPalInv, + SHADER_InGameColormapPalInvDesat, + + SHADER_BurnWipe, + SHADER_GammaCorrection, + + NUM_SHADERS + }; + static const char *const ShaderNames[NUM_SHADERS]; + void SetInitialState(); bool CreateResources(); void ReleaseResources(); + bool LoadShaders(); + void CreateBlockSurfaces(); bool CreateFBTexture(); bool CreatePaletteTexture(); bool CreateGrayPaletteTexture(); @@ -365,6 +406,7 @@ private: bool SM14; bool GatheringWipeScreen; bool AALines; + BYTE BlockNum; D3DPal *Palettes; D3DTex *Textures; PackingTexture *Packs; @@ -386,13 +428,9 @@ private: int QuadBatchPos; enum { BATCH_None, BATCH_Quads, BATCH_Lines } BatchType; - IDirect3DPixelShader9 *PalTexShader, *PalTexBilinearShader, *InvPalTexShader; - IDirect3DPixelShader9 *PlainShader, *InvPlainShader; - IDirect3DPixelShader9 *RedToAlphaShader; - IDirect3DPixelShader9 *ColorOnlyShader; - IDirect3DPixelShader9 *GammaFixerShader; - IDirect3DPixelShader9 *BurnShader; + IDirect3DPixelShader9 *Shaders[NUM_SHADERS]; + IDirect3DSurface9 *BlockSurface[2]; IDirect3DSurface9 *OldRenderTarget; IDirect3DTexture9 *InitialWipeScreen, *FinalWipeScreen; diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 8a0d78b3f..b644b3511 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -260,7 +260,7 @@ ACTOR Actor native //: Thinker action native A_ChangeVelocity(float x = 0, float y = 0, float z = 0, int flags = 0); action native A_SetArg(int pos, int value); action native A_SetUserVar(int pos, int value); - action native A_SetSpecial(int spec, int arg0, int arg1, int arg2, int arg3, int arg4); + action native A_SetSpecial(int spec, int arg0 = 0, int arg1 = 0, int arg2 = 0, int arg3 = 0, int arg4 = 0); States { diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index c3a65e025..151a47686 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -63,9 +63,15 @@ const int MRF_UNDOBYDEATH = 512; const int MRF_UNDOBYDEATHFORCED = 1024; const int MRF_UNDOBYDEATHSAVES = 2048; +// Flags for A_RailAttack and A_CustomRailgun const int RGF_SILENT = 1; const int RGF_NOPIERCING = 2; +// Flags for A_Mushroom +const int MSF_Standard = 0; +const int MSF_Classic = 1; + +// Activation flags enum { THINGSPEC_Default = 0, @@ -77,7 +83,6 @@ enum THINGSPEC_ClearSpecial = 32, }; - // constants for A_PlaySound enum { diff --git a/wadsrc/static/actors/doom/dog.txt b/wadsrc/static/actors/doom/dog.txt index ea1e72231..0feb393f5 100644 --- a/wadsrc/static/actors/doom/dog.txt +++ b/wadsrc/static/actors/doom/dog.txt @@ -1,4 +1,4 @@ -ACTOR Dog 888 +ACTOR MBFHelperDog 888 { Game Doom Health 500 diff --git a/wadsrc/static/actors/heretic/hereticweaps.txt b/wadsrc/static/actors/heretic/hereticweaps.txt index 93f1f56fb..993da1485 100644 --- a/wadsrc/static/actors/heretic/hereticweaps.txt +++ b/wadsrc/static/actors/heretic/hereticweaps.txt @@ -1034,6 +1034,7 @@ ACTOR PhoenixRodPowered : PhoenixRod native { Game Heretic +WEAPON.POWERED_UP + +WEAPON.MELEEWEAPON Weapon.SisterWeapon "PhoenixRod" Weapon.AmmoGive 0 diff --git a/wadsrc/static/actors/strife/strifestuff.txt b/wadsrc/static/actors/strife/strifestuff.txt index 5d280be2b..d8ecd9bbb 100644 --- a/wadsrc/static/actors/strife/strifestuff.txt +++ b/wadsrc/static/actors/strife/strifestuff.txt @@ -177,6 +177,7 @@ ACTOR ExplosiveBarrel2 94 Height 32 ConversationID 204, -1, -1 +SOLID +SHOOTABLE +NOBLOOD +OLDRADIUSDMG + DeathSound "world/barrelx" +INCOMBAT States { diff --git a/wadsrc/static/dehsupp.txt b/wadsrc/static/dehsupp.txt index 25829b75f..51db22e91 100644 --- a/wadsrc/static/dehsupp.txt +++ b/wadsrc/static/dehsupp.txt @@ -414,7 +414,7 @@ StateMap DoomUnusedStates, TNT, 1, // [MBF] S_TNT1 967 Grenade, Grenade, 1, // [MBF] S_GRENADE 968 Grenade, Detonate, 3, // [MBF] S_DETONATE - S_DETONATE3 969-971 - Dog, Spawn, 27, // [MBF] S_DOGS_STND - S_DOGS_RAISE6 972-998 + MBFHelperDog, Spawn, 27, // [MBF] S_DOGS_STND - S_DOGS_RAISE6 972-998 BFG9000, OldFire, 43, // [MBF] S_OLDBFG1 - S_OLDBFG43 999-1041 PlasmaBall1, Spawn, 7, // [MBF] S_PLS1BALL - S_PLS1EXP5 1042-1048 PlasmaBall2, Spawn, 5, // [MBF] S_PLS2BALL - S_PLS2BALLX3 1049-1053 @@ -681,7 +681,7 @@ InfoNames PointPusher, PointPuller, // MBF additional actors: - Dog, + MBFHelperDog, PlasmaBall1, PlasmaBall2, EvilSceptre, diff --git a/wadsrc/static/shaders/d3d/build.bat b/wadsrc/static/shaders/d3d/build.bat new file mode 100644 index 000000000..ced04cd77 --- /dev/null +++ b/wadsrc/static/shaders/d3d/build.bat @@ -0,0 +1,10 @@ +cd sm14 +call build.bat + +cd ..\sm20 +call build.bat + +cd ..\sm30 +call build.bat + +cd .. diff --git a/wadsrc/static/shaders/d3d/shaders.ps b/wadsrc/static/shaders/d3d/shaders.ps new file mode 100644 index 000000000..3039c7e2a --- /dev/null +++ b/wadsrc/static/shaders/d3d/shaders.ps @@ -0,0 +1,118 @@ +sampler2D Image : register(s0); +sampler1D Palette : register(s1); + +float4 PaletteMod : register(c2); +float4 Weights : register(c6); // RGB->Gray weighting { 77/256.0, 143/256.0, 37/256.0, 1 } +float4 Gamma : register(c7); + +float4 TextureLookup(float2 tex_coord) +{ +#if PALTEX + float index = tex2D(Image, tex_coord).x; + index = index * PaletteMod.x + PaletteMod.y; + return tex1D(Palette, index); +#else + return tex2D(Image, tex_coord); +#endif +} + +float4 Invert(float4 rgb) +{ +#if INVERT + rgb.rgb = Weights.www - rgb.xyz; +#endif + return rgb; +} + +float Grayscale(float4 rgb) +{ + return dot(rgb.rgb, Weights.rgb); +} + +float4 SampleTexture(float2 tex_coord) +{ + return Invert(TextureLookup(tex_coord)); +} + +// Normal color calculation for most drawing modes. + +float4 NormalColor(float2 tex_coord : TEXCOORD0, float4 Flash : COLOR0, float4 InvFlash : COLOR1) : COLOR +{ + return Flash + SampleTexture(tex_coord) * InvFlash; +} + +// Copy the red channel to the alpha channel. Pays no attention to palettes. + +float4 RedToAlpha(float2 tex_coord : TEXCOORD0, float4 Flash : COLOR0, float4 InvFlash : COLOR1) : COLOR +{ + float4 color = Invert(tex2D(Image, tex_coord)); + color.a = color.r; + return Flash + color * InvFlash; +} + +// Just return the value of c0. + +float4 VertexColor(float4 color : COLOR0) : COLOR +{ + return color; +} + +// Emulate one of the special colormaps. (Invulnerability, gold, etc.) + +float4 SpecialColormap(float2 tex_coord : TEXCOORD0, float4 start : COLOR0, float4 end : COLOR1) : COLOR +{ + float4 color = SampleTexture(tex_coord); + float4 range = end - start; + // We can't store values greater than 1.0 in a color register, so we multiply + // the final result by 2 and expect the caller to divide the start and end by 2. + color.rgb = 2 * (start + Grayscale(color) * range); + // Duplicate alpha semantics of NormalColor. + color.a = start.a + color.a * end.a; + return color; +} + +// In-game colormap effect: fade to a particular color and multiply by another, with +// optional desaturation of the original color. Desaturation is packed into color.a. +// Fade level is packed int fade.a. Fade.rgb has been premultiplied by alpha. +float4 InGameColormap(float2 tex_coord : TEXCOORD0, float4 color : COLOR0, float4 fade : COLOR1) : COLOR +{ + float4 rgb = SampleTexture(tex_coord); + + // Desaturate +#if DESAT + float3 intensity; + float invdesat; + intensity.rgb = Grayscale(rgb) * color.a; + invdesat = Weights.w - color.a; + rgb.rgb = intensity + rgb * invdesat; +#endif + + // Fade + rgb.rgb = rgb.rgb * fade.aaa + fade.rgb; + + // Shade + rgb.rgb = rgb.rgb * color.rgb; + return rgb; +} + +// Windowed gamma correction. + +float4 GammaCorrection(float2 tex_coord : TEXCOORD0) : COLOR +{ + float4 color = tex2D(Image, tex_coord); + color.rgb = pow(color.rgb, Gamma.rgb); + return color; +} + +// The burn wipe effect. + +sampler2D NewScreen : register(s0); +sampler2D Burn : register(s1); + +float4 BurnWipe(float2 coord[2] : TEXCOORD0) : COLOR +{ + float4 color = tex2D(NewScreen, coord[0]); + float4 alpha = tex2D(Burn, coord[1]); + color.a = alpha.r * 2; + return color; +} diff --git a/wadsrc/static/shaders/d3d/sm14/BurnWipe.pso b/wadsrc/static/shaders/d3d/sm14/BurnWipe.pso new file mode 100644 index 000000000..566e518b0 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm14/BurnWipe.pso differ diff --git a/wadsrc/static/shaders/d3d/sm14/InGameColormap.pso b/wadsrc/static/shaders/d3d/sm14/InGameColormap.pso new file mode 100644 index 000000000..e1a99904b Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm14/InGameColormap.pso differ diff --git a/wadsrc/static/shaders/d3d/sm14/InGameColormapDesat.pso b/wadsrc/static/shaders/d3d/sm14/InGameColormapDesat.pso new file mode 100644 index 000000000..2bafecca0 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm14/InGameColormapDesat.pso differ diff --git a/wadsrc/static/shaders/d3d/sm14/InGameColormapInv.pso b/wadsrc/static/shaders/d3d/sm14/InGameColormapInv.pso new file mode 100644 index 000000000..0cf0808b0 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm14/InGameColormapInv.pso differ diff --git a/wadsrc/static/shaders/d3d/sm14/InGameColormapInvDesat.pso b/wadsrc/static/shaders/d3d/sm14/InGameColormapInvDesat.pso new file mode 100644 index 000000000..286c765e2 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm14/InGameColormapInvDesat.pso differ diff --git a/wadsrc/static/shaders/d3d/sm14/InGameColormapPal.pso b/wadsrc/static/shaders/d3d/sm14/InGameColormapPal.pso new file mode 100644 index 000000000..f6a6a6fba Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm14/InGameColormapPal.pso differ diff --git a/wadsrc/static/shaders/d3d/sm14/InGameColormapPalDesat.pso b/wadsrc/static/shaders/d3d/sm14/InGameColormapPalDesat.pso new file mode 100644 index 000000000..57892bae1 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm14/InGameColormapPalDesat.pso differ diff --git a/wadsrc/static/shaders/d3d/sm14/InGameColormapPalInv.pso b/wadsrc/static/shaders/d3d/sm14/InGameColormapPalInv.pso new file mode 100644 index 000000000..3964f59dc Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm14/InGameColormapPalInv.pso differ diff --git a/wadsrc/static/shaders/d3d/sm14/InGameColormapPalInvDesat.pso b/wadsrc/static/shaders/d3d/sm14/InGameColormapPalInvDesat.pso new file mode 100644 index 000000000..7a3850318 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm14/InGameColormapPalInvDesat.pso differ diff --git a/wadsrc/static/shaders/d3d/sm14/NormalColor.pso b/wadsrc/static/shaders/d3d/sm14/NormalColor.pso new file mode 100644 index 000000000..0ab04a269 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm14/NormalColor.pso differ diff --git a/wadsrc/static/shaders/d3d/sm14/NormalColorInv.pso b/wadsrc/static/shaders/d3d/sm14/NormalColorInv.pso new file mode 100644 index 000000000..bb0869f1d Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm14/NormalColorInv.pso differ diff --git a/wadsrc/static/shaders/d3d/sm14/NormalColorPal.pso b/wadsrc/static/shaders/d3d/sm14/NormalColorPal.pso new file mode 100644 index 000000000..7dc914689 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm14/NormalColorPal.pso differ diff --git a/wadsrc/static/shaders/d3d/sm14/NormalColorPalInv.pso b/wadsrc/static/shaders/d3d/sm14/NormalColorPalInv.pso new file mode 100644 index 000000000..adfd1ab82 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm14/NormalColorPalInv.pso differ diff --git a/wadsrc/static/shaders/d3d/sm14/RedToAlpha.pso b/wadsrc/static/shaders/d3d/sm14/RedToAlpha.pso new file mode 100644 index 000000000..07e43e9f2 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm14/RedToAlpha.pso differ diff --git a/wadsrc/static/shaders/d3d/sm14/RedToAlphaInv.pso b/wadsrc/static/shaders/d3d/sm14/RedToAlphaInv.pso new file mode 100644 index 000000000..5f87a11cd Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm14/RedToAlphaInv.pso differ diff --git a/wadsrc/static/shaders/d3d/sm14/SpecialColormap.pso b/wadsrc/static/shaders/d3d/sm14/SpecialColormap.pso new file mode 100644 index 000000000..8dc3111b2 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm14/SpecialColormap.pso differ diff --git a/wadsrc/static/shaders/d3d/sm14/SpecialColormapPal.pso b/wadsrc/static/shaders/d3d/sm14/SpecialColormapPal.pso new file mode 100644 index 000000000..4b5cf3f9f Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm14/SpecialColormapPal.pso differ diff --git a/wadsrc/static/shaders/d3d/sm14/VertexColor.pso b/wadsrc/static/shaders/d3d/sm14/VertexColor.pso new file mode 100644 index 000000000..7cc88be7e Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm14/VertexColor.pso differ diff --git a/wadsrc/static/shaders/d3d/sm14/build.bat b/wadsrc/static/shaders/d3d/sm14/build.bat new file mode 100644 index 000000000..1ba201285 --- /dev/null +++ b/wadsrc/static/shaders/d3d/sm14/build.bat @@ -0,0 +1,25 @@ +fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ENormalColor -DPALTEX=0 -DINVERT=0 /FoNormalColor.pso +fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ENormalColor -DPALTEX=0 -DINVERT=1 /FoNormalColorInv.pso +fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ENormalColor -DPALTEX=1 -DINVERT=0 /FoNormalColorPal.pso +fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ENormalColor -DPALTEX=1 -DINVERT=1 /FoNormalColorPalInv.pso + +fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ERedToAlpha -DINVERT=0 /FoRedToAlpha.pso +fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ERedToAlpha -DINVERT=1 /FoRedToAlphaInv.pso + +fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EVertexColor /FoVertexColor.pso + +fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ESpecialColormap -DPALTEX=0 -DINVERT=0 /FoSpecialColormap.pso +fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ESpecialColormap -DPALTEX=1 -DINVERT=0 /FoSpecialColormapPal.pso + +fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=0 -DINVERT=0 -DDESAT=0 /FoInGameColormap.pso +fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=0 -DINVERT=0 -DDESAT=1 /FoInGameColormapDesat.pso +fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=0 -DINVERT=1 -DDESAT=0 /FoInGameColormapInv.pso +fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=0 -DINVERT=1 -DDESAT=1 /FoInGameColormapInvDesat.pso +fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=1 -DINVERT=0 -DDESAT=0 /FoInGameColormapPal.pso +fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=1 -DINVERT=0 -DDESAT=1 /FoInGameColormapPalDesat.pso +fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=1 -DINVERT=1 -DDESAT=0 /FoInGameColormapPalInv.pso +fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=1 -DINVERT=1 -DDESAT=1 /FoInGameColormapPalInvDesat.pso + +fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EBurnWipe /FoBurnWipe.pso + +@rem PS1.4 does not support the pow instruction, so no windowed gamma correction for it. \ No newline at end of file diff --git a/wadsrc/static/shaders/d3d/sm20/BurnWipe.pso b/wadsrc/static/shaders/d3d/sm20/BurnWipe.pso new file mode 100644 index 000000000..dba002169 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/BurnWipe.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/GammaCorrection.pso b/wadsrc/static/shaders/d3d/sm20/GammaCorrection.pso new file mode 100644 index 000000000..10112243d Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/GammaCorrection.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/InGameColormap.pso b/wadsrc/static/shaders/d3d/sm20/InGameColormap.pso new file mode 100644 index 000000000..29a67c1ec Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/InGameColormap.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/InGameColormapDesat.pso b/wadsrc/static/shaders/d3d/sm20/InGameColormapDesat.pso new file mode 100644 index 000000000..78ba2c4ac Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/InGameColormapDesat.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/InGameColormapInv.pso b/wadsrc/static/shaders/d3d/sm20/InGameColormapInv.pso new file mode 100644 index 000000000..be962db51 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/InGameColormapInv.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/InGameColormapInvDesat.pso b/wadsrc/static/shaders/d3d/sm20/InGameColormapInvDesat.pso new file mode 100644 index 000000000..8387b5b80 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/InGameColormapInvDesat.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/InGameColormapPal.pso b/wadsrc/static/shaders/d3d/sm20/InGameColormapPal.pso new file mode 100644 index 000000000..0eed147cd Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/InGameColormapPal.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/InGameColormapPalDesat.pso b/wadsrc/static/shaders/d3d/sm20/InGameColormapPalDesat.pso new file mode 100644 index 000000000..8029e484e Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/InGameColormapPalDesat.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/InGameColormapPalInv.pso b/wadsrc/static/shaders/d3d/sm20/InGameColormapPalInv.pso new file mode 100644 index 000000000..acdd60934 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/InGameColormapPalInv.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/InGameColormapPalInvDesat.pso b/wadsrc/static/shaders/d3d/sm20/InGameColormapPalInvDesat.pso new file mode 100644 index 000000000..f9adfebdf Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/InGameColormapPalInvDesat.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/NormalColor.pso b/wadsrc/static/shaders/d3d/sm20/NormalColor.pso new file mode 100644 index 000000000..a132b7082 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/NormalColor.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/NormalColorInv.pso b/wadsrc/static/shaders/d3d/sm20/NormalColorInv.pso new file mode 100644 index 000000000..e18767e87 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/NormalColorInv.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/NormalColorPal.pso b/wadsrc/static/shaders/d3d/sm20/NormalColorPal.pso new file mode 100644 index 000000000..68a1f3fac Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/NormalColorPal.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/NormalColorPalInv.pso b/wadsrc/static/shaders/d3d/sm20/NormalColorPalInv.pso new file mode 100644 index 000000000..8276561f0 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/NormalColorPalInv.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/RedToAlpha.pso b/wadsrc/static/shaders/d3d/sm20/RedToAlpha.pso new file mode 100644 index 000000000..cd74d5586 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/RedToAlpha.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/RedToAlphaInv.pso b/wadsrc/static/shaders/d3d/sm20/RedToAlphaInv.pso new file mode 100644 index 000000000..1aeadb9fb Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/RedToAlphaInv.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/SpecialColormap.pso b/wadsrc/static/shaders/d3d/sm20/SpecialColormap.pso new file mode 100644 index 000000000..4258efed5 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/SpecialColormap.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/SpecialColormapPal.pso b/wadsrc/static/shaders/d3d/sm20/SpecialColormapPal.pso new file mode 100644 index 000000000..d8c347c63 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/SpecialColormapPal.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/VertexColor.pso b/wadsrc/static/shaders/d3d/sm20/VertexColor.pso new file mode 100644 index 000000000..7f899a57b Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm20/VertexColor.pso differ diff --git a/wadsrc/static/shaders/d3d/sm20/build.bat b/wadsrc/static/shaders/d3d/sm20/build.bat new file mode 100644 index 000000000..3d503d4f5 --- /dev/null +++ b/wadsrc/static/shaders/d3d/sm20/build.bat @@ -0,0 +1,25 @@ +fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 /FoNormalColor.pso +fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=1 /FoNormalColorInv.pso +fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 /FoNormalColorPal.pso +fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=1 /FoNormalColorPalInv.pso + +fxc ..\shaders.ps /Tps_2_0 /O3 /ERedToAlpha -DINVERT=0 /FoRedToAlpha.pso +fxc ..\shaders.ps /Tps_2_0 /O3 /ERedToAlpha -DINVERT=1 /FoRedToAlphaInv.pso + +fxc ..\shaders.ps /Tps_2_0 /O3 /EVertexColor /FoVertexColor.pso + +fxc ..\shaders.ps /Tps_2_0 /O3 /ESpecialColormap -DPALTEX=0 -DINVERT=0 /FoSpecialColormap.pso +fxc ..\shaders.ps /Tps_2_0 /O3 /ESpecialColormap -DPALTEX=1 -DINVERT=0 /FoSpecialColormapPal.pso + +fxc ..\shaders.ps /Tps_2_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=0 -DDESAT=0 /FoInGameColormap.pso +fxc ..\shaders.ps /Tps_2_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=0 -DDESAT=1 /FoInGameColormapDesat.pso +fxc ..\shaders.ps /Tps_2_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=1 -DDESAT=0 /FoInGameColormapInv.pso +fxc ..\shaders.ps /Tps_2_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=1 -DDESAT=1 /FoInGameColormapInvDesat.pso +fxc ..\shaders.ps /Tps_2_0 /O3 /EInGameColormap -DPALTEX=1 -DINVERT=0 -DDESAT=0 /FoInGameColormapPal.pso +fxc ..\shaders.ps /Tps_2_0 /O3 /EInGameColormap -DPALTEX=1 -DINVERT=0 -DDESAT=1 /FoInGameColormapPalDesat.pso +fxc ..\shaders.ps /Tps_2_0 /O3 /EInGameColormap -DPALTEX=1 -DINVERT=1 -DDESAT=0 /FoInGameColormapPalInv.pso +fxc ..\shaders.ps /Tps_2_0 /O3 /EInGameColormap -DPALTEX=1 -DINVERT=1 -DDESAT=1 /FoInGameColormapPalInvDesat.pso + +fxc ..\shaders.ps /Tps_2_0 /O3 /EBurnWipe /FoBurnWipe.pso + +fxc ..\shaders.ps /Tps_2_0 /O3 /EGammaCorrection /FoGammaCorrection.pso diff --git a/wadsrc/static/shaders/d3d/sm30/BurnWipe.pso b/wadsrc/static/shaders/d3d/sm30/BurnWipe.pso new file mode 100644 index 000000000..0626821f7 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/BurnWipe.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/GammaCorrection.pso b/wadsrc/static/shaders/d3d/sm30/GammaCorrection.pso new file mode 100644 index 000000000..f1a4dba10 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/GammaCorrection.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/InGameColormap.pso b/wadsrc/static/shaders/d3d/sm30/InGameColormap.pso new file mode 100644 index 000000000..4f0bb474c Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/InGameColormap.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/InGameColormapDesat.pso b/wadsrc/static/shaders/d3d/sm30/InGameColormapDesat.pso new file mode 100644 index 000000000..593d69f5b Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/InGameColormapDesat.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/InGameColormapInv.pso b/wadsrc/static/shaders/d3d/sm30/InGameColormapInv.pso new file mode 100644 index 000000000..35fba3f93 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/InGameColormapInv.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/InGameColormapInvDesat.pso b/wadsrc/static/shaders/d3d/sm30/InGameColormapInvDesat.pso new file mode 100644 index 000000000..2dc07bb0a Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/InGameColormapInvDesat.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/InGameColormapPal.pso b/wadsrc/static/shaders/d3d/sm30/InGameColormapPal.pso new file mode 100644 index 000000000..8facb7f12 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/InGameColormapPal.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/InGameColormapPalDesat.pso b/wadsrc/static/shaders/d3d/sm30/InGameColormapPalDesat.pso new file mode 100644 index 000000000..8a887b064 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/InGameColormapPalDesat.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/InGameColormapPalInv.pso b/wadsrc/static/shaders/d3d/sm30/InGameColormapPalInv.pso new file mode 100644 index 000000000..c405a1ccb Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/InGameColormapPalInv.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/InGameColormapPalInvDesat.pso b/wadsrc/static/shaders/d3d/sm30/InGameColormapPalInvDesat.pso new file mode 100644 index 000000000..99e874ec6 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/InGameColormapPalInvDesat.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/NormalColor.pso b/wadsrc/static/shaders/d3d/sm30/NormalColor.pso new file mode 100644 index 000000000..b0e385fb7 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/NormalColor.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/NormalColorInv.pso b/wadsrc/static/shaders/d3d/sm30/NormalColorInv.pso new file mode 100644 index 000000000..8dfc542fa Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/NormalColorInv.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/NormalColorPal.pso b/wadsrc/static/shaders/d3d/sm30/NormalColorPal.pso new file mode 100644 index 000000000..d813d6614 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/NormalColorPal.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/NormalColorPalInv.pso b/wadsrc/static/shaders/d3d/sm30/NormalColorPalInv.pso new file mode 100644 index 000000000..8ad033495 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/NormalColorPalInv.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/RedToAlpha.pso b/wadsrc/static/shaders/d3d/sm30/RedToAlpha.pso new file mode 100644 index 000000000..749ad1aba Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/RedToAlpha.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/RedToAlphaInv.pso b/wadsrc/static/shaders/d3d/sm30/RedToAlphaInv.pso new file mode 100644 index 000000000..600de5c80 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/RedToAlphaInv.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/SpecialColormap.pso b/wadsrc/static/shaders/d3d/sm30/SpecialColormap.pso new file mode 100644 index 000000000..c1f4d8f35 Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/SpecialColormap.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/SpecialColormapPal.pso b/wadsrc/static/shaders/d3d/sm30/SpecialColormapPal.pso new file mode 100644 index 000000000..4ee1be80c Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/SpecialColormapPal.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/VertexColor.pso b/wadsrc/static/shaders/d3d/sm30/VertexColor.pso new file mode 100644 index 000000000..46e56db6b Binary files /dev/null and b/wadsrc/static/shaders/d3d/sm30/VertexColor.pso differ diff --git a/wadsrc/static/shaders/d3d/sm30/build.bat b/wadsrc/static/shaders/d3d/sm30/build.bat new file mode 100644 index 000000000..fe6602b86 --- /dev/null +++ b/wadsrc/static/shaders/d3d/sm30/build.bat @@ -0,0 +1,25 @@ +fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 /FoNormalColor.pso +fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=1 /FoNormalColorInv.pso +fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 /FoNormalColorPal.pso +fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=1 /FoNormalColorPalInv.pso + +fxc ..\shaders.ps /Tps_3_0 /O3 /ERedToAlpha -DINVERT=0 /FoRedToAlpha.pso +fxc ..\shaders.ps /Tps_3_0 /O3 /ERedToAlpha -DINVERT=1 /FoRedToAlphaInv.pso + +fxc ..\shaders.ps /Tps_3_0 /O3 /EVertexColor /FoVertexColor.pso + +fxc ..\shaders.ps /Tps_3_0 /O3 /ESpecialColormap -DPALTEX=0 -DINVERT=0 /FoSpecialColormap.pso +fxc ..\shaders.ps /Tps_3_0 /O3 /ESpecialColormap -DPALTEX=1 -DINVERT=0 /FoSpecialColormapPal.pso + +fxc ..\shaders.ps /Tps_3_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=0 -DDESAT=0 /FoInGameColormap.pso +fxc ..\shaders.ps /Tps_3_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=0 -DDESAT=1 /FoInGameColormapDesat.pso +fxc ..\shaders.ps /Tps_3_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=1 -DDESAT=0 /FoInGameColormapInv.pso +fxc ..\shaders.ps /Tps_3_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=1 -DDESAT=1 /FoInGameColormapInvDesat.pso +fxc ..\shaders.ps /Tps_3_0 /O3 /EInGameColormap -DPALTEX=1 -DINVERT=0 -DDESAT=0 /FoInGameColormapPal.pso +fxc ..\shaders.ps /Tps_3_0 /O3 /EInGameColormap -DPALTEX=1 -DINVERT=0 -DDESAT=1 /FoInGameColormapPalDesat.pso +fxc ..\shaders.ps /Tps_3_0 /O3 /EInGameColormap -DPALTEX=1 -DINVERT=1 -DDESAT=0 /FoInGameColormapPalInv.pso +fxc ..\shaders.ps /Tps_3_0 /O3 /EInGameColormap -DPALTEX=1 -DINVERT=1 -DDESAT=1 /FoInGameColormapPalInvDesat.pso + +fxc ..\shaders.ps /Tps_3_0 /O3 /EBurnWipe /FoBurnWipe.pso + +fxc ..\shaders.ps /Tps_3_0 /O3 /EGammaCorrection /FoGammaCorrection.pso diff --git a/wadsrc/static/sndinfo.txt b/wadsrc/static/sndinfo.txt index 2838be889..c8840310e 100644 --- a/wadsrc/static/sndinfo.txt +++ b/wadsrc/static/sndinfo.txt @@ -50,6 +50,13 @@ misc/icebreak icebrk1a // Retail Doom and Strife use 200. $rolloff * 200 1200 +// Marine's Best Friend -- not just for marines anymore! +dog/active dsdgact +dog/attack dsdgatk +dog/death dsdgdth +dog/pain dsdgpain +dog/sight dsdgsit + /****************************************************************************/ /* */ /* DOOM SOUNDS */ @@ -425,13 +432,6 @@ brain/cube dsboscub brain/cubeboom dsfirxpl $alias brain/spawn misc/teleport -// Marine's Best Friend -dog/active dsdgact -dog/attack dsdgatk -dog/death dsdgdth -dog/pain dsdgpain -dog/sight dsdgsit - //============================================================================ // diff --git a/wadsrc/static/sprites/PLS1A0.png b/wadsrc/static/sprites/PLS1A0.png index b1617e46c..029d0bc75 100644 Binary files a/wadsrc/static/sprites/PLS1A0.png and b/wadsrc/static/sprites/PLS1A0.png differ diff --git a/wadsrc/static/sprites/PLS1B0.png b/wadsrc/static/sprites/PLS1B0.png index 40b628f13..ed08ba371 100644 Binary files a/wadsrc/static/sprites/PLS1B0.png and b/wadsrc/static/sprites/PLS1B0.png differ diff --git a/wadsrc/static/sprites/PLS1C0.png b/wadsrc/static/sprites/PLS1C0.png index b1617e46c..029d0bc75 100644 Binary files a/wadsrc/static/sprites/PLS1C0.png and b/wadsrc/static/sprites/PLS1C0.png differ diff --git a/wadsrc/static/sprites/PLS1D0.png b/wadsrc/static/sprites/PLS1D0.png index 98dfeb0dc..ed08ba371 100644 Binary files a/wadsrc/static/sprites/PLS1D0.png and b/wadsrc/static/sprites/PLS1D0.png differ diff --git a/wadsrc/static/sprites/PLS1E0.png b/wadsrc/static/sprites/PLS1E0.png index dca03ceff..ac01390c5 100644 Binary files a/wadsrc/static/sprites/PLS1E0.png and b/wadsrc/static/sprites/PLS1E0.png differ diff --git a/wadsrc/static/sprites/PLS1F0.png b/wadsrc/static/sprites/PLS1F0.png index e43de905f..ac01390c5 100644 Binary files a/wadsrc/static/sprites/PLS1F0.png and b/wadsrc/static/sprites/PLS1F0.png differ diff --git a/wadsrc/static/sprites/PLS1G0.png b/wadsrc/static/sprites/PLS1G0.png index 5a2c9db1d..df4e1f6d4 100644 Binary files a/wadsrc/static/sprites/PLS1G0.png and b/wadsrc/static/sprites/PLS1G0.png differ diff --git a/wadsrc/static/sprites/PLS2A0.png b/wadsrc/static/sprites/PLS2A0.png index bc82af045..9c196aca7 100644 Binary files a/wadsrc/static/sprites/PLS2A0.png and b/wadsrc/static/sprites/PLS2A0.png differ diff --git a/wadsrc/static/sprites/PLS2B0.png b/wadsrc/static/sprites/PLS2B0.png index 5e1875953..b0206474c 100644 Binary files a/wadsrc/static/sprites/PLS2B0.png and b/wadsrc/static/sprites/PLS2B0.png differ diff --git a/wadsrc/static/sprites/PLS2C0.png b/wadsrc/static/sprites/PLS2C0.png index 532c7efe4..1d4148d1d 100644 Binary files a/wadsrc/static/sprites/PLS2C0.png and b/wadsrc/static/sprites/PLS2C0.png differ diff --git a/wadsrc/static/sprites/PLS2D0.png b/wadsrc/static/sprites/PLS2D0.png index e1ae4c659..b5be3aaf1 100644 Binary files a/wadsrc/static/sprites/PLS2D0.png and b/wadsrc/static/sprites/PLS2D0.png differ diff --git a/wadsrc/static/sprites/PLS2E0.png b/wadsrc/static/sprites/PLS2E0.png index 099f67ea6..842d3dc3c 100644 Binary files a/wadsrc/static/sprites/PLS2E0.png and b/wadsrc/static/sprites/PLS2E0.png differ diff --git a/wadsrc/static/sprites/pista0.png b/wadsrc/static/sprites/pista0.png index d7790c683..b3d9cd09a 100644 Binary files a/wadsrc/static/sprites/pista0.png and b/wadsrc/static/sprites/pista0.png differ diff --git a/wadsrc/static/sprites/rsmka0.png b/wadsrc/static/sprites/rsmka0.png index 5e2f4de85..cee476cd1 100644 Binary files a/wadsrc/static/sprites/rsmka0.png and b/wadsrc/static/sprites/rsmka0.png differ diff --git a/wadsrc/static/sprites/rsmkb0.png b/wadsrc/static/sprites/rsmkb0.png index fab531acf..cc7046ac6 100644 Binary files a/wadsrc/static/sprites/rsmkb0.png and b/wadsrc/static/sprites/rsmkb0.png differ diff --git a/wadsrc/static/sprites/rsmkc0.png b/wadsrc/static/sprites/rsmkc0.png index 2811d6243..17b121bf9 100644 Binary files a/wadsrc/static/sprites/rsmkc0.png and b/wadsrc/static/sprites/rsmkc0.png differ diff --git a/wadsrc/static/sprites/rsmkd0.png b/wadsrc/static/sprites/rsmkd0.png index 659ddd817..20d9aa6c9 100644 Binary files a/wadsrc/static/sprites/rsmkd0.png and b/wadsrc/static/sprites/rsmkd0.png differ diff --git a/wadsrc/static/sprites/sgrna1.png b/wadsrc/static/sprites/sgrna1.png index 39e11ce56..2ef3bbdf5 100644 Binary files a/wadsrc/static/sprites/sgrna1.png and b/wadsrc/static/sprites/sgrna1.png differ diff --git a/wadsrc/static/sprites/sgrna7a3.png b/wadsrc/static/sprites/sgrna7a3.png index 5c619d442..83cc8dcfc 100644 Binary files a/wadsrc/static/sprites/sgrna7a3.png and b/wadsrc/static/sprites/sgrna7a3.png differ diff --git a/zdoom.vcproj b/zdoom.vcproj index 9ee25f594..cbe559734 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -800,10 +800,6 @@ RelativePath=".\src\p_enemy.cpp" > - - @@ -1940,10 +1936,6 @@ RelativePath=".\src\win32\fb_d3d9.cpp" > - - @@ -2036,6 +2028,10 @@ RelativePath=".\src\win32\resource.h" > + +