mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 22:11:43 +00:00
Merge branch 'asmjit' into weapon_scriptification
# Conflicts: # src/gi.cpp # wadsrc/static/zscript/base.txt
This commit is contained in:
commit
47b1fa774d
51 changed files with 1825 additions and 1255 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
|
||||
#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")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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<typename ModeT, typename OptT>
|
||||
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<fixed_t>(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<fixed_t>(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<uint32_t>(lit_r, 255);
|
||||
lit_g = MIN<uint32_t>(lit_g, 255);
|
||||
lit_b = MIN<uint32_t>(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++)
|
||||
if (OptT::Flags & SWOPT_FixedLight)
|
||||
{
|
||||
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];
|
||||
}
|
||||
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
|
||||
else if (ModeT::SWFlags & SWSTYLEF_Translated)
|
||||
{
|
||||
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]];
|
||||
fg = translation[((const uint8_t*)texPixels)[texel[x]]];
|
||||
}
|
||||
else if (ModeT::Flags & STYLEF_RedIsAlpha)
|
||||
{
|
||||
fg = ((const uint8_t*)texPixels)[texelX * texHeight + texelY];
|
||||
fg = ((const uint8_t*)texPixels)[texel[x]];
|
||||
}
|
||||
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<typename ModeT>
|
||||
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<ModeT, DrawerOpt>(y, x0, x1, args);
|
||||
DrawSpanOpt32<ModeT, DrawerOpt>(y, x0, x1, args, thread);
|
||||
else
|
||||
DrawSpanOpt32<ModeT, DrawerOptC>(y, x0, x1, args);
|
||||
DrawSpanOpt32<ModeT, DrawerOptC>(y, x0, x1, args, thread);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (args->uniforms->SimpleShade())
|
||||
DrawSpanOpt32<ModeT, DrawerOptF>(y, x0, x1, args);
|
||||
DrawSpanOpt32<ModeT, DrawerOptF>(y, x0, x1, args, thread);
|
||||
else
|
||||
DrawSpanOpt32<ModeT, DrawerOptCF>(y, x0, x1, args);
|
||||
DrawSpanOpt32<ModeT, DrawerOptCF>(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<ModeT, DrawerOptL>(y, x0, x1, args);
|
||||
DrawSpanOpt32<ModeT, DrawerOptL>(y, x0, x1, args, thread);
|
||||
else
|
||||
DrawSpanOpt32<ModeT, DrawerOptLC>(y, x0, x1, args);
|
||||
DrawSpanOpt32<ModeT, DrawerOptLC>(y, x0, x1, args, thread);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (args->uniforms->SimpleShade())
|
||||
DrawSpanOpt32<ModeT, DrawerOptLF>(y, x0, x1, args);
|
||||
DrawSpanOpt32<ModeT, DrawerOptLF>(y, x0, x1, args, thread);
|
||||
else
|
||||
DrawSpanOpt32<ModeT, DrawerOptLCF>(y, x0, x1, args);
|
||||
DrawSpanOpt32<ModeT, DrawerOptLCF>(y, x0, x1, args, thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ModeT, typename OptT>
|
||||
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<typename ModeT>
|
||||
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<ModeT, DrawerOptC>(y, x0, x1, args);
|
||||
DrawSpanOpt8<ModeT, DrawerOptC>(y, x0, x1, args, thread);
|
||||
else
|
||||
DrawSpanOpt8<ModeT, DrawerOptCF>(y, x0, x1, args);
|
||||
DrawSpanOpt8<ModeT, DrawerOptCF>(y, x0, x1, args, thread);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!args->uniforms->FixedLight())
|
||||
DrawSpanOpt8<ModeT, DrawerOptLC>(y, x0, x1, args);
|
||||
DrawSpanOpt8<ModeT, DrawerOptLC>(y, x0, x1, args, thread);
|
||||
else
|
||||
DrawSpanOpt8<ModeT, DrawerOptLCF>(y, x0, x1, args);
|
||||
DrawSpanOpt8<ModeT, DrawerOptLCF>(y, x0, x1, args, thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2049,7 +2057,7 @@ void DrawRect32(const void *destOrg, int destWidth, int destHeight, int destPitc
|
|||
DrawRectOpt32<ModeT, DrawerOptCF>(destOrg, destWidth, destHeight, destPitch, args, thread);
|
||||
}
|
||||
|
||||
void(*ScreenTriangle::SpanDrawers8[])(int, int, int, const TriDrawTriangleArgs *) =
|
||||
void(*ScreenTriangle::SpanDrawers8[])(int, int, int, const TriDrawTriangleArgs *, PolyTriangleThreadData *) =
|
||||
{
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleOpaque>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleSkycap>,
|
||||
|
@ -2081,7 +2089,7 @@ void(*ScreenTriangle::SpanDrawers8[])(int, int, int, const TriDrawTriangleArgs *
|
|||
&DrawSpan8<TriScreenDrawerModes::StyleAddShadedTranslated>
|
||||
};
|
||||
|
||||
void(*ScreenTriangle::SpanDrawers32[])(int, int, int, const TriDrawTriangleArgs *) =
|
||||
void(*ScreenTriangle::SpanDrawers32[])(int, int, int, const TriDrawTriangleArgs *, PolyTriangleThreadData *) =
|
||||
{
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleOpaque>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleSkycap>,
|
||||
|
|
|
@ -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 *);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
50
src/r_defs.h
50
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,10 +638,11 @@ 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;
|
||||
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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<PSymbolVMFunction>(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<PFunction>(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);
|
||||
|
|
|
@ -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)
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -9,6 +9,7 @@ extern PStruct *TypeVector3;
|
|||
static void OutputJitLog(const asmjit::StringLogger &logger);
|
||||
|
||||
static TArray<uint8_t*> JitBlocks;
|
||||
static TArray<uint8_t*> 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<uint16_t> 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
|
||||
|
|
|
@ -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<void*>::kTypeId);
|
||||
key += "v";
|
||||
|
|
|
@ -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<void*>(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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
1267
src/scripting/vmthunks.cpp
Normal file
1267
src/scripting/vmthunks.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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<Object> BuiltinNameToClass(Name nm, Class<Object> filter);
|
||||
private native static Object BuiltinClassCast(Object inptr, Class<Object> test);
|
||||
|
||||
// These really should be global functions...
|
||||
native static String G_SkillName();
|
||||
native static int G_SkillPropertyInt(int p);
|
||||
|
|
|
@ -24,6 +24,7 @@ class Bishop : Actor
|
|||
DeathSound "BishopDeath";
|
||||
ActiveSound "BishopActiveSounds";
|
||||
Obituary"$OB_BISHOP";
|
||||
Tag "$FN_BISHOP";
|
||||
}
|
||||
|
||||
States
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -15,7 +15,8 @@ class ClericBoss : Actor
|
|||
+DONTMORPH
|
||||
PainSound "PlayerClericPain";
|
||||
DeathSound "PlayerClericCrazyDeath";
|
||||
Obituary "$OBCBOSS";
|
||||
Obituary "$OB_CBOSS";
|
||||
Tag "$FN_CBOSS";
|
||||
}
|
||||
|
||||
States
|
||||
|
|
|
@ -20,6 +20,7 @@ class Demon1 : Actor
|
|||
DeathSound "DemonDeath";
|
||||
ActiveSound "DemonActive";
|
||||
Obituary "$OB_DEMON1";
|
||||
Tag "$FN_DEMON1";
|
||||
}
|
||||
|
||||
const ChunkFlags = SXF_TRANSFERTRANSLATION | SXF_ABSOLUTEVELOCITY;
|
||||
|
|
|
@ -19,6 +19,7 @@ class Dragon : Actor
|
|||
DeathSound "DragonDeath";
|
||||
ActiveSound "DragonActive";
|
||||
Obituary "$OB_DRAGON";
|
||||
Tag "$FN_DRAGON";
|
||||
}
|
||||
|
||||
States
|
||||
|
|
|
@ -22,6 +22,7 @@ class Ettin : Actor
|
|||
ActiveSound "EttinActive";
|
||||
HowlSound "PuppyBeat";
|
||||
Obituary "$OB_ETTIN";
|
||||
Tag "$FN_ETTIN";
|
||||
}
|
||||
States
|
||||
{
|
||||
|
|
|
@ -17,6 +17,7 @@ class FighterBoss : Actor
|
|||
PainSound "PlayerFighterPain";
|
||||
DeathSound "PlayerFighterCrazyDeath";
|
||||
Obituary "$OB_FBOSS";
|
||||
Tag "$FN_FBOSS";
|
||||
}
|
||||
|
||||
States
|
||||
|
|
|
@ -24,6 +24,7 @@ class FireDemon : Actor
|
|||
DeathSound "FireDemonDeath";
|
||||
ActiveSound "FireDemonActive";
|
||||
Obituary "$OB_FIREDEMON";
|
||||
Tag "$FN_FIREDEMON";
|
||||
}
|
||||
|
||||
States
|
||||
|
|
|
@ -70,6 +70,7 @@ class Heresiarch : Actor
|
|||
DeathSound "SorcererDeathScream";
|
||||
ActiveSound "SorcererActive";
|
||||
Obituary "$OB_HERESIARCH";
|
||||
Tag "$FN_HERESIARCH";
|
||||
}
|
||||
|
||||
States
|
||||
|
|
|
@ -65,6 +65,7 @@ class ZRock4 : Actor
|
|||
{
|
||||
Radius 20;
|
||||
Height 16;
|
||||
+SOLID
|
||||
}
|
||||
States
|
||||
{
|
||||
|
|
|
@ -20,6 +20,7 @@ class IceGuy : Actor
|
|||
AttackSound "IceGuyAttack";
|
||||
ActiveSound "IceGuyActive";
|
||||
Obituary "$OB_ICEGUY";
|
||||
Tag "$FN_ICEGUY";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ class Korax : Actor
|
|||
DeathSound "KoraxDeath";
|
||||
ActiveSound "KoraxActive";
|
||||
Obituary "$OB_KORAX";
|
||||
Tag "$FN_KORAX";
|
||||
}
|
||||
|
||||
States
|
||||
|
|
|
@ -16,6 +16,7 @@ class MageBoss : Actor
|
|||
PainSound "PlayerMagePain";
|
||||
DeathSound "PlayerMageCrazyDeath";
|
||||
Obituary "$OB_MBOSS";
|
||||
Tag "$FN_MBOSS";
|
||||
}
|
||||
|
||||
States
|
||||
|
|
|
@ -22,6 +22,7 @@ class Serpent : Actor
|
|||
PainSound "SerpentPain";
|
||||
DeathSound "SerpentDeath";
|
||||
HitObituary "$OB_SERPENTHIT";
|
||||
Tag "$FN_SERPENT";
|
||||
}
|
||||
|
||||
States
|
||||
|
|
|
@ -21,6 +21,7 @@ class Wraith : Actor
|
|||
ActiveSound "WraithActive";
|
||||
HitObituary "$OB_WRAITHHIT";
|
||||
Obituary "$OB_WRAITH";
|
||||
Tag "$FN_WRAITH";
|
||||
}
|
||||
|
||||
States
|
||||
|
|
Loading…
Reference in a new issue