Merge remote-tracking branch 'origin/master' into SoftwareScaling

This commit is contained in:
Magnus Norddahl 2018-12-16 12:10:53 +01:00
commit 57525f1505
30 changed files with 324 additions and 269 deletions

View file

@ -2694,7 +2694,6 @@ static bool LoadDehSupp ()
return false; return false;
} }
bool gotnames = false; bool gotnames = false;
int i;
if (++DehUseCount > 1) if (++DehUseCount > 1)

View file

@ -2453,7 +2453,7 @@ void FParser::SF_PlayerKeys(void)
else else
{ {
givetake = intvalue(t_argv[2]); givetake = intvalue(t_argv[2]);
ScriptUtil::Exec(givetake?NAME_GiveInventory : NAME_TakeInventory, players[playernum].mo, keyname.GetIndex(), 1); ScriptUtil::Exec(givetake?NAME_GiveInventory : NAME_TakeInventory, ScriptUtil::Pointer, players[playernum].mo, ScriptUtil::Int, keyname.GetIndex(), ScriptUtil::Int, 1, ScriptUtil::End);
t_return.type = svt_int; t_return.type = svt_int;
t_return.value.i = 0; t_return.value.i = 0;
} }
@ -2648,7 +2648,7 @@ void FParser::SF_GiveInventory(void)
if(t_argc == 2) count=1; if(t_argc == 2) count=1;
else count=intvalue(t_argv[2]); else count=intvalue(t_argv[2]);
ScriptUtil::Exec(NAME_GiveInventory, ScriptUtil::Pointer, players[playernum].mo, FName(stringvalue(t_argv[1])).GetIndex(), count); ScriptUtil::Exec(NAME_GiveInventory, ScriptUtil::Pointer, players[playernum].mo, ScriptUtil::Int, FName(stringvalue(t_argv[1])).GetIndex(), ScriptUtil::Int, count, ScriptUtil::End);
t_return.type = svt_int; t_return.type = svt_int;
t_return.value.i = 0; t_return.value.i = 0;
} }
@ -2671,7 +2671,7 @@ void FParser::SF_TakeInventory(void)
if(t_argc == 2) count=32767; if(t_argc == 2) count=32767;
else count=intvalue(t_argv[2]); else count=intvalue(t_argv[2]);
ScriptUtil::Exec(NAME_TakeInventory, ScriptUtil::Pointer, players[playernum].mo, FName(stringvalue(t_argv[1])).GetIndex(), count); ScriptUtil::Exec(NAME_TakeInventory, ScriptUtil::Pointer, players[playernum].mo, ScriptUtil::Int, FName(stringvalue(t_argv[1])).GetIndex(), ScriptUtil::Int, count, ScriptUtil::End);
t_return.type = svt_int; t_return.type = svt_int;
t_return.value.i = 0; t_return.value.i = 0;
} }

View file

@ -247,6 +247,7 @@ enum ELevelFlags : unsigned int
LEVEL3_NOCOLOREDSPRITELIGHTING = 0x00000010, // draw sprites only with color-less light LEVEL3_NOCOLOREDSPRITELIGHTING = 0x00000010, // draw sprites only with color-less light
LEVEL3_EXITNORMALUSED = 0x00000020, LEVEL3_EXITNORMALUSED = 0x00000020,
LEVEL3_EXITSECRETUSED = 0x00000040, LEVEL3_EXITSECRETUSED = 0x00000040,
LEVEL3_FORCEWORLDPANNING = 0x00000080, // Forces the world panning flag for all textures, even those without it explicitly set.
}; };

View file

@ -1553,6 +1553,7 @@ MapFlagHandlers[] =
{ "forcefakecontrast", MITYPE_SETFLAG3, LEVEL3_FORCEFAKECONTRAST, 0 }, { "forcefakecontrast", MITYPE_SETFLAG3, LEVEL3_FORCEFAKECONTRAST, 0 },
{ "nolightfade", MITYPE_SETFLAG3, LEVEL3_NOLIGHTFADE, 0 }, { "nolightfade", MITYPE_SETFLAG3, LEVEL3_NOLIGHTFADE, 0 },
{ "nocoloredspritelighting", MITYPE_SETFLAG3, LEVEL3_NOCOLOREDSPRITELIGHTING, 0 }, { "nocoloredspritelighting", MITYPE_SETFLAG3, LEVEL3_NOCOLOREDSPRITELIGHTING, 0 },
{ "forceworldpanning", MITYPE_SETFLAG3, LEVEL3_FORCEWORLDPANNING, 0 },
{ "nobotnodes", MITYPE_IGNORE, 0, 0 }, // Skulltag option: nobotnodes { "nobotnodes", MITYPE_IGNORE, 0, 0 }, // Skulltag option: nobotnodes
{ "compat_shorttex", MITYPE_COMPATFLAG, COMPATF_SHORTTEX, 0 }, { "compat_shorttex", MITYPE_COMPATFLAG, COMPATF_SHORTTEX, 0 },
{ "compat_stairs", MITYPE_COMPATFLAG, COMPATF_STAIRINDEX, 0 }, { "compat_stairs", MITYPE_COMPATFLAG, COMPATF_STAIRINDEX, 0 },

View file

@ -335,7 +335,7 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i
if (!tex->isHardwareCanvas()) if (!tex->isHardwareCanvas())
{ {
texbuffer = std::move(tex->CreateTexBuffer(translation, flags | CTF_ProcessData)); texbuffer = tex->CreateTexBuffer(translation, flags | CTF_ProcessData);
w = texbuffer.mWidth; w = texbuffer.mWidth;
h = texbuffer.mHeight; h = texbuffer.mHeight;
} }

View file

