mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 23:01:50 +00:00
Merge remote-tracking branch 'remotes/origin/master' into asmjit
This commit is contained in:
commit
8e46cb3a21
30 changed files with 320 additions and 351 deletions
|
@ -814,7 +814,8 @@ public:
|
||||||
virtual bool Massacre ();
|
virtual bool Massacre ();
|
||||||
|
|
||||||
// Transforms the actor into a finely-ground paste
|
// Transforms the actor into a finely-ground paste
|
||||||
virtual bool Grind(bool items);
|
bool Grind(bool items);
|
||||||
|
bool CallGrind(bool items);
|
||||||
|
|
||||||
// Get this actor's team
|
// Get this actor's team
|
||||||
int GetTeam();
|
int GetTeam();
|
||||||
|
|
|
@ -173,33 +173,6 @@ void AInventory::MarkPrecacheSounds() const
|
||||||
PickupSound.MarkUsed();
|
PickupSound.MarkUsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// AInventory :: Grind
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
bool AInventory::Grind(bool items)
|
|
||||||
{
|
|
||||||
// Does this grind request even care about items?
|
|
||||||
if (!items)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Dropped items are normally destroyed by crushers. Set the DONTGIB flag,
|
|
||||||
// and they'll act like corpses with it set and be immune to crushers.
|
|
||||||
if (flags & MF_DROPPED)
|
|
||||||
{
|
|
||||||
if (!(flags3 & MF3_DONTGIB))
|
|
||||||
{
|
|
||||||
Destroy();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Non-dropped items call the super method for compatibility.
|
|
||||||
return Super::Grind(items);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// AInventory :: BecomeItem
|
// AInventory :: BecomeItem
|
||||||
|
|
|
@ -76,7 +76,6 @@ public:
|
||||||
virtual void OnDestroy() override;
|
virtual void OnDestroy() override;
|
||||||
virtual void Tick() override;
|
virtual void Tick() override;
|
||||||
virtual bool Massacre() override;
|
virtual bool Massacre() override;
|
||||||
virtual bool Grind(bool items) override;
|
|
||||||
|
|
||||||
bool CallTryPickup(AActor *toucher, AActor **toucher_return = NULL); // Wrapper for script function.
|
bool CallTryPickup(AActor *toucher, AActor **toucher_return = NULL); // Wrapper for script function.
|
||||||
|
|
||||||
|
|
|
@ -52,35 +52,11 @@ static void CollectExtensions()
|
||||||
int max = 0;
|
int max = 0;
|
||||||
glGetIntegerv(GL_NUM_EXTENSIONS, &max);
|
glGetIntegerv(GL_NUM_EXTENSIONS, &max);
|
||||||
|
|
||||||
if (max == 0)
|
// Use modern method to collect extensions
|
||||||
|
for (int i = 0; i < max; i++)
|
||||||
{
|
{
|
||||||
// Try old method to collect extensions
|
extension = (const char*)glGetStringi(GL_EXTENSIONS, i);
|
||||||
const char *supported = (char *)glGetString(GL_EXTENSIONS);
|
m_Extensions.Push(FString(extension));
|
||||||
|
|
||||||
if (nullptr != supported)
|
|
||||||
{
|
|
||||||
char *extensions = new char[strlen(supported) + 1];
|
|
||||||
strcpy(extensions, supported);
|
|
||||||
|
|
||||||
char *extension = strtok(extensions, " ");
|
|
||||||
|
|
||||||
while (extension)
|
|
||||||
{
|
|
||||||
m_Extensions.Push(FString(extension));
|
|
||||||
extension = strtok(nullptr, " ");
|
|
||||||
}
|
|
||||||
|
|
||||||
delete [] extensions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Use modern method to collect extensions
|
|
||||||
for (int i = 0; i < max; i++)
|
|
||||||
{
|
|
||||||
extension = (const char*)glGetStringi(GL_EXTENSIONS, i);
|
|
||||||
m_Extensions.Push(FString(extension));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,4 +245,4 @@ std::pair<double, bool> gl_getInfo()
|
||||||
// gl_ARB_bindless_texture is the closest we can get to determine Vulkan support from OpenGL.
|
// gl_ARB_bindless_texture is the closest we can get to determine Vulkan support from OpenGL.
|
||||||
// This isn't foolproof because Intel doesn't support it but for NVidia and AMD support of this extension means Vulkan support.
|
// This isn't foolproof because Intel doesn't support it but for NVidia and AMD support of this extension means Vulkan support.
|
||||||
return std::make_pair(realglversion, CheckExtension("GL_ARB_bindless_texture"));
|
return std::make_pair(realglversion, CheckExtension("GL_ARB_bindless_texture"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -6485,7 +6485,7 @@ void P_FindBelowIntersectors(AActor *actor)
|
||||||
|
|
||||||
void P_DoCrunch(AActor *thing, FChangePosition *cpos)
|
void P_DoCrunch(AActor *thing, FChangePosition *cpos)
|
||||||
{
|
{
|
||||||
if (!(thing && thing->Grind(true) && cpos)) return;
|
if (!(thing && thing->CallGrind(true) && cpos)) return;
|
||||||
cpos->nofit = true;
|
cpos->nofit = true;
|
||||||
|
|
||||||
if ((cpos->crushchange > 0) && !(level.maptime & 3))
|
if ((cpos->crushchange > 0) && !(level.maptime & 3))
|
||||||
|
|
|
@ -1903,6 +1903,26 @@ bool AActor::Grind(bool items)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(AActor, Grind)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
|
PARAM_BOOL(items);
|
||||||
|
ACTION_RETURN_BOOL(self->Grind(items));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AActor::CallGrind(bool items)
|
||||||
|
{
|
||||||
|
IFVIRTUAL(AActor, Grind)
|
||||||
|
{
|
||||||
|
VMValue params[] = { (DObject*)this, items };
|
||||||
|
int retv;
|
||||||
|
VMReturn ret(&retv);
|
||||||
|
VMCall(func, params, 2, &ret, 1);
|
||||||
|
return !!retv;
|
||||||
|
}
|
||||||
|
return Grind(items);
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// AActor :: Massacre
|
// AActor :: Massacre
|
||||||
|
|
|
@ -869,7 +869,7 @@ void FPolyObj::ThrustMobj (AActor *actor, side_t *side)
|
||||||
P_TraceBleed (newdam > 0 ? newdam : crush, actor);
|
P_TraceBleed (newdam > 0 ? newdam : crush, actor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (level.flags2 & LEVEL2_POLYGRIND) actor->Grind(false); // crush corpses that get caught in a polyobject's way
|
if (level.flags2 & LEVEL2_POLYGRIND) actor->CallGrind(false); // crush corpses that get caught in a polyobject's way
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -331,7 +331,7 @@ void ScreenTriangle::Draw(const TriDrawTriangleArgs *args, PolyTriangleThreadDat
|
||||||
if (x > xstart)
|
if (x > xstart)
|
||||||
{
|
{
|
||||||
if (writeColor)
|
if (writeColor)
|
||||||
drawfunc(y, xstart, x, args);
|
drawfunc(y, xstart, x, args, thread);
|
||||||
|
|
||||||
if (writeStencil)
|
if (writeStencil)
|
||||||
{
|
{
|
||||||
|
@ -528,7 +528,7 @@ void StepSpan(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTriang
|
||||||
|
|
||||||
for (int x = x0; x < x1; x += 4)
|
for (int x = x0; x < x1; x += 4)
|
||||||
{
|
{
|
||||||
__m128 rcp_posW = _mm_rcp_ps(mposW);
|
__m128 rcp_posW = _mm_div_ps(_mm_set1_ps(1.0f), mposW); // precision of _mm_rcp_ps(mposW) is terrible!
|
||||||
|
|
||||||
if (OptT::Flags & SWOPT_DynLights)
|
if (OptT::Flags & SWOPT_DynLights)
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,15 +36,69 @@
|
||||||
void PolyRenderModel(PolyRenderThread *thread, const Mat4f &worldToClip, uint32_t stencilValue, float x, float y, float z, FSpriteModelFrame *smf, AActor *actor)
|
void PolyRenderModel(PolyRenderThread *thread, const Mat4f &worldToClip, uint32_t stencilValue, float x, float y, float z, FSpriteModelFrame *smf, AActor *actor)
|
||||||
{
|
{
|
||||||
PolyModelRenderer renderer(thread, worldToClip, stencilValue);
|
PolyModelRenderer renderer(thread, worldToClip, stencilValue);
|
||||||
|
|
||||||
|
renderer.sector = actor->Sector;
|
||||||
|
renderer.RenderStyle = actor->RenderStyle;
|
||||||
|
renderer.RenderAlpha = (float)actor->Alpha;
|
||||||
|
if (!renderer.RenderStyle.IsVisible(renderer.RenderAlpha))
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool foggy = false;
|
||||||
|
int actualextralight = foggy ? 0 : PolyRenderer::Instance()->Viewpoint.extralight << 4;
|
||||||
|
bool fullbrightSprite = ((actor->renderflags & RF_FULLBRIGHT) || (actor->flags5 & MF5_BRIGHT));
|
||||||
|
renderer.lightlevel = fullbrightSprite ? 255 : actor->Sector->lightlevel + actualextralight;
|
||||||
|
renderer.visibility = PolyRenderer::Instance()->Light.SpriteGlobVis(foggy);
|
||||||
|
|
||||||
|
renderer.fillcolor = actor->fillcolor;
|
||||||
|
renderer.Translation = actor->Translation;
|
||||||
|
|
||||||
renderer.AddLights(actor);
|
renderer.AddLights(actor);
|
||||||
renderer.RenderModel(x, y, z, smf, actor, r_viewpoint.TicFrac);
|
renderer.RenderModel(x, y, z, smf, actor, r_viewpoint.TicFrac);
|
||||||
PolyTriangleDrawer::SetModelVertexShader(thread->DrawQueue, -1, -1, 0.0f);
|
PolyTriangleDrawer::SetModelVertexShader(thread->DrawQueue, -1, -1, 0.0f);
|
||||||
PolyTriangleDrawer::SetTransform(thread->DrawQueue, thread->FrameMemory->NewObject<Mat4f>(worldToClip), nullptr);
|
PolyTriangleDrawer::SetTransform(thread->DrawQueue, thread->FrameMemory->NewObject<Mat4f>(worldToClip), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isBright(DPSprite *psp)
|
||||||
|
{
|
||||||
|
if (psp != nullptr && psp->GetState() != nullptr)
|
||||||
|
{
|
||||||
|
bool disablefullbright = false;
|
||||||
|
FTextureID lump = sprites[psp->GetSprite()].GetSpriteFrame(psp->GetFrame(), 0, 0., nullptr);
|
||||||
|
if (lump.isValid())
|
||||||
|
{
|
||||||
|
FTexture * tex = TexMan(lump);
|
||||||
|
if (tex) disablefullbright = tex->bDisableFullbright;
|
||||||
|
}
|
||||||
|
return psp->GetState()->GetFullbright() && !disablefullbright;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void PolyRenderHUDModel(PolyRenderThread *thread, const Mat4f &worldToClip, uint32_t stencilValue, DPSprite *psp, float ofsx, float ofsy)
|
void PolyRenderHUDModel(PolyRenderThread *thread, const Mat4f &worldToClip, uint32_t stencilValue, DPSprite *psp, float ofsx, float ofsy)
|
||||||
{
|
{
|
||||||
PolyModelRenderer renderer(thread, worldToClip, stencilValue);
|
PolyModelRenderer renderer(thread, worldToClip, stencilValue);
|
||||||
|
|
||||||
|
AActor *playermo = players[consoleplayer].camera;
|
||||||
|
auto rs = psp->GetRenderStyle(playermo->RenderStyle, playermo->Alpha);
|
||||||
|
renderer.sector = playermo->Sector;
|
||||||
|
renderer.RenderStyle = rs.first;
|
||||||
|
renderer.RenderAlpha = rs.second;
|
||||||
|
if (psp->Flags & PSPF_FORCEALPHA) renderer.RenderAlpha = 0.0f;
|
||||||
|
if (!renderer.RenderStyle.IsVisible(renderer.RenderAlpha))
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool foggy = false;
|
||||||
|
int actualextralight = foggy ? 0 : PolyRenderer::Instance()->Viewpoint.extralight << 4;
|
||||||
|
bool fullbrightSprite = isBright(psp);
|
||||||
|
renderer.lightlevel = fullbrightSprite ? 255 : playermo->Sector->lightlevel + actualextralight;
|
||||||
|
renderer.visibility = PolyRenderer::Instance()->Light.SpriteGlobVis(foggy);
|
||||||
|
|
||||||
|
PalEntry ThingColor = (playermo->RenderStyle.Flags & STYLEF_ColorIsFixed) ? playermo->fillcolor : 0xffffff;
|
||||||
|
ThingColor.a = 255;
|
||||||
|
|
||||||
|
renderer.fillcolor = fullbrightSprite ? ThingColor : ThingColor.Modulate(playermo->Sector->SpecialColors[sector_t::sprites]);
|
||||||
|
renderer.Translation = 0xffffffff;// playermo->Translation;
|
||||||
|
|
||||||
renderer.RenderHUDModel(psp, ofsx, ofsy);
|
renderer.RenderHUDModel(psp, ofsx, ofsy);
|
||||||
PolyTriangleDrawer::SetModelVertexShader(thread->DrawQueue, -1, -1, 0.0f);
|
PolyTriangleDrawer::SetModelVertexShader(thread->DrawQueue, -1, -1, 0.0f);
|
||||||
}
|
}
|
||||||
|
@ -121,7 +175,6 @@ void PolyModelRenderer::AddLights(AActor *actor)
|
||||||
|
|
||||||
void PolyModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored)
|
void PolyModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored)
|
||||||
{
|
{
|
||||||
ModelActor = actor;
|
|
||||||
const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix);
|
const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix);
|
||||||
SetTransform();
|
SetTransform();
|
||||||
|
|
||||||
|
@ -135,8 +188,6 @@ void PolyModelRenderer::EndDrawModel(AActor *actor, FSpriteModelFrame *smf)
|
||||||
if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] || !!(smf->flags & MDL_DONTCULLBACKFACES))
|
if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] || !!(smf->flags & MDL_DONTCULLBACKFACES))
|
||||||
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false);
|
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false);
|
||||||
PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, true);
|
PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, true);
|
||||||
|
|
||||||
ModelActor = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IModelVertexBuffer *PolyModelRenderer::CreateVertexBuffer(bool needindex, bool singleframe)
|
IModelVertexBuffer *PolyModelRenderer::CreateVertexBuffer(bool needindex, bool singleframe)
|
||||||
|
@ -162,7 +213,6 @@ VSMatrix PolyModelRenderer::GetViewToWorldMatrix()
|
||||||
|
|
||||||
void PolyModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectToWorldMatrix, bool mirrored)
|
void PolyModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectToWorldMatrix, bool mirrored)
|
||||||
{
|
{
|
||||||
ModelActor = actor;
|
|
||||||
const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix);
|
const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix);
|
||||||
SetTransform();
|
SetTransform();
|
||||||
PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, true);
|
PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, true);
|
||||||
|
@ -174,7 +224,6 @@ void PolyModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectT
|
||||||
|
|
||||||
void PolyModelRenderer::EndDrawHUDModel(AActor *actor)
|
void PolyModelRenderer::EndDrawHUDModel(AActor *actor)
|
||||||
{
|
{
|
||||||
ModelActor = nullptr;
|
|
||||||
PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, false);
|
PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, false);
|
||||||
|
|
||||||
if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal])
|
if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal])
|
||||||
|
@ -206,21 +255,12 @@ void PolyModelRenderer::SetTransform()
|
||||||
|
|
||||||
void PolyModelRenderer::DrawArrays(int start, int count)
|
void PolyModelRenderer::DrawArrays(int start, int count)
|
||||||
{
|
{
|
||||||
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
|
||||||
|
|
||||||
bool foggy = false;
|
|
||||||
int actualextralight = foggy ? 0 : viewpoint.extralight << 4;
|
|
||||||
sector_t *sector = ModelActor->Sector;
|
|
||||||
|
|
||||||
bool fullbrightSprite = ((ModelActor->renderflags & RF_FULLBRIGHT) || (ModelActor->flags5 & MF5_BRIGHT));
|
|
||||||
int lightlevel = fullbrightSprite ? 255 : ModelActor->Sector->lightlevel + actualextralight;
|
|
||||||
|
|
||||||
PolyDrawArgs args;
|
PolyDrawArgs args;
|
||||||
args.SetLight(GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true), lightlevel, PolyRenderer::Instance()->Light.SpriteGlobVis(foggy), fullbrightSprite);
|
args.SetLight(GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true), lightlevel, visibility, fullbrightSprite);
|
||||||
args.SetLights(Lights, NumLights);
|
args.SetLights(Lights, NumLights);
|
||||||
args.SetStencilTestValue(StencilValue);
|
args.SetStencilTestValue(StencilValue);
|
||||||
args.SetClipPlane(0, PolyClipPlane());
|
args.SetClipPlane(0, PolyClipPlane());
|
||||||
args.SetStyle(ModelActor->RenderStyle, ModelActor->Alpha, ModelActor->fillcolor, ModelActor->Translation, SkinTexture, fullbrightSprite);
|
args.SetStyle(RenderStyle, RenderAlpha, fillcolor, Translation, SkinTexture, fullbrightSprite);
|
||||||
args.SetDepthTest(true);
|
args.SetDepthTest(true);
|
||||||
args.SetWriteDepth(true);
|
args.SetWriteDepth(true);
|
||||||
args.SetWriteStencil(false);
|
args.SetWriteStencil(false);
|
||||||
|
@ -229,21 +269,12 @@ void PolyModelRenderer::DrawArrays(int start, int count)
|
||||||
|
|
||||||
void PolyModelRenderer::DrawElements(int numIndices, size_t offset)
|
void PolyModelRenderer::DrawElements(int numIndices, size_t offset)
|
||||||
{
|
{
|
||||||
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
|
||||||
|
|
||||||
bool foggy = false;
|
|
||||||
int actualextralight = foggy ? 0 : viewpoint.extralight << 4;
|
|
||||||
sector_t *sector = ModelActor->Sector;
|
|
||||||
|
|
||||||
bool fullbrightSprite = ((ModelActor->renderflags & RF_FULLBRIGHT) || (ModelActor->flags5 & MF5_BRIGHT));
|
|
||||||
int lightlevel = fullbrightSprite ? 255 : ModelActor->Sector->lightlevel + actualextralight;
|
|
||||||
|
|
||||||
PolyDrawArgs args;
|
PolyDrawArgs args;
|
||||||
args.SetLight(GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true), lightlevel, PolyRenderer::Instance()->Light.SpriteGlobVis(foggy), fullbrightSprite);
|
args.SetLight(GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true), lightlevel, visibility, fullbrightSprite);
|
||||||
args.SetLights(Lights, NumLights);
|
args.SetLights(Lights, NumLights);
|
||||||
args.SetStencilTestValue(StencilValue);
|
args.SetStencilTestValue(StencilValue);
|
||||||
args.SetClipPlane(0, PolyClipPlane());
|
args.SetClipPlane(0, PolyClipPlane());
|
||||||
args.SetStyle(ModelActor->RenderStyle, ModelActor->Alpha, ModelActor->fillcolor, ModelActor->Translation, SkinTexture, fullbrightSprite);
|
args.SetStyle(RenderStyle, RenderAlpha, fillcolor, Translation, SkinTexture, fullbrightSprite);
|
||||||
args.SetDepthTest(true);
|
args.SetDepthTest(true);
|
||||||
args.SetWriteDepth(true);
|
args.SetWriteDepth(true);
|
||||||
args.SetWriteStencil(false);
|
args.SetWriteStencil(false);
|
||||||
|
|
|
@ -55,7 +55,15 @@ public:
|
||||||
const Mat4f &WorldToClip;
|
const Mat4f &WorldToClip;
|
||||||
uint32_t StencilValue = 0;
|
uint32_t StencilValue = 0;
|
||||||
|
|
||||||
AActor *ModelActor = nullptr;
|
FRenderStyle RenderStyle;
|
||||||
|
float RenderAlpha;
|
||||||
|
sector_t *sector;
|
||||||
|
bool fullbrightSprite;
|
||||||
|
int lightlevel;
|
||||||
|
double visibility;
|
||||||
|
uint32_t fillcolor;
|
||||||
|
uint32_t Translation;
|
||||||
|
|
||||||
Mat4f ObjectToWorld;
|
Mat4f ObjectToWorld;
|
||||||
FTexture *SkinTexture = nullptr;
|
FTexture *SkinTexture = nullptr;
|
||||||
unsigned int *IndexBuffer = nullptr;
|
unsigned int *IndexBuffer = nullptr;
|
||||||
|
|
|
@ -236,7 +236,7 @@ bool FOBJModel::Load(const char* fn, int lumpnum, const char* buffer, int length
|
||||||
*/
|
*/
|
||||||
template<typename T, size_t L> void FOBJModel::ParseVector(TArray<T> &array)
|
template<typename T, size_t L> void FOBJModel::ParseVector(TArray<T> &array)
|
||||||
{
|
{
|
||||||
float *coord = new float[L];
|
float coord[L];
|
||||||
for (size_t axis = 0; axis < L; axis++)
|
for (size_t axis = 0; axis < L; axis++)
|
||||||
{
|
{
|
||||||
sc.MustGetFloat();
|
sc.MustGetFloat();
|
||||||
|
@ -244,7 +244,6 @@ template<typename T, size_t L> void FOBJModel::ParseVector(TArray<T> &array)
|
||||||
}
|
}
|
||||||
T vec(coord);
|
T vec(coord);
|
||||||
array.Push(vec);
|
array.Push(vec);
|
||||||
delete[] coord;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -150,8 +150,7 @@ FSoundChan *Channels;
|
||||||
FSoundChan *FreeChannels;
|
FSoundChan *FreeChannels;
|
||||||
|
|
||||||
FRolloffInfo S_Rolloff;
|
FRolloffInfo S_Rolloff;
|
||||||
uint8_t *S_SoundCurve;
|
TArray<uint8_t> S_SoundCurve;
|
||||||
int S_SoundCurveSize;
|
|
||||||
|
|
||||||
FBoolCVar noisedebug ("noise", false, 0); // [RH] Print sound debugging info?
|
FBoolCVar noisedebug ("noise", false, 0); // [RH] Print sound debugging info?
|
||||||
CUSTOM_CVAR (Int, snd_channels, 128, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // number of channels available
|
CUSTOM_CVAR (Int, snd_channels, 128, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // number of channels available
|
||||||
|
@ -311,20 +310,16 @@ void S_Init ()
|
||||||
|
|
||||||
atterm (S_Shutdown);
|
atterm (S_Shutdown);
|
||||||
|
|
||||||
// remove old data (S_Init can be called multiple times!)
|
|
||||||
if (S_SoundCurve != NULL)
|
|
||||||
{
|
|
||||||
delete[] S_SoundCurve;
|
|
||||||
S_SoundCurve = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Heretic and Hexen have sound curve lookup tables. Doom does not.
|
// Heretic and Hexen have sound curve lookup tables. Doom does not.
|
||||||
curvelump = Wads.CheckNumForName ("SNDCURVE");
|
curvelump = Wads.CheckNumForName ("SNDCURVE");
|
||||||
if (curvelump >= 0)
|
if (curvelump >= 0)
|
||||||
{
|
{
|
||||||
S_SoundCurveSize = Wads.LumpLength (curvelump);
|
S_SoundCurve.Resize(Wads.LumpLength (curvelump));
|
||||||
S_SoundCurve = new uint8_t[S_SoundCurveSize];
|
Wads.ReadLump(curvelump, S_SoundCurve.Data());
|
||||||
Wads.ReadLump(curvelump, S_SoundCurve);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
S_SoundCurve.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free all channels for use.
|
// Free all channels for use.
|
||||||
|
@ -376,11 +371,6 @@ void S_Shutdown ()
|
||||||
}
|
}
|
||||||
FreeChannels = NULL;
|
FreeChannels = NULL;
|
||||||
|
|
||||||
if (S_SoundCurve != NULL)
|
|
||||||
{
|
|
||||||
delete[] S_SoundCurve;
|
|
||||||
S_SoundCurve = NULL;
|
|
||||||
}
|
|
||||||
if (PlayList != NULL)
|
if (PlayList != NULL)
|
||||||
{
|
{
|
||||||
delete PlayList;
|
delete PlayList;
|
||||||
|
@ -1504,34 +1494,32 @@ sfxinfo_t *S_LoadSound(sfxinfo_t *sfx, FSoundLoadBuffer *pBuffer)
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
{
|
{
|
||||||
auto wlump = Wads.OpenLumpReader(sfx->lumpnum);
|
auto wlump = Wads.OpenLumpReader(sfx->lumpnum);
|
||||||
uint8_t *sfxdata = new uint8_t[size];
|
auto sfxdata = wlump.Read(size);
|
||||||
wlump.Read(sfxdata, size);
|
int32_t dmxlen = LittleLong(((int32_t *)sfxdata.Data())[1]);
|
||||||
int32_t dmxlen = LittleLong(((int32_t *)sfxdata)[1]);
|
|
||||||
std::pair<SoundHandle,bool> snd;
|
std::pair<SoundHandle,bool> snd;
|
||||||
|
|
||||||
// If the sound is voc, use the custom loader.
|
// If the sound is voc, use the custom loader.
|
||||||
if (strncmp ((const char *)sfxdata, "Creative Voice File", 19) == 0)
|
if (strncmp ((const char *)sfxdata.Data(), "Creative Voice File", 19) == 0)
|
||||||
{
|
{
|
||||||
snd = GSnd->LoadSoundVoc(sfxdata, size);
|
snd = GSnd->LoadSoundVoc(sfxdata.Data(), size);
|
||||||
}
|
}
|
||||||
// If the sound is raw, just load it as such.
|
// If the sound is raw, just load it as such.
|
||||||
else if (sfx->bLoadRAW)
|
else if (sfx->bLoadRAW)
|
||||||
{
|
{
|
||||||
snd = GSnd->LoadSoundRaw(sfxdata, size, sfx->RawRate, 1, 8, sfx->LoopStart);
|
snd = GSnd->LoadSoundRaw(sfxdata.Data(), size, sfx->RawRate, 1, 8, sfx->LoopStart);
|
||||||
}
|
}
|
||||||
// Otherwise, try the sound as DMX format.
|
// Otherwise, try the sound as DMX format.
|
||||||
else if (((uint8_t *)sfxdata)[0] == 3 && ((uint8_t *)sfxdata)[1] == 0 && dmxlen <= size - 8)
|
else if (((uint8_t *)sfxdata.Data())[0] == 3 && ((uint8_t *)sfxdata.Data())[1] == 0 && dmxlen <= size - 8)
|
||||||
{
|
{
|
||||||
int frequency = LittleShort(((uint16_t *)sfxdata)[1]);
|
int frequency = LittleShort(((uint16_t *)sfxdata.Data())[1]);
|
||||||
if (frequency == 0) frequency = 11025;
|
if (frequency == 0) frequency = 11025;
|
||||||
snd = GSnd->LoadSoundRaw(sfxdata+8, dmxlen, frequency, 1, 8, sfx->LoopStart);
|
snd = GSnd->LoadSoundRaw(sfxdata.Data()+8, dmxlen, frequency, 1, 8, sfx->LoopStart);
|
||||||
}
|
}
|
||||||
// If that fails, let the sound system try and figure it out.
|
// If that fails, let the sound system try and figure it out.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
snd = GSnd->LoadSound(sfxdata, size, false, pBuffer);
|
snd = GSnd->LoadSound(sfxdata.Data(), size, false, pBuffer);
|
||||||
}
|
}
|
||||||
delete[] sfxdata;
|
|
||||||
|
|
||||||
sfx->data = snd.first;
|
sfx->data = snd.first;
|
||||||
if(snd.second)
|
if(snd.second)
|
||||||
|
@ -1572,33 +1560,31 @@ static void S_LoadSound3D(sfxinfo_t *sfx, FSoundLoadBuffer *pBuffer)
|
||||||
if (size <= 0) return;
|
if (size <= 0) return;
|
||||||
|
|
||||||
auto wlump = Wads.OpenLumpReader(sfx->lumpnum);
|
auto wlump = Wads.OpenLumpReader(sfx->lumpnum);
|
||||||
uint8_t *sfxdata = new uint8_t[size];
|
auto sfxdata = wlump.Read(size);
|
||||||
wlump.Read(sfxdata, size);
|
int32_t dmxlen = LittleLong(((int32_t *)sfxdata.Data())[1]);
|
||||||
int32_t dmxlen = LittleLong(((int32_t *)sfxdata)[1]);
|
|
||||||
|
|
||||||
// If the sound is voc, use the custom loader.
|
// If the sound is voc, use the custom loader.
|
||||||
if (strncmp((const char *)sfxdata, "Creative Voice File", 19) == 0)
|
if (strncmp((const char *)sfxdata.Data(), "Creative Voice File", 19) == 0)
|
||||||
{
|
{
|
||||||
snd = GSnd->LoadSoundVoc(sfxdata, size, true);
|
snd = GSnd->LoadSoundVoc(sfxdata.Data(), size, true);
|
||||||
}
|
}
|
||||||
// If the sound is raw, just load it as such.
|
// If the sound is raw, just load it as such.
|
||||||
else if (sfx->bLoadRAW)
|
else if (sfx->bLoadRAW)
|
||||||
{
|
{
|
||||||
snd = GSnd->LoadSoundRaw(sfxdata, size, sfx->RawRate, 1, 8, sfx->LoopStart, true);
|
snd = GSnd->LoadSoundRaw(sfxdata.Data(), size, sfx->RawRate, 1, 8, sfx->LoopStart, true);
|
||||||
}
|
}
|
||||||
// Otherwise, try the sound as DMX format.
|
// Otherwise, try the sound as DMX format.
|
||||||
else if (((uint8_t *)sfxdata)[0] == 3 && ((uint8_t *)sfxdata)[1] == 0 && dmxlen <= size - 8)
|
else if (((uint8_t *)sfxdata.Data())[0] == 3 && ((uint8_t *)sfxdata.Data())[1] == 0 && dmxlen <= size - 8)
|
||||||
{
|
{
|
||||||
int frequency = LittleShort(((uint16_t *)sfxdata)[1]);
|
int frequency = LittleShort(((uint16_t *)sfxdata.Data())[1]);
|
||||||
if (frequency == 0) frequency = 11025;
|
if (frequency == 0) frequency = 11025;
|
||||||
snd = GSnd->LoadSoundRaw(sfxdata + 8, dmxlen, frequency, 1, 8, sfx->LoopStart, -1, true);
|
snd = GSnd->LoadSoundRaw(sfxdata.Data() + 8, dmxlen, frequency, 1, 8, sfx->LoopStart, -1, true);
|
||||||
}
|
}
|
||||||
// If that fails, let the sound system try and figure it out.
|
// If that fails, let the sound system try and figure it out.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
snd = GSnd->LoadSound(sfxdata, size, true, pBuffer);
|
snd = GSnd->LoadSound(sfxdata.Data(), size, true, pBuffer);
|
||||||
}
|
}
|
||||||
delete[] sfxdata;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sfx->data3d = snd.first;
|
sfx->data3d = snd.first;
|
||||||
|
@ -2274,9 +2260,9 @@ float S_GetRolloff(FRolloffInfo *rolloff, float distance, bool logarithmic)
|
||||||
}
|
}
|
||||||
|
|
||||||
float volume = (rolloff->MaxDistance - distance) / (rolloff->MaxDistance - rolloff->MinDistance);
|
float volume = (rolloff->MaxDistance - distance) / (rolloff->MaxDistance - rolloff->MinDistance);
|
||||||
if (rolloff->RolloffType == ROLLOFF_Custom && S_SoundCurve != NULL)
|
if (rolloff->RolloffType == ROLLOFF_Custom && S_SoundCurve.Size() > 0)
|
||||||
{
|
{
|
||||||
volume = S_SoundCurve[int(S_SoundCurveSize * (1 - volume))] / 127.f;
|
volume = S_SoundCurve[int(S_SoundCurve.Size() * (1 - volume))] / 127.f;
|
||||||
}
|
}
|
||||||
if (logarithmic)
|
if (logarithmic)
|
||||||
{
|
{
|
||||||
|
|
|
@ -165,8 +165,8 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
extern FRolloffInfo S_Rolloff;
|
extern FRolloffInfo S_Rolloff;
|
||||||
extern uint8_t *S_SoundCurve;
|
extern TArray<uint8_t> S_SoundCurve;
|
||||||
extern int S_SoundCurveSize;
|
|
||||||
|
|
||||||
// Information about one playing sound.
|
// Information about one playing sound.
|
||||||
struct sector_t;
|
struct sector_t;
|
||||||
|
|
|
@ -249,14 +249,10 @@ bool FScanner::OpenFile (const char *name)
|
||||||
FileReader fr;
|
FileReader fr;
|
||||||
if (!fr.OpenFile(name)) return false;
|
if (!fr.OpenFile(name)) return false;
|
||||||
auto filesize = fr.GetLength();
|
auto filesize = fr.GetLength();
|
||||||
auto filebuf = new uint8_t[filesize];
|
auto filebuff = fr.Read();
|
||||||
if (fr.Read(filebuf, filesize) != filesize)
|
if (filebuff.Size() == 0 && filesize > 0) return false;
|
||||||
{
|
|
||||||
delete[] filebuf;
|
ScriptBuffer = FString((const char *)filebuff.Data(), filesize);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ScriptBuffer = FString((const char *)filebuf, filesize);
|
|
||||||
delete[] filebuf;
|
|
||||||
ScriptName = name; // This is used for error messages so the full file name is preferable
|
ScriptName = name; // This is used for error messages so the full file name is preferable
|
||||||
LumpNum = -1;
|
LumpNum = -1;
|
||||||
PrepareScript ();
|
PrepareScript ();
|
||||||
|
|
|
@ -688,8 +688,8 @@ static float GetRolloff(const FRolloffInfo *rolloff, float distance)
|
||||||
if(rolloff->RolloffType == ROLLOFF_Linear)
|
if(rolloff->RolloffType == ROLLOFF_Linear)
|
||||||
return volume;
|
return volume;
|
||||||
|
|
||||||
if(rolloff->RolloffType == ROLLOFF_Custom && S_SoundCurve != NULL)
|
if(rolloff->RolloffType == ROLLOFF_Custom && S_SoundCurve.Size() > 0)
|
||||||
return S_SoundCurve[int(S_SoundCurveSize * (1.f - volume))] / 127.f;
|
return S_SoundCurve[int(S_SoundCurve.Size() * (1.f - volume))] / 127.f;
|
||||||
return (powf(10.f, volume) - 1.f) / 9.f;
|
return (powf(10.f, volume) - 1.f) / 9.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@ void FSoftwareRenderer::RenderView(player_t *player, DCanvas *target, void *vide
|
||||||
|
|
||||||
void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, int height)
|
void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, int height)
|
||||||
{
|
{
|
||||||
DSimpleCanvas pic(width, height, false);
|
DCanvas pic(width, height, false);
|
||||||
PalEntry palette[256];
|
PalEntry palette[256];
|
||||||
|
|
||||||
// Take a snapshot of the player's view
|
// Take a snapshot of the player's view
|
||||||
|
@ -241,7 +241,7 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin
|
||||||
cameraViewwindow = r_viewwindow;
|
cameraViewwindow = r_viewwindow;
|
||||||
|
|
||||||
uint8_t *Pixels = renderTarget->IsBgra() ? (uint8_t*)tex->GetPixelsBgra() : (uint8_t*)tex->GetPixels(DefaultRenderStyle());
|
uint8_t *Pixels = renderTarget->IsBgra() ? (uint8_t*)tex->GetPixelsBgra() : (uint8_t*)tex->GetPixels(DefaultRenderStyle());
|
||||||
DSimpleCanvas *Canvas = renderTarget->IsBgra() ? tex->GetCanvasBgra() : tex->GetCanvas();
|
DCanvas *Canvas = renderTarget->IsBgra() ? tex->GetCanvasBgra() : tex->GetCanvas();
|
||||||
|
|
||||||
// curse Doom's overuse of global variables in the renderer.
|
// curse Doom's overuse of global variables in the renderer.
|
||||||
// These get clobbered by rendering to a camera texture but they need to be preserved so the final rendering can be done with the correct palette.
|
// These get clobbered by rendering to a camera texture but they need to be preserved so the final rendering can be done with the correct palette.
|
||||||
|
|
|
@ -96,7 +96,7 @@ sector_t *SWSceneDrawer::RenderView(player_t *player)
|
||||||
mat->AddTextureLayer(PaletteTexture.get());
|
mat->AddTextureLayer(PaletteTexture.get());
|
||||||
|
|
||||||
Canvas.reset();
|
Canvas.reset();
|
||||||
Canvas.reset(new DSimpleCanvas(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor()));
|
Canvas.reset(new DCanvas(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto buf = fbtex->SystemTexture[0]->MapBuffer();
|
auto buf = fbtex->SystemTexture[0]->MapBuffer();
|
||||||
|
|
|
@ -16,7 +16,7 @@ class SWSceneDrawer
|
||||||
std::unique_ptr<FWrapperTexture> FBTexture[2];
|
std::unique_ptr<FWrapperTexture> FBTexture[2];
|
||||||
int FBTextureIndex = 0;
|
int FBTextureIndex = 0;
|
||||||
bool FBIsTruecolor = false;
|
bool FBIsTruecolor = false;
|
||||||
std::unique_ptr<DSimpleCanvas> Canvas;
|
std::unique_ptr<DCanvas> Canvas;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SWSceneDrawer();
|
SWSceneDrawer();
|
||||||
|
|
|
@ -75,6 +75,22 @@ namespace swrenderer
|
||||||
void RenderModel::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor)
|
void RenderModel::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor)
|
||||||
{
|
{
|
||||||
SWModelRenderer renderer(thread, clip3DFloor, &WorldToClip, MirrorWorldToClip);
|
SWModelRenderer renderer(thread, clip3DFloor, &WorldToClip, MirrorWorldToClip);
|
||||||
|
|
||||||
|
renderer.sector = actor->Sector;
|
||||||
|
renderer.RenderStyle = actor->RenderStyle;
|
||||||
|
renderer.RenderAlpha = (float)actor->Alpha;
|
||||||
|
if (!renderer.RenderStyle.IsVisible(renderer.RenderAlpha))
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool foggy = false;
|
||||||
|
int actualextralight = foggy ? 0 : PolyRenderer::Instance()->Viewpoint.extralight << 4;
|
||||||
|
bool fullbrightSprite = ((actor->renderflags & RF_FULLBRIGHT) || (actor->flags5 & MF5_BRIGHT));
|
||||||
|
renderer.lightlevel = fullbrightSprite ? 255 : actor->Sector->lightlevel + actualextralight;
|
||||||
|
renderer.visibility = PolyRenderer::Instance()->Light.SpriteGlobVis(foggy);
|
||||||
|
|
||||||
|
renderer.fillcolor = actor->fillcolor;
|
||||||
|
renderer.Translation = actor->Translation;
|
||||||
|
|
||||||
renderer.AddLights(actor);
|
renderer.AddLights(actor);
|
||||||
renderer.RenderModel(x, y, z, smf, actor, r_viewpoint.TicFrac);
|
renderer.RenderModel(x, y, z, smf, actor, r_viewpoint.TicFrac);
|
||||||
PolyTriangleDrawer::SetModelVertexShader(thread->DrawQueue, -1, -1, 0.0f);
|
PolyTriangleDrawer::SetModelVertexShader(thread->DrawQueue, -1, -1, 0.0f);
|
||||||
|
@ -82,9 +98,47 @@ namespace swrenderer
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static bool isBright(DPSprite *psp)
|
||||||
|
{
|
||||||
|
if (psp != nullptr && psp->GetState() != nullptr)
|
||||||
|
{
|
||||||
|
bool disablefullbright = false;
|
||||||
|
FTextureID lump = sprites[psp->GetSprite()].GetSpriteFrame(psp->GetFrame(), 0, 0., nullptr);
|
||||||
|
if (lump.isValid())
|
||||||
|
{
|
||||||
|
FTexture * tex = TexMan(lump);
|
||||||
|
if (tex) disablefullbright = tex->bDisableFullbright;
|
||||||
|
}
|
||||||
|
return psp->GetState()->GetFullbright() && !disablefullbright;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void RenderHUDModel(RenderThread *thread, DPSprite *psp, float ofsx, float ofsy)
|
void RenderHUDModel(RenderThread *thread, DPSprite *psp, float ofsx, float ofsy)
|
||||||
{
|
{
|
||||||
SWModelRenderer renderer(thread, Fake3DTranslucent(), &thread->Viewport->WorldToClip, false);
|
SWModelRenderer renderer(thread, Fake3DTranslucent(), &thread->Viewport->WorldToClip, false);
|
||||||
|
|
||||||
|
AActor *playermo = players[consoleplayer].camera;
|
||||||
|
auto rs = psp->GetRenderStyle(playermo->RenderStyle, playermo->Alpha);
|
||||||
|
renderer.sector = playermo->Sector;
|
||||||
|
renderer.RenderStyle = rs.first;
|
||||||
|
renderer.RenderAlpha = rs.second;
|
||||||
|
if (psp->Flags & PSPF_FORCEALPHA) renderer.RenderAlpha = 0.0f;
|
||||||
|
if (!renderer.RenderStyle.IsVisible(renderer.RenderAlpha))
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool foggy = false;
|
||||||
|
int actualextralight = foggy ? 0 : PolyRenderer::Instance()->Viewpoint.extralight << 4;
|
||||||
|
bool fullbrightSprite = isBright(psp);
|
||||||
|
renderer.lightlevel = fullbrightSprite ? 255 : playermo->Sector->lightlevel + actualextralight;
|
||||||
|
renderer.visibility = PolyRenderer::Instance()->Light.SpriteGlobVis(foggy);
|
||||||
|
|
||||||
|
PalEntry ThingColor = (playermo->RenderStyle.Flags & STYLEF_ColorIsFixed) ? playermo->fillcolor : 0xffffff;
|
||||||
|
ThingColor.a = 255;
|
||||||
|
|
||||||
|
renderer.fillcolor = fullbrightSprite ? ThingColor : ThingColor.Modulate(playermo->Sector->SpecialColors[sector_t::sprites]);
|
||||||
|
renderer.Translation = 0xffffffff;// playermo->Translation;
|
||||||
|
|
||||||
renderer.RenderHUDModel(psp, ofsx, ofsy);
|
renderer.RenderHUDModel(psp, ofsx, ofsy);
|
||||||
PolyTriangleDrawer::SetModelVertexShader(thread->DrawQueue, -1, -1, 0.0f);
|
PolyTriangleDrawer::SetModelVertexShader(thread->DrawQueue, -1, -1, 0.0f);
|
||||||
}
|
}
|
||||||
|
@ -162,7 +216,6 @@ namespace swrenderer
|
||||||
|
|
||||||
void SWModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored)
|
void SWModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored)
|
||||||
{
|
{
|
||||||
ModelActor = actor;
|
|
||||||
const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix);
|
const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix);
|
||||||
|
|
||||||
ClipTop = {};
|
ClipTop = {};
|
||||||
|
@ -209,8 +262,6 @@ namespace swrenderer
|
||||||
if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] || !!(smf->flags & MDL_DONTCULLBACKFACES))
|
if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] || !!(smf->flags & MDL_DONTCULLBACKFACES))
|
||||||
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false);
|
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false);
|
||||||
PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, true);
|
PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, true);
|
||||||
|
|
||||||
ModelActor = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IModelVertexBuffer *SWModelRenderer::CreateVertexBuffer(bool needindex, bool singleframe)
|
IModelVertexBuffer *SWModelRenderer::CreateVertexBuffer(bool needindex, bool singleframe)
|
||||||
|
@ -255,7 +306,6 @@ namespace swrenderer
|
||||||
|
|
||||||
void SWModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectToWorldMatrix, bool mirrored)
|
void SWModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectToWorldMatrix, bool mirrored)
|
||||||
{
|
{
|
||||||
ModelActor = actor;
|
|
||||||
const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix);
|
const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix);
|
||||||
ClipTop = {};
|
ClipTop = {};
|
||||||
ClipBottom = {};
|
ClipBottom = {};
|
||||||
|
@ -269,7 +319,6 @@ namespace swrenderer
|
||||||
|
|
||||||
void SWModelRenderer::EndDrawHUDModel(AActor *actor)
|
void SWModelRenderer::EndDrawHUDModel(AActor *actor)
|
||||||
{
|
{
|
||||||
ModelActor = nullptr;
|
|
||||||
PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, false);
|
PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, false);
|
||||||
|
|
||||||
if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal])
|
if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal])
|
||||||
|
@ -301,20 +350,11 @@ namespace swrenderer
|
||||||
|
|
||||||
void SWModelRenderer::DrawArrays(int start, int count)
|
void SWModelRenderer::DrawArrays(int start, int count)
|
||||||
{
|
{
|
||||||
const auto &viewpoint = Thread->Viewport->viewpoint;
|
|
||||||
|
|
||||||
bool foggy = false;
|
|
||||||
int actualextralight = foggy ? 0 : viewpoint.extralight << 4;
|
|
||||||
sector_t *sector = ModelActor->Sector;
|
|
||||||
|
|
||||||
bool fullbrightSprite = ((ModelActor->renderflags & RF_FULLBRIGHT) || (ModelActor->flags5 & MF5_BRIGHT));
|
|
||||||
int lightlevel = fullbrightSprite ? 255 : ModelActor->Sector->lightlevel + actualextralight;
|
|
||||||
|
|
||||||
PolyDrawArgs args;
|
PolyDrawArgs args;
|
||||||
args.SetLight(GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true), lightlevel, Thread->Light->SpriteGlobVis(foggy), fullbrightSprite);
|
args.SetLight(GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true), lightlevel, visibility, fullbrightSprite);
|
||||||
args.SetLights(Lights, NumLights);
|
args.SetLights(Lights, NumLights);
|
||||||
args.SetNormal(FVector3(0.0f, 0.0f, 0.0f));
|
args.SetNormal(FVector3(0.0f, 0.0f, 0.0f));
|
||||||
args.SetStyle(ModelActor->RenderStyle, ModelActor->Alpha, ModelActor->fillcolor, ModelActor->Translation, SkinTexture, fullbrightSprite);
|
args.SetStyle(RenderStyle, RenderAlpha, fillcolor, Translation, SkinTexture, fullbrightSprite);
|
||||||
args.SetDepthTest(true);
|
args.SetDepthTest(true);
|
||||||
args.SetWriteDepth(true);
|
args.SetWriteDepth(true);
|
||||||
args.SetWriteStencil(false);
|
args.SetWriteStencil(false);
|
||||||
|
@ -327,20 +367,11 @@ namespace swrenderer
|
||||||
|
|
||||||
void SWModelRenderer::DrawElements(int numIndices, size_t offset)
|
void SWModelRenderer::DrawElements(int numIndices, size_t offset)
|
||||||
{
|
{
|
||||||
const auto &viewpoint = Thread->Viewport->viewpoint;
|
|
||||||
|
|
||||||
bool foggy = false;
|
|
||||||
int actualextralight = foggy ? 0 : viewpoint.extralight << 4;
|
|
||||||
sector_t *sector = ModelActor->Sector;
|
|
||||||
|
|
||||||
bool fullbrightSprite = ((ModelActor->renderflags & RF_FULLBRIGHT) || (ModelActor->flags5 & MF5_BRIGHT));
|
|
||||||
int lightlevel = fullbrightSprite ? 255 : ModelActor->Sector->lightlevel + actualextralight;
|
|
||||||
|
|
||||||
PolyDrawArgs args;
|
PolyDrawArgs args;
|
||||||
args.SetLight(GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true), lightlevel, Thread->Light->SpriteGlobVis(foggy), fullbrightSprite);
|
args.SetLight(GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true), lightlevel, visibility, fullbrightSprite);
|
||||||
args.SetLights(Lights, NumLights);
|
args.SetLights(Lights, NumLights);
|
||||||
args.SetNormal(FVector3(0.0f, 0.0f, 0.0f));
|
args.SetNormal(FVector3(0.0f, 0.0f, 0.0f));
|
||||||
args.SetStyle(ModelActor->RenderStyle, ModelActor->Alpha, ModelActor->fillcolor, ModelActor->Translation, SkinTexture, fullbrightSprite);
|
args.SetStyle(RenderStyle, RenderAlpha, fillcolor, Translation, SkinTexture, fullbrightSprite);
|
||||||
args.SetDepthTest(true);
|
args.SetDepthTest(true);
|
||||||
args.SetWriteDepth(true);
|
args.SetWriteDepth(true);
|
||||||
args.SetWriteStencil(false);
|
args.SetWriteStencil(false);
|
||||||
|
|
|
@ -78,7 +78,15 @@ namespace swrenderer
|
||||||
RenderThread *Thread = nullptr;
|
RenderThread *Thread = nullptr;
|
||||||
Fake3DTranslucent Clip3DFloor;
|
Fake3DTranslucent Clip3DFloor;
|
||||||
|
|
||||||
AActor *ModelActor = nullptr;
|
FRenderStyle RenderStyle;
|
||||||
|
float RenderAlpha;
|
||||||
|
sector_t *sector;
|
||||||
|
bool fullbrightSprite;
|
||||||
|
int lightlevel;
|
||||||
|
double visibility;
|
||||||
|
uint32_t fillcolor;
|
||||||
|
uint32_t Translation;
|
||||||
|
|
||||||
Mat4f ObjectToWorld;
|
Mat4f ObjectToWorld;
|
||||||
PolyClipPlane ClipTop, ClipBottom;
|
PolyClipPlane ClipTop, ClipBottom;
|
||||||
FTexture *SkinTexture = nullptr;
|
FTexture *SkinTexture = nullptr;
|
||||||
|
|
|
@ -108,7 +108,7 @@ const uint32_t *FCanvasTexture::GetPixelsBgra()
|
||||||
|
|
||||||
void FCanvasTexture::MakeTexture (FRenderStyle) // This ignores the render style because making it work as alpha texture is impractical.
|
void FCanvasTexture::MakeTexture (FRenderStyle) // This ignores the render style because making it work as alpha texture is impractical.
|
||||||
{
|
{
|
||||||
Canvas = new DSimpleCanvas (Width, Height, false);
|
Canvas = new DCanvas (Width, Height, false);
|
||||||
|
|
||||||
if (Width != Height || Width != Canvas->GetPitch())
|
if (Width != Height || Width != Canvas->GetPitch())
|
||||||
{
|
{
|
||||||
|
@ -128,7 +128,7 @@ void FCanvasTexture::MakeTexture (FRenderStyle) // This ignores the render style
|
||||||
|
|
||||||
void FCanvasTexture::MakeTextureBgra()
|
void FCanvasTexture::MakeTextureBgra()
|
||||||
{
|
{
|
||||||
CanvasBgra = new DSimpleCanvas(Width, Height, true);
|
CanvasBgra = new DCanvas(Width, Height, true);
|
||||||
|
|
||||||
if (Width != Height || Width != CanvasBgra->GetPitch())
|
if (Width != Height || Width != CanvasBgra->GetPitch())
|
||||||
{
|
{
|
||||||
|
|
|
@ -754,7 +754,7 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
// A texture that can be drawn to.
|
// A texture that can be drawn to.
|
||||||
class DSimpleCanvas;
|
class DCanvas;
|
||||||
class AActor;
|
class AActor;
|
||||||
|
|
||||||
class FCanvasTexture : public FTexture
|
class FCanvasTexture : public FTexture
|
||||||
|
@ -770,16 +770,16 @@ public:
|
||||||
bool CheckModified (FRenderStyle) override;
|
bool CheckModified (FRenderStyle) override;
|
||||||
void NeedUpdate() { bNeedsUpdate=true; }
|
void NeedUpdate() { bNeedsUpdate=true; }
|
||||||
void SetUpdated() { bNeedsUpdate = false; bDidUpdate = true; bFirstUpdate = false; }
|
void SetUpdated() { bNeedsUpdate = false; bDidUpdate = true; bFirstUpdate = false; }
|
||||||
DSimpleCanvas *GetCanvas() { return Canvas; }
|
DCanvas *GetCanvas() { return Canvas; }
|
||||||
DSimpleCanvas *GetCanvasBgra() { return CanvasBgra; }
|
DCanvas *GetCanvasBgra() { return CanvasBgra; }
|
||||||
bool Mipmapped() override { return false; }
|
bool Mipmapped() override { return false; }
|
||||||
void MakeTexture (FRenderStyle style);
|
void MakeTexture (FRenderStyle style);
|
||||||
void MakeTextureBgra ();
|
void MakeTextureBgra ();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
DSimpleCanvas *Canvas = nullptr;
|
DCanvas *Canvas = nullptr;
|
||||||
DSimpleCanvas *CanvasBgra = nullptr;
|
DCanvas *CanvasBgra = nullptr;
|
||||||
uint8_t *Pixels = nullptr;
|
uint8_t *Pixels = nullptr;
|
||||||
uint32_t *PixelsBgra = nullptr;
|
uint32_t *PixelsBgra = nullptr;
|
||||||
Span DummySpans[2];
|
Span DummySpans[2];
|
||||||
|
|
|
@ -357,7 +357,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
||||||
int i;
|
int i;
|
||||||
FTextureID lump;
|
FTextureID lump;
|
||||||
char buffer[12];
|
char buffer[12];
|
||||||
FTexture **charlumps;
|
TArray<FTexture*> charLumps;
|
||||||
int maxyoffs;
|
int maxyoffs;
|
||||||
bool doomtemplate = gameinfo.gametype & GAME_DoomChex ? strncmp (nametemplate, "STCFN", 5) == 0 : false;
|
bool doomtemplate = gameinfo.gametype & GAME_DoomChex ? strncmp (nametemplate, "STCFN", 5) == 0 : false;
|
||||||
bool stcfn121 = false;
|
bool stcfn121 = false;
|
||||||
|
@ -365,7 +365,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
||||||
noTranslate = notranslate;
|
noTranslate = notranslate;
|
||||||
Lump = fdlump;
|
Lump = fdlump;
|
||||||
Chars = new CharData[count];
|
Chars = new CharData[count];
|
||||||
charlumps = new FTexture *[count];
|
charLumps.Resize(count);
|
||||||
PatchRemap = new uint8_t[256];
|
PatchRemap = new uint8_t[256];
|
||||||
FirstChar = first;
|
FirstChar = first;
|
||||||
LastChar = first + count - 1;
|
LastChar = first + count - 1;
|
||||||
|
@ -381,7 +381,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
charlumps[i] = NULL;
|
charLumps[i] = NULL;
|
||||||
mysnprintf (buffer, countof(buffer), nametemplate, i + start);
|
mysnprintf (buffer, countof(buffer), nametemplate, i + start);
|
||||||
|
|
||||||
lump = TexMan.CheckForTexture(buffer, ETextureType::MiscPatch);
|
lump = TexMan.CheckForTexture(buffer, ETextureType::MiscPatch);
|
||||||
|
@ -395,7 +395,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
||||||
!TexMan.CheckForTexture("STCFN122", ETextureType::MiscPatch).isValid())
|
!TexMan.CheckForTexture("STCFN122", ETextureType::MiscPatch).isValid())
|
||||||
{
|
{
|
||||||
// insert the incorrectly named '|' graphic in its correct position.
|
// insert the incorrectly named '|' graphic in its correct position.
|
||||||
if (count > 124-start) charlumps[124-start] = TexMan[lump];
|
if (count > 124-start) charLumps[124-start] = TexMan[lump];
|
||||||
lump.SetInvalid();
|
lump.SetInvalid();
|
||||||
stcfn121 = true;
|
stcfn121 = true;
|
||||||
}
|
}
|
||||||
|
@ -408,7 +408,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
||||||
{
|
{
|
||||||
// set the lump here only if it represents a valid texture
|
// set the lump here only if it represents a valid texture
|
||||||
if (i != 124-start || !stcfn121)
|
if (i != 124-start || !stcfn121)
|
||||||
charlumps[i] = pic;
|
charLumps[i] = pic;
|
||||||
|
|
||||||
int height = pic->GetScaledHeight();
|
int height = pic->GetScaledHeight();
|
||||||
int yoffs = pic->GetScaledTopOffset(0);
|
int yoffs = pic->GetScaledTopOffset(0);
|
||||||
|
@ -425,10 +425,10 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (charlumps[i] != NULL)
|
if (charLumps[i] != nullptr)
|
||||||
{
|
{
|
||||||
if (!noTranslate) Chars[i].Pic = new FFontChar1 (charlumps[i]);
|
if (!noTranslate) Chars[i].Pic = new FFontChar1 (charLumps[i]);
|
||||||
else Chars[i].Pic = charlumps[i];
|
else Chars[i].Pic = charLumps[i];
|
||||||
Chars[i].XMove = Chars[i].Pic->GetScaledWidth();
|
Chars[i].XMove = Chars[i].Pic->GetScaledWidth();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -454,8 +454,6 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
||||||
FixXMoves();
|
FixXMoves();
|
||||||
|
|
||||||
if (!noTranslate) LoadTranslations();
|
if (!noTranslate) LoadTranslations();
|
||||||
|
|
||||||
delete[] charlumps;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -82,87 +82,6 @@ void DFrameBuffer::CalcGamma (float gamma, uint8_t gammalookup[256])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// DSimpleCanvas Constructor
|
|
||||||
//
|
|
||||||
// A simple canvas just holds a buffer in main memory.
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
DSimpleCanvas::DSimpleCanvas (int width, int height, bool bgra)
|
|
||||||
: DCanvas (width, height, bgra)
|
|
||||||
{
|
|
||||||
PixelBuffer = nullptr;
|
|
||||||
Resize(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DSimpleCanvas::Resize(int width, int height)
|
|
||||||
{
|
|
||||||
Width = width;
|
|
||||||
Height = height;
|
|
||||||
|
|
||||||
if (PixelBuffer != NULL)
|
|
||||||
{
|
|
||||||
delete[] PixelBuffer;
|
|
||||||
PixelBuffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Making the pitch a power of 2 is very bad for performance
|
|
||||||
// Try to maximize the number of cache lines that can be filled
|
|
||||||
// for each column drawing operation by making the pitch slightly
|
|
||||||
// longer than the width. The values used here are all based on
|
|
||||||
// empirical evidence.
|
|
||||||
|
|
||||||
if (width <= 640)
|
|
||||||
{
|
|
||||||
// For low resolutions, just keep the pitch the same as the width.
|
|
||||||
// Some speedup can be seen using the technique below, but the speedup
|
|
||||||
// is so marginal that I don't consider it worthwhile.
|
|
||||||
Pitch = width;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If we couldn't figure out the CPU's L1 cache line size, assume
|
|
||||||
// it's 32 bytes wide.
|
|
||||||
if (CPU.DataL1LineSize == 0)
|
|
||||||
{
|
|
||||||
CPU.DataL1LineSize = 32;
|
|
||||||
}
|
|
||||||
// The Athlon and P3 have very different caches, apparently.
|
|
||||||
// I am going to generalize the Athlon's performance to all AMD
|
|
||||||
// processors and the P3's to all non-AMD processors. I don't know
|
|
||||||
// how smart that is, but I don't have a vast plethora of
|
|
||||||
// processors to test with.
|
|
||||||
if (CPU.bIsAMD)
|
|
||||||
{
|
|
||||||
Pitch = width + CPU.DataL1LineSize;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Pitch = width + MAX(0, CPU.DataL1LineSize - 8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int bytes_per_pixel = Bgra ? 4 : 1;
|
|
||||||
PixelBuffer = new uint8_t[Pitch * height * bytes_per_pixel];
|
|
||||||
memset (PixelBuffer, 0, Pitch * height * bytes_per_pixel);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// DSimpleCanvas Destructor
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
DSimpleCanvas::~DSimpleCanvas ()
|
|
||||||
{
|
|
||||||
if (PixelBuffer != NULL)
|
|
||||||
{
|
|
||||||
delete[] PixelBuffer;
|
|
||||||
PixelBuffer = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// DFrameBuffer Constructor
|
// DFrameBuffer Constructor
|
||||||
|
|
|
@ -177,6 +177,7 @@ DCanvas::DCanvas (int _width, int _height, bool _bgra)
|
||||||
Width = _width;
|
Width = _width;
|
||||||
Height = _height;
|
Height = _height;
|
||||||
Bgra = _bgra;
|
Bgra = _bgra;
|
||||||
|
Resize(_width, _height);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -189,6 +190,58 @@ DCanvas::~DCanvas ()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void DCanvas::Resize(int width, int height)
|
||||||
|
{
|
||||||
|
Width = width;
|
||||||
|
Height = height;
|
||||||
|
|
||||||
|
// Making the pitch a power of 2 is very bad for performance
|
||||||
|
// Try to maximize the number of cache lines that can be filled
|
||||||
|
// for each column drawing operation by making the pitch slightly
|
||||||
|
// longer than the width. The values used here are all based on
|
||||||
|
// empirical evidence.
|
||||||
|
|
||||||
|
if (width <= 640)
|
||||||
|
{
|
||||||
|
// For low resolutions, just keep the pitch the same as the width.
|
||||||
|
// Some speedup can be seen using the technique below, but the speedup
|
||||||
|
// is so marginal that I don't consider it worthwhile.
|
||||||
|
Pitch = width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If we couldn't figure out the CPU's L1 cache line size, assume
|
||||||
|
// it's 32 bytes wide.
|
||||||
|
if (CPU.DataL1LineSize == 0)
|
||||||
|
{
|
||||||
|
CPU.DataL1LineSize = 32;
|
||||||
|
}
|
||||||
|
// The Athlon and P3 have very different caches, apparently.
|
||||||
|
// I am going to generalize the Athlon's performance to all AMD
|
||||||
|
// processors and the P3's to all non-AMD processors. I don't know
|
||||||
|
// how smart that is, but I don't have a vast plethora of
|
||||||
|
// processors to test with.
|
||||||
|
if (CPU.bIsAMD)
|
||||||
|
{
|
||||||
|
Pitch = width + CPU.DataL1LineSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Pitch = width + MAX(0, CPU.DataL1LineSize - 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int bytes_per_pixel = Bgra ? 4 : 1;
|
||||||
|
Pixels.Resize(Pitch * height * bytes_per_pixel);
|
||||||
|
memset (Pixels.Data(), 0, Pixels.Size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// V_GetColorFromString
|
// V_GetColorFromString
|
||||||
|
|
|
@ -292,53 +292,29 @@ struct VMVa_List
|
||||||
//
|
//
|
||||||
// VIDEO
|
// VIDEO
|
||||||
//
|
//
|
||||||
// [RH] Made screens more implementation-independant:
|
|
||||||
//
|
//
|
||||||
class DCanvas
|
class DCanvas
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DCanvas (int width, int height, bool bgra);
|
DCanvas (int width, int height, bool bgra);
|
||||||
virtual ~DCanvas ();
|
~DCanvas ();
|
||||||
|
void Resize(int width, int height);
|
||||||
|
|
||||||
// Member variable access
|
// Member variable access
|
||||||
inline uint8_t *GetPixels () const { return PixelBuffer; }
|
inline uint8_t *GetPixels () const { return Pixels.Data(); }
|
||||||
inline int GetWidth () const { return Width; }
|
inline int GetWidth () const { return Width; }
|
||||||
inline int GetHeight () const { return Height; }
|
inline int GetHeight () const { return Height; }
|
||||||
inline int GetPitch () const { return Pitch; }
|
inline int GetPitch () const { return Pitch; }
|
||||||
inline bool IsBgra() const { return Bgra; }
|
inline bool IsBgra() const { return Bgra; }
|
||||||
|
|
||||||
// Note: pitch here is in pixels, not bytes.
|
|
||||||
bool SetBuffer(int width, int height, int pitch, uint8_t *buffer)
|
|
||||||
{
|
|
||||||
assert(buffer);
|
|
||||||
Width = width;
|
|
||||||
Height = height;
|
|
||||||
Pitch = pitch;
|
|
||||||
PixelBuffer = buffer;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint8_t *PixelBuffer;
|
TArray<uint8_t> Pixels;
|
||||||
int Width;
|
int Width;
|
||||||
int Height;
|
int Height;
|
||||||
int Pitch;
|
int Pitch;
|
||||||
bool Bgra;
|
bool Bgra;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A canvas in system memory.
|
|
||||||
|
|
||||||
class DSimpleCanvas : public DCanvas
|
|
||||||
{
|
|
||||||
typedef DCanvas Super;
|
|
||||||
public:
|
|
||||||
DSimpleCanvas (int width, int height, bool bgra);
|
|
||||||
~DSimpleCanvas ();
|
|
||||||
void Resize(int width, int height);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class FUniquePalette;
|
class FUniquePalette;
|
||||||
class IHardwareTexture;
|
class IHardwareTexture;
|
||||||
class FTexture;
|
class FTexture;
|
||||||
|
@ -349,7 +325,6 @@ class FTexture;
|
||||||
|
|
||||||
class DFrameBuffer
|
class DFrameBuffer
|
||||||
{
|
{
|
||||||
typedef DSimpleCanvas Super;
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void DrawTextureV(FTexture *img, double x, double y, uint32_t tag, va_list tags) = delete;
|
void DrawTextureV(FTexture *img, double x, double y, uint32_t tag, va_list tags) = delete;
|
||||||
|
|
|
@ -2530,22 +2530,7 @@ OPTSTR_SIMPLEARROW = "Simple arrow";
|
||||||
OPTSTR_HERETIC = "Heretic";
|
OPTSTR_HERETIC = "Heretic";
|
||||||
OPTSTR_CHEX = "Chex";
|
OPTSTR_CHEX = "Chex";
|
||||||
OPTSTR_SYSTEMCURSOR = "System cursor";
|
OPTSTR_SYSTEMCURSOR = "System cursor";
|
||||||
OPTSTR_DIRECTSOUND = "DirectSound";
|
|
||||||
OPTSTR_WASAPI = "Vista WASAPI";
|
|
||||||
OPTSTR_ASIO = "ASIO";
|
|
||||||
OPTSTR_WAVEOUT = "WaveOut";
|
|
||||||
OPTSTR_NOSOUND = "No Sound";
|
OPTSTR_NOSOUND = "No Sound";
|
||||||
OPTSTR_OSS = "OSS";
|
|
||||||
OPTSTR_ALSA = "ALSA";
|
|
||||||
OPTSTR_SDL = "SDL";
|
|
||||||
OPTSTR_ESD = "ESD";
|
|
||||||
OPTSTR_PULSEAUDIO = "PulseAudio";
|
|
||||||
OPTSTR_COREAUDIO = "Core Audio";
|
|
||||||
OPTSTR_PCM8BIT = "8-bit";
|
|
||||||
OPTSTR_PCM16BIT = "16-bit";
|
|
||||||
OPTSTR_PCM24BIT = "24-bit";
|
|
||||||
OPTSTR_PCM32BIT = "32-bit";
|
|
||||||
OPTSTR_PCMFLOAT = "32-bit float";
|
|
||||||
OPTSTR_AUTO = "Auto";
|
OPTSTR_AUTO = "Auto";
|
||||||
OPTSTR_MONO = "Mono";
|
OPTSTR_MONO = "Mono";
|
||||||
OPTSTR_STEREO = "Stereo";
|
OPTSTR_STEREO = "Stereo";
|
||||||
|
|
|
@ -1553,16 +1553,6 @@ OptionString ALResamplers
|
||||||
// filled in by the sound code
|
// filled in by the sound code
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionString OutputFormats
|
|
||||||
{
|
|
||||||
"PCM-8", "$OPTSTR_PCM8BIT"
|
|
||||||
"PCM-16", "$OPTSTR_PCM16BIT"
|
|
||||||
"PCM-24", "$OPTSTR_PCM24BIT"
|
|
||||||
"PCM-32", "$OPTSTR_PCM32BIT"
|
|
||||||
"PCM-Float", "$OPTSTR_PCMFLOAT"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
OptionString SpeakerModes
|
OptionString SpeakerModes
|
||||||
{
|
{
|
||||||
"Auto", "$OPTSTR_AUTO"
|
"Auto", "$OPTSTR_AUTO"
|
||||||
|
@ -1585,12 +1575,6 @@ OptionString Resamplers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
OptionString SoundBackendsOpenALOnly
|
|
||||||
{
|
|
||||||
"openal", "$OPTSTR_OPENAL"
|
|
||||||
"null", "$OPTSTR_NOSOUND"
|
|
||||||
}
|
|
||||||
|
|
||||||
OptionMenu OpenALSoundItems protected
|
OptionMenu OpenALSoundItems protected
|
||||||
{
|
{
|
||||||
Title "$OPENALMNU_TITLE"
|
Title "$OPENALMNU_TITLE"
|
||||||
|
@ -1616,23 +1600,8 @@ OptionMenu SoundOptions protected
|
||||||
Option "$SNDMNU_UNDERWATERREVERB", "snd_waterreverb", "OnOff"
|
Option "$SNDMNU_UNDERWATERREVERB", "snd_waterreverb", "OnOff"
|
||||||
Option "$SNDMNU_RANDOMIZEPITCHES", "snd_pitched", "OnOff"
|
Option "$SNDMNU_RANDOMIZEPITCHES", "snd_pitched", "OnOff"
|
||||||
Slider "$SNDMNU_CHANNELS", "snd_channels", 64, 256, 8, 0
|
Slider "$SNDMNU_CHANNELS", "snd_channels", 64, 256, 8, 0
|
||||||
StaticText " "
|
|
||||||
Option "$SNDMNU_BACKGROUND", "i_soundinbackground", "OnOff"
|
|
||||||
StaticText " "
|
|
||||||
|
|
||||||
ifoption(openal)
|
|
||||||
{
|
|
||||||
Option "$SNDMNU_BACKEND", "snd_backend", "SoundBackendsOpenALOnly"
|
|
||||||
Submenu "$SNDMNU_OPENAL", "OpenALSoundItems"
|
|
||||||
}
|
|
||||||
StaticText " "
|
|
||||||
Command "$SNDMNU_RESTART", "snd_reset"
|
|
||||||
|
|
||||||
StaticText " "
|
StaticText " "
|
||||||
Submenu "$SNDMNU_ADVANCED", "AdvSoundOptions"
|
Submenu "$SNDMNU_ADVANCED", "AdvSoundOptions"
|
||||||
Submenu "$SNDMNU_MIDIPLAYER", "MidiPlayerOptions"
|
|
||||||
Submenu "$SNDMNU_MODREPLAYER", "ModReplayerOptions"
|
|
||||||
StaticText " "
|
|
||||||
Submenu "$OPTMNU_REVERB", "ReverbEdit"
|
Submenu "$OPTMNU_REVERB", "ReverbEdit"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1665,6 +1634,21 @@ OptionMenu AdvSoundOptions protected
|
||||||
Title "$ADVSNDMNU_TITLE"
|
Title "$ADVSNDMNU_TITLE"
|
||||||
Option "$ADVSNDMNU_SAMPLERATE", "snd_samplerate", "SampleRates"
|
Option "$ADVSNDMNU_SAMPLERATE", "snd_samplerate", "SampleRates"
|
||||||
Option "$ADVSNDMNU_HRTF", "snd_hrtf", "AutoOffOn"
|
Option "$ADVSNDMNU_HRTF", "snd_hrtf", "AutoOffOn"
|
||||||
|
StaticText " "
|
||||||
|
Option "$SNDMNU_BACKGROUND", "i_soundinbackground", "OnOff"
|
||||||
|
StaticText " "
|
||||||
|
|
||||||
|
ifoption(openal)
|
||||||
|
{
|
||||||
|
StaticText " "
|
||||||
|
Submenu "$SNDMNU_OPENAL", "OpenALSoundItems"
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticText " "
|
||||||
|
Submenu "$SNDMNU_MIDIPLAYER", "MidiPlayerOptions"
|
||||||
|
Submenu "$SNDMNU_MODREPLAYER", "ModReplayerOptions"
|
||||||
|
StaticText " "
|
||||||
|
Command "$SNDMNU_RESTART", "snd_reset"
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionMenu GusConfigMenu protected
|
OptionMenu GusConfigMenu protected
|
||||||
|
|
|
@ -581,6 +581,7 @@ class Actor : Thinker native
|
||||||
native void ClearCounters();
|
native void ClearCounters();
|
||||||
native bool GiveBody (int num, int max=0);
|
native bool GiveBody (int num, int max=0);
|
||||||
native bool HitFloor();
|
native bool HitFloor();
|
||||||
|
native virtual bool Grind(bool items);
|
||||||
native clearscope bool isTeammate(Actor other) const;
|
native clearscope bool isTeammate(Actor other) const;
|
||||||
native clearscope int PlayerNumber() const;
|
native clearscope int PlayerNumber() const;
|
||||||
native void SetFriendPlayer(PlayerInfo player);
|
native void SetFriendPlayer(PlayerInfo player);
|
||||||
|
|
|
@ -144,7 +144,33 @@ class Inventory : Actor native
|
||||||
Spawn ("ItemFog", Pos, ALLOW_REPLACE);
|
Spawn ("ItemFog", Pos, ALLOW_REPLACE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// AInventory :: Grind
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
override bool Grind(bool items)
|
||||||
|
{
|
||||||
|
// Does this grind request even care about items?
|
||||||
|
if (!items)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Dropped items are normally destroyed by crushers. Set the DONTGIB flag,
|
||||||
|
// and they'll act like corpses with it set and be immune to crushers.
|
||||||
|
if (bDropped)
|
||||||
|
{
|
||||||
|
if (!bDontGib)
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Non-dropped items call the super method for compatibility.
|
||||||
|
return Super.Grind(items);
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue