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;
}
bool gotnames = false;
int i;
if (++DehUseCount > 1)

View file

@ -2453,7 +2453,7 @@ void FParser::SF_PlayerKeys(void)
else
{
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.value.i = 0;
}
@ -2648,7 +2648,7 @@ void FParser::SF_GiveInventory(void)
if(t_argc == 2) count=1;
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.value.i = 0;
}
@ -2671,7 +2671,7 @@ void FParser::SF_TakeInventory(void)
if(t_argc == 2) count=32767;
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.value.i = 0;
}

View file

@ -247,6 +247,7 @@ enum ELevelFlags : unsigned int
LEVEL3_NOCOLOREDSPRITELIGHTING = 0x00000010, // draw sprites only with color-less light
LEVEL3_EXITNORMALUSED = 0x00000020,
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 },
{ "nolightfade", MITYPE_SETFLAG3, LEVEL3_NOLIGHTFADE, 0 },
{ "nocoloredspritelighting", MITYPE_SETFLAG3, LEVEL3_NOCOLOREDSPRITELIGHTING, 0 },
{ "forceworldpanning", MITYPE_SETFLAG3, LEVEL3_FORCEWORLDPANNING, 0 },
{ "nobotnodes", MITYPE_IGNORE, 0, 0 }, // Skulltag option: nobotnodes
{ "compat_shorttex", MITYPE_COMPATFLAG, COMPATF_SHORTTEX, 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())
{
texbuffer = std::move(tex->CreateTexBuffer(translation, flags | CTF_ProcessData));
texbuffer = tex->CreateTexBuffer(translation, flags | CTF_ProcessData);
w = texbuffer.mWidth;
h = texbuffer.mHeight;
}

View file

@ -56,6 +56,7 @@ struct RenderJob
WallJob,
SpriteJob,
ParticleJob,
PortalJob,
TerminateJob // inserted when all work is done so that the worker can return.
};
@ -177,7 +178,12 @@ void HWDrawInfo::WorkerThread()
RenderParticles(job->sub, front);
SetupSprite.Unclock();
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->MoreFlags |= SECMF_DRAWN;
if (gl_render_things && sector->touching_renderthings)
if (gl_render_things && (sector->touching_renderthings || sector->sectorportal_thinglist))
{
if (multithread)
{
@ -706,16 +712,35 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
// This is for portal coverage.
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);
if (portal != nullptr)
{
AddSubsectorToPortal(portal, sub);
if (multithread)
{
jobQueue.AddJob(RenderJob::PortalJob, sub, (seg_t *)portal);
}
else
{
AddSubsectorToPortal(portal, sub);
}
}
portal = fakesector->GetPortalGroup(sector_t::floor);
if (portal != nullptr)
{
AddSubsectorToPortal(portal, sub);
if (multithread)
{
jobQueue.AddJob(RenderJob::PortalJob, sub, (seg_t *)portal);
}
else
{
AddSubsectorToPortal(portal, 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));
}
void HWDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort)
void HWDrawList::SortSpriteIntoWall(HWDrawInfo *di, SortNode * head,SortNode * sort)
{
GLWall *wh= walls[drawitems[head->itemindex].index];
GLSprite * ss= sprites[drawitems[sort->itemindex].index];
@ -560,6 +560,16 @@ void HWDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort)
head->AddToLeft(sort);
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;
case GLDIT_SPRITE:
SortSpriteIntoWall(head,node);
SortSpriteIntoWall(di, head, node);
break;
case GLDIT_FLAT: break;

View file

@ -101,7 +101,7 @@ public:
void SortWallIntoPlane(SortNode * head,SortNode * sort);
void SortSpriteIntoPlane(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);
SortNode * SortSpriteList(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);
if (screen->BuffersArePersistent())
{
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);
}
if (type != RENDERWALL_COLOR)
if (type != RENDERWALL_COLOR && seg->sidedef != nullptr)
{
auto side = seg->sidedef;
auto tierndx = renderwalltotier[type];

View file

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

View file

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

View file

@ -633,148 +633,140 @@ bool FRemapTable::AddToTranslation(const char *range)
sc.OpenMem("translation", range, int(strlen(range)));
sc.SetCMode(true);
try
sc.MustGetToken(TK_IntConst);
start = sc.Number;
sc.MustGetToken(':');
sc.MustGetToken(TK_IntConst);
end = sc.Number;
sc.MustGetToken('=');
if (start < 0 || start > 255 || end < 0 || end > 255)
{
sc.ScriptError("Palette index out of range");
return false;
}
sc.MustGetAnyToken();
if (sc.TokenType == '[')
{
// translation using RGB values
int r1,g1,b1,r2,g2,b2;
sc.MustGetToken(TK_IntConst);
start = sc.Number;
r1 = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
g1 = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
b1 = sc.Number;
sc.MustGetToken(']');
sc.MustGetToken(':');
sc.MustGetToken('[');
sc.MustGetToken(TK_IntConst);
end = sc.Number;
sc.MustGetToken('=');
if (start < 0 || start > 255 || end < 0 || end > 255)
{
sc.ScriptError("Palette index out of range");
return false;
}
r2 = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
g2 = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
b2 = sc.Number;
sc.MustGetToken(']');
return AddColorRange(start, end, r1, g1, b1, r2, g2, b2);
}
else if (sc.TokenType == '%')
{
// translation using RGB values
double r1,g1,b1,r2,g2,b2;
sc.MustGetToken('[');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
r1 = sc.Float;
sc.MustGetToken(',');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
g1 = sc.Float;
sc.MustGetToken(',');
if (sc.TokenType == '[')
{
// translation using RGB values
int r1,g1,b1,r2,g2,b2;
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
b1 = sc.Float;
sc.MustGetToken(']');
sc.MustGetToken(':');
sc.MustGetToken('[');
sc.MustGetToken(TK_IntConst);
r1 = sc.Number;
sc.MustGetToken(',');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
r2 = sc.Float;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
g1 = sc.Number;
sc.MustGetToken(',');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
g2 = sc.Float;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
b1 = sc.Number;
sc.MustGetToken(']');
sc.MustGetToken(':');
sc.MustGetToken('[');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
b2 = sc.Float;
sc.MustGetToken(']');
sc.MustGetToken(TK_IntConst);
r2 = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
g2 = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
b2 = sc.Number;
sc.MustGetToken(']');
return AddColorRange(start, end, r1, g1, b1, r2, g2, b2);
}
else if (sc.TokenType == '%')
{
// translation using RGB values
double r1,g1,b1,r2,g2,b2;
sc.MustGetToken('[');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
r1 = sc.Float;
sc.MustGetToken(',');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
g1 = sc.Float;
sc.MustGetToken(',');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
b1 = sc.Float;
sc.MustGetToken(']');
sc.MustGetToken(':');
sc.MustGetToken('[');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
r2 = sc.Float;
sc.MustGetToken(',');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
g2 = sc.Float;
sc.MustGetToken(',');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
b2 = sc.Float;
sc.MustGetToken(']');
return AddDesaturation(start, end, r1, g1, b1, r2, g2, b2);
}
else if (sc.TokenType == '#')
{
// Colourise translation
int r, g, b;
sc.MustGetToken('[');
sc.MustGetToken(TK_IntConst);
r = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
g = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
b = sc.Number;
sc.MustGetToken(']');
return AddColourisation(start, end, r, g, b);
}
else if (sc.TokenType == '@')
{
// Tint translation
int a, r, g, b;
sc.MustGetToken(TK_IntConst);
a = sc.Number;
sc.MustGetToken('[');
sc.MustGetToken(TK_IntConst);
r = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
g = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
b = sc.Number;
sc.MustGetToken(']');
return AddTint(start, end, r, g, b, a);
}
else
{
int pal1, pal2;
sc.TokenMustBe(TK_IntConst);
pal1 = sc.Number;
sc.MustGetToken(':');
sc.MustGetToken(TK_IntConst);
pal2 = sc.Number;
return AddIndexRange(start, end, pal1, pal2);
}
return AddDesaturation(start, end, r1, g1, b1, r2, g2, b2);
}
catch (CRecoverableError &err)
else if (sc.TokenType == '#')
{
Printf("Error in translation '%s':\n%s\n", range, err.GetMessage());
return false;
// Colourise translation
int r, g, b;
sc.MustGetToken('[');
sc.MustGetToken(TK_IntConst);
r = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
g = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
b = sc.Number;
sc.MustGetToken(']');
return AddColourisation(start, end, r, g, b);
}
else if (sc.TokenType == '@')
{
// Tint translation
int a, r, g, b;
sc.MustGetToken(TK_IntConst);
a = sc.Number;
sc.MustGetToken('[');
sc.MustGetToken(TK_IntConst);
r = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
g = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
b = sc.Number;
sc.MustGetToken(']');
return AddTint(start, end, r, g, b, a);
}
else
{
int pal1, pal2;
sc.TokenMustBe(TK_IntConst);
pal1 = sc.Number;
sc.MustGetToken(':');
sc.MustGetToken(TK_IntConst);
pal2 = sc.Number;
return AddIndexRange(start, end, pal1, pal2);
}
}
@ -1529,7 +1521,16 @@ void R_ParseTrnslate()
do
{
sc.MustGetToken(TK_StringConst);
NewTranslation.AddToTranslation(sc.String);
try
{
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(','));
int trans = NewTranslation.StoreTranslation(TRANSLATION_Custom);

View file

@ -1120,7 +1120,7 @@ void FScanner::ScriptMessage (const char *message, ...)
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());
}

View file

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

View file

@ -729,7 +729,6 @@ DEFINE_PROPERTY(translation, L, Actor)
else
{
FRemapTable CurrentTranslation;
bool success = true;
CurrentTranslation.MakeIdentity();
for(int i = 1; i < PROP_PARM_COUNT; i++)
@ -744,14 +743,17 @@ DEFINE_PROPERTY(translation, L, Actor)
else
{
// 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);
if (!success)
{
bag.ScriptPosition.Message(MSG_WARNING, "Failed to parse translation");
}
}
}

View file

@ -551,7 +551,6 @@ namespace swrenderer
void DrawSingleSky1PalCommand::Execute(DrawerThread *thread)
{
uint8_t *dest = args.Dest();
int count = args.Count();
int pitch = args.Viewport()->RenderTarget->GetPitch();
const uint8_t *source0 = args.FrontTexturePixels();
int textureheight0 = args.FrontTextureHeight();
@ -559,6 +558,25 @@ namespace swrenderer
int32_t frac = args.TextureVPos();
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:
int start_fade = 2; // How fast it should fade out
int fade_length = (1 << (24 - start_fade));
@ -571,28 +589,11 @@ namespace swrenderer
start_fadebottom_y = clamp(start_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);
frac += fracstep * skipped;
fracstep *= 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_bottom = args.SolidBottomColor();

View file

@ -39,7 +39,6 @@ namespace swrenderer
void Execute(DrawerThread *thread) override
{
uint32_t *dest = (uint32_t *)args.Dest();
int count = args.Count();
int pitch = args.Viewport()->RenderTarget->GetPitch();
const uint32_t *source0 = (const uint32_t *)args.FrontTexturePixels();
int textureheight0 = args.FrontTextureHeight();
@ -51,6 +50,25 @@ namespace swrenderer
uint32_t solid_bottom = args.SolidBottomColor();
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:
int start_fade = 2; // How fast it should fade out
int fade_length = (1 << (24 - start_fade));
@ -63,28 +81,11 @@ namespace swrenderer
start_fadebottom_y = clamp(start_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);
frac += fracstep * skipped;
fracstep *= 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_bottom_fill = solid_bottom;

View file

@ -38,7 +38,6 @@ namespace swrenderer
void Execute(DrawerThread *thread) override
{
uint32_t *dest = (uint32_t *)args.Dest();
int count = args.Count();
int pitch = args.Viewport()->RenderTarget->GetPitch();
const uint32_t *source0 = (const uint32_t *)args.FrontTexturePixels();
int textureheight0 = args.FrontTextureHeight();
@ -50,6 +49,25 @@ namespace swrenderer
uint32_t solid_bottom = args.SolidBottomColor();
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:
int start_fade = 2; // How fast it should fade out
int fade_length = (1 << (24 - start_fade));
@ -62,28 +80,11 @@ namespace swrenderer
start_fadebottom_y = clamp(start_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);
frac += fracstep * skipped;
fracstep *= 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_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
DrawerCommandQueuePtr list = active_commands[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();
// Do the work:
@ -206,8 +208,6 @@ void DrawerThreads::StartThreads()
thread->num_cores = I_GetNumaNodeThreadCount(numaNode);
thread->numa_node = numaNode;
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); });
I_SetThreadNumaNode(thread->thread, numaNode);
}
@ -223,8 +223,6 @@ void DrawerThreads::StartThreads()
thread->num_cores = num_threads;
thread->numa_node = 0;
thread->num_numa_nodes = 1;
thread->numa_start_y = 0;
thread->numa_end_y = viewheight;
thread->thread = std::thread([=]() { queue->WorkerMain(thread); });
I_SetThreadNumaNode(thread->thread, 0);
}
@ -288,7 +286,4 @@ void MemcpyCommand::Execute(DrawerThread *thread)
d += dstep;
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
#include "textures/textures.h"
#include "v_video.h"
#include "g_levellocals.h"
struct FSoftwareTextureSpan
@ -46,7 +47,7 @@ public:
// The feature from hell... :(
bool useWorldPanning() const
{
return mTexture->bWorldPanning;
return mTexture->bWorldPanning || (level.flags3 & LEVEL3_FORCEWORLDPANNING);
}
bool isMasked()