@ -56,6 +56,7 @@ struct RenderJob
WallJob, WallJob,
SpriteJob, SpriteJob,
ParticleJob, ParticleJob,
PortalJob,
TerminateJob // inserted when all work is done so that the worker can return. TerminateJob // inserted when all work is done so that the worker can return.
}; };
@ -177,7 +178,12 @@ void HWDrawInfo::WorkerThread()
RenderParticles(job->sub, front); RenderParticles(job->sub, front);
SetupSprite.Unclock(); SetupSprite.Unclock();
break; break;
case RenderJob::PortalJob:
AddSubsectorToPortal((FSectorPortalGroup *)job->seg, job->sub);
break;
} }
} }
} }
@ -646,7 +652,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
sector->validcount = validcount; sector->validcount = validcount;
sector->MoreFlags |= SECMF_DRAWN; sector->MoreFlags |= SECMF_DRAWN;
if (gl_render_things && sector->touching_renderthings) if (gl_render_things && (sector->touching_renderthings || sector->sectorportal_thinglist))
{ {
if (multithread) if (multithread)
{ {
@ -706,14 +712,32 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
// This is for portal coverage. // This is for portal coverage.
FSectorPortalGroup *portal; FSectorPortalGroup *portal;
// AddSubsectorToPortal cannot be called here when using multithreaded processing,
// because the wall processing code in the worker can also modify the portal state.
// To avoid costly synchronization for every access to the portal list,
// the call to AddSubsectorToPortal will be deferred to the worker.
// (GetPortalGruop only accesses static sector data so this check can be done here, restricting the new job to the minimum possible extent.)
portal = fakesector->GetPortalGroup(sector_t::ceiling); portal = fakesector->GetPortalGroup(sector_t::ceiling);
if (portal != nullptr) if (portal != nullptr)
{
if (multithread)
{
jobQueue.AddJob(RenderJob::PortalJob, sub, (seg_t *)portal);
}
else
{ {
AddSubsectorToPortal(portal, sub); AddSubsectorToPortal(portal, sub);
} }
}
portal = fakesector->GetPortalGroup(sector_t::floor); portal = fakesector->GetPortalGroup(sector_t::floor);
if (portal != nullptr) if (portal != nullptr)
{
if (multithread)
{
jobQueue.AddJob(RenderJob::PortalJob, sub, (seg_t *)portal);
}
else
{ {
AddSubsectorToPortal(portal, sub); AddSubsectorToPortal(portal, sub);
} }
@ -721,6 +745,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
} }
} }
} }
}

View file

@ -483,7 +483,7 @@ inline double CalcIntersectionVertex(GLSprite *s, GLWall * w2)
return ((ay - cy)*(dx - cx) - (ax - cx)*(dy - cy)) / ((bx - ax)*(dy - cy) - (by - ay)*(dx - cx)); return ((ay - cy)*(dx - cx) - (ax - cx)*(dy - cy)) / ((bx - ax)*(dy - cy) - (by - ay)*(dx - cx));
} }
void HWDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort) void HWDrawList::SortSpriteIntoWall(HWDrawInfo *di, SortNode * head,SortNode * sort)
{ {
GLWall *wh= walls[drawitems[head->itemindex].index]; GLWall *wh= walls[drawitems[head->itemindex].index];
GLSprite * ss= sprites[drawitems[sort->itemindex].index]; GLSprite * ss= sprites[drawitems[sort->itemindex].index];
@ -560,6 +560,16 @@ void HWDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort)
head->AddToLeft(sort); head->AddToLeft(sort);
head->AddToRight(sort2); head->AddToRight(sort2);
} }
if (screen->BuffersArePersistent())
{
s->vertexindex = ss->vertexindex = -1;
}
else
{
s->CreateVertices(di);
ss->CreateVertices(di);
}
} }
} }
@ -667,7 +677,7 @@ SortNode * HWDrawList::DoSort(HWDrawInfo *di, SortNode * head)
break; break;
case GLDIT_SPRITE: case GLDIT_SPRITE:
SortSpriteIntoWall(head,node); SortSpriteIntoWall(di, head, node);
break; break;
case GLDIT_FLAT: break; case GLDIT_FLAT: break;

View file

@ -101,7 +101,7 @@ public:
void SortWallIntoPlane(SortNode * head,SortNode * sort); void SortWallIntoPlane(SortNode * head,SortNode * sort);
void SortSpriteIntoPlane(SortNode * head,SortNode * sort); void SortSpriteIntoPlane(SortNode * head,SortNode * sort);
void SortWallIntoWall(HWDrawInfo *di, SortNode * head,SortNode * sort); void SortWallIntoWall(HWDrawInfo *di, SortNode * head,SortNode * sort);
void SortSpriteIntoWall(SortNode * head,SortNode * sort); void SortSpriteIntoWall(HWDrawInfo *di, SortNode * head,SortNode * sort);
int CompareSprites(SortNode * a,SortNode * b); int CompareSprites(SortNode * a,SortNode * b);
SortNode * SortSpriteList(SortNode * head); SortNode * SortSpriteList(SortNode * head);
SortNode * DoSort(HWDrawInfo *di, SortNode * head); SortNode * DoSort(HWDrawInfo *di, SortNode * head);

View file

