diff --git a/game-music-emu/gme/gme_types.h b/game-music-emu/gme/gme_types.h old mode 100644 new mode 100755 index 06226f4aa1..bd3670e64b --- a/game-music-emu/gme/gme_types.h +++ b/game-music-emu/gme/gme_types.h @@ -1,11 +1,13 @@ #ifndef GME_TYPES_H #define GME_TYPES_H -/* - * This is a default gme_types.h for use when *not* using - * CMake. If CMake is in use gme_types.h.in will be - * processed instead. +/* CMake will either define the following to 1, or #undef it, + * depending on the options passed to CMake. This is used to + * conditionally compile in the various emulator types. + * + * See gme_type_list() in gme.cpp */ + #define USE_GME_AY #define USE_GME_GBS #define USE_GME_GYM diff --git a/src/actor.h b/src/actor.h index 12bb4dc281..18c3ecb17c 100644 --- a/src/actor.h +++ b/src/actor.h @@ -33,6 +33,7 @@ // States are tied to finite states are tied to animation frames. #include "info.h" +#include #include "doomdef.h" #include "textures/textures.h" #include "r_data/renderstyle.h" @@ -1035,6 +1036,7 @@ public: struct sector_t *ceilingsector; FTextureID ceilingpic; // contacted sec ceilingpic double radius, Height; // for movement checking + double renderradius; double projectilepassheight; // height for clipping projectile movement against this actor @@ -1141,6 +1143,8 @@ public: struct msecnode_t *touching_sectorlist; // phares 3/14/98 struct msecnode_t *render_sectorlist; // same for cross-sectorportal rendering struct portnode_t *render_portallist; // and for cross-lineportal + std::forward_list* touching_render_sectors; // this is the list of sectors that this thing interesects with it's max(radius, renderradius). + int validcount; TObjPtr Inventory; // [RH] This actor's inventory diff --git a/src/p_local.h b/src/p_local.h index ef702e0188..4244005c39 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -400,6 +400,8 @@ void P_DelSeclist(msecnode_t *); // phares 3/16/98 msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode, msecnode_t *&sec_thinglist); msecnode_t* P_DelSecnode(msecnode_t *, msecnode_t *sector_t::*head); void P_CreateSecNodeList(AActor*); // phares 3/14/98 +void P_LinkRenderSectors(AActor*); +void P_UnlinkRenderSectors(AActor*); double P_GetMoveFactor(const AActor *mo, double *frictionp); // phares 3/6/98 double P_GetFriction(const AActor *mo, double *frictionfactor); diff --git a/src/p_map.cpp b/src/p_map.cpp index 81934ceb76..e1e42db606 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -6640,6 +6640,97 @@ void P_CreateSecNodeList(AActor *thing) } +//============================================================================= +// +// P_LinkRenderSectors +// +// Alters/creates the list of touched sectors for thing's render radius. +// +//============================================================================= + +void P_LinkRenderSectors(AActor* thing) +{ + FBoundingBox box(thing->X(), thing->Y(), std::max(thing->renderradius, thing->radius)); + FBlockLinesIterator it(box); + line_t *ld; + + // add to surrounding sectors + while ((ld = it.Next())) + { + if (!box.inRange(ld) || box.BoxOnLineSide(ld) != -1) + continue; + + // + // create necessary lists. + if (!thing->touching_render_sectors) thing->touching_render_sectors = new std::forward_list(); + + // + if (ld->frontsector != thing->Sector) + { + if (std::find(thing->touching_render_sectors->begin(), thing->touching_render_sectors->end(), ld->frontsector) == thing->touching_render_sectors->end()) + thing->touching_render_sectors->push_front(ld->frontsector); + if (!ld->frontsector->touching_render_things) ld->frontsector->touching_render_things = new std::forward_list(); + ld->frontsector->touching_render_things->push_front(thing); + } + + if (ld->backsector && ld->backsector != thing->Sector) + { + if (std::find(thing->touching_render_sectors->begin(), thing->touching_render_sectors->end(), ld->backsector) == thing->touching_render_sectors->end()) + thing->touching_render_sectors->push_front(ld->backsector); + if (!ld->backsector->touching_render_things) ld->backsector->touching_render_things = new std::forward_list(); + ld->backsector->touching_render_things->push_front(thing); + } + } + + // add to own sector + if (!thing->Sector->touching_render_things) thing->Sector->touching_render_things = new std::forward_list(); + thing->Sector->touching_render_things->push_front(thing); +} + + +//============================================================================= +// +// P_UnlinkRenderSectors +// +// Reverses P_LinkRenderSectors. +// +//============================================================================= + +void P_UnlinkRenderSectors(AActor* thing) +{ + if (thing->touching_render_sectors) + { + for (std::forward_list::iterator it = thing->touching_render_sectors->begin(); + it != thing->touching_render_sectors->end(); it++) + { + sector_t* sec = (*it); + if (sec->touching_render_things) + { + sec->touching_render_things->remove(thing); + if (sec->touching_render_things->empty()) + { + delete sec->touching_render_things; + sec->touching_render_things = NULL; + } + } + } + + delete thing->touching_render_sectors; + thing->touching_render_sectors = NULL; + } + + if (thing->Sector->touching_render_things) + { + thing->Sector->touching_render_things->remove(thing); + if (thing->Sector->touching_render_things->empty()) + { + delete thing->Sector->touching_render_things; + thing->Sector->touching_render_things = NULL; + } + } +} + + //============================================================================= // // P_DelPortalnode diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index d676e966cc..57c86587d0 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -277,6 +277,8 @@ void AActor::UnlinkFromWorld () sector_list = touching_sectorlist; touching_sectorlist = NULL; //to be restored by P_SetThingPosition + + P_UnlinkRenderSectors(this); } } @@ -456,6 +458,8 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector) P_CreateSecNodeList(this); touching_sectorlist = sector_list; // Attach to thing sector_list = NULL; // clear for next time + + P_LinkRenderSectors(this); } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 72ddd9395b..6f54b59ff2 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -204,6 +204,7 @@ DEFINE_FIELD(AActor, ceilingsector) DEFINE_FIELD(AActor, ceilingpic) DEFINE_FIELD(AActor, Height) DEFINE_FIELD(AActor, radius) +DEFINE_FIELD(AActor, renderradius) DEFINE_FIELD(AActor, projectilepassheight) DEFINE_FIELD(AActor, tics) DEFINE_FIELD_NAMED(AActor, state, curstate) // clashes with type 'state'. @@ -510,6 +511,8 @@ void AActor::Serialize(FSerializer &arc) void AActor::PostSerialize() { touching_sectorlist = NULL; + if (touching_render_sectors) delete touching_render_sectors; + touching_render_sectors = NULL; LinkToWorld(false, Sector); AddToHash(); @@ -4544,6 +4547,7 @@ AActor *AActor::StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t a actor->frame = st->GetFrame(); actor->renderflags = (actor->renderflags & ~RF_FULLBRIGHT) | ActorRenderFlags::FromInt (st->GetFullbright()); actor->touching_sectorlist = NULL; // NULL head of sector list // phares 3/13/98 + actor->touching_render_sectors = NULL; if (G_SkillProperty(SKILLP_FastMonsters) && actor->GetClass()->FastSpeed >= 0) actor->Speed = actor->GetClass()->FastSpeed; diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 11aef9d8db..7c663508b1 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1512,6 +1512,7 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex) ss->thinglist = NULL; ss->touching_thinglist = NULL; // phares 3/14/98 ss->render_thinglist = NULL; + ss->touching_render_things = NULL; ss->seqType = defSeqType; ss->SeqName = NAME_None; ss->nextsec = -1; //jff 2/26/98 add fields to support locking out diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index c1a64f84b7..2e335f4f07 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1297,6 +1297,7 @@ public: sec->thinglist = NULL; sec->touching_thinglist = NULL; // phares 3/14/98 sec->render_thinglist = NULL; + sec->touching_render_things = NULL; sec->seqType = (level.flags & LEVEL_SNDSEQTOTALCTRL) ? 0 : -1; sec->nextsec = -1; //jff 2/26/98 add fields to support locking out sec->prevsec = -1; // stair retriggering until build completes diff --git a/src/r_defs.h b/src/r_defs.h index 6f3b925c77..c63e5b46c3 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -23,6 +23,7 @@ #ifndef __R_DEFS_H__ #define __R_DEFS_H__ +#include #include "doomdef.h" #include "templates.h" #include "memarena.h" @@ -1001,6 +1002,7 @@ public: // thinglist is a subset of touching_thinglist struct msecnode_t *touching_thinglist; // phares 3/14/98 struct msecnode_t *render_thinglist; // for cross-portal rendering. + std::forward_list* touching_render_things; // this is used to allow wide things to be rendered not only from their main sector. double gravity; // [RH] Sector gravity (1.0 is normal) FNameNoInit damagetype; // [RH] Means-of-death for applied damage diff --git a/src/r_things.cpp b/src/r_things.cpp index a1ace0d49c..77f45188cf 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -1225,7 +1225,7 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside) // A sector might have been split into several // subsectors during BSP building. // Thus we check whether it was already added. - if (sec->thinglist == NULL || sec->validcount == validcount) + if (sec->touching_render_things == NULL || sec->validcount == validcount) return; // Well, now it will be done. @@ -1234,8 +1234,13 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside) spriteshade = LIGHT2SHADE(lightlevel + r_actualextralight); // Handle all things in sector. - for (thing = sec->thinglist; thing; thing = thing->snext) + for (std::forward_list::iterator it = sec->touching_render_things->begin(); + it != sec->touching_render_things->end(); it++) { + thing = (*it); + if (thing->validcount == validcount) continue; + thing->validcount = validcount; + FIntCVar *cvar = thing->GetClass()->distancecheck; if (cvar != NULL && *cvar >= 0) { diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index e318a98062..08dd62dfb8 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -713,6 +713,15 @@ DEFINE_PROPERTY(radius, F, Actor) defaults->radius = id; } +//========================================================================== +// +//========================================================================== +DEFINE_PROPERTY(renderradius, F, Actor) +{ + PROP_DOUBLE_PARM(id, 0); + defaults->renderradius = id; +} + //========================================================================== // //========================================================================== diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 4324f162aa..2ced709aee 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -45,6 +45,7 @@ class Actor : Thinker native native TextureID ceilingpic; native double Height; native readonly double Radius; + native readonly double RenderRadius; native double projectilepassheight; native int tics; native readonly State CurState; @@ -201,6 +202,7 @@ class Actor : Thinker native Health DEFAULT_HEALTH; Reactiontime 8; Radius 20; + RenderRadius 0; Height 16; Mass 100; RenderStyle 'Normal';