diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 056897f409..9df7f2d0a7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1150,6 +1150,7 @@ set (PCH_SOURCES r_data/models/models_ue1.cpp r_data/models/models_obj.cpp scripting/symbols.cpp + scripting/vmthunks.cpp scripting/types.cpp scripting/thingdef.cpp scripting/thingdef_data.cpp diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 506e49ff2e..de6e37815c 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -749,7 +749,7 @@ static void (*MBFCodePointerFactories[])(FunctionCallEmitter&, int, int) = void SetDehParams(FState *state, int codepointer) { - static uint8_t regts[] = { REGT_POINTER, REGT_POINTER, REGT_POINTER }; + static const uint8_t regts[] = { REGT_POINTER, REGT_POINTER, REGT_POINTER }; int value1 = state->GetMisc1(); int value2 = state->GetMisc2(); if (!(value1|value2)) return; diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 990382016f..d96695cee2 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -266,8 +266,6 @@ void PClass::StaticShutdown () // This flags DObject::Destroy not to call any scripted OnDestroy methods anymore. bVMOperational = false; - // PendingWeapon must be cleared manually because it is not subjected to the GC if it contains WP_NOCHANGE, which is just RUNTIME_CLASS(AWWeapon). - // But that will get cleared here, confusing the GC if the value is left in. for (auto &p : players) { p.PendingWeapon = nullptr; diff --git a/src/doomerrors.h b/src/doomerrors.h index a7ec026540..52bc3c12bb 100644 --- a/src/doomerrors.h +++ b/src/doomerrors.h @@ -38,6 +38,7 @@ #include #include #include +#include #define MAX_ERRORTEXT 1024 @@ -70,7 +71,7 @@ public: else return NULL; } - char const *what() const override + char const *what() const noexcept override { return m_Message; } @@ -80,10 +81,10 @@ protected: char m_Message[MAX_ERRORTEXT]; }; -class CNoRunExit : public std::exception +class CNoRunExit : public std::runtime_error { public: - CNoRunExit() : std::exception("NoRunExit") + CNoRunExit() : std::runtime_error("NoRunExit") { } }; diff --git a/src/edata.cpp b/src/edata.cpp index ee60356a75..41aa61a2f8 100644 --- a/src/edata.cpp +++ b/src/edata.cpp @@ -735,7 +735,7 @@ void ProcessEDSector(sector_t *sec, int recordnum) sec->terrainnum[sector_t::floor] = esec->floorterrain; sec->terrainnum[sector_t::ceiling] = esec->ceilingterrain; - if (esec->colorSet) sec->SetColor(RPART(esec->color), GPART(esec->color), BPART(esec->color), 0); + if (esec->colorSet) sec->SetColor(esec->color, 0); const uint32_t pflagmask = PLANEF_DISABLED | PLANEF_NORENDER | PLANEF_NOPASS | PLANEF_BLOCKSOUND | PLANEF_ADDITIVE; for (int i = 0; i < 2; i++) diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index b26f54d0ec..b8799505e3 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -3833,7 +3833,7 @@ void FParser::SF_SetColor(void) { if (!DFraggleThinker::ActiveThinker->setcolormaterial) { - level.sectors[i].SetColor(color.r, color.g, color.b, 0); + level.sectors[i].SetColor(color, 0); } else { diff --git a/src/gi.cpp b/src/gi.cpp index 45deb93ea0..8587aa1434 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -61,10 +61,10 @@ DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, statusscreen_single) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, statusscreen_coop) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, statusscreen_dm) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, mSliderColor) +DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, defaultbloodcolor) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, telefogheight) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, defKickback) - const char *GameNames[17] = { NULL, "Doom", "Heretic", NULL, "Hexen", NULL, NULL, NULL, "Strife", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Chex" diff --git a/src/hwrenderer/models/hw_models.cpp b/src/hwrenderer/models/hw_models.cpp index d4241c0263..95ee844118 100644 --- a/src/hwrenderer/models/hw_models.cpp +++ b/src/hwrenderer/models/hw_models.cpp @@ -147,7 +147,7 @@ FModelVertexBuffer::FModelVertexBuffer(bool needindex, bool singleframe) { 1, VATTR_VERTEX2, VFmt_Float3, (int)myoffsetof(FModelVertex, x) }, { 1, VATTR_NORMAL2, VFmt_Packed_A2R10G10B10, (int)myoffsetof(FModelVertex, packedNormal) } }; - mVertexBuffer->SetFormat(2, 4, sizeof(FModelVertex), format); + mVertexBuffer->SetFormat(2, 5, sizeof(FModelVertex), format); } //=========================================================================== diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index e8dc860e94..91f94643ea 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -957,33 +957,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_CopyFriendliness) // //========================================================================== -DEFINE_ACTION_FUNCTION(AActor, A_PlaySound) -{ - PARAM_SELF_PROLOGUE(AActor); - PARAM_SOUND (soundid); - PARAM_INT (channel); - PARAM_FLOAT (volume); - PARAM_BOOL (looping); - PARAM_FLOAT (attenuation); - PARAM_BOOL (local); - - if (!looping) - { - if (!(channel & CHAN_NOSTOP) || !S_IsActorPlayingSomething(self, channel & 7, soundid)) - { - S_PlaySound(self, channel, soundid, (float)volume, (float)attenuation, local); - } - } - else - { - if (!S_IsActorPlayingSomething (self, channel&7, soundid)) - { - S_PlaySound(self, channel | CHAN_LOOP, soundid, (float)volume, (float)attenuation, local); - } - } - return 0; -} - DEFINE_ACTION_FUNCTION(AActor, A_StopSound) { PARAM_SELF_PROLOGUE(AActor); diff --git a/src/p_ceiling.cpp b/src/p_ceiling.cpp index 02448f07ce..c7f9753024 100644 --- a/src/p_ceiling.cpp +++ b/src/p_ceiling.cpp @@ -368,13 +368,13 @@ bool P_CreateCeiling(sector_t *sec, DCeiling::ECeiling type, line_t *line, int t break; case DCeiling::ceilLowerByTexture: - targheight = sec->ceilingplane.ZatPoint (spot) - sec->FindShortestUpperAround (); + targheight = sec->ceilingplane.ZatPoint (spot) - FindShortestUpperAround (sec); ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight); ceiling->m_Direction = -1; break; case DCeiling::ceilRaiseByTexture: - targheight = sec->ceilingplane.ZatPoint (spot) + sec->FindShortestUpperAround (); + targheight = sec->ceilingplane.ZatPoint (spot) + FindShortestUpperAround (sec); ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight); ceiling->m_Direction = 1; break; @@ -420,8 +420,8 @@ bool P_CreateCeiling(sector_t *sec, DCeiling::ECeiling type, line_t *line, int t type == DCeiling::ceilRaiseToFloor || /*type == ceilLowerToHighest ||*/ type == DCeiling::ceilLowerToFloor) ? - sec->FindModelFloorSector (targheight) : - sec->FindModelCeilingSector (targheight); + FindModelFloorSector(sec, targheight) : + FindModelCeilingSector(sec, targheight); if (modelsec != NULL) { ceiling->m_Texture = modelsec->GetTexture(sector_t::ceiling); diff --git a/src/p_floor.cpp b/src/p_floor.cpp index f9d72c57ac..305d750197 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -392,7 +392,7 @@ bool P_CreateFloor(sector_t *sec, DFloor::EFloor floortype, line_t *line, case DFloor::floorLowerByTexture: floor->m_Direction = -1; - newheight = sec->CenterFloor() - sec->FindShortestTextureAround(); + newheight = sec->CenterFloor() - FindShortestTextureAround(sec); floor->m_FloorDestDist = sec->floorplane.PointToDist(sec->centerspot, newheight); break; @@ -409,7 +409,7 @@ bool P_CreateFloor(sector_t *sec, DFloor::EFloor floortype, line_t *line, // since the code is identical to what was here. (Oddly // enough, BOOM preserved the code here even though it // also had this function.) - newheight = sec->CenterFloor() + sec->FindShortestTextureAround(); + newheight = sec->CenterFloor() + FindShortestTextureAround(sec); floor->m_FloorDestDist = sec->floorplane.PointToDist(sec->centerspot, newheight); break; @@ -440,7 +440,7 @@ bool P_CreateFloor(sector_t *sec, DFloor::EFloor floortype, line_t *line, //jff 5/23/98 use model subroutine to unify fixes and handling sector_t *modelsec; - modelsec = sec->FindModelFloorSector(newheight); + modelsec = FindModelFloorSector(sec, newheight); if (modelsec != NULL) { floor->m_Texture = modelsec->GetTexture(sector_t::floor); @@ -485,8 +485,8 @@ bool P_CreateFloor(sector_t *sec, DFloor::EFloor floortype, line_t *line, floortype == DFloor::floorLowerToLowestCeiling || floortype == DFloor::floorRaiseToCeiling || floortype == DFloor::floorLowerToCeiling) ? - sec->FindModelCeilingSector(-floor->m_FloorDestDist) : - sec->FindModelFloorSector(-floor->m_FloorDestDist); + FindModelCeilingSector(sec, -floor->m_FloorDestDist) : + FindModelFloorSector(sec, -floor->m_FloorDestDist); if (modelsec != NULL) { @@ -1126,7 +1126,7 @@ bool EV_DoChange (line_t *line, EChange changetype, int tag) } break; case numChangeOnly: - secm = sec->FindModelFloorSector (sec->CenterFloor()); + secm = FindModelFloorSector(sec, sec->CenterFloor()); if (secm) { // if no model, no change sec->SetTexture(sector_t::floor, secm->GetTexture(sector_t::floor)); diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 85d40081a2..64184ea3a9 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2434,7 +2434,7 @@ FUNC(LS_Sector_SetColor) int secnum; while ((secnum = itr.Next()) >= 0) { - level.sectors[secnum].SetColor(arg1, arg2, arg3, arg4); + level.sectors[secnum].SetColor(PalEntry(255, arg1, arg2, arg3), arg4); } return true; @@ -2447,7 +2447,7 @@ FUNC(LS_Sector_SetFade) int secnum; while ((secnum = itr.Next()) >= 0) { - level.sectors[secnum].SetFade(arg1, arg2, arg3); + level.sectors[secnum].SetFade(PalEntry(255, arg1, arg2, arg3)); } return true; } diff --git a/src/p_map.cpp b/src/p_map.cpp index eeee54bc6d..7f0fb7db8e 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -4508,7 +4508,7 @@ DEFINE_ACTION_FUNCTION(AActor, AimLineAttack) PARAM_SELF_PROLOGUE(AActor); PARAM_ANGLE(angle); PARAM_FLOAT(distance); - PARAM_POINTER(pLineTarget, FTranslatedLineTarget); + PARAM_OUTPOINTER(pLineTarget, FTranslatedLineTarget); PARAM_ANGLE(vrange); PARAM_INT(flags); PARAM_OBJECT(target, AActor); @@ -4920,7 +4920,7 @@ DEFINE_ACTION_FUNCTION(AActor, LineAttack) PARAM_NAME(damageType); PARAM_CLASS(puffType, AActor); PARAM_INT(flags); - PARAM_POINTER(victim, FTranslatedLineTarget); + PARAM_OUTPOINTER(victim, FTranslatedLineTarget); PARAM_FLOAT(offsetz); PARAM_FLOAT(offsetforward); PARAM_FLOAT(offsetside); @@ -5086,7 +5086,7 @@ DEFINE_ACTION_FUNCTION(AActor, LineTrace) PARAM_FLOAT(offsetz); PARAM_FLOAT(offsetforward); PARAM_FLOAT(offsetside); - PARAM_POINTER(data, FLineTraceData); + PARAM_OUTPOINTER(data, FLineTraceData); ACTION_RETURN_BOOL(P_LineTrace(self,angle,distance,pitch,flags,offsetz,offsetforward,offsetside,data)); } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 4d5e345233..c2d247d38d 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -7375,7 +7375,7 @@ DEFINE_ACTION_FUNCTION(AActor, SpawnPlayerMissile) PARAM_FLOAT(x); PARAM_FLOAT(y); PARAM_FLOAT(z); - PARAM_POINTER(lt, FTranslatedLineTarget); + PARAM_OUTPOINTER(lt, FTranslatedLineTarget); PARAM_BOOL(nofreeaim); PARAM_BOOL(noautoaim); PARAM_INT(aimflags); diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 1ed2c78d63..6eeea54422 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -571,11 +571,11 @@ static inline void CheckShortestTex (FTextureID texnum, double &minsize) } } -double sector_t::FindShortestTextureAround () const +double FindShortestTextureAround (sector_t *sec) { double minsize = FLT_MAX; - for (auto check : Lines) + for (auto check : sec->Lines) { if (check->flags & ML_TWOSIDED) { @@ -586,14 +586,6 @@ double sector_t::FindShortestTextureAround () const return minsize < FLT_MAX ? minsize : TexMan[0]->GetHeight(); } -DEFINE_ACTION_FUNCTION(_Sector, FindShortestTextureAround) -{ - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - double h = self->FindShortestTextureAround(); - ACTION_RETURN_FLOAT(h); -} - - // // P_FindShortestUpperAround() // @@ -604,11 +596,11 @@ DEFINE_ACTION_FUNCTION(_Sector, FindShortestTextureAround) // // jff 03/20/98 Add routine to find shortest upper texture // -double sector_t::FindShortestUpperAround () const +double FindShortestUpperAround (sector_t *sec) { double minsize = FLT_MAX; - for (auto check : Lines) + for (auto check : sec->Lines) { if (check->flags & ML_TWOSIDED) { @@ -619,13 +611,6 @@ double sector_t::FindShortestUpperAround () const return minsize < FLT_MAX ? minsize : TexMan[0]->GetHeight(); } -DEFINE_ACTION_FUNCTION(_Sector, FindShortestUpperAround) -{ - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - double h = self->FindShortestUpperAround(); - ACTION_RETURN_FLOAT(h); -} - // // P_FindModelFloorSector() // @@ -640,13 +625,13 @@ DEFINE_ACTION_FUNCTION(_Sector, FindShortestUpperAround) // jff 3/14/98 change first parameter to plain height to allow call // from routine not using floormove_t // -sector_t *sector_t::FindModelFloorSector (double floordestheight) const +sector_t *FindModelFloorSector (sector_t *sect, double floordestheight) { sector_t *sec; - for (auto check : Lines) + for (auto check : sect->Lines) { - sec = getNextSector (check, this); + sec = getNextSector (check, sect); if (sec != NULL && (sec->floorplane.ZatPoint(check->v1) == floordestheight || sec->floorplane.ZatPoint(check->v2) == floordestheight)) @@ -657,15 +642,6 @@ sector_t *sector_t::FindModelFloorSector (double floordestheight) const return NULL; } -DEFINE_ACTION_FUNCTION(_Sector, FindModelFloorSector) -{ - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_FLOAT(fdh); - auto h = self->FindModelFloorSector(fdh); - ACTION_RETURN_POINTER(h); -} - - // // P_FindModelCeilingSector() // @@ -681,13 +657,13 @@ DEFINE_ACTION_FUNCTION(_Sector, FindModelFloorSector) // jff 3/14/98 change first parameter to plain height to allow call // from routine not using ceiling_t // -sector_t *sector_t::FindModelCeilingSector (double floordestheight) const +sector_t *FindModelCeilingSector (sector_t *sect, double floordestheight) { sector_t *sec; - for (auto check : Lines) + for (auto check : sect->Lines) { - sec = getNextSector (check, this); + sec = getNextSector (check, sect); if (sec != NULL && (sec->ceilingplane.ZatPoint(check->v1) == floordestheight || sec->ceilingplane.ZatPoint(check->v2) == floordestheight)) @@ -698,14 +674,6 @@ sector_t *sector_t::FindModelCeilingSector (double floordestheight) const return NULL; } -DEFINE_ACTION_FUNCTION(_Sector, FindModelCeilingSector) -{ - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_FLOAT(fdh); - auto h = self->FindModelCeilingSector(fdh); - ACTION_RETURN_POINTER(h); -} - // // Find minimum light from an adjacent sector // @@ -832,25 +800,27 @@ DEFINE_ACTION_FUNCTION(_Sector, FindLowestCeilingPoint) //===================================================================================== // +// 'color' is intentionally an int here // //===================================================================================== -void sector_t::SetColor(int r, int g, int b, int desat) +void SetColor(sector_t *sector, int color, int desat) { - Colormap.LightColor = PalEntry(r, g, b); - Colormap.Desaturation = desat; - P_RecalculateAttachedLights(this); + sector->Colormap.LightColor = color; + sector->Colormap.Desaturation = desat; + P_RecalculateAttachedLights(sector); } -DEFINE_ACTION_FUNCTION(_Sector, SetColor) +//===================================================================================== +// +// 'color' is intentionally an int here +// +//===================================================================================== + +void SetFade(sector_t *sector, int color) { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_COLOR(color); - PARAM_INT(desat); - self->Colormap.LightColor.SetRGB(color); - self->Colormap.Desaturation = desat; - P_RecalculateAttachedLights(self); - return 0; + sector->Colormap.FadeColor = color; + P_RecalculateAttachedLights(sector); } //===================================================================================== @@ -858,39 +828,6 @@ DEFINE_ACTION_FUNCTION(_Sector, SetColor) // //===================================================================================== -void sector_t::SetFade(int r, int g, int b) -{ - Colormap.FadeColor = PalEntry (r,g,b); - P_RecalculateAttachedLights(this); -} - -DEFINE_ACTION_FUNCTION(_Sector, SetFade) -{ - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_COLOR(fade); - self->Colormap.FadeColor.SetRGB(fade); - P_RecalculateAttachedLights(self); - return 0; -} - -//===================================================================================== -// -// -//===================================================================================== - -DEFINE_ACTION_FUNCTION(_Sector, SetSpecialColor) -{ - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(num); - PARAM_COLOR(color); - if (num >= 0 && num < 5) - { - color.a = 255; - self->SetSpecialColor(num, color); - } - return 0; -} - //===================================================================================== // // @@ -901,14 +838,6 @@ void sector_t::SetFogDensity(int dens) Colormap.FogDensity = dens; } -DEFINE_ACTION_FUNCTION(_Sector, SetFogDensity) -{ - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(dens); - self->Colormap.FogDensity = dens; - return 0; -} - //=========================================================================== // // sector_t :: ClosestPoint @@ -977,19 +906,12 @@ void sector_t::ClosestPoint(const DVector2 &in, DVector2 &out) const // //===================================================================================== -bool sector_t::PlaneMoving(int pos) +bool PlaneMoving(sector_t *sector, int pos) { - if (pos == floor) - return (floordata != NULL || (planes[floor].Flags & PLANEF_BLOCKED)); + if (pos == sector_t::floor) + return (sector->floordata != nullptr || (sector->planes[sector_t::floor].Flags & PLANEF_BLOCKED)); else - return (ceilingdata != NULL || (planes[ceiling].Flags & PLANEF_BLOCKED)); -} - -DEFINE_ACTION_FUNCTION(_Sector, PlaneMoving) -{ - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_BOOL(self->PlaneMoving(pos)); + return (sector->ceilingdata != nullptr || (sector->planes[sector_t::ceiling].Flags & PLANEF_BLOCKED)); } //===================================================================================== @@ -997,47 +919,35 @@ DEFINE_ACTION_FUNCTION(_Sector, PlaneMoving) // //===================================================================================== -int sector_t::GetFloorLight () const +int GetFloorLight(const sector_t *sector) { - if (GetFlags(sector_t::floor) & PLANEF_ABSLIGHTING) + if (sector->GetFlags(sector_t::floor) & PLANEF_ABSLIGHTING) { - return GetPlaneLight(floor); + return sector->GetPlaneLight(sector_t::floor); } else { - return ClampLight(lightlevel + GetPlaneLight(floor)); + return sector->ClampLight(sector->lightlevel + sector->GetPlaneLight(sector_t::floor)); } } -DEFINE_ACTION_FUNCTION(_Sector, GetFloorLight) -{ - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - ACTION_RETURN_INT(self->GetFloorLight()); -} - //===================================================================================== // // //===================================================================================== -int sector_t::GetCeilingLight () const +int GetCeilingLight(const sector_t *sector) { - if (GetFlags(ceiling) & PLANEF_ABSLIGHTING) + if (sector->GetFlags(sector_t::ceiling) & PLANEF_ABSLIGHTING) { - return GetPlaneLight(ceiling); + return sector->GetPlaneLight(sector_t::ceiling); } else { - return ClampLight(lightlevel + GetPlaneLight(ceiling)); + return sector->ClampLight(sector->lightlevel + sector->GetPlaneLight(sector_t::ceiling)); } } -DEFINE_ACTION_FUNCTION(_Sector, GetCeilingLight) -{ - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - ACTION_RETURN_INT(self->GetCeilingLight()); -} - //===================================================================================== // // @@ -1057,10 +967,14 @@ FSectorPortal *sector_t::ValidatePortal(int which) // //===================================================================================== -DEFINE_ACTION_FUNCTION(_Sector, GetHeightSec) +void GetSpecial(sector_t *sector, secspecial_t *spec) { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - ACTION_RETURN_POINTER(self->GetHeightSec()); + spec->special = sector->special; + spec->damageamount = sector->damageamount; + spec->damagetype = sector->damagetype; + spec->damageinterval = sector->damageinterval; + spec->leakydamage = sector->leakydamage; + spec->Flags = sector->Flags & SECF_SPECIALFLAGS; } //===================================================================================== @@ -1068,22 +982,14 @@ DEFINE_ACTION_FUNCTION(_Sector, GetHeightSec) // //===================================================================================== -void sector_t::GetSpecial(secspecial_t *spec) +void SetSpecial(sector_t *sector, const secspecial_t *spec) { - spec->special = special; - spec->damageamount = damageamount; - spec->damagetype = damagetype; - spec->damageinterval = damageinterval; - spec->leakydamage = leakydamage; - spec->Flags = Flags & SECF_SPECIALFLAGS; -} - -DEFINE_ACTION_FUNCTION(_Sector, GetSpecial) -{ - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_POINTER(spec, secspecial_t); - self->GetSpecial(spec); - return 0; + sector->special = spec->special; + sector->damageamount = spec->damageamount; + sector->damagetype = spec->damagetype; + sector->damageinterval = spec->damageinterval; + sector->leakydamage = spec->leakydamage; + sector->Flags = (sector->Flags & ~SECF_SPECIALFLAGS) | (spec->Flags & SECF_SPECIALFLAGS); } //===================================================================================== @@ -1091,46 +997,14 @@ DEFINE_ACTION_FUNCTION(_Sector, GetSpecial) // //===================================================================================== -void sector_t::SetSpecial(const secspecial_t *spec) +void TransferSpecial(sector_t *sector, sector_t *model) { - special = spec->special; - damageamount = spec->damageamount; - damagetype = spec->damagetype; - damageinterval = spec->damageinterval; - leakydamage = spec->leakydamage; - Flags = (Flags & ~SECF_SPECIALFLAGS) | (spec->Flags & SECF_SPECIALFLAGS); -} - -DEFINE_ACTION_FUNCTION(_Sector, SetSpecial) -{ - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_POINTER(spec, secspecial_t); - self->SetSpecial(spec); - return 0; -} - - -//===================================================================================== -// -// -//===================================================================================== - -void sector_t::TransferSpecial(sector_t *model) -{ - special = model->special; - damageamount = model->damageamount; - damagetype = model->damagetype; - damageinterval = model->damageinterval; - leakydamage = model->leakydamage; - Flags = (Flags&~SECF_SPECIALFLAGS) | (model->Flags & SECF_SPECIALFLAGS); -} - -DEFINE_ACTION_FUNCTION(_Sector, TransferSpecial) -{ - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_POINTER(spec, sector_t); - self->TransferSpecial(spec); - return 0; + sector->special = model->special; + sector->damageamount = model->damageamount; + sector->damagetype = model->damagetype; + sector->damageinterval = model->damageinterval; + sector->leakydamage = model->leakydamage; + sector->Flags = (sector->Flags&~SECF_SPECIALFLAGS) | (model->Flags & SECF_SPECIALFLAGS); } //===================================================================================== @@ -1138,42 +1012,27 @@ DEFINE_ACTION_FUNCTION(_Sector, TransferSpecial) // //===================================================================================== -int sector_t::GetTerrain(int pos) const +int GetTerrain(const sector_t *sector, int pos) { - return terrainnum[pos] >= 0 ? terrainnum[pos] : TerrainTypes[GetTexture(pos)]; + return sector->terrainnum[pos] >= 0 ? sector->terrainnum[pos] : TerrainTypes[sector->GetTexture(pos)]; } -DEFINE_ACTION_FUNCTION(_Sector, GetTerrain) -{ - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_INT(self->GetTerrain(pos)); -} - -//===================================================================================== + //===================================================================================== // // //===================================================================================== -void sector_t::CheckPortalPlane(int plane) +void CheckPortalPlane(sector_t *sector, int plane) { - if (GetPortalType(plane) == PORTS_LINKEDPORTAL) + if (sector->GetPortalType(plane) == PORTS_LINKEDPORTAL) { - double portalh = GetPortalPlaneZ(plane); - double planeh = GetPlaneTexZ(plane); + double portalh = sector->GetPortalPlaneZ(plane); + double planeh = sector->GetPlaneTexZ(plane); int obstructed = PLANEF_OBSTRUCTED * (plane == sector_t::floor ? planeh > portalh : planeh < portalh); - planes[plane].Flags = (planes[plane].Flags & ~PLANEF_OBSTRUCTED) | obstructed; + sector->planes[plane].Flags = (sector->planes[plane].Flags & ~PLANEF_OBSTRUCTED) | obstructed; } } -DEFINE_ACTION_FUNCTION(_Sector, CheckPortalPlane) -{ - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(plane); - self->CheckPortalPlane(plane); - return 0; -} - //=========================================================================== // // Finds the highest ceiling at the given position, all portals considered @@ -1443,9 +1302,9 @@ DEFINE_ACTION_FUNCTION(_Sector, NextLowestFloorAt) // //=========================================================================== - void sector_t::RemoveForceField() + void RemoveForceField(sector_t *sector) { - for (auto line : Lines) + for (auto line : sector->Lines) { if (line->backsector != NULL && line->special == ForceField) { @@ -1457,24 +1316,17 @@ DEFINE_ACTION_FUNCTION(_Sector, NextLowestFloorAt) } } - DEFINE_ACTION_FUNCTION(_Sector, RemoveForceField) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - self->RemoveForceField(); - return 0; - } - //=========================================================================== // // phares 3/12/98: End of friction effects // //=========================================================================== - void sector_t::AdjustFloorClip() const + void AdjustFloorClip(const sector_t *sector) { msecnode_t *node; - for (node = touching_thinglist; node; node = node->m_snext) + for (node = sector->touching_thinglist; node; node = node->m_snext) { if (node->m_thing->flags2 & MF2_FLOORCLIP) { @@ -1483,14 +1335,6 @@ DEFINE_ACTION_FUNCTION(_Sector, NextLowestFloorAt) } } - DEFINE_ACTION_FUNCTION(_Sector, AdjustFloorClip) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - self->AdjustFloorClip(); - return 0; - } - - //========================================================================== // // Checks whether a sprite should be affected by a glow @@ -1662,594 +1506,6 @@ DEFINE_ACTION_FUNCTION(_Sector, NextLowestFloorAt) } } - //=========================================================================== - // - // - // - //=========================================================================== - - DEFINE_ACTION_FUNCTION(_Sector, PointInSector) - { - PARAM_PROLOGUE; - PARAM_FLOAT(x); - PARAM_FLOAT(y); - ACTION_RETURN_POINTER(P_PointInSector(x, y)); - } - - DEFINE_ACTION_FUNCTION(_Sector, SetXOffset) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - PARAM_FLOAT(o); - self->SetXOffset(pos, o); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Sector, AddXOffset) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - PARAM_FLOAT(o); - self->AddXOffset(pos, o); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Sector, GetXOffset) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_FLOAT(self->GetXOffset(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, SetYOffset) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - PARAM_FLOAT(o); - self->SetXOffset(pos, o); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Sector, AddYOffset) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - PARAM_FLOAT(o); - self->AddXOffset(pos, o); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Sector, GetYOffset) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - PARAM_BOOL(addbase); - ACTION_RETURN_FLOAT(self->GetYOffset(pos, addbase)); - } - - DEFINE_ACTION_FUNCTION(_Sector, SetXScale) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - PARAM_FLOAT(o); - self->SetXScale(pos, o); - return 0; - } - - - DEFINE_ACTION_FUNCTION(_Sector, GetXScale) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_FLOAT(self->GetXScale(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, SetYScale) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - PARAM_FLOAT(o); - self->SetYScale(pos, o); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Sector, GetYScale) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_FLOAT(self->GetYScale(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, SetAngle) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - PARAM_ANGLE(o); - self->SetAngle(pos, o); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Sector, GetAngle) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - PARAM_BOOL(addbase); - ACTION_RETURN_FLOAT(self->GetAngle(pos, addbase).Degrees); - } - - DEFINE_ACTION_FUNCTION(_Sector, SetBase) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - PARAM_FLOAT(o); - PARAM_ANGLE(a); - self->SetBase(pos, o, a); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Sector, SetAlpha) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - PARAM_FLOAT(o); - self->SetAlpha(pos, o); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Sector, GetAlpha) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_FLOAT(self->GetAlpha(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, GetFlags) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_INT(self->GetFlags(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, GetVisFlags) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_INT(self->GetVisFlags(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, ChangeFlags) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - PARAM_INT(a); - PARAM_INT(o); - self->ChangeFlags(pos, a, o); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Sector, SetPlaneLight) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - PARAM_INT(o); - self->SetPlaneLight(pos, o); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Sector, GetPlaneLight) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_INT(self->GetPlaneLight(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, SetTexture) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - PARAM_INT(o); - PARAM_BOOL(adj); - self->SetTexture(pos, FSetTextureID(o), adj); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Sector, GetTexture) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_INT(self->GetTexture(pos).GetIndex()); - } - - DEFINE_ACTION_FUNCTION(_Sector, SetPlaneTexZ) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - PARAM_FLOAT(o); - PARAM_BOOL(dirty); - self->SetPlaneTexZ(pos, o, true); // not setting 'dirty' here is a guaranteed cause for problems. - return 0; - } - - DEFINE_ACTION_FUNCTION(_Sector, GetPlaneTexZ) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_FLOAT(self->GetPlaneTexZ(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, SetLightLevel) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(o); - self->SetLightLevel(o); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Sector, ChangeLightLevel) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(o); - self->ChangeLightLevel(o); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Sector, GetLightLevel) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - ACTION_RETURN_INT(self->GetLightLevel()); - } - - DEFINE_ACTION_FUNCTION(_Sector, PortalBlocksView) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_BOOL(self->PortalBlocksView(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, PortalBlocksSight) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_BOOL(self->PortalBlocksSight(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, PortalBlocksMovement) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_BOOL(self->PortalBlocksMovement(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, PortalBlocksSound) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_BOOL(self->PortalBlocksSound(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, PortalIsLinked) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_BOOL(self->PortalIsLinked(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, ClearPortal) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - self->ClearPortal(pos); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Sector, GetPortalPlaneZ) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_FLOAT(self->GetPortalPlaneZ(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, GetPortalDisplacement) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_VEC2(self->GetPortalDisplacement(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, GetPortalType) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_INT(self->GetPortalType(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, GetOppositePortalGroup) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_INT(self->GetOppositePortalGroup(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, CenterFloor) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - ACTION_RETURN_FLOAT(self->CenterFloor()); - } - - DEFINE_ACTION_FUNCTION(_Sector, CenterCeiling) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - ACTION_RETURN_FLOAT(self->CenterCeiling()); - } - - DEFINE_ACTION_FUNCTION(_Sector, Index) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - unsigned ndx = self->Index(); - if (ndx >= level.sectors.Size()) - { - // This qualifies as an array out of bounds exception. Normally it can only happen when a sector copy is concerned which scripts should not be able to create. - ThrowAbortException(X_ARRAY_OUT_OF_BOUNDS, "Accessed invalid sector"); - } - ACTION_RETURN_INT(ndx); - } - - DEFINE_ACTION_FUNCTION(_Sector, SetEnvironmentID) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(envnum); - level.Zones[self->ZoneNumber].Environment = S_FindEnvironment(envnum); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Sector, SetEnvironment) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_STRING(env); - level.Zones[self->ZoneNumber].Environment = S_FindEnvironment(env); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Sector, GetGlowHeight) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_FLOAT(self->GetGlowHeight(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, GetGlowColor) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - ACTION_RETURN_INT(self->GetGlowColor(pos)); - } - - DEFINE_ACTION_FUNCTION(_Sector, SetGlowHeight) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - PARAM_FLOAT(o); - self->SetGlowHeight(pos, float(o)); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Sector, SetGlowColor) - { - PARAM_SELF_STRUCT_PROLOGUE(sector_t); - PARAM_INT(pos); - PARAM_COLOR(o); - self->SetGlowColor(pos, o); - return 0; - } - - //=========================================================================== - // - // line_t exports - // - //=========================================================================== - - DEFINE_ACTION_FUNCTION(_Line, isLinePortal) - { - PARAM_SELF_STRUCT_PROLOGUE(line_t); - ACTION_RETURN_BOOL(self->isLinePortal()); - } - - DEFINE_ACTION_FUNCTION(_Line, isVisualPortal) - { - PARAM_SELF_STRUCT_PROLOGUE(line_t); - ACTION_RETURN_BOOL(self->isVisualPortal()); - } - - DEFINE_ACTION_FUNCTION(_Line, getPortalDestination) - { - PARAM_SELF_STRUCT_PROLOGUE(line_t); - ACTION_RETURN_POINTER(self->getPortalDestination()); - } - - DEFINE_ACTION_FUNCTION(_Line, getPortalAlignment) - { - PARAM_SELF_STRUCT_PROLOGUE(line_t); - ACTION_RETURN_INT(self->getPortalAlignment()); - } - - DEFINE_ACTION_FUNCTION(_Line, Index) - { - PARAM_SELF_STRUCT_PROLOGUE(line_t); - unsigned ndx = self->Index(); - if (ndx >= level.lines.Size()) - { - ThrowAbortException(X_ARRAY_OUT_OF_BOUNDS, "Accessed invalid line"); - } - ACTION_RETURN_INT(ndx); - } - - //=========================================================================== - // - // - // - //=========================================================================== - - DEFINE_ACTION_FUNCTION(_Side, GetTexture) - { - PARAM_SELF_STRUCT_PROLOGUE(side_t); - PARAM_INT(which); - ACTION_RETURN_INT(self->GetTexture(which).GetIndex()); - } - - DEFINE_ACTION_FUNCTION(_Side, SetTexture) - { - PARAM_SELF_STRUCT_PROLOGUE(side_t); - PARAM_INT(which); - PARAM_INT(tex); - self->SetTexture(which, FSetTextureID(tex)); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Side, SetTextureXOffset) - { - PARAM_SELF_STRUCT_PROLOGUE(side_t); - PARAM_INT(which); - PARAM_FLOAT(ofs); - self->SetTextureXOffset(which, ofs); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Side, AddTextureXOffset) - { - PARAM_SELF_STRUCT_PROLOGUE(side_t); - PARAM_INT(which); - PARAM_FLOAT(ofs); - self->AddTextureXOffset(which, ofs); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Side, GetTextureXOffset) - { - PARAM_SELF_STRUCT_PROLOGUE(side_t); - PARAM_INT(which); - ACTION_RETURN_FLOAT(self->GetTextureXOffset(which)); - } - - DEFINE_ACTION_FUNCTION(_Side, SetTextureYOffset) - { - PARAM_SELF_STRUCT_PROLOGUE(side_t); - PARAM_INT(which); - PARAM_FLOAT(ofs); - self->SetTextureYOffset(which, ofs); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Side, AddTextureYOffset) - { - PARAM_SELF_STRUCT_PROLOGUE(side_t); - PARAM_INT(which); - PARAM_FLOAT(ofs); - self->AddTextureYOffset(which, ofs); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Side, GetTextureYOffset) - { - PARAM_SELF_STRUCT_PROLOGUE(side_t); - PARAM_INT(which); - ACTION_RETURN_FLOAT(self->GetTextureYOffset(which)); - } - - DEFINE_ACTION_FUNCTION(_Side, SetTextureXScale) - { - PARAM_SELF_STRUCT_PROLOGUE(side_t); - PARAM_INT(which); - PARAM_FLOAT(ofs); - self->SetTextureXScale(which, ofs); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Side, MultiplyTextureXScale) - { - PARAM_SELF_STRUCT_PROLOGUE(side_t); - PARAM_INT(which); - PARAM_FLOAT(ofs); - self->MultiplyTextureXScale(which, ofs); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Side, GetTextureXScale) - { - PARAM_SELF_STRUCT_PROLOGUE(side_t); - PARAM_INT(which); - ACTION_RETURN_FLOAT(self->GetTextureXScale(which)); - } - - DEFINE_ACTION_FUNCTION(_Side, SetTextureYScale) - { - PARAM_SELF_STRUCT_PROLOGUE(side_t); - PARAM_INT(which); - PARAM_FLOAT(ofs); - self->SetTextureYScale(which, ofs); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Side, MultiplyTextureYScale) - { - PARAM_SELF_STRUCT_PROLOGUE(side_t); - PARAM_INT(which); - PARAM_FLOAT(ofs); - self->MultiplyTextureYScale(which, ofs); - return 0; - } - - DEFINE_ACTION_FUNCTION(_Side, GetTextureYScale) - { - PARAM_SELF_STRUCT_PROLOGUE(side_t); - PARAM_INT(which); - ACTION_RETURN_FLOAT(self->GetTextureYScale(which)); - } - - DEFINE_ACTION_FUNCTION(_Side, V1) - { - PARAM_SELF_STRUCT_PROLOGUE(side_t); - ACTION_RETURN_POINTER(self->V1()); - } - - DEFINE_ACTION_FUNCTION(_Side, V2) - { - PARAM_SELF_STRUCT_PROLOGUE(side_t); - ACTION_RETURN_POINTER(self->V2()); - } - - DEFINE_ACTION_FUNCTION(_Side, Index) - { - PARAM_SELF_STRUCT_PROLOGUE(side_t); - ACTION_RETURN_INT(self->Index()); - } - - //===================================================================================== -// -// -//===================================================================================== - - DEFINE_ACTION_FUNCTION(_Side, SetSpecialColor) - { - PARAM_SELF_STRUCT_PROLOGUE(side_t); - PARAM_INT(tier); - PARAM_INT(position); - PARAM_COLOR(color); - if (tier >= 0 && tier < 3 && position >= 0 && position < 2) - { - color.a = 255; - self->SetSpecialColor(tier, position, color); - } - return 0; - } - - - DEFINE_ACTION_FUNCTION(_Vertex, Index) - { - PARAM_SELF_STRUCT_PROLOGUE(vertex_t); - ACTION_RETURN_INT(self->Index()); - } - - //=========================================================================== // // @@ -2383,16 +1639,6 @@ void P_ReplaceTextures(const char *fromname, const char *toname, int flags) } } -DEFINE_ACTION_FUNCTION(_TexMan, ReplaceTextures) -{ - PARAM_PROLOGUE; - PARAM_STRING(from); - PARAM_STRING(to); - PARAM_INT(flags); - P_ReplaceTextures(from, to, flags); - return 0; -} - //========================================================================== // // P_BuildPolyBSP @@ -2427,6 +1673,7 @@ void subsector_t::BuildPolyBSP() for (unsigned int i = 0; i < BSP->Subsectors.Size(); ++i) { BSP->Subsectors[i].sector = sector; + BSP->Subsectors[i].section = section; } } @@ -2535,86 +1782,11 @@ void vertex_t::RecalcVertexHeights() dirty = false; } - - - -DEFINE_ACTION_FUNCTION(_Secplane, isSlope) +DEFINE_ACTION_FUNCTION(_Sector, GetPortalDisplacement) { - PARAM_SELF_STRUCT_PROLOGUE(secplane_t); - ACTION_RETURN_BOOL(!self->normal.XY().isZero()); -} - -DEFINE_ACTION_FUNCTION(_Secplane, PointOnSide) -{ - PARAM_SELF_STRUCT_PROLOGUE(secplane_t); - PARAM_FLOAT(x); - PARAM_FLOAT(y); - PARAM_FLOAT(z); - ACTION_RETURN_INT(self->PointOnSide(DVector3(x, y, z))); -} - -DEFINE_ACTION_FUNCTION(_Secplane, ZatPoint) -{ - PARAM_SELF_STRUCT_PROLOGUE(secplane_t); - PARAM_FLOAT(x); - PARAM_FLOAT(y); - ACTION_RETURN_FLOAT(self->ZatPoint(x, y)); -} - -DEFINE_ACTION_FUNCTION(_Secplane, ZatPointDist) -{ - PARAM_SELF_STRUCT_PROLOGUE(secplane_t); - PARAM_FLOAT(x); - PARAM_FLOAT(y); - PARAM_FLOAT(d); - ACTION_RETURN_FLOAT((d + self->normal.X*x + self->normal.Y*y) * self->negiC); -} - -DEFINE_ACTION_FUNCTION(_Secplane, isEqual) -{ - PARAM_SELF_STRUCT_PROLOGUE(secplane_t); - PARAM_POINTER(other, secplane_t); - ACTION_RETURN_BOOL(*self == *other); -} - -DEFINE_ACTION_FUNCTION(_Secplane, ChangeHeight) -{ - PARAM_SELF_STRUCT_PROLOGUE(secplane_t); - PARAM_FLOAT(hdiff); - self->ChangeHeight(hdiff); - return 0; -} - -DEFINE_ACTION_FUNCTION(_Secplane, GetChangedHeight) -{ - PARAM_SELF_STRUCT_PROLOGUE(secplane_t); - PARAM_FLOAT(hdiff); - ACTION_RETURN_FLOAT(self->GetChangedHeight(hdiff)); -} - -DEFINE_ACTION_FUNCTION(_Secplane, HeightDiff) -{ - PARAM_SELF_STRUCT_PROLOGUE(secplane_t); - PARAM_FLOAT(oldd); - PARAM_FLOAT(newd); - if (newd != 1e37) - { - ACTION_RETURN_FLOAT(self->HeightDiff(oldd)); - } - else - { - PARAM_FLOAT(newd); - ACTION_RETURN_FLOAT(self->HeightDiff(oldd, newd)); - } -} - -DEFINE_ACTION_FUNCTION(_Secplane, PointToDist) -{ - PARAM_SELF_STRUCT_PROLOGUE(secplane_t); - PARAM_FLOAT(x); - PARAM_FLOAT(y); - PARAM_FLOAT(z); - ACTION_RETURN_FLOAT(self->PointToDist(DVector2(x, y), z)); + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_VEC2(self->GetPortalDisplacement(pos)); } diff --git a/src/p_terrain.cpp b/src/p_terrain.cpp index 73756ec57b..d1f6d7e3aa 100644 --- a/src/p_terrain.cpp +++ b/src/p_terrain.cpp @@ -556,17 +556,17 @@ static void GenericParse (FScanner &sc, FGenericParse *parser, const char **keyw else { info = PClass::FindClass (sc.String); - if (!info->IsDescendantOf (RUNTIME_CLASS(AActor))) + if (info == NULL) + { + Printf ("Unknown actor %s in %s %s\n", + sc.String, type, name.GetChars()); + } + else if (!info->IsDescendantOf (RUNTIME_CLASS(AActor))) { Printf ("%s is not an Actor (in %s %s)\n", sc.String, type, name.GetChars()); info = NULL; } - else if (info == NULL) - { - Printf ("Unknown actor %s in %s %s\n", - sc.String, type, name.GetChars()); - } } SET_FIELD (const PClass *, info); break; diff --git a/src/polyrenderer/drawers/poly_triangle.h b/src/polyrenderer/drawers/poly_triangle.h index 6ed9ee8a43..0d369fa000 100644 --- a/src/polyrenderer/drawers/poly_triangle.h +++ b/src/polyrenderer/drawers/poly_triangle.h @@ -77,6 +77,15 @@ public: return clip_first_line + core_skip - first_line; } + // Varyings + float worldposX[MAXWIDTH]; + float worldposY[MAXWIDTH]; + float worldposZ[MAXWIDTH]; + uint32_t texel[MAXWIDTH]; + int32_t texelV[MAXWIDTH]; + fixed_t lightarray[MAXWIDTH]; + uint32_t dynlights[MAXWIDTH]; + static PolyTriangleThreadData *Get(DrawerThread *thread); private: diff --git a/src/polyrenderer/drawers/screen_triangle.cpp b/src/polyrenderer/drawers/screen_triangle.cpp index 30f0231662..f897684b51 100644 --- a/src/polyrenderer/drawers/screen_triangle.cpp +++ b/src/polyrenderer/drawers/screen_triangle.cpp @@ -227,7 +227,7 @@ void ScreenTriangle::Draw(const TriDrawTriangleArgs *args, PolyTriangleThreadDat if (x > xstart) { if (writeColor) - drawfunc(y, xstart, x, args); + drawfunc(y, xstart, x, args, thread); if (writeStencil) { @@ -379,29 +379,54 @@ void ScreenTriangle::Draw(const TriDrawTriangleArgs *args, PolyTriangleThreadDat } template -void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) +void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread) { using namespace TriScreenDrawerModes; + uint32_t fixedlight; + uint32_t shade_fade_r, shade_fade_g, shade_fade_b, shade_light_r, shade_light_g, shade_light_b, desaturate, inv_desaturate; + fixed_t fuzzscale; + int _fuzzpos; + const uint32_t *texPixels, *translation; + int texWidth, texHeight; + uint32_t fillcolor; + int actoralpha; float v1X, v1Y, v1W, v1U, v1V, v1WorldX, v1WorldY, v1WorldZ; float startX, startY; float stepW, stepU, stepV, stepWorldX, stepWorldY, stepWorldZ; float posW, posU, posV, posWorldX, posWorldY, posWorldZ; - - PolyLight *lights; - int num_lights; - float worldnormalX, worldnormalY, worldnormalZ; - uint32_t dynlightcolor; - const uint32_t *texPixels, *translation; - int texWidth, texHeight; - uint32_t fillcolor; - int alpha; uint32_t light; fixed_t shade, lightpos, lightstep; - uint32_t shade_fade_r, shade_fade_g, shade_fade_b, shade_light_r, shade_light_g, shade_light_b, desaturate, inv_desaturate; - int16_t dynlights_r[MAXWIDTH / 16], dynlights_g[MAXWIDTH / 16], dynlights_b[MAXWIDTH / 16]; - int16_t posdynlight_r, posdynlight_g, posdynlight_b; - fixed_t lightarray[MAXWIDTH / 16]; + + float *worldposX = thread->worldposX; + float *worldposY = thread->worldposY; + float *worldposZ = thread->worldposZ; + uint32_t *texel = thread->texel; + int32_t *texelV = thread->texelV; + fixed_t *lightarray = thread->lightarray; + uint32_t *dynlights = thread->dynlights; + + if (!(ModeT::SWFlags & SWSTYLEF_Fill) && !(ModeT::SWFlags & SWSTYLEF_FogBoundary)) + { + texPixels = (const uint32_t*)args->uniforms->TexturePixels(); + texWidth = args->uniforms->TextureWidth(); + texHeight = args->uniforms->TextureHeight(); + } + + if (ModeT::SWFlags & SWSTYLEF_Translated) + { + translation = (const uint32_t*)args->uniforms->Translation(); + } + + if ((ModeT::SWFlags & SWSTYLEF_Fill) || (ModeT::SWFlags & SWSTYLEF_Skycap) || (ModeT::Flags & STYLEF_ColorIsFixed)) + { + fillcolor = args->uniforms->Color(); + } + + if (!(ModeT::Flags & STYLEF_Alpha1)) + { + actoralpha = args->uniforms->Alpha(); + } v1X = args->v1->x; v1Y = args->v1->y; @@ -417,50 +442,6 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) posU = v1U + stepU * startX + args->gradientY.U * startY; posV = v1V + stepV * startX + args->gradientY.V * startY; - texPixels = (const uint32_t*)args->uniforms->TexturePixels(); - translation = (const uint32_t*)args->uniforms->Translation(); - texWidth = args->uniforms->TextureWidth(); - texHeight = args->uniforms->TextureHeight(); - fillcolor = args->uniforms->Color(); - alpha = args->uniforms->Alpha(); - light = args->uniforms->Light(); - - if (OptT::Flags & SWOPT_FixedLight) - { - light += light >> 7; // 255 -> 256 - } - else - { - float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f); - - shade = (fixed_t)((2.0f - (light + 12.0f) / 128.0f) * (float)FRACUNIT); - lightpos = (fixed_t)(globVis * posW * (float)FRACUNIT); - lightstep = (fixed_t)(globVis * stepW * (float)FRACUNIT); - - int affineOffset = x0 / 16 * 16 - x0; - lightpos = lightpos + lightstep * affineOffset; - lightstep = lightstep * 16; - - fixed_t maxvis = 24 * FRACUNIT / 32; - fixed_t maxlight = 31 * FRACUNIT / 32; - - for (int x = x0 / 16; x <= x1 / 16 + 1; x++) - { - lightarray[x] = (FRACUNIT - clamp(shade - MIN(maxvis, lightpos), 0, maxlight)) >> 8; - lightpos += lightstep; - } - - int offset = x0 >> 4; - int t1 = x0 & 15; - int t0 = 16 - t1; - lightpos = (lightarray[offset] * t0 + lightarray[offset + 1] * t1); - - for (int x = x0 / 16; x <= x1 / 16; x++) - { - lightarray[x] = lightarray[x + 1] - lightarray[x]; - } - } - if (OptT::Flags & SWOPT_DynLights) { v1WorldX = args->v1->worldX * v1W; @@ -472,6 +453,61 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) posWorldX = v1WorldX + stepWorldX * startX + args->gradientY.WorldX * startY; posWorldY = v1WorldY + stepWorldY * startX + args->gradientY.WorldY * startY; posWorldZ = v1WorldZ + stepWorldZ * startX + args->gradientY.WorldZ * startY; + } + + if (!(OptT::Flags & SWOPT_FixedLight)) + { + float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f); + + light = args->uniforms->Light(); + shade = (fixed_t)((2.0f - (light + 12.0f) / 128.0f) * (float)FRACUNIT); + lightpos = (fixed_t)(globVis * posW * (float)FRACUNIT); + lightstep = (fixed_t)(globVis * stepW * (float)FRACUNIT); + } + + for (int x = x0; x < x1; x++) + { + if (OptT::Flags & SWOPT_DynLights) + { + float rcp_posW = 1.0f / posW; + worldposX[x] = posWorldX * rcp_posW; + worldposY[x] = posWorldY * rcp_posW; + worldposZ[x] = posWorldZ * rcp_posW; + posWorldX += stepWorldX; + posWorldY += stepWorldY; + posWorldZ += stepWorldZ; + } + + if (!(OptT::Flags & SWOPT_FixedLight)) + { + fixed_t maxvis = 24 * FRACUNIT / 32; + fixed_t maxlight = 31 * FRACUNIT / 32; + lightarray[x] = (FRACUNIT - clamp(shade - MIN(maxvis, lightpos), 0, maxlight)) >> 8; + lightpos += lightstep; + } + + if (!(ModeT::SWFlags & SWSTYLEF_Fill) && !(ModeT::SWFlags & SWSTYLEF_FogBoundary)) + { + float rcpW = 0x01000000 / posW; + int32_t u = (int32_t)(posU * rcpW); + int32_t v = (int32_t)(posV * rcpW); + uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; + uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; + texel[x] = texelX * texHeight + texelY; + texelV[x] = v; + posU += stepU; + posV += stepV; + } + + posW += stepW; + } + + if (OptT::Flags & SWOPT_DynLights) + { + PolyLight *lights; + int num_lights; + float worldnormalX, worldnormalY, worldnormalZ; + uint32_t dynlightcolor; lights = args->uniforms->Lights(); num_lights = args->uniforms->NumLights(); @@ -503,26 +539,12 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) worldnormalZ *= rcplen; } - int affineOffset = x0 / 16 * 16 - x0; - float posLightW = posW + stepW * affineOffset; - posWorldX = posWorldX + stepWorldX * affineOffset; - posWorldY = posWorldY + stepWorldY * affineOffset; - posWorldZ = posWorldZ + stepWorldZ * affineOffset; - float stepLightW = stepW * 16.0f; - stepWorldX *= 16.0f; - stepWorldY *= 16.0f; - stepWorldZ *= 16.0f; - - for (int x = x0 / 16; x <= x1 / 16 + 1; x++) + for (int x = x0; x < x1; x++) { uint32_t lit_r = RPART(dynlightcolor); uint32_t lit_g = GPART(dynlightcolor); uint32_t lit_b = BPART(dynlightcolor); - float rcp_posW = 1.0f / posLightW; - float worldposX = posWorldX * rcp_posW; - float worldposY = posWorldY * rcp_posW; - float worldposZ = posWorldZ * rcp_posW; for (int i = 0; i < num_lights; i++) { float lightposX = lights[i].x; @@ -538,9 +560,9 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) // L = light-pos // dist = sqrt(dot(L, L)) // distance_attenuation = 1 - MIN(dist * (1/radius), 1) - float Lx = lightposX - worldposX; - float Ly = lightposY - worldposY; - float Lz = lightposZ - worldposZ; + float Lx = lightposX - worldposX[x]; + float Ly = lightposY - worldposY[x]; + float Lz = lightposZ - worldposZ[x]; float dist2 = Lx * Lx + Ly * Ly + Lz * Lz; #ifdef NO_SSE //float rcp_dist = 1.0f / sqrt(dist2); @@ -572,29 +594,14 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) lit_r = MIN(lit_r, 255); lit_g = MIN(lit_g, 255); lit_b = MIN(lit_b, 255); - dynlights_r[x] = lit_r; - dynlights_g[x] = lit_g; - dynlights_b[x] = lit_b; - - posLightW += stepLightW; - posWorldX += stepWorldX; - posWorldY += stepWorldY; - posWorldZ += stepWorldZ; + dynlights[x] = MAKEARGB(255, lit_r, lit_g, lit_b); } + } - int offset = x0 >> 4; - int t1 = x0 & 15; - int t0 = 16 - t1; - posdynlight_r = (dynlights_r[offset] * t0 + dynlights_r[offset + 1] * t1); - posdynlight_g = (dynlights_g[offset] * t0 + dynlights_g[offset + 1] * t1); - posdynlight_b = (dynlights_b[offset] * t0 + dynlights_b[offset + 1] * t1); - - for (int x = x0 / 16; x <= x1 / 16; x++) - { - dynlights_r[x] = dynlights_r[x + 1] - dynlights_r[x]; - dynlights_g[x] = dynlights_g[x + 1] - dynlights_g[x]; - dynlights_b[x] = dynlights_b[x + 1] - dynlights_b[x]; - } + if (OptT::Flags & SWOPT_FixedLight) + { + fixedlight = args->uniforms->Light(); + fixedlight += fixedlight >> 7; // 255 -> 256 } if (OptT::Flags & SWOPT_ColoredFog) @@ -609,8 +616,6 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) inv_desaturate = 256 - desaturate; } - fixed_t fuzzscale; - int _fuzzpos; if (ModeT::BlendOp == STYLEOP_Fuzz) { fuzzscale = (200 << FRACBITS) / viewheight; @@ -620,19 +625,55 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) uint32_t *dest = (uint32_t*)args->dest; uint32_t *destLine = dest + args->pitch * y; - int x = x0; - while (x < x1) + int sseend = x0; +#ifndef NO_SSE + if (ModeT::BlendOp == STYLEOP_Add && + ModeT::BlendSrc == STYLEALPHA_One && + ModeT::BlendDest == STYLEALPHA_Zero && + (ModeT::Flags & STYLEF_Alpha1) && + !(OptT::Flags & SWOPT_ColoredFog) && + !(ModeT::Flags & STYLEF_RedIsAlpha) && + !(ModeT::SWFlags & SWSTYLEF_Skycap) && + !(ModeT::SWFlags & SWSTYLEF_FogBoundary) && + !(ModeT::SWFlags & SWSTYLEF_Fill)) + { + sseend += (x1 - x0) / 2 * 2; + + __m128i mlightshade; + if (OptT::Flags & SWOPT_FixedLight) + mlightshade = _mm_set1_epi16(fixedlight); + + __m128i alphamask = _mm_set1_epi32(0xff000000); + + for (int x = x0; x < sseend; x += 2) + { + __m128i mfg = _mm_unpacklo_epi8(_mm_setr_epi32(texPixels[texel[x]], texPixels[texel[x + 1]], 0, 0), _mm_setzero_si128()); + + if (!(OptT::Flags & SWOPT_FixedLight)) + mlightshade = _mm_shuffle_epi32(_mm_shufflelo_epi16(_mm_loadl_epi64((const __m128i*)&lightarray[x]), _MM_SHUFFLE(2, 2, 0, 0)), _MM_SHUFFLE(1, 1, 0, 0)); + + if (OptT::Flags & SWOPT_DynLights) + { + __m128i mdynlight = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)&dynlights[x]), _mm_setzero_si128()); + mfg = _mm_srli_epi16(_mm_mullo_epi16(_mm_min_epi16(_mm_add_epi16(mdynlight, mlightshade), _mm_set1_epi16(256)), mfg), 8); + } + else + { + mfg = _mm_srli_epi16(_mm_mullo_epi16(mlightshade, mfg), 8); + } + + _mm_storel_epi64((__m128i*)&destLine[x], _mm_or_si128(_mm_packus_epi16(mfg, _mm_setzero_si128()), alphamask)); + } + } +#endif + + for (int x = sseend; x < x1; x++) { if (ModeT::BlendOp == STYLEOP_Fuzz) { using namespace swrenderer; - float rcpW = 0x01000000 / posW; - int32_t u = (int32_t)(posU * rcpW); - int32_t v = (int32_t)(posV * rcpW); - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - unsigned int sampleshadeout = APART(texPixels[texelX * texHeight + texelY]); + unsigned int sampleshadeout = APART(texPixels[texel[x]]); sampleshadeout += sampleshadeout >> 7; // 255 -> 256 int scaled_x = (x * fuzzscale) >> FRACBITS; @@ -654,14 +695,9 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) } else if (ModeT::SWFlags & SWSTYLEF_Skycap) { - float rcpW = 0x01000000 / posW; - int32_t u = (int32_t)(posU * rcpW); - int32_t v = (int32_t)(posV * rcpW); - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - - uint32_t fg = texPixels[texelX * texHeight + texelY]; + uint32_t fg = texPixels[texel[x]]; + int v = texelV[x]; int start_fade = 2; // How fast it should fade out int alpha_top = clamp(v >> (16 - start_fade), 0, 256); int alpha_bottom = clamp(((2 << 24) - v) >> (16 - start_fade), 0, 256); @@ -695,11 +731,11 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) int lightshade; if (OptT::Flags & SWOPT_FixedLight) { - lightshade = light; + lightshade = fixedlight; } else { - lightshade = lightpos >> 4; + lightshade = lightarray[x]; } uint32_t shadedfg_r, shadedfg_g, shadedfg_b; @@ -731,26 +767,17 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) { fg = fillcolor; } + else if (ModeT::SWFlags & SWSTYLEF_Translated) + { + fg = translation[((const uint8_t*)texPixels)[texel[x]]]; + } + else if (ModeT::Flags & STYLEF_RedIsAlpha) + { + fg = ((const uint8_t*)texPixels)[texel[x]]; + } else { - float rcpW = 0x01000000 / posW; - int32_t u = (int32_t)(posU * rcpW); - int32_t v = (int32_t)(posV * rcpW); - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - - if (ModeT::SWFlags & SWSTYLEF_Translated) - { - fg = translation[((const uint8_t*)texPixels)[texelX * texHeight + texelY]]; - } - else if (ModeT::Flags & STYLEF_RedIsAlpha) - { - fg = ((const uint8_t*)texPixels)[texelX * texHeight + texelY]; - } - else - { - fg = texPixels[texelX * texHeight + texelY]; - } + fg = texPixels[texel[x]]; } if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill)) @@ -765,17 +792,17 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) if (!(ModeT::Flags & STYLEF_Alpha1)) { - fgalpha = (fgalpha * alpha) >> 8; + fgalpha = (fgalpha * actoralpha) >> 8; } - int lightshade; + uint32_t lightshade; if (OptT::Flags & SWOPT_FixedLight) { - lightshade = light; + lightshade = fixedlight; } else { - lightshade = lightpos >> 4; + lightshade = lightarray[x]; } uint32_t shadedfg_r, shadedfg_g, shadedfg_b; @@ -792,24 +819,18 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) if (OptT::Flags & SWOPT_DynLights) { - uint32_t lit_r = posdynlight_r >> 4; - uint32_t lit_g = posdynlight_g >> 4; - uint32_t lit_b = posdynlight_b >> 4; - shadedfg_r = MIN(shadedfg_r + ((fg_r * lit_r) >> 8), (uint32_t)255); - shadedfg_g = MIN(shadedfg_g + ((fg_g * lit_g) >> 8), (uint32_t)255); - shadedfg_b = MIN(shadedfg_b + ((fg_b * lit_b) >> 8), (uint32_t)255); + shadedfg_r = MIN(shadedfg_r + ((fg_r * RPART(dynlights[x])) >> 8), (uint32_t)255); + shadedfg_g = MIN(shadedfg_g + ((fg_g * GPART(dynlights[x])) >> 8), (uint32_t)255); + shadedfg_b = MIN(shadedfg_b + ((fg_b * BPART(dynlights[x])) >> 8), (uint32_t)255); } } else { if (OptT::Flags & SWOPT_DynLights) { - uint32_t lit_r = posdynlight_r >> 4; - uint32_t lit_g = posdynlight_g >> 4; - uint32_t lit_b = posdynlight_b >> 4; - shadedfg_r = (RPART(fg) * MIN(lightshade + lit_r, (uint32_t)256)) >> 8; - shadedfg_g = (GPART(fg) * MIN(lightshade + lit_g, (uint32_t)256)) >> 8; - shadedfg_b = (BPART(fg) * MIN(lightshade + lit_b, (uint32_t)256)) >> 8; + shadedfg_r = (RPART(fg) * MIN(lightshade + RPART(dynlights[x]), (uint32_t)256)) >> 8; + shadedfg_g = (GPART(fg) * MIN(lightshade + GPART(dynlights[x]), (uint32_t)256)) >> 8; + shadedfg_b = (BPART(fg) * MIN(lightshade + BPART(dynlights[x]), (uint32_t)256)) >> 8; } else { @@ -927,24 +948,11 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) destLine[x] = MAKEARGB(255, out_r, out_g, out_b); } } - - posW += stepW; - posU += stepU; - posV += stepV; - if (OptT::Flags & SWOPT_DynLights) - { - posdynlight_r += dynlights_r[x >> 4]; - posdynlight_g += dynlights_g[x >> 4]; - posdynlight_b += dynlights_b[x >> 4]; - } - if (!(OptT::Flags & SWOPT_FixedLight)) - lightpos += lightarray[x >> 4]; - x++; } } template -void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) +void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread) { using namespace TriScreenDrawerModes; @@ -953,16 +961,16 @@ void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) if (!args->uniforms->FixedLight()) { if (args->uniforms->SimpleShade()) - DrawSpanOpt32(y, x0, x1, args); + DrawSpanOpt32(y, x0, x1, args, thread); else - DrawSpanOpt32(y, x0, x1, args); + DrawSpanOpt32(y, x0, x1, args, thread); } else { if (args->uniforms->SimpleShade()) - DrawSpanOpt32(y, x0, x1, args); + DrawSpanOpt32(y, x0, x1, args, thread); else - DrawSpanOpt32(y, x0, x1, args); + DrawSpanOpt32(y, x0, x1, args, thread); } } else @@ -970,22 +978,22 @@ void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) if (!args->uniforms->FixedLight()) { if (args->uniforms->SimpleShade()) - DrawSpanOpt32(y, x0, x1, args); + DrawSpanOpt32(y, x0, x1, args, thread); else - DrawSpanOpt32(y, x0, x1, args); + DrawSpanOpt32(y, x0, x1, args, thread); } else { if (args->uniforms->SimpleShade()) - DrawSpanOpt32(y, x0, x1, args); + DrawSpanOpt32(y, x0, x1, args, thread); else - DrawSpanOpt32(y, x0, x1, args); + DrawSpanOpt32(y, x0, x1, args, thread); } } } template -void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args) +void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread) { using namespace TriScreenDrawerModes; @@ -1501,23 +1509,23 @@ void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args) } template -void DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args) +void DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread) { using namespace TriScreenDrawerModes; if (args->uniforms->NumLights() == 0 && args->uniforms->DynLightColor() == 0) { if (!args->uniforms->FixedLight()) - DrawSpanOpt8(y, x0, x1, args); + DrawSpanOpt8(y, x0, x1, args, thread); else - DrawSpanOpt8(y, x0, x1, args); + DrawSpanOpt8(y, x0, x1, args, thread); } else { if (!args->uniforms->FixedLight()) - DrawSpanOpt8(y, x0, x1, args); + DrawSpanOpt8(y, x0, x1, args, thread); else - DrawSpanOpt8(y, x0, x1, args); + DrawSpanOpt8(y, x0, x1, args, thread); } } @@ -2049,7 +2057,7 @@ void DrawRect32(const void *destOrg, int destWidth, int destHeight, int destPitc DrawRectOpt32(destOrg, destWidth, destHeight, destPitch, args, thread); } -void(*ScreenTriangle::SpanDrawers8[])(int, int, int, const TriDrawTriangleArgs *) = +void(*ScreenTriangle::SpanDrawers8[])(int, int, int, const TriDrawTriangleArgs *, PolyTriangleThreadData *) = { &DrawSpan8, &DrawSpan8, @@ -2081,7 +2089,7 @@ void(*ScreenTriangle::SpanDrawers8[])(int, int, int, const TriDrawTriangleArgs * &DrawSpan8 }; -void(*ScreenTriangle::SpanDrawers32[])(int, int, int, const TriDrawTriangleArgs *) = +void(*ScreenTriangle::SpanDrawers32[])(int, int, int, const TriDrawTriangleArgs *, PolyTriangleThreadData *) = { &DrawSpan32, &DrawSpan32, diff --git a/src/polyrenderer/drawers/screen_triangle.h b/src/polyrenderer/drawers/screen_triangle.h index 72c8f82654..dc8809b0d8 100644 --- a/src/polyrenderer/drawers/screen_triangle.h +++ b/src/polyrenderer/drawers/screen_triangle.h @@ -142,8 +142,8 @@ class ScreenTriangle public: static void Draw(const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread); - static void(*SpanDrawers8[])(int y, int x0, int x1, const TriDrawTriangleArgs *args); - static void(*SpanDrawers32[])(int y, int x0, int x1, const TriDrawTriangleArgs *args); + static void(*SpanDrawers8[])(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread); + static void(*SpanDrawers32[])(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread); static void(*RectDrawers8[])(const void *, int, int, int, const RectDrawArgs *, PolyTriangleThreadData *); static void(*RectDrawers32[])(const void *, int, int, int, const RectDrawArgs *, PolyTriangleThreadData *); diff --git a/src/posix/sdl/i_main.cpp b/src/posix/sdl/i_main.cpp index 8e7230777e..0c23892948 100644 --- a/src/posix/sdl/i_main.cpp +++ b/src/posix/sdl/i_main.cpp @@ -265,11 +265,11 @@ int main (int argc, char **argv) fprintf (stderr, "%s\n", error.what ()); #ifdef __APPLE__ - Mac_I_FatalError(error.GetMessage()); + Mac_I_FatalError(error.what()); #endif // __APPLE__ #ifdef __linux__ - Linux_I_FatalError(error.GetMessage()); + Linux_I_FatalError(error.what()); #endif // __linux__ exit (-1); diff --git a/src/r_defs.h b/src/r_defs.h index ad128c4dc8..2214eac299 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -630,10 +630,6 @@ public: double FindHighestCeilingSurrounding(vertex_t **v) const; // jff 2/04/98 double FindNextLowestCeiling(vertex_t **v) const; // jff 2/04/98 double FindNextHighestCeiling(vertex_t **v) const; // jff 2/04/98 - double FindShortestTextureAround() const; // jff 2/04/98 - double FindShortestUpperAround() const; // jff 2/04/98 - sector_t *FindModelFloorSector(double floordestheight) const; // jff 2/04/98 - sector_t *FindModelCeilingSector(double floordestheight) const; // jff 2/04/98 int FindMinSurroundingLight (int max) const; sector_t *NextSpecialSector (int type, sector_t *prev) const; // [RH] double FindLowestCeilingPoint(vertex_t **v) const; @@ -642,12 +638,13 @@ public: int Index() const; void AdjustFloorClip () const; - void SetColor(int r, int g, int b, int desat); - void SetFade(int r, int g, int b); + void SetColor(PalEntry pe, int desat); + void SetFade(PalEntry pe); void SetFogDensity(int dens); void ClosestPoint(const DVector2 &pos, DVector2 &out) const; - int GetFloorLight () const; - int GetCeilingLight () const; + + int GetFloorLight() const; + int GetCeilingLight() const; sector_t *GetHeightSec() const { @@ -1585,6 +1582,11 @@ inline sector_t *P_PointInSector(double X, double Y) return P_PointInSubsector(X, Y)->sector; } +inline sector_t *P_PointInSectorXY(double X, double Y) // This is for the benefit of unambiguously looking up this function's address +{ + return P_PointInSubsector(X, Y)->sector; +} + inline bool FBoundingBox::inRange(const line_t *ld) const { return Left() < ld->bbox[BOXRIGHT] && @@ -1603,4 +1605,40 @@ inline void FColormap::CopyFrom3DLight(lightlist_t *light) } } + +double FindShortestTextureAround(sector_t *sector); // jff 2/04/98 +double FindShortestUpperAround(sector_t *sector); // jff 2/04/98 +sector_t *FindModelFloorSector(sector_t *sec, double floordestheight); // jff 2/04/98 +sector_t *FindModelCeilingSector(sector_t *sec, double floordestheight); // jff 2/04/98 + +// This setup is to allow the VM call directily into the implementation. +// With a member function this may be subject to OS implementation details, e.g. on Windows 32 bit members use a different calling convention than regular functions. +void RemoveForceField(sector_t *sec); +bool PlaneMoving(sector_t *sector, int pos); +void TransferSpecial(sector_t *self, sector_t *model); +void GetSpecial(sector_t *self, secspecial_t *spec); +void SetSpecial(sector_t *self, const secspecial_t *spec); +int GetTerrain(const sector_t *, int pos); +void CheckPortalPlane(sector_t *sector, int plane); +void AdjustFloorClip(const sector_t *sector); +void SetColor(sector_t *sector, int color, int desat); +void SetFade(sector_t *sector, int color); +int GetFloorLight(const sector_t *); +int GetCeilingLight(const sector_t *); + + +inline void sector_t::RemoveForceField() { return ::RemoveForceField(this); } +inline bool sector_t::PlaneMoving(int pos) { return ::PlaneMoving(this, pos); } +inline void sector_t::TransferSpecial(sector_t *model) { return ::TransferSpecial(this, model); } +inline void sector_t::GetSpecial(secspecial_t *spec) { ::GetSpecial(this, spec); } +inline void sector_t::SetSpecial(const secspecial_t *spec) { ::SetSpecial(this, spec); } +inline int sector_t::GetTerrain(int pos) const { return ::GetTerrain(this, pos); } +inline void sector_t::CheckPortalPlane(int plane) { return ::CheckPortalPlane(this, plane); } +inline void sector_t::AdjustFloorClip() const { ::AdjustFloorClip(this); } +inline void sector_t::SetColor(PalEntry pe, int desat) { ::SetColor(this, pe, desat); } +inline void sector_t::SetFade(PalEntry pe) { ::SetFade(this, pe); } +inline int sector_t::GetFloorLight() const { return ::GetFloorLight(this); } +inline int sector_t::GetCeilingLight() const { return ::GetCeilingLight(this); } + + #endif diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 3eec90d39d..6d63eb4128 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -1438,6 +1438,24 @@ void S_PlaySound(AActor *a, int chan, FSoundID sid, float vol, float atten, bool } } +void A_PlaySound(AActor *self, int soundid, int channel, double volume, int looping, double attenuation, int local) +{ + if (!looping) + { + if (!(channel & CHAN_NOSTOP) || !S_IsActorPlayingSomething(self, channel & 7, soundid)) + { + S_PlaySound(self, channel, soundid, (float)volume, (float)attenuation, local); + } + } + else + { + if (!S_IsActorPlayingSomething(self, channel & 7, soundid)) + { + S_PlaySound(self, channel | CHAN_LOOP, soundid, (float)volume, (float)attenuation, local); + } + } +} + //========================================================================== // // S_LoadSound diff --git a/src/s_sound.h b/src/s_sound.h index 1d42cb2aed..bf937e893e 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -371,6 +371,7 @@ sfxinfo_t *S_LoadSound(sfxinfo_t *sfx, FSoundLoadBuffer *pBuffer = nullptr); unsigned int S_GetMSLength(FSoundID sound); void S_ParseMusInfo(); bool S_ParseTimeTag(const char *tag, bool *as_samples, unsigned int *time); +void A_PlaySound(AActor *self, int soundid, int channel, double volume, int looping, double attenuation, int local); // [RH] Prints sound debug info to the screen. // Modelled after Hexen's noise cheat. diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index b13537762e..c61daa0ac6 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -259,20 +259,9 @@ void ExpEmit::Reuse(VMFunctionBuilder *build) // //========================================================================== -static PSymbol *FindBuiltinFunction(FName funcname, VMNativeFunction::NativeCallType func, const uint8_t *reginfo) +static PFunction *FindBuiltinFunction(FName funcname) { - PSymbol *sym = Namespaces.GlobalNamespace->Symbols.FindSymbol(funcname, false); - if (sym == nullptr) - { - PSymbolVMFunction *symfunc = Create(funcname); - VMNativeFunction *calldec = new VMNativeFunction(func, funcname); - calldec->PrintableName = funcname.GetChars(); - calldec->RegTypes = reginfo; - symfunc->Function = calldec; - sym = symfunc; - Namespaces.GlobalNamespace->Symbols.AddSymbol(sym); - } - return sym; + return dyn_cast(RUNTIME_CLASS(DObject)->FindSymbol(funcname, true)); } //========================================================================== @@ -5471,33 +5460,35 @@ FxExpression *FxRandom::Resolve(FCompileContext &ctx) // //========================================================================== -int BuiltinRandom(VM_ARGS) +static int NativeRandom(FRandom *rng, int min, int max) +{ + if (max < min) + { + std::swap(max, min); + } + return (*rng)(max - min + 1) + min; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DObject, BuiltinRandom, NativeRandom) { PARAM_PROLOGUE; PARAM_POINTER(rng, FRandom); PARAM_INT(min); PARAM_INT(max); - if (max < min) - { - std::swap(max, min); - } - ACTION_RETURN_INT((*rng)(max - min + 1) + min); + ACTION_RETURN_INT(NativeRandom(rng, min, max)); } ExpEmit FxRandom::Emit(VMFunctionBuilder *build) { // Call DecoRandom to generate a random number. VMFunction *callfunc; - static const uint8_t reginfo[] = { REGT_POINTER, REGT_INT, REGT_INT }; - PSymbol *sym = FindBuiltinFunction(NAME_BuiltinRandom, BuiltinRandom, reginfo); + auto sym = FindBuiltinFunction(NAME_BuiltinRandom); - assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction))); - assert(((PSymbolVMFunction *)sym)->Function != nullptr); + assert(sym); + callfunc = sym->Variants[0].Implementation; assert(min && max); - callfunc = ((PSymbolVMFunction *)sym)->Function; FunctionCallEmitter emitters(callfunc); - emitters.AddParameterPointerConst(rng); emitters.AddParameter(build, min); emitters.AddParameter(build, max); @@ -5596,12 +5587,10 @@ ExpEmit FxRandomPick::Emit(VMFunctionBuilder *build) // Call BuiltinRandom to generate a random number. VMFunction *callfunc; - static const uint8_t reginfo[] = { REGT_POINTER, REGT_INT, REGT_INT }; - PSymbol *sym = FindBuiltinFunction(NAME_BuiltinRandom, BuiltinRandom, reginfo); + auto sym = FindBuiltinFunction(NAME_BuiltinRandom); - assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction))); - assert(((PSymbolVMFunction *)sym)->Function != nullptr); - callfunc = ((PSymbolVMFunction *)sym)->Function; + assert(sym); + callfunc = sym->Variants[0].Implementation; FunctionCallEmitter emitters(callfunc); emitters.AddParameterPointerConst(rng); @@ -5694,13 +5683,8 @@ FxFRandom::FxFRandom(FRandom *r, FxExpression *mi, FxExpression *ma, const FScri // //========================================================================== -int BuiltinFRandom(VM_ARGS) +static double NativeFRandom(FRandom *rng, double min, double max) { - PARAM_PROLOGUE; - PARAM_POINTER(rng, FRandom); - PARAM_FLOAT(min); - PARAM_FLOAT(max); - int random = (*rng)(0x40000000); double frandom = random / double(0x40000000); @@ -5708,20 +5692,29 @@ int BuiltinFRandom(VM_ARGS) { std::swap(max, min); } - ACTION_RETURN_FLOAT(frandom * (max - min) + min); + return frandom * (max - min) + min; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DObject, BuiltinFRandom, NativeFRandom) +{ + PARAM_PROLOGUE; + PARAM_POINTER(rng, FRandom); + PARAM_FLOAT(min); + PARAM_FLOAT(max); + + ACTION_RETURN_FLOAT(NativeFRandom(rng, min, max)); } ExpEmit FxFRandom::Emit(VMFunctionBuilder *build) { // Call the BuiltinFRandom function to generate a floating point random number.. VMFunction *callfunc; - static uint8_t reginfo[] = { REGT_POINTER, REGT_FLOAT, REGT_FLOAT }; - PSymbol *sym = FindBuiltinFunction(NAME_BuiltinFRandom, BuiltinFRandom, reginfo); + auto sym = FindBuiltinFunction(NAME_BuiltinFRandom); + + assert(sym); + callfunc = sym->Variants[0].Implementation; - assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction))); - assert(((PSymbolVMFunction *)sym)->Function != nullptr); assert(min && max); - callfunc = ((PSymbolVMFunction *)sym)->Function; FunctionCallEmitter emitters(callfunc); emitters.AddParameterPointerConst(rng); @@ -5776,7 +5769,12 @@ FxExpression *FxRandom2::Resolve(FCompileContext &ctx) // //========================================================================== -int BuiltinRandom2(VM_ARGS) +static int NativeRandom2(FRandom *rng, int maskval) +{ + return rng->Random2(maskval); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DObject, BuiltinRandom2, NativeRandom2) { PARAM_PROLOGUE; PARAM_POINTER(rng, FRandom); @@ -5794,12 +5792,10 @@ ExpEmit FxRandom2::Emit(VMFunctionBuilder *build) { // Call the BuiltinRandom function to generate the random number. VMFunction *callfunc; - static uint8_t reginfo[] = { REGT_POINTER, REGT_INT }; - PSymbol *sym = FindBuiltinFunction(NAME_BuiltinRandom2, BuiltinRandom2, reginfo); + auto sym = FindBuiltinFunction(NAME_BuiltinRandom2); - assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction))); - assert(((PSymbolVMFunction *)sym)->Function != nullptr); - callfunc = ((PSymbolVMFunction *)sym)->Function; + assert(sym); + callfunc = sym->Variants[0].Implementation; FunctionCallEmitter emitters(callfunc); @@ -5853,7 +5849,12 @@ FxExpression *FxRandomSeed::Resolve(FCompileContext &ctx) // //========================================================================== -int BuiltinRandomSeed(VM_ARGS) +static void NativeRandomSeed(FRandom *rng, int seed) +{ + rng->Init(seed); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DObject, BuiltinRandomSeed, NativeRandomSeed) { PARAM_PROLOGUE; PARAM_POINTER(rng, FRandom) @@ -5866,12 +5867,10 @@ ExpEmit FxRandomSeed::Emit(VMFunctionBuilder *build) { // Call DecoRandom to generate a random number. VMFunction *callfunc; - static uint8_t reginfo[] = { REGT_POINTER, REGT_INT }; - PSymbol *sym = FindBuiltinFunction(NAME_BuiltinRandomSeed, BuiltinRandomSeed, reginfo); + auto sym = FindBuiltinFunction(NAME_BuiltinRandomSeed); - assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction))); - assert(((PSymbolVMFunction *)sym)->Function != nullptr); - callfunc = ((PSymbolVMFunction *)sym)->Function; + assert(sym); + callfunc = sym->Variants[0].Implementation; FunctionCallEmitter emitters(callfunc); emitters.AddParameterPointerConst(rng); @@ -8525,7 +8524,7 @@ FxExpression *FxActionSpecialCall::Resolve(FCompileContext& ctx) // //========================================================================== -int BuiltinCallLineSpecial(VM_ARGS) +DEFINE_ACTION_FUNCTION(DObject, BuiltinCallLineSpecial) { PARAM_PROLOGUE; PARAM_INT(special); @@ -8545,11 +8544,10 @@ ExpEmit FxActionSpecialCall::Emit(VMFunctionBuilder *build) // Call the BuiltinCallLineSpecial function to perform the desired special. static uint8_t reginfo[] = { REGT_INT, REGT_POINTER, REGT_INT, REGT_INT, REGT_INT, REGT_INT, REGT_INT }; - PSymbol *sym = FindBuiltinFunction(NAME_BuiltinCallLineSpecial, BuiltinCallLineSpecial, reginfo); + auto sym = FindBuiltinFunction(NAME_BuiltinCallLineSpecial); - assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction))); - assert(((PSymbolVMFunction *)sym)->Function != nullptr); - VMFunction *callfunc = ((PSymbolVMFunction *)sym)->Function; + assert(sym); + auto callfunc = sym->Variants[0].Implementation; FunctionCallEmitter emitters(callfunc); @@ -10749,23 +10747,29 @@ FxExpression *FxClassTypeCast::Resolve(FCompileContext &ctx) // //========================================================================== -int BuiltinNameToClass(VM_ARGS) +static PClass *NativeNameToClass(int _clsname, PClass *desttype) { - PARAM_PROLOGUE; - PARAM_NAME(clsname); - PARAM_CLASS(desttype, DObject); - PClass *cls = nullptr; + FName clsname = ENamedName(_clsname); if (clsname != NAME_None) { cls = PClass::FindClass(clsname); if (cls != nullptr && (cls->VMType == nullptr || !cls->IsDescendantOf(desttype))) { // does not match required parameters or is invalid. - cls = nullptr; + return nullptr; } } - ACTION_RETURN_POINTER(cls); + return cls; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DObject, BuiltinNameToClass, NativeNameToClass) +{ + PARAM_PROLOGUE; + PARAM_NAME(clsname); + PARAM_CLASS(desttype, DObject); + + ACTION_RETURN_POINTER(NativeNameToClass(clsname, desttype)); } ExpEmit FxClassTypeCast::Emit(VMFunctionBuilder *build) @@ -10777,12 +10781,10 @@ ExpEmit FxClassTypeCast::Emit(VMFunctionBuilder *build) // Call the BuiltinNameToClass function to convert from 'name' to class. VMFunction *callfunc; - static uint8_t reginfo[] = { REGT_INT, REGT_POINTER }; - PSymbol *sym = FindBuiltinFunction(NAME_BuiltinNameToClass, BuiltinNameToClass, reginfo); + auto sym = FindBuiltinFunction(NAME_BuiltinNameToClass); - assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction))); - assert(((PSymbolVMFunction *)sym)->Function != nullptr); - callfunc = ((PSymbolVMFunction *)sym)->Function; + assert(sym); + callfunc = sym->Variants[0].Implementation; FunctionCallEmitter emitters(callfunc); emitters.AddParameter(build, basex); @@ -10871,12 +10873,17 @@ FxExpression *FxClassPtrCast::Resolve(FCompileContext &ctx) // //========================================================================== -int BuiltinClassCast(VM_ARGS) +static PClass *NativeClassCast(PClass *from, PClass *to) +{ + return from && to && from->IsDescendantOf(to) ? from : nullptr; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DObject, BuiltinClassCast, NativeClassCast) { PARAM_PROLOGUE; PARAM_CLASS(from, DObject); PARAM_CLASS(to, DObject); - ACTION_RETURN_POINTER(from && to && from->IsDescendantOf(to) ? from : nullptr); + ACTION_RETURN_POINTER(NativeClassCast(from, to)); } ExpEmit FxClassPtrCast::Emit(VMFunctionBuilder *build) @@ -10884,12 +10891,10 @@ ExpEmit FxClassPtrCast::Emit(VMFunctionBuilder *build) ExpEmit clsname = basex->Emit(build); VMFunction *callfunc; - static uint8_t reginfo[] = { REGT_POINTER, REGT_POINTER }; - PSymbol *sym = FindBuiltinFunction(NAME_BuiltinClassCast, BuiltinClassCast, reginfo); + auto sym = FindBuiltinFunction(NAME_BuiltinClassCast); - assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction))); - assert(((PSymbolVMFunction *)sym)->Function != nullptr); - callfunc = ((PSymbolVMFunction *)sym)->Function; + assert(sym); + callfunc = sym->Variants[0].Implementation; FunctionCallEmitter emitters(callfunc); emitters.AddParameter(clsname, false); diff --git a/src/scripting/symbols.cpp b/src/scripting/symbols.cpp index fbb06e9008..a892489376 100644 --- a/src/scripting/symbols.cpp +++ b/src/scripting/symbols.cpp @@ -52,7 +52,6 @@ IMPLEMENT_CLASS(PSymbolConstNumeric, false, false); IMPLEMENT_CLASS(PSymbolConstString, false, false); IMPLEMENT_CLASS(PSymbolTreeNode, false, false) IMPLEMENT_CLASS(PSymbolType, false, false) -IMPLEMENT_CLASS(PSymbolVMFunction, false, false) IMPLEMENT_CLASS(PFunction, false, false) //========================================================================== diff --git a/src/scripting/symbols.h b/src/scripting/symbols.h index 954edc85a7..d211aaabad 100644 --- a/src/scripting/symbols.h +++ b/src/scripting/symbols.h @@ -37,16 +37,6 @@ protected: // A VM function ------------------------------------------------------------ -class PSymbolVMFunction : public PSymbol -{ - DECLARE_CLASS(PSymbolVMFunction, PSymbol); -public: - VMFunction *Function; - - PSymbolVMFunction(FName name) : PSymbol(name) {} - PSymbolVMFunction() : PSymbol(NAME_None) {} -}; - // A symbol for a type ------------------------------------------------------ class PSymbolType : public PSymbol diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 210fb7cfc3..8190fb94d4 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -944,6 +944,7 @@ void InitThingdef() assert(afunc->VMPointer != NULL); *(afunc->VMPointer) = new VMNativeFunction(afunc->Function, afunc->FuncName); (*(afunc->VMPointer))->PrintableName.Format("%s.%s [Native]", afunc->ClassName+1, afunc->FuncName); + (*(afunc->VMPointer))->DirectNativeCall = afunc->DirectNative; AFTable.Push(*afunc); } AFTable.ShrinkToFit(); diff --git a/src/scripting/vm/jit.cpp b/src/scripting/vm/jit.cpp index d80485fcbd..1c46590481 100644 --- a/src/scripting/vm/jit.cpp +++ b/src/scripting/vm/jit.cpp @@ -9,6 +9,7 @@ extern PStruct *TypeVector3; static void OutputJitLog(const asmjit::StringLogger &logger); static TArray JitBlocks; +static TArray JitFrames; static size_t JitBlockPos = 0; static size_t JitBlockSize = 0; @@ -61,6 +62,25 @@ static void *AllocJitMemory(size_t size) #define UWOP_SAVE_XMM128_FAR 9 #define UWOP_PUSH_MACHFRAME 10 + +void JitRelease() +{ +#ifdef _WIN64 + for (auto p : JitFrames) + { + RtlDeleteFunctionTable((PRUNTIME_FUNCTION)p); + } +#endif + for (auto p : JitBlocks) + { + asmjit::OSUtils::releaseVirtualMemory(p, 1024 * 1024); + } + JitFrames.Clear(); + JitBlocks.Clear(); + JitBlockPos = 0; + JitBlockSize = 0; +} + static TArray CreateUnwindInfo(asmjit::CCFunc *func) { using namespace asmjit; @@ -276,6 +296,7 @@ static void *AddJitFunction(asmjit::CodeHolder* code, asmjit::CCFunc *func) table[0].EndAddress = (DWORD)(ptrdiff_t)(endaddr - baseaddr); table[0].UnwindInfoAddress = (DWORD)(ptrdiff_t)(unwindptr - baseaddr); BOOLEAN result = RtlAddFunctionTable(table, 1, (DWORD64)baseaddr); + JitFrames.Push((uint8_t*)table); if (result == 0) I_FatalError("RtlAddFunctionTable failed"); #endif diff --git a/src/scripting/vm/jit_call.cpp b/src/scripting/vm/jit_call.cpp index d8f665f15d..c86176c349 100644 --- a/src/scripting/vm/jit_call.cpp +++ b/src/scripting/vm/jit_call.cpp @@ -317,13 +317,16 @@ void JitCompiler::EmitNativeCall(VMNativeFunction *target) { using namespace asmjit; - auto call = cc.call(imm_ptr(target->DirectNativeCall), CreateFuncSignature(target)); - if ((pc - 1)->op == OP_VTBL) { I_FatalError("Native direct member function calls not implemented\n"); } + asmjit::CBNode *cursorBefore = cc.getCursor(); + auto call = cc.call(imm_ptr(target->DirectNativeCall), CreateFuncSignature(target)); + asmjit::CBNode *cursorAfter = cc.getCursor(); + cc.setCursor(cursorBefore); + X86Gp tmp; X86Xmm tmp2; @@ -398,6 +401,8 @@ void JitCompiler::EmitNativeCall(VMNativeFunction *target) } } + cc.setCursor(cursorAfter); + if (numparams != B) I_FatalError("OP_CALL parameter count does not match the number of preceding OP_PARAM instructions\n"); @@ -461,7 +466,7 @@ asmjit::FuncSignature JitCompiler::CreateFuncSignature(VMFunction *func) for (unsigned int i = 0; i < func->Proto->ArgumentTypes.Size(); i++) { const PType *type = func->Proto->ArgumentTypes[i]; - if (func->ArgFlags[i] & (VARF_Out | VARF_Ref)) + if (func->ArgFlags.Size() && func->ArgFlags[i] & (VARF_Out | VARF_Ref)) { args.Push(TypeIdOf::kTypeId); key += "v"; diff --git a/src/scripting/vm/vm.h b/src/scripting/vm/vm.h index aabff3c2d4..f367de4139 100644 --- a/src/scripting/vm/vm.h +++ b/src/scripting/vm/vm.h @@ -53,6 +53,8 @@ extern FMemArena ClassDataAllocator; #define MAX_RETURNS 8 // Maximum number of results a function called by script code can return #define MAX_TRY_DEPTH 8 // Maximum number of nested TRYs in a single function +void JitRelease(); + typedef unsigned char VM_UBYTE; typedef signed char VM_SBYTE; @@ -432,6 +434,8 @@ public: f->~VMFunction(); } AllFunctions.Clear(); + // also release any JIT data + JitRelease(); } static void CreateRegUseInfo() { @@ -511,6 +515,7 @@ bool AssertObject(void * ob); #define PARAM_STATE_AT(p,x) assert((p) < numparam); assert(reginfo[p] == REGT_INT); FState *x = (FState *)StateLabels.GetState(param[p].i, self->GetClass()); #define PARAM_STATE_ACTION_AT(p,x) assert((p) < numparam); assert(reginfo[p] == REGT_INT); FState *x = (FState *)StateLabels.GetState(param[p].i, stateowner->GetClass()); #define PARAM_POINTER_AT(p,x,type) assert((p) < numparam); assert(reginfo[p] == REGT_POINTER); type *x = (type *)param[p].a; +#define PARAM_OUTPOINTER_AT(p,x,type) assert((p) < numparam); type *x = (type *)param[p].a; #define PARAM_POINTERTYPE_AT(p,x,type) assert((p) < numparam); assert(reginfo[p] == REGT_POINTER); type x = (type )param[p].a; #define PARAM_OBJECT_AT(p,x,type) assert((p) < numparam); assert(reginfo[p] == REGT_POINTER && AssertObject(param[p].a)); type *x = (type *)param[p].a; assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type))); #define PARAM_CLASS_AT(p,x,base) assert((p) < numparam); assert(reginfo[p] == REGT_POINTER); base::MetaClass *x = (base::MetaClass *)param[p].a; assert(x == NULL || x->IsDescendantOf(RUNTIME_CLASS(base))); @@ -534,6 +539,7 @@ bool AssertObject(void * ob); #define PARAM_STATE(x) ++paramnum; PARAM_STATE_AT(paramnum,x) #define PARAM_STATE_ACTION(x) ++paramnum; PARAM_STATE_ACTION_AT(paramnum,x) #define PARAM_POINTER(x,type) ++paramnum; PARAM_POINTER_AT(paramnum,x,type) +#define PARAM_OUTPOINTER(x,type) ++paramnum; PARAM_OUTPOINTER_AT(paramnum,x,type) #define PARAM_POINTERTYPE(x,type) ++paramnum; PARAM_POINTERTYPE_AT(paramnum,x,type) #define PARAM_OBJECT(x,type) ++paramnum; PARAM_OBJECT_AT(paramnum,x,type) #define PARAM_CLASS(x,base) ++paramnum; PARAM_CLASS_AT(paramnum,x,base) @@ -559,6 +565,7 @@ struct AFuncDesc const char *FuncName; actionf_p Function; VMNativeFunction **VMPointer; + void *DirectNative; }; #if defined(_MSC_VER) @@ -579,10 +586,19 @@ struct AFuncDesc // Macros to handle action functions. These are here so that I don't have to // change every single use in case the parameters change. +#define DEFINE_ACTION_FUNCTION_NATIVE(cls, name, native) \ + static int AF_##cls##_##name(VM_ARGS); \ + VMNativeFunction *cls##_##name##_VMPtr; \ + static const AFuncDesc cls##_##name##_Hook = { #cls, #name, AF_##cls##_##name, &cls##_##name##_VMPtr, reinterpret_cast(native) }; \ + extern AFuncDesc const *const cls##_##name##_HookPtr; \ + MSVC_ASEG AFuncDesc const *const cls##_##name##_HookPtr GCC_ASEG = &cls##_##name##_Hook; \ + static int AF_##cls##_##name(VM_ARGS) + +//#define DEFINE_ACTION_FUNCTION(cls, name) DEFINE_ACTION_FUNCTION_NATIVE(cls, name, nullptr) #define DEFINE_ACTION_FUNCTION(cls, name) \ static int AF_##cls##_##name(VM_ARGS); \ VMNativeFunction *cls##_##name##_VMPtr; \ - static const AFuncDesc cls##_##name##_Hook = { #cls, #name, AF_##cls##_##name, &cls##_##name##_VMPtr }; \ + static const AFuncDesc cls##_##name##_Hook = { #cls, #name, AF_##cls##_##name, &cls##_##name##_VMPtr, nullptr }; \ extern AFuncDesc const *const cls##_##name##_HookPtr; \ MSVC_ASEG AFuncDesc const *const cls##_##name##_HookPtr GCC_ASEG = &cls##_##name##_Hook; \ static int AF_##cls##_##name(VM_ARGS) diff --git a/src/scripting/vm/vmframe.cpp b/src/scripting/vm/vmframe.cpp index fd2a41f9f5..8996f24895 100644 --- a/src/scripting/vm/vmframe.cpp +++ b/src/scripting/vm/vmframe.cpp @@ -80,6 +80,7 @@ void VMFunction::CreateRegUse() return; } assert(Proto->isPrototype()); + for (auto arg : Proto->ArgumentTypes) { count += arg? arg->GetRegCount() : 1; @@ -87,14 +88,20 @@ void VMFunction::CreateRegUse() uint8_t *regp; RegTypes = regp = (uint8_t*)ClassDataAllocator.Alloc(count); count = 0; - for (auto arg : Proto->ArgumentTypes) + for (unsigned i = 0; i < Proto->ArgumentTypes.Size(); i++) { + auto arg = Proto->ArgumentTypes[i]; + auto flg = ArgFlags.Size() > i ? ArgFlags[i] : 0; if (arg == nullptr) { // Marker for start of varargs. *regp++ = REGT_NIL; } - else for (int i = 0; i < arg->GetRegCount(); i++) + else if ((flg & VARF_Out) && !arg->isPointer()) + { + *regp++ = REGT_POINTER; + } + else for (int j = 0; j < arg->GetRegCount(); j++) { *regp++ = arg->GetRegType(); } diff --git a/src/scripting/vmthunks.cpp b/src/scripting/vmthunks.cpp new file mode 100644 index 0000000000..65953ec91f --- /dev/null +++ b/src/scripting/vmthunks.cpp @@ -0,0 +1,1267 @@ +//----------------------------------------------------------------------------- +// +// Copyright 2016-2018 Christoph Oelckers +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see http://www.gnu.org/licenses/ +// +//----------------------------------------------------------------------------- +// +// VM thunks for simple functions. +// +//----------------------------------------------------------------------------- + +#include "vm.h" +#include "r_defs.h" +#include "g_levellocals.h" +#include "s_sound.h" +#include "p_local.h" + +DEFINE_ACTION_FUNCTION_NATIVE(_Sector, FindShortestTextureAround, FindShortestTextureAround) +{ + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + ACTION_RETURN_FLOAT(FindShortestTextureAround(self)); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Sector, FindShortestUpperAround, FindShortestUpperAround) +{ + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + ACTION_RETURN_FLOAT(FindShortestUpperAround(self)); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Sector, FindModelFloorSector, FindModelFloorSector) +{ + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_FLOAT(fdh); + auto h = FindModelFloorSector(self, fdh); + ACTION_RETURN_POINTER(h); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Sector, FindModelCeilingSector, FindModelCeilingSector) +{ + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_FLOAT(fdh); + auto h = FindModelCeilingSector(self, fdh); + ACTION_RETURN_POINTER(h); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetColor, SetColor) +{ + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_COLOR(color); + PARAM_INT(desat); + SetColor(self, color, desat); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetFade, SetFade) +{ + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_COLOR(fade); + SetFade(self, fade); + return 0; +} + +static void SetSpecialColor(sector_t *self, int num, int color) +{ + if (num >= 0 && num < 5) + { + self->SetSpecialColor(num, color); + } +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetSpecialColor, SetSpecialColor) +{ + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(num); + PARAM_COLOR(color); + SetSpecialColor(self, num, color); + return 0; +} + +static void SetFogDensity(sector_t *self, int dens) +{ + self->Colormap.FogDensity = dens; +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetFogDensity, SetFogDensity) +{ + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(dens); + self->Colormap.FogDensity = dens; + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Sector, PlaneMoving, PlaneMoving) +{ + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_BOOL(PlaneMoving(self, pos)); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetFloorLight, GetFloorLight) +{ + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + ACTION_RETURN_INT(self->GetFloorLight()); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetCeilingLight, GetCeilingLight) +{ + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + ACTION_RETURN_INT(self->GetCeilingLight()); +} + +static sector_t *GetHeightSec(sector_t *self) +{ + return self->GetHeightSec(); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetHeightSec, GetHeightSec) +{ + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + ACTION_RETURN_POINTER(self->GetHeightSec()); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetSpecial, GetSpecial) +{ + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_POINTER(spec, secspecial_t); + GetSpecial(self, spec); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetSpecial, SetSpecial) +{ + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_POINTER(spec, secspecial_t); + SetSpecial(self, spec); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Sector, TransferSpecial, TransferSpecial) +{ + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_POINTER(spec, sector_t); + TransferSpecial(self, spec); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetTerrain, GetTerrain) +{ + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_INT(GetTerrain(self, pos)); +} + + +DEFINE_ACTION_FUNCTION_NATIVE(_Sector, CheckPortalPlane, CheckPortalPlane) +{ + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(plane); + self->CheckPortalPlane(plane); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Sector, RemoveForceField, RemoveForceField) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + RemoveForceField(self); + return 0; + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, AdjustFloorClip, AdjustFloorClip) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + AdjustFloorClip(self); + return 0; + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, PointInSector, P_PointInSectorXY) + { + PARAM_PROLOGUE; + PARAM_FLOAT(x); + PARAM_FLOAT(y); + ACTION_RETURN_POINTER(P_PointInSector(x, y)); + } + + static void SetXOffset(sector_t *self, int pos, double o) + { + self->SetXOffset(pos, o); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetXOffset, SetXOffset) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + PARAM_FLOAT(o); + self->SetXOffset(pos, o); + return 0; + } + + static void AddXOffset(sector_t *self, int pos, double o) + { + self->AddXOffset(pos, o); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, AddXOffset, AddXOffset) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + PARAM_FLOAT(o); + self->AddXOffset(pos, o); + return 0; + } + + static double GetXOffset(sector_t *self, int pos) + { + return self->GetXOffset(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetXOffset, GetXOffset) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_FLOAT(self->GetXOffset(pos)); + } + + static void SetYOffset(sector_t *self, int pos, double o) + { + self->SetYOffset(pos, o); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetYOffset, SetYOffset) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + PARAM_FLOAT(o); + self->SetXOffset(pos, o); + return 0; + } + + static void AddYOffset(sector_t *self, int pos, double o) + { + self->AddYOffset(pos, o); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, AddYOffset, AddYOffset) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + PARAM_FLOAT(o); + self->AddYOffset(pos, o); + return 0; + } + + static double GetYOffset(sector_t *self, int pos) + { + return self->GetYOffset(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetYOffset, GetYOffset) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + PARAM_BOOL(addbase); + ACTION_RETURN_FLOAT(self->GetYOffset(pos, addbase)); + } + + static void SetXScale(sector_t *self, int pos, double o) + { + self->SetXScale(pos, o); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetXScale, SetXScale) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + PARAM_FLOAT(o); + self->SetXScale(pos, o); + return 0; + } + + static double GetXScale(sector_t *self, int pos) + { + return self->GetXScale(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetXScale, GetXScale) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_FLOAT(self->GetXScale(pos)); + } + + static void SetYScale(sector_t *self, int pos, double o) + { + self->SetYScale(pos, o); + } + + DEFINE_ACTION_FUNCTION(_Sector, SetYScale) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + PARAM_FLOAT(o); + self->SetYScale(pos, o); + return 0; + } + + static double GetYScale(sector_t *self, int pos) + { + return self->GetYScale(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetYScale, GetYScale) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_FLOAT(self->GetYScale(pos)); + } + + static void SetAngle(sector_t *self, int pos, double o) + { + self->SetAngle(pos, o); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetAngle, SetAngle) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + PARAM_ANGLE(o); + self->SetAngle(pos, o); + return 0; + } + + static double GetAngle(sector_t *self, int pos, bool addbase) + { + return self->GetAngle(pos, addbase).Degrees; + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetAngle, GetAngle) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + PARAM_BOOL(addbase); + ACTION_RETURN_FLOAT(self->GetAngle(pos, addbase).Degrees); + } + + static void SetBase(sector_t *self, int pos, double o, double a) + { + self->SetBase(pos, o, a); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetBase, SetBase) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + PARAM_FLOAT(o); + PARAM_ANGLE(a); + self->SetBase(pos, o, a); + return 0; + } + + static void SetAlpha(sector_t *self, int pos, double o) + { + self->SetAlpha(pos, o); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetAlpha, SetAlpha) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + PARAM_FLOAT(o); + self->SetAlpha(pos, o); + return 0; + } + + static double GetAlpha(sector_t *self, int pos) + { + return self->GetAlpha(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetAlpha, GetAlpha) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_FLOAT(self->GetAlpha(pos)); + } + + static int GetFlags(sector_t *self, int pos) + { + return self->GetFlags(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetFlags, GetFlags) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_INT(self->GetFlags(pos)); + } + + static int GetVisFlags(sector_t *self, int pos) + { + return self->GetVisFlags(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetVisFlags, GetVisFlags) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_INT(self->GetVisFlags(pos)); + } + + static void ChangeFlags(sector_t *self, int pos, int a, int o) + { + self->ChangeFlags(pos, a, o); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, ChangeFlags, ChangeFlags) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + PARAM_INT(a); + PARAM_INT(o); + self->ChangeFlags(pos, a, o); + return 0; + } + + static void SetPlaneLight(sector_t *self, int pos, int o) + { + self->SetPlaneLight(pos, o); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetPlaneLight, SetPlaneLight) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + PARAM_INT(o); + self->SetPlaneLight(pos, o); + return 0; + } + + static int GetPlaneLight(sector_t *self, int pos) + { + return self->GetPlaneLight(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetPlaneLight, GetPlaneLight) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_INT(self->GetPlaneLight(pos)); + } + + static void SetTexture(sector_t *self, int pos, int o, bool adj) + { + self->SetTexture(pos, FSetTextureID(o), adj); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetTexture, SetTexture) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + PARAM_INT(o); + PARAM_BOOL(adj); + self->SetTexture(pos, FSetTextureID(o), adj); + return 0; + } + + static int GetSectorTexture(sector_t *self, int pos) + { + return self->GetTexture(pos).GetIndex(); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetTexture, GetSectorTexture) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_INT(self->GetTexture(pos).GetIndex()); + } + + static void SetPlaneTexZ(sector_t *self, int pos, double o, bool) + { + self->SetPlaneTexZ(pos, o, true); // not setting 'dirty' here is a guaranteed cause for problems. + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetPlaneTexZ, SetPlaneTexZ) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + PARAM_FLOAT(o); + PARAM_BOOL(dirty); + self->SetPlaneTexZ(pos, o, true); // not setting 'dirty' here is a guaranteed cause for problems. + return 0; + } + + static double GetPlaneTexZ(sector_t *self, int pos) + { + return self->GetPlaneTexZ(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetPlaneTexZ, GetPlaneTexZ) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_FLOAT(self->GetPlaneTexZ(pos)); + } + + static void SetLightLevel(sector_t *self, int o) + { + self->SetLightLevel(o); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetLightLevel, SetLightLevel) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(o); + self->SetLightLevel(o); + return 0; + } + + static void ChangeLightLevel(sector_t *self, int o) + { + self->ChangeLightLevel(o); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, ChangeLightLevel, ChangeLightLevel) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(o); + self->ChangeLightLevel(o); + return 0; + } + + static int GetLightLevel(sector_t *self) + { + return self->GetLightLevel(); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetLightLevel, GetLightLevel) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + ACTION_RETURN_INT(self->GetLightLevel()); + } + + static int PortalBlocksView(sector_t *self, int pos) + { + return self->PortalBlocksView(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, PortalBlocksView, PortalBlocksView) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_BOOL(self->PortalBlocksView(pos)); + } + + static int PortalBlocksSight(sector_t *self, int pos) + { + return self->PortalBlocksSight(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, PortalBlocksSight, PortalBlocksSight) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_BOOL(self->PortalBlocksSight(pos)); + } + + static int PortalBlocksMovement(sector_t *self, int pos) + { + return self->PortalBlocksMovement(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, PortalBlocksMovement, PortalBlocksMovement) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_BOOL(self->PortalBlocksMovement(pos)); + } + + static int PortalBlocksSound(sector_t *self, int pos) + { + return self->PortalBlocksSound(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, PortalBlocksSound, PortalBlocksSound) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_BOOL(self->PortalBlocksSound(pos)); + } + + static int PortalIsLinked(sector_t *self, int pos) + { + return self->PortalIsLinked(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, PortalIsLinked, PortalIsLinked) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_BOOL(self->PortalIsLinked(pos)); + } + + static void ClearPortal(sector_t *self, int pos) + { + self->ClearPortal(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, ClearPortal, ClearPortal) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + self->ClearPortal(pos); + return 0; + } + + static double GetPortalPlaneZ(sector_t *self, int pos) + { + return self->GetPortalPlaneZ(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetPortalPlaneZ, GetPortalPlaneZ) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_FLOAT(self->GetPortalPlaneZ(pos)); + } + + static int GetPortalType(sector_t *self, int pos) + { + return self->GetPortalType(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetPortalType, GetPortalType) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_INT(self->GetPortalType(pos)); + } + + static int GetOppositePortalGroup(sector_t *self, int pos) + { + return self->GetOppositePortalGroup(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetOppositePortalGroup, GetOppositePortalGroup) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_INT(self->GetOppositePortalGroup(pos)); + } + + static double CenterFloor(sector_t *self) + { + return self->CenterFloor(); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, CenterFloor, CenterFloor) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + ACTION_RETURN_FLOAT(self->CenterFloor()); + } + + static double CenterCeiling(sector_t *self) + { + return self->CenterCeiling(); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, CenterCeiling, CenterCeiling) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + ACTION_RETURN_FLOAT(self->CenterCeiling()); + } + + static int SectorIndex(sector_t *self) + { + unsigned ndx = self->Index(); + if (ndx >= level.sectors.Size()) return -1; // This must not throw because it is the only means to check that the given pointer is valid. + return ndx; + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, Index, SectorIndex) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + ACTION_RETURN_INT(SectorIndex(self)); + } + + static void SetEnvironmentID(sector_t *self, int envnum) + { + level.Zones[self->ZoneNumber].Environment = S_FindEnvironment(envnum); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetEnvironmentID, SetEnvironmentID) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(envnum); + SetEnvironmentID(self, envnum); + return 0; + } + + static void SetEnvironment(sector_t *self, const FString &env) + { + level.Zones[self->ZoneNumber].Environment = S_FindEnvironment(env); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetEnvironment, SetEnvironment) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_STRING(env); + SetEnvironment(self, env); + return 0; + } + + static double GetGlowHeight(sector_t *self, int pos) + { + return self->GetGlowHeight(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetGlowHeight, GetGlowHeight) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_FLOAT(self->GetGlowHeight(pos)); + } + + static double GetGlowColor(sector_t *self, int pos) + { + return self->GetGlowColor(pos); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, GetGlowColor, GetGlowColor) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + ACTION_RETURN_INT(self->GetGlowColor(pos)); + } + + static void SetGlowHeight(sector_t *self, int pos, double o) + { + self->SetGlowHeight(pos, float(o)); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetGlowHeight, SetGlowHeight) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + PARAM_FLOAT(o); + self->SetGlowHeight(pos, float(o)); + return 0; + } + + static void SetGlowColor(sector_t *self, int pos, int o) + { + self->SetGlowColor(pos, o); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetGlowColor, SetGlowColor) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + PARAM_INT(pos); + PARAM_COLOR(o); + self->SetGlowColor(pos, o); + return 0; + } + + //=========================================================================== + // + // line_t exports + // + //=========================================================================== + + static int isLinePortal(line_t *self) + { + return self->isLinePortal(); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Line, isLinePortal, isLinePortal) + { + PARAM_SELF_STRUCT_PROLOGUE(line_t); + ACTION_RETURN_BOOL(self->isLinePortal()); + } + + static int isVisualPortal(line_t *self) + { + return self->isVisualPortal(); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Line, isVisualPortal, isVisualPortal) + { + PARAM_SELF_STRUCT_PROLOGUE(line_t); + ACTION_RETURN_BOOL(self->isVisualPortal()); + } + + static line_t *getPortalDestination(line_t *self) + { + return self->getPortalDestination(); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Line, getPortalDestination, getPortalDestination) + { + PARAM_SELF_STRUCT_PROLOGUE(line_t); + ACTION_RETURN_POINTER(self->getPortalDestination()); + } + + static int getPortalAlignment(line_t *self) + { + return self->getPortalAlignment(); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Line, getPortalAlignment, getPortalAlignment) + { + PARAM_SELF_STRUCT_PROLOGUE(line_t); + ACTION_RETURN_INT(self->getPortalAlignment()); + } + + static int LineIndex(line_t *self) + { + unsigned ndx = self->Index(); + if (ndx >= level.lines.Size()) + { + return -1; + } + return ndx; + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Line, Index, LineIndex) + { + PARAM_SELF_STRUCT_PROLOGUE(line_t); + ACTION_RETURN_INT(LineIndex(self)); + } + + //=========================================================================== + // + // + // + //=========================================================================== + + static int GetSideTexture(side_t *self, int which) + { + return self->GetTexture(which).GetIndex(); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Side, GetTexture, GetSideTexture) + { + PARAM_SELF_STRUCT_PROLOGUE(side_t); + PARAM_INT(which); + ACTION_RETURN_INT(self->GetTexture(which).GetIndex()); + } + + static void SetSideTexture(side_t *self, int which, int tex) + { + self->SetTexture(which, FSetTextureID(tex)); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Side, SetTexture, SetSideTexture) + { + PARAM_SELF_STRUCT_PROLOGUE(side_t); + PARAM_INT(which); + PARAM_INT(tex); + self->SetTexture(which, FSetTextureID(tex)); + return 0; + } + + static void SetTextureXOffset(side_t *self, int which, double ofs) + { + self->SetTextureXOffset(which, ofs); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Side, SetTextureXOffset, SetTextureXOffset) + { + PARAM_SELF_STRUCT_PROLOGUE(side_t); + PARAM_INT(which); + PARAM_FLOAT(ofs); + self->SetTextureXOffset(which, ofs); + return 0; + } + + static void AddTextureXOffset(side_t *self, int which, double ofs) + { + self->AddTextureXOffset(which, ofs); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Side, AddTextureXOffset, AddTextureXOffset) + { + PARAM_SELF_STRUCT_PROLOGUE(side_t); + PARAM_INT(which); + PARAM_FLOAT(ofs); + self->AddTextureXOffset(which, ofs); + return 0; + } + + static double GetTextureXOffset(side_t *self, int which) + { + return self->GetTextureXOffset(which); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Side, GetTextureXOffset, GetTextureXOffset) + { + PARAM_SELF_STRUCT_PROLOGUE(side_t); + PARAM_INT(which); + ACTION_RETURN_FLOAT(self->GetTextureXOffset(which)); + } + + static void SetTextureYOffset(side_t *self, int which, double ofs) + { + self->SetTextureYOffset(which, ofs); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Side, SetTextureYOffset, SetTextureYOffset) + { + PARAM_SELF_STRUCT_PROLOGUE(side_t); + PARAM_INT(which); + PARAM_FLOAT(ofs); + self->SetTextureYOffset(which, ofs); + return 0; + } + + static void AddTextureYOffset(side_t *self, int which, double ofs) + { + self->AddTextureYOffset(which, ofs); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Side, AddTextureYOffset, AddTextureYOffset) + { + PARAM_SELF_STRUCT_PROLOGUE(side_t); + PARAM_INT(which); + PARAM_FLOAT(ofs); + self->AddTextureYOffset(which, ofs); + return 0; + } + + static double GetTextureYOffset(side_t *self, int which) + { + return self->GetTextureYOffset(which); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Side, GetTextureYOffset, GetTextureYOffset) + { + PARAM_SELF_STRUCT_PROLOGUE(side_t); + PARAM_INT(which); + ACTION_RETURN_FLOAT(self->GetTextureYOffset(which)); + } + + static void SetTextureXScale(side_t *self, int which, double ofs) + { + self->SetTextureXScale(which, ofs); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Side, SetTextureXScale, SetTextureXScale) + { + PARAM_SELF_STRUCT_PROLOGUE(side_t); + PARAM_INT(which); + PARAM_FLOAT(ofs); + self->SetTextureXScale(which, ofs); + return 0; + } + + static void MultiplyTextureXScale(side_t *self, int which, double ofs) + { + self->MultiplyTextureXScale(which, ofs); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Side, MultiplyTextureXScale, MultiplyTextureXScale) + { + PARAM_SELF_STRUCT_PROLOGUE(side_t); + PARAM_INT(which); + PARAM_FLOAT(ofs); + self->MultiplyTextureXScale(which, ofs); + return 0; + } + + static double GetTextureXScale(side_t *self, int which) + { + return self->GetTextureXScale(which); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Side, GetTextureXScale, GetTextureXScale) + { + PARAM_SELF_STRUCT_PROLOGUE(side_t); + PARAM_INT(which); + ACTION_RETURN_FLOAT(self->GetTextureXScale(which)); + } + + static void SetTextureYScale(side_t *self, int which, double ofs) + { + self->SetTextureYScale(which, ofs); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Side, SetTextureYScale, SetTextureYScale) + { + PARAM_SELF_STRUCT_PROLOGUE(side_t); + PARAM_INT(which); + PARAM_FLOAT(ofs); + self->SetTextureYScale(which, ofs); + return 0; + } + + static void MultiplyTextureYScale(side_t *self, int which, double ofs) + { + self->MultiplyTextureYScale(which, ofs); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Side, MultiplyTextureYScale, MultiplyTextureYScale) + { + PARAM_SELF_STRUCT_PROLOGUE(side_t); + PARAM_INT(which); + PARAM_FLOAT(ofs); + self->MultiplyTextureYScale(which, ofs); + return 0; + } + + static double GetTextureYScale(side_t *self, int which) + { + return self->GetTextureYScale(which); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Side, GetTextureYScale, GetTextureYScale) + { + PARAM_SELF_STRUCT_PROLOGUE(side_t); + PARAM_INT(which); + ACTION_RETURN_FLOAT(self->GetTextureYScale(which)); + } + + static vertex_t *GetSideV1(side_t *self) + { + return self->V1(); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Side, V1, GetSideV1) + { + PARAM_SELF_STRUCT_PROLOGUE(side_t); + ACTION_RETURN_POINTER(self->V1()); + } + + static vertex_t *GetSideV2(side_t *self) + { + return self->V2(); + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Side, V2, GetSideV2) + { + PARAM_SELF_STRUCT_PROLOGUE(side_t); + ACTION_RETURN_POINTER(self->V2()); + } + + static void SetSideSpecialColor(side_t *self, int tier, int position, int color) + { + if (tier >= 0 && tier < 3 && position >= 0 && position < 2) + { + self->SetSpecialColor(tier, position, color); + } + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Side, SetSpecialColor, SetSideSpecialColor) + { + PARAM_SELF_STRUCT_PROLOGUE(side_t); + PARAM_INT(tier); + PARAM_INT(position); + PARAM_COLOR(color); + SetSideSpecialColor(self, tier, position, color); + return 0; + } + + static int SideIndex(side_t *self) + { + unsigned ndx = self->Index(); + if (ndx >= level.sides.Size()) + { + return -1; + } + return ndx; + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Side, Index, SideIndex) + { + PARAM_SELF_STRUCT_PROLOGUE(side_t); + ACTION_RETURN_INT(SideIndex(self)); + } + + //===================================================================================== +// +// +//===================================================================================== + + static int VertexIndex(vertex_t *self) + { + unsigned ndx = self->Index(); + if (ndx >= level.vertexes.Size()) + { + return -1; + } + return ndx; + } + + DEFINE_ACTION_FUNCTION_NATIVE(_Vertex, Index, VertexIndex) + { + PARAM_SELF_STRUCT_PROLOGUE(vertex_t); + ACTION_RETURN_INT(VertexIndex(self)); + } + + // This is needed to convert the strings to char pointers. + static void ReplaceTextures(const FString &from, const FString &to, int flags) + { + P_ReplaceTextures(from, to, flags); + } + +DEFINE_ACTION_FUNCTION_NATIVE(_TexMan, ReplaceTextures, ReplaceTextures) +{ + PARAM_PROLOGUE; + PARAM_STRING(from); + PARAM_STRING(to); + PARAM_INT(flags); + P_ReplaceTextures(from, to, flags); + return 0; +} + +//===================================================================================== +// +// +//===================================================================================== + +static int isSlope(secplane_t *self) +{ + return !self->normal.XY().isZero(); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Secplane, isSlope, isSlope) +{ + PARAM_SELF_STRUCT_PROLOGUE(secplane_t); + ACTION_RETURN_BOOL(!self->normal.XY().isZero()); +} + +static int PointOnSide(const secplane_t *self, double x, double y, double z) +{ + return self->PointOnSide(DVector3(x, y, z)); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Secplane, PointOnSide, PointOnSide) +{ + PARAM_SELF_STRUCT_PROLOGUE(secplane_t); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + PARAM_FLOAT(z); + ACTION_RETURN_INT(self->PointOnSide(DVector3(x, y, z))); +} + +static double ZatPoint(const secplane_t *self, double x, double y) +{ + return self->ZatPoint(x, y); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Secplane, ZatPoint, ZatPoint) +{ + PARAM_SELF_STRUCT_PROLOGUE(secplane_t); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + ACTION_RETURN_FLOAT(self->ZatPoint(x, y)); +} + +static double ZatPointDist(const secplane_t *self, double x, double y, double d) +{ + return (d + self->normal.X*x + self->normal.Y*y) * self->negiC; +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Secplane, ZatPointDist, ZatPointDist) +{ + PARAM_SELF_STRUCT_PROLOGUE(secplane_t); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + PARAM_FLOAT(d); + ACTION_RETURN_FLOAT(ZatPointDist(self, x, y, d)); +} + +static int isPlaneEqual(const secplane_t *self, const secplane_t *other) +{ + return *self == *other; +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Secplane, isEqual, isPlaneEqual) +{ + PARAM_SELF_STRUCT_PROLOGUE(secplane_t); + PARAM_POINTER(other, secplane_t); + ACTION_RETURN_BOOL(*self == *other); +} + +static void ChangeHeight(secplane_t *self, double hdiff) +{ + self->ChangeHeight(hdiff); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Secplane, ChangeHeight, ChangeHeight) +{ + PARAM_SELF_STRUCT_PROLOGUE(secplane_t); + PARAM_FLOAT(hdiff); + self->ChangeHeight(hdiff); + return 0; +} + +static double GetChangedHeight(const secplane_t *self, double hdiff) +{ + return self->GetChangedHeight(hdiff); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Secplane, GetChangedHeight, GetChangedHeight) +{ + PARAM_SELF_STRUCT_PROLOGUE(secplane_t); + PARAM_FLOAT(hdiff); + ACTION_RETURN_FLOAT(self->GetChangedHeight(hdiff)); +} + +static double HeightDiff(const secplane_t *self, double oldd, double newd) +{ + if (newd != 1e37) + { + return self->HeightDiff(oldd); + } + else + { + return self->HeightDiff(oldd, newd); + } +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Secplane, HeightDiff, HeightDiff) +{ + PARAM_SELF_STRUCT_PROLOGUE(secplane_t); + PARAM_FLOAT(oldd); + PARAM_FLOAT(newd); + ACTION_RETURN_FLOAT(HeightDiff(self, oldd, newd)); +} + +static double PointToDist(const secplane_t *self, double x, double y, double z) +{ + return self->PointToDist(DVector2(x, y), z); +} + + +DEFINE_ACTION_FUNCTION_NATIVE(_Secplane, PointToDist, PointToDist) +{ + PARAM_SELF_STRUCT_PROLOGUE(secplane_t); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + PARAM_FLOAT(z); + ACTION_RETURN_FLOAT(self->PointToDist(DVector2(x, y), z)); +} + +DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_PlaySound, A_PlaySound) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_SOUND(soundid); + PARAM_INT(channel); + PARAM_FLOAT(volume); + PARAM_BOOL(looping); + PARAM_FLOAT(attenuation); + PARAM_BOOL(local); + A_PlaySound(self, soundid, channel, volume, looping, attenuation, local); + return 0; +} diff --git a/src/serializer.cpp b/src/serializer.cpp index fe8864a337..e0f74420f1 100644 --- a/src/serializer.cpp +++ b/src/serializer.cpp @@ -1586,17 +1586,13 @@ FSerializer &Serialize(FSerializer &arc, const char *key, DObject *&value, DObje if (retcode) *retcode = true; if (arc.isWriting()) { - if (value != nullptr) + if (value != nullptr && !(value->ObjectFlags & (OF_EuthanizeMe | OF_Transient))) { int ndx; if (value == WP_NOCHANGE) { ndx = -1; } - else if (value->ObjectFlags & (OF_EuthanizeMe | OF_Transient)) - { - return arc; - } else { int *pndx = arc.w->mObjectMap.CheckKey(value); diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index c5fe1da0af..5d9ec105b5 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -1423,6 +1423,24 @@ TXT_QUIETUS_PIECE = "SEGMENT OF QUIETUS"; TXT_WRAITHVERGE_PIECE = "SEGMENT OF WRAITHVERGE"; TXT_BLOODSCOURGE_PIECE = "SEGMENT OF BLOODSCOURGE"; +// Friendly names + +FN_FIREDEMON = "Afrit"; +FN_DEMON1 = "Serpent"; +FN_ETTIN = "Ettin"; +FN_CENTAUR = "Centaur"; +FN_SLAUGHTAUR = "Slaughtaur"; +FN_BISHOP = "Bishop"; +FN_ICEGUY = "Wendigo"; +FN_SERPENT = "Stalker"; +FN_WRAITH = "Reiver"; +FN_DRAGON = "Death Wyvern"; +FN_KORAX = "Korax"; +FN_FBOSS = "Zedek"; +FN_MBOSS = "Menelkir"; +FN_CBOSS = "Traductus"; +FN_HERESIARCH = "Heresiarch"; + // Strife locks TXT_NEEDKEY = "You don't have the key"; diff --git a/wadsrc/static/sprites/tnt1a0.png b/wadsrc/static/sprites/tnt1a0.lmp similarity index 100% rename from wadsrc/static/sprites/tnt1a0.png rename to wadsrc/static/sprites/tnt1a0.lmp diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 3aec2fef7b..5ec8cf4859 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -366,6 +366,7 @@ struct GameInfoStruct native native double gibfactor; native bool intermissioncounter; native Name mSliderColor; + native Color defaultbloodcolor; native double telefogheight; native int defKickback; } @@ -374,6 +375,15 @@ class Object native { native bool bDestroyed; + // These must be defined in some class, so that the compiler can find them. Object is just fine, as long as they are private to external code. + private native static int BuiltinRandom(voidptr rng, int min, int max); + private native static double BuiltinFRandom(voidptr rng, double min, double max); + private native static int BuiltinRandom2(voidptr rng, int mask); + private native static void BuiltinRandomSeed(voidptr rng, int seed); + private native static int BuiltinCallLineSpecial(int special, Actor activator, int arg1, int arg2, int arg3, int arg4, int arg5); + private native static Class BuiltinNameToClass(Name nm, Class filter); + private native static Object BuiltinClassCast(Object inptr, Class test); + // These really should be global functions... native static String G_SkillName(); native static int G_SkillPropertyInt(int p); diff --git a/wadsrc/static/zscript/hexen/bishop.txt b/wadsrc/static/zscript/hexen/bishop.txt index 4fd0cde411..63b0168b5b 100644 --- a/wadsrc/static/zscript/hexen/bishop.txt +++ b/wadsrc/static/zscript/hexen/bishop.txt @@ -24,6 +24,7 @@ class Bishop : Actor DeathSound "BishopDeath"; ActiveSound "BishopActiveSounds"; Obituary"$OB_BISHOP"; + Tag "$FN_BISHOP"; } States diff --git a/wadsrc/static/zscript/hexen/centaur.txt b/wadsrc/static/zscript/hexen/centaur.txt index 8cd5639a21..4be9860ee9 100644 --- a/wadsrc/static/zscript/hexen/centaur.txt +++ b/wadsrc/static/zscript/hexen/centaur.txt @@ -21,6 +21,7 @@ class Centaur : Actor HowlSound "PuppyBeat"; Obituary "$OB_CENTAUR"; DamageFactor "Electric", 3; + Tag "$FN_CENTAUR"; } States { @@ -107,6 +108,7 @@ class CentaurLeader : Centaur Speed 10; Obituary "$OB_SLAUGHTAUR"; HitObituary "$OB_SLAUGHTAURHIT"; + Tag "$FN_SLAUGHTAUR"; } States { diff --git a/wadsrc/static/zscript/hexen/clericboss.txt b/wadsrc/static/zscript/hexen/clericboss.txt index 4bf2235171..a472c1ac4c 100644 --- a/wadsrc/static/zscript/hexen/clericboss.txt +++ b/wadsrc/static/zscript/hexen/clericboss.txt @@ -15,7 +15,8 @@ class ClericBoss : Actor +DONTMORPH PainSound "PlayerClericPain"; DeathSound "PlayerClericCrazyDeath"; - Obituary "$OBCBOSS"; + Obituary "$OB_CBOSS"; + Tag "$FN_CBOSS"; } States diff --git a/wadsrc/static/zscript/hexen/demons.txt b/wadsrc/static/zscript/hexen/demons.txt index 778bb957ee..08f81b2a81 100644 --- a/wadsrc/static/zscript/hexen/demons.txt +++ b/wadsrc/static/zscript/hexen/demons.txt @@ -20,6 +20,7 @@ class Demon1 : Actor DeathSound "DemonDeath"; ActiveSound "DemonActive"; Obituary "$OB_DEMON1"; + Tag "$FN_DEMON1"; } const ChunkFlags = SXF_TRANSFERTRANSLATION | SXF_ABSOLUTEVELOCITY; diff --git a/wadsrc/static/zscript/hexen/dragon.txt b/wadsrc/static/zscript/hexen/dragon.txt index 5eafb3201c..bf5d91b169 100644 --- a/wadsrc/static/zscript/hexen/dragon.txt +++ b/wadsrc/static/zscript/hexen/dragon.txt @@ -19,6 +19,7 @@ class Dragon : Actor DeathSound "DragonDeath"; ActiveSound "DragonActive"; Obituary "$OB_DRAGON"; + Tag "$FN_DRAGON"; } States diff --git a/wadsrc/static/zscript/hexen/ettin.txt b/wadsrc/static/zscript/hexen/ettin.txt index 8ddf9e7d2c..6650c6a412 100644 --- a/wadsrc/static/zscript/hexen/ettin.txt +++ b/wadsrc/static/zscript/hexen/ettin.txt @@ -22,6 +22,7 @@ class Ettin : Actor ActiveSound "EttinActive"; HowlSound "PuppyBeat"; Obituary "$OB_ETTIN"; + Tag "$FN_ETTIN"; } States { diff --git a/wadsrc/static/zscript/hexen/fighterboss.txt b/wadsrc/static/zscript/hexen/fighterboss.txt index 9871cf5717..6ff4c90b1e 100644 --- a/wadsrc/static/zscript/hexen/fighterboss.txt +++ b/wadsrc/static/zscript/hexen/fighterboss.txt @@ -17,6 +17,7 @@ class FighterBoss : Actor PainSound "PlayerFighterPain"; DeathSound "PlayerFighterCrazyDeath"; Obituary "$OB_FBOSS"; + Tag "$FN_FBOSS"; } States diff --git a/wadsrc/static/zscript/hexen/firedemon.txt b/wadsrc/static/zscript/hexen/firedemon.txt index e101564021..5ea5e27bde 100644 --- a/wadsrc/static/zscript/hexen/firedemon.txt +++ b/wadsrc/static/zscript/hexen/firedemon.txt @@ -24,6 +24,7 @@ class FireDemon : Actor DeathSound "FireDemonDeath"; ActiveSound "FireDemonActive"; Obituary "$OB_FIREDEMON"; + Tag "$FN_FIREDEMON"; } States diff --git a/wadsrc/static/zscript/hexen/heresiarch.txt b/wadsrc/static/zscript/hexen/heresiarch.txt index cd55021776..d7888ccfde 100644 --- a/wadsrc/static/zscript/hexen/heresiarch.txt +++ b/wadsrc/static/zscript/hexen/heresiarch.txt @@ -70,6 +70,7 @@ class Heresiarch : Actor DeathSound "SorcererDeathScream"; ActiveSound "SorcererActive"; Obituary "$OB_HERESIARCH"; + Tag "$FN_HERESIARCH"; } States diff --git a/wadsrc/static/zscript/hexen/hexendecorations.txt b/wadsrc/static/zscript/hexen/hexendecorations.txt index 937034bd88..2d33241686 100644 --- a/wadsrc/static/zscript/hexen/hexendecorations.txt +++ b/wadsrc/static/zscript/hexen/hexendecorations.txt @@ -65,6 +65,7 @@ class ZRock4 : Actor { Radius 20; Height 16; + +SOLID } States { diff --git a/wadsrc/static/zscript/hexen/iceguy.txt b/wadsrc/static/zscript/hexen/iceguy.txt index 41105b728e..4a293b94ec 100644 --- a/wadsrc/static/zscript/hexen/iceguy.txt +++ b/wadsrc/static/zscript/hexen/iceguy.txt @@ -20,6 +20,7 @@ class IceGuy : Actor AttackSound "IceGuyAttack"; ActiveSound "IceGuyActive"; Obituary "$OB_ICEGUY"; + Tag "$FN_ICEGUY"; } diff --git a/wadsrc/static/zscript/hexen/korax.txt b/wadsrc/static/zscript/hexen/korax.txt index b94664bea9..316bba1d22 100644 --- a/wadsrc/static/zscript/hexen/korax.txt +++ b/wadsrc/static/zscript/hexen/korax.txt @@ -60,6 +60,7 @@ class Korax : Actor DeathSound "KoraxDeath"; ActiveSound "KoraxActive"; Obituary "$OB_KORAX"; + Tag "$FN_KORAX"; } States diff --git a/wadsrc/static/zscript/hexen/mageboss.txt b/wadsrc/static/zscript/hexen/mageboss.txt index 0c081d786d..eea86e33ea 100644 --- a/wadsrc/static/zscript/hexen/mageboss.txt +++ b/wadsrc/static/zscript/hexen/mageboss.txt @@ -16,6 +16,7 @@ class MageBoss : Actor PainSound "PlayerMagePain"; DeathSound "PlayerMageCrazyDeath"; Obituary "$OB_MBOSS"; + Tag "$FN_MBOSS"; } States diff --git a/wadsrc/static/zscript/hexen/serpent.txt b/wadsrc/static/zscript/hexen/serpent.txt index 3ebf5aad21..9d68263811 100644 --- a/wadsrc/static/zscript/hexen/serpent.txt +++ b/wadsrc/static/zscript/hexen/serpent.txt @@ -22,6 +22,7 @@ class Serpent : Actor PainSound "SerpentPain"; DeathSound "SerpentDeath"; HitObituary "$OB_SERPENTHIT"; + Tag "$FN_SERPENT"; } States diff --git a/wadsrc/static/zscript/hexen/wraith.txt b/wadsrc/static/zscript/hexen/wraith.txt index 4b90dc4f68..ad4d00db62 100644 --- a/wadsrc/static/zscript/hexen/wraith.txt +++ b/wadsrc/static/zscript/hexen/wraith.txt @@ -21,6 +21,7 @@ class Wraith : Actor ActiveSound "WraithActive"; HitObituary "$OB_WRAITHHIT"; Obituary "$OB_WRAITH"; + Tag "$FN_WRAITH"; } States