@ -244,6 +244,7 @@ void GLSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent)
{ {
state.SetNormal(0, 0, 0); state.SetNormal(0, 0, 0);
if (screen->BuffersArePersistent()) if (screen->BuffersArePersistent())
{ {
CreateVertices(di); CreateVertices(di);

View file

@ -165,7 +165,7 @@ void GLWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
} }
state.SetFog(255, 0, di->isFullbrightScene(), nullptr, false); state.SetFog(255, 0, di->isFullbrightScene(), nullptr, false);
} }
if (type != RENDERWALL_COLOR) if (type != RENDERWALL_COLOR && seg->sidedef != nullptr)
{ {
auto side = seg->sidedef; auto side = seg->sidedef;
auto tierndx = renderwalltotier[type]; auto tierndx = renderwalltotier[type];

View file

@ -572,23 +572,22 @@ static int SpawnableSort(const void *a, const void *b)
static void DumpClassMap(FClassMap &themap) static void DumpClassMap(FClassMap &themap)
{ {
FClassMap::Iterator it(themap); FClassMap::Iterator it(themap);
FClassMap::Pair *pair, **allpairs; FClassMap::Pair *pair;
TArray<FClassMap::Pair*> allpairs(themap.CountUsed(), true);
int i = 0; int i = 0;
// Sort into numerical order, since their arrangement in the map can // Sort into numerical order, since their arrangement in the map can
// be in an unspecified order. // be in an unspecified order.
allpairs = new FClassMap::Pair *[themap.CountUsed()];
while (it.NextPair(pair)) while (it.NextPair(pair))
{ {
allpairs[i++] = pair; allpairs[i++] = pair;
} }
qsort(allpairs, i, sizeof(*allpairs), SpawnableSort); qsort(allpairs.Data(), i, sizeof(allpairs[0]), SpawnableSort);
for (int j = 0; j < i; ++j) for (int j = 0; j < i; ++j)
{ {
pair = allpairs[j]; pair = allpairs[j];
Printf ("%d %s\n", pair->Key, pair->Value->TypeName.GetChars()); Printf ("%d %s\n", pair->Key, pair->Value->TypeName.GetChars());
} }
delete[] allpairs;
} }
CCMD(dumpspawnables) CCMD(dumpspawnables)

View file

@ -429,12 +429,8 @@ void player_t::SetLogNumber (int num)
} }
else else
{ {
int length=Wads.LumpLength(lumpnum); auto lump = Wads.ReadLump(lumpnum);
char *data= new char[length+1]; SetLogText (lump.GetString());
Wads.ReadLump (lumpnum, data);
data[length]=0;
SetLogText (data);
delete[] data;
} }
} }

View file

@ -633,8 +633,6 @@ bool FRemapTable::AddToTranslation(const char *range)
sc.OpenMem("translation", range, int(strlen(range))); sc.OpenMem("translation", range, int(strlen(range)));
sc.SetCMode(true); sc.SetCMode(true);
try
{
sc.MustGetToken(TK_IntConst); sc.MustGetToken(TK_IntConst);
start = sc.Number; start = sc.Number;
sc.MustGetToken(':'); sc.MustGetToken(':');
@ -771,12 +769,6 @@ bool FRemapTable::AddToTranslation(const char *range)
return AddIndexRange(start, end, pal1, pal2); return AddIndexRange(start, end, pal1, pal2);
} }
} }
catch (CRecoverableError &err)
{
Printf("Error in translation '%s':\n%s\n", range, err.GetMessage());
return false;
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// //
@ -1529,7 +1521,16 @@ void R_ParseTrnslate()
do do
{ {
sc.MustGetToken(TK_StringConst); sc.MustGetToken(TK_StringConst);
try
{
NewTranslation.AddToTranslation(sc.String); NewTranslation.AddToTranslation(sc.String);
}
catch (CRecoverableError &err)
{
sc.ScriptMessage("Error in translation '%s':\n" TEXTCOLOR_YELLOW "%s\n", sc.String, err.GetMessage());
}
} while (sc.CheckToken(',')); } while (sc.CheckToken(','));
int trans = NewTranslation.StoreTranslation(TRANSLATION_Custom); int trans = NewTranslation.StoreTranslation(TRANSLATION_Custom);

View file

@ -1120,7 +1120,7 @@ void FScanner::ScriptMessage (const char *message, ...)
va_end (arglist); va_end (arglist);
} }
Printf (TEXTCOLOR_RED "Script error, \"%s\" line %d:\n" TEXTCOLOR_RED "%s\n", ScriptName.GetChars(), Printf (TEXTCOLOR_RED "Script error, \"%s\"" TEXTCOLOR_RED "line %d:\n" TEXTCOLOR_RED "%s\n", ScriptName.GetChars(),
AlreadyGot? AlreadyGotLine : Line, composed.GetChars()); AlreadyGot? AlreadyGotLine : Line, composed.GetChars());
} }

View file

@ -2104,6 +2104,7 @@ public:
: FxExpression(EFX_Nop, p) : FxExpression(EFX_Nop, p)
{ {
isresolved = true; isresolved = true;
ValueType = TypeError;
} }
ExpEmit Emit(VMFunctionBuilder *build) ExpEmit Emit(VMFunctionBuilder *build)
{ {

View file

@ -729,7 +729,6 @@ DEFINE_PROPERTY(translation, L, Actor)
else else
{ {
FRemapTable CurrentTranslation; FRemapTable CurrentTranslation;
bool success = true;
CurrentTranslation.MakeIdentity(); CurrentTranslation.MakeIdentity();
for(int i = 1; i < PROP_PARM_COUNT; i++) for(int i = 1; i < PROP_PARM_COUNT; i++)
@ -744,14 +743,17 @@ DEFINE_PROPERTY(translation, L, Actor)
else else
{ {
// parse all ranges to get a complete list of errors, if more than one range fails. // parse all ranges to get a complete list of errors, if more than one range fails.
success |= CurrentTranslation.AddToTranslation(str); try
{
CurrentTranslation.AddToTranslation(str);
}
catch (CRecoverableError &err)
{
bag.ScriptPosition.Message(MSG_WARNING, "Error in translation '%s':\n" TEXTCOLOR_CYAN "%s\n", str, err.GetMessage());
}
} }
} }
defaults->Translation = CurrentTranslation.StoreTranslation (TRANSLATION_Decorate); defaults->Translation = CurrentTranslation.StoreTranslation (TRANSLATION_Decorate);
if (!success)
{
bag.ScriptPosition.Message(MSG_WARNING, "Failed to parse translation");
}
} }
} }

View file

@ -551,7 +551,6 @@ namespace swrenderer
void DrawSingleSky1PalCommand::Execute(DrawerThread *thread) void DrawSingleSky1PalCommand::Execute(DrawerThread *thread)
{ {
uint8_t *dest = args.Dest(); uint8_t *dest = args.Dest();
int count = args.Count();
int pitch = args.Viewport()->RenderTarget->GetPitch(); int pitch = args.Viewport()->RenderTarget->GetPitch();
const uint8_t *source0 = args.FrontTexturePixels(); const uint8_t *source0 = args.FrontTexturePixels();
int textureheight0 = args.FrontTextureHeight(); int textureheight0 = args.FrontTextureHeight();
@ -559,6 +558,25 @@ namespace swrenderer
int32_t frac = args.TextureVPos(); int32_t frac = args.TextureVPos();
int32_t fracstep = args.TextureVStep(); int32_t fracstep = args.TextureVStep();
if (!args.FadeSky())
{
int count = thread->count_for_thread(args.DestY(), args.Count());
for (int index = 0; index < count; index++)
{
uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
*dest = source0[sample_index];
dest += pitch;
frac += fracstep;
}
return;
}
int num_cores = thread->num_cores;
int skipped = thread->skipped_by_thread(args.DestY());
int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores;
// Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color: // Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color:
int start_fade = 2; // How fast it should fade out int start_fade = 2; // How fast it should fade out
int fade_length = (1 << (24 - start_fade)); int fade_length = (1 << (24 - start_fade));
@ -571,28 +589,11 @@ namespace swrenderer
start_fadebottom_y = clamp(start_fadebottom_y, 0, count); start_fadebottom_y = clamp(start_fadebottom_y, 0, count);
end_fadebottom_y = clamp(end_fadebottom_y, 0, count); end_fadebottom_y = clamp(end_fadebottom_y, 0, count);
int num_cores = thread->num_cores;
int skipped = thread->skipped_by_thread(args.DestY());
dest = thread->dest_for_thread(args.DestY(), pitch, dest); dest = thread->dest_for_thread(args.DestY(), pitch, dest);
frac += fracstep * skipped; frac += fracstep * skipped;
fracstep *= num_cores; fracstep *= num_cores;
pitch *= num_cores; pitch *= num_cores;
if (!args.FadeSky())
{
count = thread->count_for_thread(args.DestY(), count);
for (int index = 0; index < count; index++)
{
uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
*dest = source0[sample_index];
dest += pitch;
frac += fracstep;
}
return;
}
uint32_t solid_top = args.SolidTopColor(); uint32_t solid_top = args.SolidTopColor();
uint32_t solid_bottom = args.SolidBottomColor(); uint32_t solid_bottom = args.SolidBottomColor();

View file

@ -39,7 +39,6 @@ namespace swrenderer
void Execute(DrawerThread *thread) override void Execute(DrawerThread *thread) override
{ {
uint32_t *dest = (uint32_t *)args.Dest(); uint32_t *dest = (uint32_t *)args.Dest();
int count = args.Count();
int pitch = args.Viewport()->RenderTarget->GetPitch(); int pitch = args.Viewport()->RenderTarget->GetPitch();
const uint32_t *source0 = (const uint32_t *)args.FrontTexturePixels(); const uint32_t *source0 = (const uint32_t *)args.FrontTexturePixels();
int textureheight0 = args.FrontTextureHeight(); int textureheight0 = args.FrontTextureHeight();
@ -51,6 +50,25 @@ namespace swrenderer
uint32_t solid_bottom = args.SolidBottomColor(); uint32_t solid_bottom = args.SolidBottomColor();
bool fadeSky = args.FadeSky(); bool fadeSky = args.FadeSky();
if (!fadeSky)
{
int count = thread->count_for_thread(args.DestY(), args.Count());
for (int index = 0; index < count; index++)
{
uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
*dest = source0[sample_index];
dest += pitch;
frac += fracstep;
}
return;
}
int num_cores = thread->num_cores;
int skipped = thread->skipped_by_thread(args.DestY());
int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores;
// Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color: // Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color:
int start_fade = 2; // How fast it should fade out int start_fade = 2; // How fast it should fade out
int fade_length = (1 << (24 - start_fade)); int fade_length = (1 << (24 - start_fade));
@ -63,28 +81,11 @@ namespace swrenderer
start_fadebottom_y = clamp(start_fadebottom_y, 0, count); start_fadebottom_y = clamp(start_fadebottom_y, 0, count);
end_fadebottom_y = clamp(end_fadebottom_y, 0, count); end_fadebottom_y = clamp(end_fadebottom_y, 0, count);
int num_cores = thread->num_cores;
int skipped = thread->skipped_by_thread(args.DestY());
dest = thread->dest_for_thread(args.DestY(), pitch, dest); dest = thread->dest_for_thread(args.DestY(), pitch, dest);
frac += fracstep * skipped; frac += fracstep * skipped;
fracstep *= num_cores; fracstep *= num_cores;
pitch *= num_cores; pitch *= num_cores;
if (!fadeSky)
{
count = thread->count_for_thread(args.DestY(), count);
for (int index = 0; index < count; index++)
{
uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
*dest = source0[sample_index];
dest += pitch;
frac += fracstep;
}
return;
}
BgraColor solid_top_fill = solid_top; BgraColor solid_top_fill = solid_top;
BgraColor solid_bottom_fill = solid_bottom; BgraColor solid_bottom_fill = solid_bottom;

View file

@ -38,7 +38,6 @@ namespace swrenderer
void Execute(DrawerThread *thread) override void Execute(DrawerThread *thread) override
{ {
uint32_t *dest = (uint32_t *)args.Dest(); uint32_t *dest = (uint32_t *)args.Dest();
int count = args.Count();
int pitch = args.Viewport()->RenderTarget->GetPitch(); int pitch = args.Viewport()->RenderTarget->GetPitch();
const uint32_t *source0 = (const uint32_t *)args.FrontTexturePixels(); const uint32_t *source0 = (const uint32_t *)args.FrontTexturePixels();
int textureheight0 = args.FrontTextureHeight(); int textureheight0 = args.FrontTextureHeight();
@ -50,6 +49,25 @@ namespace swrenderer
uint32_t solid_bottom = args.SolidBottomColor(); uint32_t solid_bottom = args.SolidBottomColor();
bool fadeSky = args.FadeSky(); bool fadeSky = args.FadeSky();
if (!fadeSky)
{
int count = thread->count_for_thread(args.DestY(), args.Count());
for (int index = 0; index < count; index++)
{
uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
*dest = source0[sample_index];
dest += pitch;
frac += fracstep;
}
return;
}
int num_cores = thread->num_cores;
int skipped = thread->skipped_by_thread(args.DestY());
int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores;
// Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color: // Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color:
int start_fade = 2; // How fast it should fade out int start_fade = 2; // How fast it should fade out
int fade_length = (1 << (24 - start_fade)); int fade_length = (1 << (24 - start_fade));
@ -62,28 +80,11 @@ namespace swrenderer
start_fadebottom_y = clamp(start_fadebottom_y, 0, count); start_fadebottom_y = clamp(start_fadebottom_y, 0, count);
end_fadebottom_y = clamp(end_fadebottom_y, 0, count); end_fadebottom_y = clamp(end_fadebottom_y, 0, count);
int num_cores = thread->num_cores;
int skipped = thread->skipped_by_thread(args.DestY());
dest = thread->dest_for_thread(args.DestY(), pitch, dest); dest = thread->dest_for_thread(args.DestY(), pitch, dest);
frac += fracstep * skipped; frac += fracstep * skipped;
fracstep *= num_cores; fracstep *= num_cores;
pitch *= num_cores; pitch *= num_cores;
if (!fadeSky)
{
count = thread->count_for_thread(args.DestY(), count);
for (int index = 0; index < count; index++)
{
uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
*dest = source0[sample_index];
dest += pitch;
frac += fracstep;
}
return;
}
__m128i solid_top_fill = _mm_unpacklo_epi8(_mm_cvtsi32_si128(solid_top), _mm_setzero_si128()); __m128i solid_top_fill = _mm_unpacklo_epi8(_mm_cvtsi32_si128(solid_top), _mm_setzero_si128());
__m128i solid_bottom_fill = _mm_unpacklo_epi8(_mm_cvtsi32_si128(solid_bottom), _mm_setzero_si128()); __m128i solid_bottom_fill = _mm_unpacklo_epi8(_mm_cvtsi32_si128(solid_bottom), _mm_setzero_si128());

View file

@ -140,6 +140,8 @@ void DrawerThreads::WorkerMain(DrawerThread *thread)
// Grab the commands // Grab the commands
DrawerCommandQueuePtr list = active_commands[thread->current_queue]; DrawerCommandQueuePtr list = active_commands[thread->current_queue];
thread->current_queue++; thread->current_queue++;
thread->numa_start_y = thread->numa_node * viewheight / thread->num_numa_nodes;
thread->numa_end_y = (thread->numa_node + 1) * viewheight / thread->num_numa_nodes;
start_lock.unlock(); start_lock.unlock();
// Do the work: // Do the work:
@ -206,8 +208,6 @@ void DrawerThreads::StartThreads()
thread->num_cores = I_GetNumaNodeThreadCount(numaNode); thread->num_cores = I_GetNumaNodeThreadCount(numaNode);
thread->numa_node = numaNode; thread->numa_node = numaNode;
thread->num_numa_nodes = I_GetNumaNodeCount(); thread->num_numa_nodes = I_GetNumaNodeCount();
thread->numa_start_y = numaNode * viewheight / I_GetNumaNodeCount();
thread->numa_end_y = (numaNode + 1) * viewheight / I_GetNumaNodeCount();
thread->thread = std::thread([=]() { queue->WorkerMain(thread); }); thread->thread = std::thread([=]() { queue->WorkerMain(thread); });
I_SetThreadNumaNode(thread->thread, numaNode); I_SetThreadNumaNode(thread->thread, numaNode);
} }
@ -223,8 +223,6 @@ void DrawerThreads::StartThreads()
thread->num_cores = num_threads; thread->num_cores = num_threads;
thread->numa_node = 0; thread->numa_node = 0;
thread->num_numa_nodes = 1; thread->num_numa_nodes = 1;
thread->numa_start_y = 0;
thread->numa_end_y = viewheight;
thread->thread = std::thread([=]() { queue->WorkerMain(thread); }); thread->thread = std::thread([=]() { queue->WorkerMain(thread); });
I_SetThreadNumaNode(thread->thread, 0); I_SetThreadNumaNode(thread->thread, 0);
} }
@ -288,7 +286,4 @@ void MemcpyCommand::Execute(DrawerThread *thread)
d += dstep; d += dstep;
s += sstep; s += sstep;
} }
thread->numa_start_y = thread->numa_node * viewheight / thread->num_numa_nodes;
thread->numa_end_y = (thread->numa_node + 1) * viewheight / thread->num_numa_nodes;
} }

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "textures/textures.h" #include "textures/textures.h"
#include "v_video.h" #include "v_video.h"
#include "g_levellocals.h"
struct FSoftwareTextureSpan struct FSoftwareTextureSpan
@ -46,7 +47,7 @@ public:
// The feature from hell... :( // The feature from hell... :(
bool useWorldPanning() const bool useWorldPanning() const
{ {
return mTexture->bWorldPanning; return mTexture->bWorldPanning || (level.flags3 & LEVEL3_FORCEWORLDPANNING);
} }
bool isMasked() bool isMasked()