View file

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

View file

@ -53,6 +53,7 @@
#include "imagehelpers.h"
#include "image.h"
#include "formats/multipatchtexture.h"
#include "doomerrors.h"
// 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
@ -499,7 +500,15 @@ void FMultipatchTextureBuilder::ParsePatch(FScanner &sc, BuildInfo &info, TexPar
do
{
sc.MustGetString();
part.Translation->AddToTranslation(sc.String);
try
{
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(","));
}

View file

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

View file

@ -50,6 +50,8 @@
#include "swrenderer/textures/r_swtexture.h"
#include "imagehelpers.h"
#include "image.h"
#include "formats/multipatchtexture.h"
#include "g_levellocals.h"
FTexture *CreateBrightmapTexture(FImageSource*);
@ -221,7 +223,20 @@ FBitmap FTexture::GetBgraBitmap(PalEntry *remap, int *ptrans)
FTexture *FTexture::GetRawTexture()
{
return this;
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;
}
// 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)
@ -889,7 +904,7 @@ void FTexCoordInfo::GetFromTexture(FTexture *tex, float x, float y)
mScale.Y = -mScale.Y;
mRenderHeight = -mRenderHeight;
}
mWorldPanning = tex->bWorldPanning;
mWorldPanning = tex->bWorldPanning || (level.flags3 & LEVEL3_FORCEWORLDPANNING);
mWidth = tex->GetWidth();
}

View file

@ -339,7 +339,7 @@ public:
int GetSkyOffset() const { return SkyOffset; }
FTextureID GetID() const { return id; }
PalEntry GetSkyCapColor(bool bottom);
virtual FTexture *GetRawTexture(); // for FMultiPatchTexture to override
FTexture *GetRawTexture();
virtual int GetSourceLump() { return SourceLump; } // needed by the scripted GetName method.
void GetGlowColor(float *data);
bool isGlowing() const { return bGlowing; }
@ -372,11 +372,12 @@ protected:
public:
FHardwareTextureContainer SystemTextures;
protected:
//IHardwareTexture *SystemTexture[2] = { nullptr, nullptr };
FSoftwareTexture *SoftwareTexture = nullptr;
// 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
FTexture *PalVersion = nullptr;
// External hires texture

View file