View file

@ -1,4 +1,5 @@
#pragma once #pragma once
#include "sc_man.h"
//========================================================================== //==========================================================================
// //
@ -28,6 +29,7 @@ struct TexPart
class FMultiPatchTexture : public FImageSource class FMultiPatchTexture : public FImageSource
{ {
friend class FTexture;
public: public:
FMultiPatchTexture(int w, int h, const TArray<TexPart> &parts, bool complex, bool textual); FMultiPatchTexture(int w, int h, const TArray<TexPart> &parts, bool complex, bool textual);

View file

@ -53,6 +53,7 @@
#include "imagehelpers.h" #include "imagehelpers.h"
#include "image.h" #include "image.h"
#include "formats/multipatchtexture.h" #include "formats/multipatchtexture.h"
#include "doomerrors.h"
// On the Alpha, accessing the shorts directly if they aren't aligned on a // On the Alpha, accessing the shorts directly if they aren't aligned on a
// 4-byte boundary causes unaligned access warnings. Why it does this at // 4-byte boundary causes unaligned access warnings. Why it does this at
@ -499,7 +500,15 @@ void FMultipatchTextureBuilder::ParsePatch(FScanner &sc, BuildInfo &info, TexPar
do do
{ {
sc.MustGetString(); sc.MustGetString();
try
{
part.Translation->AddToTranslation(sc.String); part.Translation->AddToTranslation(sc.String);
}
catch (CRecoverableError &err)
{
sc.ScriptMessage("Error in translation '%s':\n" TEXTCOLOR_YELLOW "%s\n", sc.String, err.GetMessage());
}
} while (sc.CheckString(",")); } while (sc.CheckString(","));
} }

View file

@ -38,6 +38,7 @@ FSkyBox::FSkyBox(const char *name)
: FTexture(name) : FTexture(name)
{ {
FTextureID texid = TexMan.CheckForTexture(name, ETextureType::Wall); FTextureID texid = TexMan.CheckForTexture(name, ETextureType::Wall);
previous = nullptr;
if (texid.isValid()) if (texid.isValid())
{ {
previous = TexMan.GetTexture(texid); previous = TexMan.GetTexture(texid);

View file

@ -50,6 +50,8 @@
#include "swrenderer/textures/r_swtexture.h" #include "swrenderer/textures/r_swtexture.h"
#include "imagehelpers.h" #include "imagehelpers.h"
#include "image.h" #include "image.h"
#include "formats/multipatchtexture.h"
#include "g_levellocals.h"
FTexture *CreateBrightmapTexture(FImageSource*); FTexture *CreateBrightmapTexture(FImageSource*);
@ -221,8 +223,21 @@ FBitmap FTexture::GetBgraBitmap(PalEntry *remap, int *ptrans)
FTexture *FTexture::GetRawTexture() FTexture *FTexture::GetRawTexture()
{ {
if (OffsetLess) return OffsetLess;
// Reject anything that cannot have been a single-patch multipatch texture in vanilla.
auto image = static_cast<FMultiPatchTexture *>(GetImage());
if (bMultiPatch != 1 || UseType != ETextureType::Wall || Scale.X != 1 || Scale.Y != 1 || bWorldPanning || image == nullptr || image->NumParts != 1)
{
OffsetLess = this;
return this; return this;
} }
// Set up a new texture that directly references the underlying patch.
// From here we cannot retrieve the original texture made for it, so just create a new one.
FImageSource *source = image->Parts[0].Image;
OffsetLess = new FImageTexture(source, "");
TexMan.AddTexture(OffsetLess);
return OffsetLess;
}
void FTexture::SetScaledSize(int fitwidth, int fitheight) void FTexture::SetScaledSize(int fitwidth, int fitheight)
{ {
@ -889,7 +904,7 @@ void FTexCoordInfo::GetFromTexture(FTexture *tex, float x, float y)
mScale.Y = -mScale.Y; mScale.Y = -mScale.Y;
mRenderHeight = -mRenderHeight; mRenderHeight = -mRenderHeight;
} }
mWorldPanning = tex->bWorldPanning; mWorldPanning = tex->bWorldPanning || (level.flags3 & LEVEL3_FORCEWORLDPANNING);
mWidth = tex->GetWidth(); mWidth = tex->GetWidth();
} }

View file

@ -339,7 +339,7 @@ public:
int GetSkyOffset() const { return SkyOffset; } int GetSkyOffset() const { return SkyOffset; }
FTextureID GetID() const { return id; } FTextureID GetID() const { return id; }
PalEntry GetSkyCapColor(bool bottom); PalEntry GetSkyCapColor(bool bottom);
virtual FTexture *GetRawTexture(); // for FMultiPatchTexture to override FTexture *GetRawTexture();
virtual int GetSourceLump() { return SourceLump; } // needed by the scripted GetName method. virtual int GetSourceLump() { return SourceLump; } // needed by the scripted GetName method.
void GetGlowColor(float *data); void GetGlowColor(float *data);
bool isGlowing() const { return bGlowing; } bool isGlowing() const { return bGlowing; }
@ -372,11 +372,12 @@ protected:
public: public:
FHardwareTextureContainer SystemTextures; FHardwareTextureContainer SystemTextures;
protected: protected:
//IHardwareTexture *SystemTexture[2] = { nullptr, nullptr };
FSoftwareTexture *SoftwareTexture = nullptr; FSoftwareTexture *SoftwareTexture = nullptr;
// None of the following pointers are owned by this texture, they are all controlled by the texture manager. // None of the following pointers are owned by this texture, they are all controlled by the texture manager.
// Offset-less version for COMPATF_MASKEDMIDTEX
FTexture *OffsetLess = nullptr;
// Paletted variant // Paletted variant
FTexture *PalVersion = nullptr; FTexture *PalVersion = nullptr;
// External hires texture // External hires texture

View file

@ -149,7 +149,7 @@ public:
FSinglePicFont(const char *picname); FSinglePicFont(const char *picname);
// FFont interface // FFont interface
FTexture *GetChar (int code, int *const width) const; FTexture *GetChar(int code, int translation, int *const width, bool *redirected = nullptr) const override;
int GetCharWidth (int code) const; int GetCharWidth (int code) const;
protected: protected:
@ -381,20 +381,19 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
if (charLumps[i] != nullptr) if (charLumps[i] != nullptr)
{ {
Chars[i].OriginalPic = charLumps[i];
if (!noTranslate) if (!noTranslate)
{ {
Chars[i].OriginalPic = charLumps[i];
Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charLumps[i]->GetImage()), ""); Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charLumps[i]->GetImage()), "");
TexMan.AddTexture(Chars[i].TranslatedPic); TexMan.AddTexture(Chars[i].TranslatedPic);
} }
else Chars[i].TranslatedPic = charLumps[i]; else Chars[i].TranslatedPic = charLumps[i];
Chars[i].XMove = Chars[i].OriginalPic->GetDisplayWidth(); Chars[i].XMove = Chars[i].TranslatedPic->GetDisplayWidth();
} }
else else
{ {
Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr; Chars[i].TranslatedPic = nullptr;
Chars[i].XMove = INT_MIN; Chars[i].XMove = INT_MIN;
} }
} }
@ -403,7 +402,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
{ {
SpaceWidth = spacewidth; SpaceWidth = spacewidth;
} }
else if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].OriginalPic != nullptr) else if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].TranslatedPic != nullptr)
{ {
SpaceWidth = (Chars['N' - first].XMove + 1) / 2; SpaceWidth = (Chars['N' - first].XMove + 1) / 2;
} }
@ -706,7 +705,7 @@ int FFont::GetCharCode(int code, bool needpic) const
// regular chars turn negative when the 8th bit is set. // regular chars turn negative when the 8th bit is set.
code &= 255; code &= 255;
} }
if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].OriginalPic != nullptr)) if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].TranslatedPic != nullptr))
{ {
return code; return code;
} }
@ -714,7 +713,7 @@ int FFont::GetCharCode(int code, bool needpic) const
if (myislower(code)) if (myislower(code))
{ {
code -= 32; code -= 32;
if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].OriginalPic != nullptr)) if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].TranslatedPic != nullptr))
{ {
return code; return code;
} }
@ -724,7 +723,7 @@ int FFont::GetCharCode(int code, bool needpic) const
if (newcode != code) if (newcode != code)
{ {
code = newcode; code = newcode;
if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].OriginalPic != nullptr)) if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].TranslatedPic != nullptr))
{ {
return code; return code;
} }
@ -747,7 +746,7 @@ FTexture *FFont::GetChar (int code, int translation, int *const width, bool *red
{ {
code -= FirstChar; code -= FirstChar;
xmove = Chars[code].XMove; xmove = Chars[code].XMove;
if (Chars[code].OriginalPic == nullptr) if (Chars[code].TranslatedPic == nullptr)
{ {
code = GetCharCode(code + FirstChar, true); code = GetCharCode(code + FirstChar, true);
if (code >= 0) if (code >= 0)
@ -766,8 +765,9 @@ FTexture *FFont::GetChar (int code, int translation, int *const width, bool *red
if (translation == CR_UNTRANSLATED) if (translation == CR_UNTRANSLATED)
{ {
if (redirected) bool redirect = Chars[code].OriginalPic && Chars[code].OriginalPic != Chars[code].TranslatedPic;
*redirected = Chars[code].OriginalPic != Chars[code].TranslatedPic; if (redirected) *redirected = redirect;
if (redirect)
return Chars[code].OriginalPic; return Chars[code].OriginalPic;
} }
if (redirected) *redirected = false; if (redirected) *redirected = false;
@ -899,6 +899,8 @@ FFont::FFont (int lump)
FontName = NAME_None; FontName = NAME_None;
Cursor = '_'; Cursor = '_';
noTranslate = false; noTranslate = false;
uint8_t pp = 0;
for (auto &p : PatchRemap) p = pp++;
} }
//========================================================================== //==========================================================================
@ -961,7 +963,7 @@ void FSingleLumpFont::CreateFontFromPic (FTextureID picnum)
FirstChar = LastChar = 'A'; FirstChar = LastChar = 'A';
Chars.Resize(1); Chars.Resize(1);
Chars[0].TranslatedPic = Chars[0].OriginalPic = pic; Chars[0].TranslatedPic = pic;
// Only one color range. Don't bother with the others. // Only one color range. Don't bother with the others.
ActiveColors = 0; ActiveColors = 0;
@ -1038,10 +1040,6 @@ void FSingleLumpFont::LoadFON1 (int lump, const uint8_t *data)
LastChar = 255; LastChar = 255;
GlobalKerning = 0; GlobalKerning = 0;
translateUntranslated = true; translateUntranslated = true;
for(unsigned int i = 0;i < 256;++i)
Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr;
LoadTranslations(); LoadTranslations();
} }
@ -1126,12 +1124,12 @@ void FSingleLumpFont::LoadFON2 (int lump, const uint8_t *data)
Chars[i].XMove = widths2[i]; Chars[i].XMove = widths2[i];
if (destSize <= 0) if (destSize <= 0)
{ {
Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr; Chars[i].TranslatedPic = nullptr;
} }
else else
{ {
Chars[i].TranslatedPic = Chars[i].OriginalPic = new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight)); Chars[i].TranslatedPic = new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight));
TexMan.AddTexture(Chars[i].OriginalPic); TexMan.AddTexture(Chars[i].TranslatedPic);
do do
{ {
int8_t code = *data_p++; int8_t code = *data_p++;
@ -1214,12 +1212,6 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data)
} }
count = LastChar - FirstChar + 1; count = LastChar - FirstChar + 1;
Chars.Resize(count); Chars.Resize(count);
for (i = 0; i < count; ++i)
{
Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr;
Chars[i].XMove = INT_MIN;
}
// BMF palettes are only six bits per component. Fix that. // BMF palettes are only six bits per component. Fix that.
for (i = 0; i < ActiveColors*3; ++i) for (i = 0; i < ActiveColors*3; ++i)
{ {
@ -1271,7 +1263,7 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data)
-(int8_t)chardata[chari+3], // x offset -(int8_t)chardata[chari+3], // x offset
-(int8_t)chardata[chari+4] // y offset -(int8_t)chardata[chari+4] // y offset
)); ));
Chars[chardata[chari] - FirstChar].TranslatedPic = Chars[chardata[chari] - FirstChar].OriginalPic = tex; Chars[chardata[chari] - FirstChar].TranslatedPic = tex;
TexMan.AddTexture(tex); TexMan.AddTexture(tex);
} }
@ -1335,13 +1327,12 @@ void FSingleLumpFont::CheckFON1Chars (double *luminosity)
{ {
int destSize = SpaceWidth * FontHeight; int destSize = SpaceWidth * FontHeight;
if(!Chars[i].OriginalPic) if(!Chars[i].TranslatedPic)
{ {
Chars[i].OriginalPic = new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight)); Chars[i].TranslatedPic = new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight));
Chars[i].XMove = SpaceWidth; Chars[i].XMove = SpaceWidth;
TexMan.AddTexture(Chars[i].OriginalPic); TexMan.AddTexture(Chars[i].TranslatedPic);
} }
Chars[i].TranslatedPic = Chars[i].OriginalPic;
// Advance to next char's data and count the used colors. // Advance to next char's data and count the used colors.
do do
@ -1474,9 +1465,10 @@ FSinglePicFont::FSinglePicFont(const char *picname) :
// //
//========================================================================== //==========================================================================
FTexture *FSinglePicFont::GetChar (int code, int *const width) const FTexture *FSinglePicFont::GetChar (int code, int translation, int *const width, bool *redirected) const
{ {
*width = SpaceWidth; *width = SpaceWidth;
if (redirected) *redirected = false;
if (code == 'a' || code == 'A') if (code == 'a' || code == 'A')
{ {
return TexMan.GetPalettedTexture(PicNum, true); return TexMan.GetPalettedTexture(PicNum, true);
@ -1557,17 +1549,17 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
TexMan.AddTexture(Chars[i].TranslatedPic); TexMan.AddTexture(Chars[i].TranslatedPic);
} }
else Chars[i].TranslatedPic = charlumps[i]; else Chars[i].TranslatedPic = charlumps[i];
Chars[i].XMove = Chars[i].OriginalPic->GetDisplayWidth(); Chars[i].XMove = Chars[i].TranslatedPic->GetDisplayWidth();
} }
else else
{ {
Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr; Chars[i].TranslatedPic = nullptr;
Chars[i].XMove = INT_MIN; Chars[i].XMove = INT_MIN;
} }
} }
// Special fonts normally don't have all characters so be careful here! // Special fonts normally don't have all characters so be careful here!
if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].OriginalPic != nullptr) if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].TranslatedPic != nullptr)
{ {
SpaceWidth = (Chars['N' - first].XMove + 1) / 2; SpaceWidth = (Chars['N' - first].XMove + 1) / 2;
} }

View file

@ -82,7 +82,7 @@ public:
FFont (const char *fontname, const char *nametemplate, int first, int count, int base, int fdlump, int spacewidth=-1, bool notranslate = false); FFont (const char *fontname, const char *nametemplate, int first, int count, int base, int fdlump, int spacewidth=-1, bool notranslate = false);
virtual ~FFont (); virtual ~FFont ();
FTexture *GetChar (int code, int translation, int *const width, bool *redirected = nullptr) const; virtual FTexture *GetChar (int code, int translation, int *const width, bool *redirected = nullptr) const;
virtual int GetCharWidth (int code) const; virtual int GetCharWidth (int code) const;
FRemapTable *GetColorTranslation (EColorRange range, PalEntry *color = nullptr) const; FRemapTable *GetColorTranslation (EColorRange range, PalEntry *color = nullptr) const;
int GetLump() const { return Lump; } int GetLump() const { return Lump; }
@ -123,9 +123,9 @@ protected:
bool translateUntranslated; bool translateUntranslated;
struct CharData struct CharData
{ {
FTexture *TranslatedPic; // Texture for use with font translations. FTexture *TranslatedPic = nullptr; // Texture for use with font translations.
FTexture *OriginalPic; // Texture for use with CR_UNTRANSLATED or font colorization. FTexture *OriginalPic = nullptr; // Texture for use with CR_UNTRANSLATED or font colorization.
int XMove; int XMove = INT_MIN;
}; };
TArray<CharData> Chars; TArray<CharData> Chars;
int ActiveColors; int ActiveColors;