@ -149,7 +149,7 @@ public:
FSinglePicFont(const char *picname);
// 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;
protected:
@ -381,20 +381,19 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
if (charLumps[i] != nullptr)
{
Chars[i].OriginalPic = charLumps[i];
if (!noTranslate)
{
Chars[i].OriginalPic = charLumps[i];
Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charLumps[i]->GetImage()), "");
TexMan.AddTexture(Chars[i].TranslatedPic);
}
else Chars[i].TranslatedPic = charLumps[i];
Chars[i].XMove = Chars[i].OriginalPic->GetDisplayWidth();
Chars[i].XMove = Chars[i].TranslatedPic->GetDisplayWidth();
}
else
{
Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr;
Chars[i].TranslatedPic = nullptr;
Chars[i].XMove = INT_MIN;
}
}
@ -403,7 +402,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
{
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;
}
@ -706,7 +705,7 @@ int FFont::GetCharCode(int code, bool needpic) const
// regular chars turn negative when the 8th bit is set.
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;
}
@ -714,7 +713,7 @@ int FFont::GetCharCode(int code, bool needpic) const
if (myislower(code))
{
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;
}
@ -724,7 +723,7 @@ int FFont::GetCharCode(int code, bool needpic) const
if (newcode != code)
{
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;
}
@ -747,7 +746,7 @@ FTexture *FFont::GetChar (int code, int translation, int *const width, bool *red
{
code -= FirstChar;
xmove = Chars[code].XMove;
if (Chars[code].OriginalPic == nullptr)
if (Chars[code].TranslatedPic == nullptr)
{
code = GetCharCode(code + FirstChar, true);
if (code >= 0)
@ -766,9 +765,10 @@ FTexture *FFont::GetChar (int code, int translation, int *const width, bool *red
if (translation == CR_UNTRANSLATED)
{
if (redirected)
*redirected = Chars[code].OriginalPic != Chars[code].TranslatedPic;
return Chars[code].OriginalPic;
bool redirect = Chars[code].OriginalPic && Chars[code].OriginalPic != Chars[code].TranslatedPic;
if (redirected) *redirected = redirect;
if (redirect)
return Chars[code].OriginalPic;
}
if (redirected) *redirected = false;
return Chars[code].TranslatedPic;
@ -899,6 +899,8 @@ FFont::FFont (int lump)
FontName = NAME_None;
Cursor = '_';
noTranslate = false;
uint8_t pp = 0;
for (auto &p : PatchRemap) p = pp++;
}
//==========================================================================
@ -961,7 +963,7 @@ void FSingleLumpFont::CreateFontFromPic (FTextureID picnum)
FirstChar = LastChar = 'A';
Chars.Resize(1);
Chars[0].TranslatedPic = Chars[0].OriginalPic = pic;
Chars[0].TranslatedPic = pic;
// Only one color range. Don't bother with the others.
ActiveColors = 0;
@ -1038,10 +1040,6 @@ void FSingleLumpFont::LoadFON1 (int lump, const uint8_t *data)
LastChar = 255;
GlobalKerning = 0;
translateUntranslated = true;
for(unsigned int i = 0;i < 256;++i)
Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr;
LoadTranslations();
}
@ -1126,12 +1124,12 @@ void FSingleLumpFont::LoadFON2 (int lump, const uint8_t *data)
Chars[i].XMove = widths2[i];
if (destSize <= 0)
{
Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr;
Chars[i].TranslatedPic = nullptr;
}
else
{
Chars[i].TranslatedPic = Chars[i].OriginalPic = new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight));
TexMan.AddTexture(Chars[i].OriginalPic);
Chars[i].TranslatedPic = new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight));
TexMan.AddTexture(Chars[i].TranslatedPic);
do
{
int8_t code = *data_p++;
@ -1214,12 +1212,6 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data)
}
count = LastChar - FirstChar + 1;
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.
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+4] // y offset
));
Chars[chardata[chari] - FirstChar].TranslatedPic = Chars[chardata[chari] - FirstChar].OriginalPic = tex;
Chars[chardata[chari] - FirstChar].TranslatedPic = tex;
TexMan.AddTexture(tex);
}
@ -1335,13 +1327,12 @@ void FSingleLumpFont::CheckFON1Chars (double *luminosity)
{
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;
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.
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;
if (redirected) *redirected = false;
if (code == 'a' || code == 'A')
{
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);
}
else Chars[i].TranslatedPic = charlumps[i];
Chars[i].XMove = Chars[i].OriginalPic->GetDisplayWidth();
Chars[i].XMove = Chars[i].TranslatedPic->GetDisplayWidth();
}
else
{
Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr;
Chars[i].TranslatedPic = nullptr;
Chars[i].XMove = INT_MIN;
}
}
// 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;
}

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);
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;
FRemapTable *GetColorTranslation (EColorRange range, PalEntry *color = nullptr) const;
int GetLump() const { return Lump; }
@ -123,9 +123,9 @@ protected:
bool translateUntranslated;
struct CharData
{
FTexture *TranslatedPic; // Texture for use with font translations.
FTexture *OriginalPic; // Texture for use with CR_UNTRANSLATED or font colorization.
int XMove;
FTexture *TranslatedPic = nullptr; // Texture for use with font translations.
FTexture *OriginalPic = nullptr; // Texture for use with CR_UNTRANSLATED or font colorization.
int XMove = INT_MIN;
};
TArray<CharData> Chars;
int ActiveColors;

View file

@ -169,15 +169,16 @@ void DFrameBuffer::DrawChar(FFont *font, int normalcolor, double x, double y, in
FTexture *pic;
int dummy;
bool redirected;
if (NULL != (pic = font->GetChar(character, normalcolor, &dummy)))
if (NULL != (pic = font->GetChar(character, normalcolor, &dummy, &redirected)))
{
DrawParms parms;
uint32_t tag = ListGetInt(args);
bool res = ParseDrawTextureTags(pic, x, y, tag, args, &parms, false);
if (!res) return;
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);
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)
{
HCURSOR cursor;