View file

@ -169,15 +169,16 @@ void DFrameBuffer::DrawChar(FFont *font, int normalcolor, double x, double y, in
FTexture *pic; FTexture *pic;
int dummy; int dummy;
bool redirected;
if (NULL != (pic = font->GetChar(character, normalcolor, &dummy))) if (NULL != (pic = font->GetChar(character, normalcolor, &dummy, &redirected)))
{ {
DrawParms parms; DrawParms parms;
uint32_t tag = ListGetInt(args); uint32_t tag = ListGetInt(args);
bool res = ParseDrawTextureTags(pic, x, y, tag, args, &parms, false); bool res = ParseDrawTextureTags(pic, x, y, tag, args, &parms, false);
if (!res) return; if (!res) return;
PalEntry color = 0xffffffff; PalEntry color = 0xffffffff;
parms.remap = font->GetColorTranslation((EColorRange)normalcolor, &color); parms.remap = redirected ? nullptr : font->GetColorTranslation((EColorRange)normalcolor, &color);
parms.color = PalEntry((color.a * parms.color.a) / 255, (color.r * parms.color.r) / 255, (color.g * parms.color.g) / 255, (color.b * parms.color.b) / 255); parms.color = PalEntry((color.a * parms.color.a) / 255, (color.r * parms.color.r) / 255, (color.g * parms.color.g) / 255, (color.b * parms.color.b) / 255);
DrawTextureParms(pic, parms); DrawTextureParms(pic, parms);
} }

View file

@ -912,7 +912,6 @@ int I_PickIWad(WadStuff *wads, int numwads, bool showwin, int defaultiwad)
// //
//========================================================================== //==========================================================================
// Custom cursors temporarily disabled until this can directly reference a texture's backing image.
bool I_SetCursor(FTexture *cursorpic) bool I_SetCursor(FTexture *cursorpic)
{ {
HCURSOR cursor; HCURSOR cursor;