mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-03-17 00:11:05 +00:00
Merge branch 'master' of https://github.com/coelckers/gzdoom
This commit is contained in:
commit
e946f11006
79 changed files with 1228 additions and 1997 deletions
|
@ -639,6 +639,12 @@ elseif( FLUIDSYNTH_FOUND )
|
|||
add_definitions( -DHAVE_FLUIDSYNTH )
|
||||
endif()
|
||||
|
||||
option( SEND_ANON_STATS "Enable sending of anonymous hardware statistics" ON )
|
||||
|
||||
if( NOT SEND_ANON_STATS )
|
||||
add_definitions( -DNO_SEND_STATS )
|
||||
endif()
|
||||
|
||||
# Project files should be aware of the header files. We can GLOB these since
|
||||
# there's generally a new cpp for every header so this file will get changed
|
||||
if( WIN32 )
|
||||
|
@ -1104,6 +1110,7 @@ set (PCH_SOURCES
|
|||
textures/tgatexture.cpp
|
||||
textures/warptexture.cpp
|
||||
textures/skyboxtexture.cpp
|
||||
textures/worldtexture.cpp
|
||||
xlat/parse_xlat.cpp
|
||||
fragglescript/t_func.cpp
|
||||
fragglescript/t_load.cpp
|
||||
|
|
|
@ -3088,7 +3088,7 @@ static void DrawMarker (FTexture *tex, double x, double y, int yadjust,
|
|||
DTA_TranslationIndex, translation,
|
||||
DTA_Alpha, alpha,
|
||||
DTA_FillColor, fillcolor,
|
||||
DTA_RenderStyle, uint32_t(renderstyle),
|
||||
DTA_RenderStyle, renderstyle.AsDWORD,
|
||||
TAG_DONE);
|
||||
}
|
||||
|
||||
|
|
|
@ -564,6 +564,8 @@ static void stripwhite (char *str)
|
|||
|
||||
static char *igets (void)
|
||||
{
|
||||
assert(PatchPt != nullptr);
|
||||
|
||||
char *line;
|
||||
|
||||
if (*PatchPt == '\0' || PatchPt >= PatchFile + PatchSize )
|
||||
|
@ -2536,7 +2538,7 @@ static bool DoDehPatch()
|
|||
cont = 0;
|
||||
if (0 == strncmp (PatchFile, "Patch File for DeHackEd v", 25))
|
||||
{
|
||||
if (PatchFile[25] < '3' && PatchFile[25] != '2' && PatchFile[27] != '3')
|
||||
if (PatchFile[25] < '3' && (PatchFile[25] < '2' || PatchFile[27] < '3'))
|
||||
{
|
||||
Printf (PRINT_BOLD, "\"%s\" is an old and unsupported DeHackEd patch\n", PatchName);
|
||||
delete[] PatchName;
|
||||
|
@ -2550,16 +2552,16 @@ static bool DoDehPatch()
|
|||
}
|
||||
|
||||
PatchPt = strchr (PatchFile, '\n');
|
||||
while ((cont = GetLine()) == 1)
|
||||
while (PatchPt != nullptr && (cont = GetLine()) == 1)
|
||||
{
|
||||
CHECKKEY ("Doom version", dversion)
|
||||
else CHECKKEY ("Patch format", pversion)
|
||||
}
|
||||
if (!cont || dversion == -1 || pversion == -1)
|
||||
{
|
||||
Printf (PRINT_BOLD, "\"%s\" is not a DeHackEd patch file\n", PatchName);
|
||||
delete[] PatchName;
|
||||
delete[] PatchFile;
|
||||
Printf (PRINT_BOLD, "\"%s\" is not a DeHackEd patch file\n", PatchFile);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2352,6 +2352,9 @@ void D_DoomMain (void)
|
|||
|
||||
D_DoomInit();
|
||||
|
||||
extern void D_ConfirmSendStats();
|
||||
D_ConfirmSendStats();
|
||||
|
||||
// [RH] Make sure zdoom.pk3 is always loaded,
|
||||
// as it contains magic stuff we need.
|
||||
wad = BaseFileSearch (BASEWAD, NULL, true);
|
||||
|
|
|
@ -1914,6 +1914,10 @@ void TryRunTics (void)
|
|||
// Check possible stall conditions
|
||||
Net_CheckLastReceived (counts);
|
||||
|
||||
// Update time returned by I_GetTime, but only if we are stuck in this loop
|
||||
if (lowtic < gametic + counts)
|
||||
I_SetFrameTime();
|
||||
|
||||
// don't stay in here forever -- give the menu a chance to work
|
||||
if (I_GetTime () - entertic >= 1)
|
||||
{
|
||||
|
|
134
src/d_stats.cpp
134
src/d_stats.cpp
|
@ -1,3 +1,16 @@
|
|||
|
||||
#ifdef NO_SEND_STATS
|
||||
|
||||
void D_DoAnonStats()
|
||||
{
|
||||
}
|
||||
|
||||
void D_ConfirmSendStats()
|
||||
{
|
||||
}
|
||||
|
||||
#else // !NO_SEND_STATS
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
@ -5,6 +18,11 @@
|
|||
#include <winsock2.h>
|
||||
extern int sys_ostype;
|
||||
#else
|
||||
#ifdef __APPLE__
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#else // !__APPLE__
|
||||
#include <SDL.h>
|
||||
#endif // __APPLE__
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
|
@ -20,12 +38,13 @@ extern int sys_ostype;
|
|||
|
||||
EXTERN_CVAR(Bool, vid_glswfb)
|
||||
extern int currentrenderer;
|
||||
CVAR(Int, sys_statsenabled, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET)
|
||||
CVAR(String, sys_statshost, "gzstats.drdteam.org", CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOSET)
|
||||
CVAR(Int, sys_statsport, 80, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOSET)
|
||||
|
||||
// Each machine will only send two reports, one when started with hardware rendering and one when started with software rendering.
|
||||
#define CHECKVERSION 330
|
||||
#define CHECKVERSIONSTR "330"
|
||||
#define CHECKVERSION 331
|
||||
#define CHECKVERSIONSTR "331"
|
||||
CVAR(Int, sentstats_swr_done, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET)
|
||||
CVAR(Int, sentstats_hwr_done, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET)
|
||||
|
||||
|
@ -48,6 +67,11 @@ bool I_HTTPRequest(const char* request)
|
|||
SOCKET Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
struct hostent *host;
|
||||
host = gethostbyname(sys_statshost.GetHumanString());
|
||||
if (host == nullptr)
|
||||
{
|
||||
DPrintf(DMSG_ERROR, "Error looking up hostname.\n");
|
||||
return false;
|
||||
}
|
||||
SOCKADDR_IN SockAddr;
|
||||
SockAddr.sin_port = htons(sys_statsport);
|
||||
SockAddr.sin_family = AF_INET;
|
||||
|
@ -113,18 +137,15 @@ bool I_HTTPRequest(const char* request)
|
|||
return false;
|
||||
}
|
||||
|
||||
char buffer[1024];
|
||||
sprintf(buffer, "%s", request);
|
||||
Printf("Buffer: %s", buffer);
|
||||
n = write(sockfd, (char*)buffer, (int)strlen(request));
|
||||
n = write(sockfd, request, strlen(request));
|
||||
if (n<0)
|
||||
{
|
||||
DPrintf(DMSG_ERROR, "Error writing to socket.\n");
|
||||
close(sockfd);
|
||||
return false;
|
||||
}
|
||||
bzero(buffer, 1024);
|
||||
|
||||
char buffer[1024] = {};
|
||||
n = read(sockfd, buffer, 1023);
|
||||
close(sockfd);
|
||||
DPrintf(DMSG_NOTIFY, "Stats send successful.\n");
|
||||
|
@ -185,12 +206,49 @@ static int GetOSVersion()
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
static int GetCoreInfo()
|
||||
{
|
||||
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
|
||||
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = NULL;
|
||||
DWORD returnLength = 0;
|
||||
int cores = 0;
|
||||
uint32_t byteOffset = 0;
|
||||
|
||||
auto rc = GetLogicalProcessorInformation(buffer, &returnLength);
|
||||
|
||||
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(returnLength);
|
||||
if (!GetLogicalProcessorInformation(buffer, &returnLength)) return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ptr = buffer;
|
||||
|
||||
while (byteOffset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= returnLength)
|
||||
{
|
||||
if (ptr->Relationship == RelationProcessorCore) cores++;
|
||||
byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
|
||||
ptr++;
|
||||
}
|
||||
free(buffer);
|
||||
return cores < 2 ? 0 : cores < 4 ? 1 : cores < 6 ? 2 : cores < 8 ? 3 : 4;
|
||||
}
|
||||
|
||||
#else
|
||||
static int GetCoreInfo()
|
||||
{
|
||||
int cores = std::thread::hardware_concurrency();
|
||||
if (CPU.HyperThreading) cores /= 2;
|
||||
return cores < 2? 0 : cores < 4? 1 : cores < 6? 2 : cores < 8? 3 : 4;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int GetRenderInfo()
|
||||
{
|
||||
|
@ -227,6 +285,11 @@ static void D_DoHTTPRequest(const char *request)
|
|||
|
||||
void D_DoAnonStats()
|
||||
{
|
||||
if (sys_statsenabled != 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static bool done = false; // do this only once per session.
|
||||
if (done) return;
|
||||
done = true;
|
||||
|
@ -236,9 +299,62 @@ void D_DoAnonStats()
|
|||
if (currentrenderer == 1 && sentstats_hwr_done >= CHECKVERSION) return;
|
||||
|
||||
static char requeststring[1024];
|
||||
sprintf(requeststring, "GET /stats.php?render=%i&cores=%i&os=%i HTTP/1.1\nHost: %s\nConnection: close\nUser-Agent: %s %s\n\n",
|
||||
GetRenderInfo(), GetCoreInfo(), GetOSVersion(), sys_statshost.GetHumanString(), GAMENAME, VERSIONSTR);
|
||||
mysnprintf(requeststring, sizeof requeststring, "GET /stats.py?render=%i&cores=%i&os=%i&renderconfig=%i HTTP/1.1\nHost: %s\nConnection: close\nUser-Agent: %s %s\n\n",
|
||||
GetRenderInfo(), GetCoreInfo(), GetOSVersion(), currentrenderer, sys_statshost.GetHumanString(), GAMENAME, VERSIONSTR);
|
||||
DPrintf(DMSG_NOTIFY, "Sending %s", requeststring);
|
||||
std::thread t1(D_DoHTTPRequest, requeststring);
|
||||
t1.detach();
|
||||
}
|
||||
|
||||
void D_ConfirmSendStats()
|
||||
{
|
||||
if (sys_statsenabled >= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: texts
|
||||
static const char *const MESSAGE_TEXT = "send stats?";
|
||||
static const char *const TITLE_TEXT = GAMENAME;
|
||||
|
||||
UCVarValue enabled = { 0 };
|
||||
|
||||
#ifdef _WIN32
|
||||
extern HWND Window;
|
||||
enabled.Int = MessageBox(Window, MESSAGE_TEXT, TITLE_TEXT, MB_ICONQUESTION | MB_YESNO) == IDYES;
|
||||
#elif defined __APPLE__
|
||||
const CFStringRef messageString = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, MESSAGE_TEXT, kCFStringEncodingASCII, kCFAllocatorNull);
|
||||
const CFStringRef titleString = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, TITLE_TEXT, kCFStringEncodingASCII, kCFAllocatorNull);
|
||||
if (messageString != nullptr && titleString != nullptr)
|
||||
{
|
||||
CFOptionFlags response;
|
||||
const SInt32 result = CFUserNotificationDisplayAlert(0, kCFUserNotificationNoteAlertLevel, nullptr, nullptr, nullptr,
|
||||
titleString, messageString, CFSTR("Yes"), CFSTR("No"), nullptr, &response);
|
||||
enabled.Int = result == 0 && (response & 3) == kCFUserNotificationDefaultResponse;
|
||||
CFRelease(titleString);
|
||||
CFRelease(messageString);
|
||||
}
|
||||
#else // !__APPLE__
|
||||
const SDL_MessageBoxButtonData buttons[] =
|
||||
{
|
||||
{ SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, "Yes" },
|
||||
{ SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 1, "No" },
|
||||
};
|
||||
const SDL_MessageBoxData messageboxdata =
|
||||
{
|
||||
SDL_MESSAGEBOX_INFORMATION,
|
||||
nullptr,
|
||||
TITLE_TEXT,
|
||||
MESSAGE_TEXT,
|
||||
SDL_arraysize(buttons),
|
||||
buttons,
|
||||
nullptr
|
||||
};
|
||||
int buttonid;
|
||||
enabled.Int = SDL_ShowMessageBox(&messageboxdata, &buttonid) == 0 && buttonid == 0;
|
||||
#endif // _WIN32
|
||||
|
||||
sys_statsenabled.ForceSet(enabled, CVAR_Int);
|
||||
}
|
||||
|
||||
#endif // NO_SEND_STATS
|
||||
|
|
16
src/files.h
16
src/files.h
|
@ -201,56 +201,56 @@ public:
|
|||
|
||||
uint8_t ReadUInt8()
|
||||
{
|
||||
uint8_t v;
|
||||
uint8_t v = 0;
|
||||
Read(&v, 1);
|
||||
return v;
|
||||
}
|
||||
|
||||
int8_t ReadInt8()
|
||||
{
|
||||
int8_t v;
|
||||
int8_t v = 0;
|
||||
Read(&v, 1);
|
||||
return v;
|
||||
}
|
||||
|
||||
uint16_t ReadUInt16()
|
||||
{
|
||||
uint16_t v;
|
||||
uint16_t v = 0;
|
||||
Read(&v, 2);
|
||||
return LittleShort(v);
|
||||
}
|
||||
|
||||
int16_t ReadInt16()
|
||||
{
|
||||
uint16_t v;
|
||||
uint16_t v = 0;
|
||||
Read(&v, 2);
|
||||
return LittleShort(v);
|
||||
}
|
||||
|
||||
uint32_t ReadUInt32()
|
||||
{
|
||||
uint32_t v;
|
||||
uint32_t v = 0;
|
||||
Read(&v, 4);
|
||||
return LittleLong(v);
|
||||
}
|
||||
|
||||
int32_t ReadInt32()
|
||||
{
|
||||
uint32_t v;
|
||||
uint32_t v = 0;
|
||||
Read(&v, 4);
|
||||
return LittleLong(v);
|
||||
}
|
||||
|
||||
uint32_t ReadUInt32BE()
|
||||
{
|
||||
uint32_t v;
|
||||
uint32_t v = 0;
|
||||
Read(&v, 4);
|
||||
return BigLong(v);
|
||||
}
|
||||
|
||||
int32_t ReadInt32BE()
|
||||
{
|
||||
uint32_t v;
|
||||
uint32_t v = 0;
|
||||
Read(&v, 4);
|
||||
return BigLong(v);
|
||||
}
|
||||
|
|
|
@ -82,6 +82,7 @@ DEFINE_FIELD(AInventory, MaxAmount)
|
|||
DEFINE_FIELD(AInventory, InterHubAmount)
|
||||
DEFINE_FIELD(AInventory, RespawnTics)
|
||||
DEFINE_FIELD(AInventory, Icon)
|
||||
DEFINE_FIELD(AInventory, AltHUDIcon)
|
||||
DEFINE_FIELD(AInventory, DropTime)
|
||||
DEFINE_FIELD(AInventory, SpawnPointClass)
|
||||
DEFINE_FIELD(AInventory, PickupFlash)
|
||||
|
@ -147,6 +148,7 @@ void AInventory::Serialize(FSerializer &arc)
|
|||
("respawntics", RespawnTics, def->RespawnTics)
|
||||
("itemflags", ItemFlags, def->ItemFlags)
|
||||
("icon", Icon, def->Icon)
|
||||
("althudicon", AltHUDIcon, def->AltHUDIcon)
|
||||
("pickupsound", PickupSound, def->PickupSound)
|
||||
("spawnpointclass", SpawnPointClass, def->SpawnPointClass)
|
||||
("droptime", DropTime, def->DropTime);
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "r_utility.h"
|
||||
#include "templates.h"
|
||||
#include "sc_man.h"
|
||||
#include "r_data/renderstyle.h"
|
||||
#include "colormatcher.h"
|
||||
#include "textures/warpbuffer.h"
|
||||
#include "textures/bitmap.h"
|
||||
|
@ -297,7 +298,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla
|
|||
if (hwtex)
|
||||
{
|
||||
// Texture has become invalid
|
||||
if ((!tex->bHasCanvas && (!tex->bWarped || gl.legacyMode)) && tex->CheckModified())
|
||||
if ((!tex->bHasCanvas && (!tex->bWarped || gl.legacyMode)) && tex->CheckModified(DefaultRenderStyle()))
|
||||
{
|
||||
Clean(true);
|
||||
hwtex = CreateHwTexture();
|
||||
|
@ -323,7 +324,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla
|
|||
WarpBuffer((uint32_t*)warpbuffer, (const uint32_t*)buffer, w, h, wt->WidthOffsetMultiplier, wt->HeightOffsetMultiplier, screen->FrameTime, wt->Speed, tex->bWarped);
|
||||
delete[] buffer;
|
||||
buffer = warpbuffer;
|
||||
wt->GenTime = screen->FrameTime;
|
||||
wt->GenTime[0] = screen->FrameTime;
|
||||
}
|
||||
tex->ProcessData(buffer, w, h, false);
|
||||
}
|
||||
|
|
|
@ -238,7 +238,7 @@ void FTexture::CreateDefaultBrightmap()
|
|||
)
|
||||
{
|
||||
// May have one - let's check when we use this texture
|
||||
const uint8_t *texbuf = GetPixels();
|
||||
const uint8_t *texbuf = GetPixels(DefaultRenderStyle());
|
||||
const int white = ColorMatcher.Pick(255,255,255);
|
||||
|
||||
int size = GetWidth() * GetHeight();
|
||||
|
@ -523,24 +523,11 @@ FBrightmapTexture::FBrightmapTexture (FTexture *source)
|
|||
SourceLump = -1;
|
||||
}
|
||||
|
||||
FBrightmapTexture::~FBrightmapTexture ()
|
||||
{
|
||||
}
|
||||
|
||||
const uint8_t *FBrightmapTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
{
|
||||
// not needed
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const uint8_t *FBrightmapTexture::GetPixels ()
|
||||
{
|
||||
// not needed
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void FBrightmapTexture::Unload ()
|
||||
uint8_t *FBrightmapTexture::MakeTexture(FRenderStyle style)
|
||||
{
|
||||
// This function is only necessary to satisfy the parent class's interface.
|
||||
// This will never be called.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int FBrightmapTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf)
|
||||
|
|
|
@ -4,23 +4,17 @@
|
|||
#include "r_defs.h"
|
||||
#include "textures/textures.h"
|
||||
|
||||
class FBrightmapTexture : public FTexture
|
||||
class FBrightmapTexture : public FWorldTexture
|
||||
{
|
||||
public:
|
||||
FBrightmapTexture (FTexture *source);
|
||||
~FBrightmapTexture ();
|
||||
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
void Unload ();
|
||||
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf);
|
||||
bool UseBasePalette() { return false; }
|
||||
uint8_t *MakeTexture(FRenderStyle style) override;
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override;
|
||||
bool UseBasePalette() override { return false; }
|
||||
|
||||
protected:
|
||||
FTexture *SourcePic;
|
||||
//uint8_t *Pixels;
|
||||
//Span **Spans;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -8516,5 +8516,7 @@ void PrintMiscActorInfo(AActor *query)
|
|||
query->Speed, query->Vel.X, query->Vel.Y, query->Vel.Z, query->Vel.Length());
|
||||
Printf("Scale: x:%f, y:%f\n", query->Scale.X, query->Scale.Y);
|
||||
Printf("FriendlySeeBlocks: %d\n", query->friendlyseeblocks);
|
||||
Printf("Target: %s\n", query->target ? query->target->GetClass()->TypeName.GetChars() : "-");
|
||||
Printf("Last enemy: %s\n", query->lastenemy ? query->lastenemy->GetClass()->TypeName.GetChars() : "-");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,20 +46,21 @@ void PolyDrawArgs::SetTexture(const uint8_t *texels, int width, int height)
|
|||
mTranslation = nullptr;
|
||||
}
|
||||
|
||||
void PolyDrawArgs::SetTexture(FTexture *texture)
|
||||
void PolyDrawArgs::SetTexture(FTexture *texture, FRenderStyle style)
|
||||
{
|
||||
mTextureWidth = texture->GetWidth();
|
||||
mTextureHeight = texture->GetHeight();
|
||||
if (PolyRenderer::Instance()->RenderTarget->IsBgra())
|
||||
mTexturePixels = (const uint8_t *)texture->GetPixelsBgra();
|
||||
else
|
||||
mTexturePixels = texture->GetPixels();
|
||||
mTexturePixels = texture->GetPixels(style);
|
||||
mTranslation = nullptr;
|
||||
}
|
||||
|
||||
void PolyDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, bool forcePal)
|
||||
void PolyDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, FRenderStyle style)
|
||||
{
|
||||
if (translationID != 0xffffffff && translationID != 0)
|
||||
// Alphatexture overrides translations.
|
||||
if (translationID != 0xffffffff && translationID != 0 && !(style.Flags & STYLEF_RedIsAlpha))
|
||||
{
|
||||
FRemapTable *table = TranslationToTable(translationID);
|
||||
if (table != nullptr && !table->Inactive)
|
||||
|
@ -71,20 +72,20 @@ void PolyDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, bool fo
|
|||
|
||||
mTextureWidth = texture->GetWidth();
|
||||
mTextureHeight = texture->GetHeight();
|
||||
mTexturePixels = texture->GetPixels();
|
||||
mTexturePixels = texture->GetPixels(style);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (forcePal)
|
||||
if (style.Flags & STYLEF_RedIsAlpha)
|
||||
{
|
||||
mTextureWidth = texture->GetWidth();
|
||||
mTextureHeight = texture->GetHeight();
|
||||
mTexturePixels = texture->GetPixels();
|
||||
mTexturePixels = texture->GetPixels(style);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetTexture(texture);
|
||||
SetTexture(texture, style);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,8 +165,7 @@ void PolyDrawArgs::DrawElements(PolyRenderThread *thread, const TriVertex *verti
|
|||
|
||||
void PolyDrawArgs::SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *tex, bool fullbright)
|
||||
{
|
||||
bool forcePal = (renderstyle == LegacyRenderStyles[STYLE_Shaded] || renderstyle == LegacyRenderStyles[STYLE_AddShaded]);
|
||||
SetTexture(tex, translationID, forcePal);
|
||||
SetTexture(tex, translationID, renderstyle);
|
||||
|
||||
if (renderstyle == LegacyRenderStyles[STYLE_Normal] || (r_drawfuzz == 0 && renderstyle == LegacyRenderStyles[STYLE_OptFuzzy]))
|
||||
{
|
||||
|
@ -232,20 +232,20 @@ void RectDrawArgs::SetTexture(const uint8_t *texels, int width, int height)
|
|||
mTranslation = nullptr;
|
||||
}
|
||||
|
||||
void RectDrawArgs::SetTexture(FTexture *texture)
|
||||
void RectDrawArgs::SetTexture(FTexture *texture, FRenderStyle style)
|
||||
{
|
||||
mTextureWidth = texture->GetWidth();
|
||||
mTextureHeight = texture->GetHeight();
|
||||
if (PolyRenderer::Instance()->RenderTarget->IsBgra())
|
||||
mTexturePixels = (const uint8_t *)texture->GetPixelsBgra();
|
||||
else
|
||||
mTexturePixels = texture->GetPixels();
|
||||
mTexturePixels = texture->GetPixels(style);
|
||||
mTranslation = nullptr;
|
||||
}
|
||||
|
||||
void RectDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, bool forcePal)
|
||||
void RectDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, FRenderStyle style)
|
||||
{
|
||||
if (translationID != 0xffffffff && translationID != 0)
|
||||
if (translationID != 0xffffffff && translationID != 0 && !(style.Flags & STYLEF_RedIsAlpha))
|
||||
{
|
||||
FRemapTable *table = TranslationToTable(translationID);
|
||||
if (table != nullptr && !table->Inactive)
|
||||
|
@ -257,20 +257,20 @@ void RectDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, bool fo
|
|||
|
||||
mTextureWidth = texture->GetWidth();
|
||||
mTextureHeight = texture->GetHeight();
|
||||
mTexturePixels = texture->GetPixels();
|
||||
mTexturePixels = texture->GetPixels(style);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (forcePal)
|
||||
if (style.Flags & STYLEF_RedIsAlpha)
|
||||
{
|
||||
mTextureWidth = texture->GetWidth();
|
||||
mTextureHeight = texture->GetHeight();
|
||||
mTexturePixels = texture->GetPixels();
|
||||
mTexturePixels = texture->GetPixels(style);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetTexture(texture);
|
||||
SetTexture(texture, style);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -315,10 +315,9 @@ void RectDrawArgs::Draw(PolyRenderThread *thread, double x0, double x1, double y
|
|||
thread->DrawQueue->Push<DrawRectCommand>(*this);
|
||||
}
|
||||
|
||||
void RectDrawArgs::SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *tex, bool fullbright)
|
||||
void RectDrawArgs::SetStyle(FRenderStyle renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *tex, bool fullbright)
|
||||
{
|
||||
bool forcePal = (renderstyle == LegacyRenderStyles[STYLE_Shaded] || renderstyle == LegacyRenderStyles[STYLE_AddShaded]);
|
||||
SetTexture(tex, translationID, forcePal);
|
||||
SetTexture(tex, translationID, renderstyle);
|
||||
|
||||
if (renderstyle == LegacyRenderStyles[STYLE_Normal] || (r_drawfuzz == 0 && renderstyle == LegacyRenderStyles[STYLE_OptFuzzy]))
|
||||
{
|
||||
|
|
|
@ -67,8 +67,8 @@ class PolyDrawArgs
|
|||
public:
|
||||
void SetClipPlane(int index, const PolyClipPlane &plane) { mClipPlane[index] = plane; }
|
||||
void SetTexture(const uint8_t *texels, int width, int height);
|
||||
void SetTexture(FTexture *texture);
|
||||
void SetTexture(FTexture *texture, uint32_t translationID, bool forcePal = false);
|
||||
void SetTexture(FTexture *texture, FRenderStyle style);
|
||||
void SetTexture(FTexture *texture, uint32_t translationID, FRenderStyle style);
|
||||
void SetLight(FSWColormap *basecolormap, uint32_t lightlevel, double globVis, bool fixed);
|
||||
void SetDepthTest(bool enable) { mDepthTest = enable; }
|
||||
void SetStencilTestValue(uint8_t stencilTestValue) { mStencilTestValue = stencilTestValue; }
|
||||
|
@ -186,11 +186,11 @@ class RectDrawArgs
|
|||
{
|
||||
public:
|
||||
void SetTexture(const uint8_t *texels, int width, int height);
|
||||
void SetTexture(FTexture *texture);
|
||||
void SetTexture(FTexture *texture, uint32_t translationID, bool forcePal = false);
|
||||
void SetTexture(FTexture *texture, FRenderStyle style);
|
||||
void SetTexture(FTexture *texture, uint32_t translationID, FRenderStyle style);
|
||||
void SetLight(FSWColormap *basecolormap, uint32_t lightlevel);
|
||||
void SetStyle(TriBlendMode blendmode, double srcalpha = 1.0, double destalpha = 1.0) { mBlendMode = blendmode; mSrcAlpha = (uint32_t)(srcalpha * 256.0 + 0.5); mDestAlpha = (uint32_t)(destalpha * 256.0 + 0.5); }
|
||||
void SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *texture, bool fullbright);
|
||||
void SetStyle(FRenderStyle renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *texture, bool fullbright);
|
||||
void SetColor(uint32_t bgra, uint8_t palindex);
|
||||
void Draw(PolyRenderThread *thread, double x0, double x1, double y0, double y1, double u0, double u1, double v0, double v1);
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ void PolyRenderThread::FlushDrawQueue()
|
|||
}
|
||||
}
|
||||
|
||||
void PolyRenderThread::PrepareTexture(FTexture *texture)
|
||||
void PolyRenderThread::PrepareTexture(FTexture *texture, FRenderStyle style)
|
||||
{
|
||||
if (texture == nullptr)
|
||||
return;
|
||||
|
@ -91,9 +91,9 @@ void PolyRenderThread::PrepareTexture(FTexture *texture)
|
|||
|
||||
std::unique_lock<std::mutex> lock(loadmutex);
|
||||
|
||||
texture->GetPixels();
|
||||
texture->GetPixels(style);
|
||||
const FTexture::Span *spans;
|
||||
texture->GetColumn(0, &spans);
|
||||
texture->GetColumn(style, 0, &spans);
|
||||
if (PolyRenderer::Instance()->RenderTarget->IsBgra())
|
||||
{
|
||||
texture->GetPixelsBgra();
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
DrawerCommandQueuePtr DrawQueue;
|
||||
|
||||
// Make sure texture can accessed safely
|
||||
void PrepareTexture(FTexture *texture);
|
||||
void PrepareTexture(FTexture *texture, FRenderStyle style);
|
||||
|
||||
// Setup poly object in a threadsafe manner
|
||||
void PreparePolyObject(subsector_t *sub);
|
||||
|
|
|
@ -33,26 +33,15 @@ void PolyCull::CullScene(const PolyClipPlane &portalClipPlane)
|
|||
ClearSolidSegments();
|
||||
MarkViewFrustum();
|
||||
|
||||
if (level.LevelName != lastLevelName) // Is this the best way to detect a level change?
|
||||
{
|
||||
lastLevelName = level.LevelName;
|
||||
SubsectorDepths.clear();
|
||||
SubsectorDepths.resize(level.subsectors.Size(), 0xffffffff);
|
||||
SectorSeen.clear();
|
||||
SectorSeen.resize(level.sectors.Size());
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto &sub : PvsSectors)
|
||||
SubsectorDepths[sub->Index()] = 0xffffffff;
|
||||
SubsectorDepths.resize(level.subsectors.Size(), 0xffffffff);
|
||||
for (uint32_t sub : PvsSubsectors)
|
||||
SubsectorDepths[sub] = 0xffffffff;
|
||||
SubsectorDepths.resize(level.subsectors.Size(), 0xffffffff);
|
||||
|
||||
for (const auto §or : SeenSectors)
|
||||
SectorSeen[sector->Index()] = false;
|
||||
SectorSeen.resize(level.sectors.Size());
|
||||
}
|
||||
for (uint32_t sector : SeenSectors)
|
||||
SectorSeen[sector] = false;
|
||||
SectorSeen.resize(level.sectors.Size());
|
||||
|
||||
PvsSectors.clear();
|
||||
PvsSubsectors.clear();
|
||||
SeenSectors.clear();
|
||||
|
||||
NextPvsLineStart = 0;
|
||||
|
@ -125,10 +114,10 @@ void PolyCull::CullSubsector(subsector_t *sub)
|
|||
FirstSkyHeight = false;
|
||||
}
|
||||
|
||||
uint32_t subsectorDepth = (uint32_t)PvsSectors.size();
|
||||
uint32_t subsectorDepth = (uint32_t)PvsSubsectors.size();
|
||||
|
||||
// Mark that we need to render this
|
||||
PvsSectors.push_back(sub);
|
||||
PvsSubsectors.push_back(sub->Index());
|
||||
PvsLineStart.push_back(NextPvsLineStart);
|
||||
|
||||
DVector3 viewpos = PolyRenderer::Instance()->Viewpoint.Pos;
|
||||
|
@ -169,7 +158,7 @@ void PolyCull::CullSubsector(subsector_t *sub)
|
|||
if (!SectorSeen[sub->sector->Index()])
|
||||
{
|
||||
SectorSeen[sub->sector->Index()] = true;
|
||||
SeenSectors.push_back(sub->sector);
|
||||
SeenSectors.push_back(sub->sector->Index());
|
||||
}
|
||||
|
||||
SubsectorDepths[sub->Index()] = subsectorDepth;
|
||||
|
|
|
@ -36,11 +36,11 @@ public:
|
|||
return PvsLineVisible[PvsLineStart[subsectorDepth] + lineIndex];
|
||||
}
|
||||
|
||||
std::vector<subsector_t *> PvsSectors;
|
||||
std::vector<uint32_t> PvsSubsectors;
|
||||
double MaxCeilingHeight = 0.0;
|
||||
double MinFloorHeight = 0.0;
|
||||
|
||||
std::vector<sector_t *> SeenSectors;
|
||||
std::vector<uint32_t> SeenSectors;
|
||||
std::vector<bool> SectorSeen;
|
||||
std::vector<uint32_t> SubsectorDepths;
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ void PolyModelRenderer::DrawArrays(int start, int count)
|
|||
args.SetStencilTestValue(StencilValue);
|
||||
args.SetClipPlane(0, PolyClipPlane());
|
||||
args.SetStyle(TriBlendMode::TextureOpaque);
|
||||
args.SetTexture(SkinTexture);
|
||||
args.SetTexture(SkinTexture, DefaultRenderStyle());
|
||||
args.SetDepthTest(true);
|
||||
args.SetWriteDepth(true);
|
||||
args.SetWriteStencil(false);
|
||||
|
@ -181,7 +181,7 @@ void PolyModelRenderer::DrawElements(int numIndices, size_t offset)
|
|||
args.SetStencilTestValue(StencilValue);
|
||||
args.SetClipPlane(0, PolyClipPlane());
|
||||
args.SetStyle(TriBlendMode::TextureOpaque);
|
||||
args.SetTexture(SkinTexture);
|
||||
args.SetTexture(SkinTexture, DefaultRenderStyle());
|
||||
args.SetDepthTest(true);
|
||||
args.SetWriteDepth(true);
|
||||
args.SetWriteStencil(false);
|
||||
|
|
|
@ -81,7 +81,7 @@ void RenderPolyPlane::RenderNormal(PolyRenderThread *thread, const TriMatrix &wo
|
|||
args.SetStencilTestValue(stencilValue);
|
||||
args.SetWriteStencil(true, stencilValue + 1);
|
||||
args.SetClipPlane(0, clipPlane);
|
||||
args.SetTexture(tex);
|
||||
args.SetTexture(tex, DefaultRenderStyle());
|
||||
args.SetStyle(TriBlendMode::TextureOpaque);
|
||||
args.DrawArray(thread, vertices, fakeflat.Subsector->numlines, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
|
@ -572,7 +572,7 @@ void Render3DFloorPlane::Render(PolyRenderThread *thread, const TriMatrix &world
|
|||
args.SetFaceCullCCW(true);
|
||||
args.SetStencilTestValue(stencilValue);
|
||||
args.SetWriteStencil(true, stencilValue + 1);
|
||||
args.SetTexture(tex);
|
||||
args.SetTexture(tex, DefaultRenderStyle());
|
||||
args.SetClipPlane(0, clipPlane);
|
||||
args.DrawArray(thread, vertices, sub->numlines, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
|
|
|
@ -69,8 +69,8 @@ void RenderPolyScene::RenderSectors()
|
|||
{
|
||||
PolyRenderThread *mainthread = PolyRenderer::Instance()->Threads.MainThread();
|
||||
|
||||
int totalcount = (int)Cull.PvsSectors.size();
|
||||
auto subsectors = Cull.PvsSectors.data();
|
||||
int totalcount = (int)Cull.PvsSubsectors.size();
|
||||
uint32_t *subsectors = Cull.PvsSubsectors.data();
|
||||
|
||||
TranslucentObjects.resize(PolyRenderer::Instance()->Threads.NumThreads());
|
||||
|
||||
|
@ -82,7 +82,7 @@ void RenderPolyScene::RenderSectors()
|
|||
int end = thread->End;
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
RenderSubsector(thread, subsectors[i], i);
|
||||
RenderSubsector(thread, &level.subsectors[subsectors[i]], i);
|
||||
}
|
||||
}, [&](PolyRenderThread *thread)
|
||||
{
|
||||
|
@ -372,8 +372,9 @@ void RenderPolyScene::RenderTranslucent(int portalDepth)
|
|||
}
|
||||
|
||||
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
||||
for (sector_t *sector : Cull.SeenSectors)
|
||||
for (uint32_t sectorIndex : Cull.SeenSectors)
|
||||
{
|
||||
sector_t *sector = &level.sectors[sectorIndex];
|
||||
for (AActor *thing = sector->thinglist; thing != nullptr; thing = thing->snext)
|
||||
{
|
||||
DVector2 left, right;
|
||||
|
|
|
@ -91,7 +91,7 @@ void PolySkyDome::Render(PolyRenderThread *thread, const TriMatrix &worldToClip)
|
|||
RenderCapColorRow(thread, args, mCurrentSetup.frontskytex, 0, false);
|
||||
RenderCapColorRow(thread, args, mCurrentSetup.frontskytex, rc, true);
|
||||
|
||||
args.SetTexture(mCurrentSetup.frontskytex);
|
||||
args.SetTexture(mCurrentSetup.frontskytex, DefaultRenderStyle());
|
||||
|
||||
uint32_t topcapcolor = mCurrentSetup.frontskytex->GetSkyCapColor(false);
|
||||
uint32_t bottomcapcolor = mCurrentSetup.frontskytex->GetSkyCapColor(true);
|
||||
|
|
|
@ -327,7 +327,7 @@ void RenderPolyWall::Render(PolyRenderThread *thread, const TriMatrix &worldToCl
|
|||
args.SetStencilTestValue(StencilValue);
|
||||
args.SetWriteStencil(true, StencilValue + 1);
|
||||
if (Texture && !Polyportal)
|
||||
args.SetTexture(Texture);
|
||||
args.SetTexture(Texture, DefaultRenderStyle());
|
||||
args.SetClipPlane(0, clipPlane);
|
||||
|
||||
SetDynLights(thread, args);
|
||||
|
|
|
@ -105,7 +105,7 @@ void RenderPolyWallSprite::Render(PolyRenderThread *thread, const TriMatrix &wor
|
|||
args.SetTransform(&worldToClip);
|
||||
args.SetFaceCullCCW(true);
|
||||
args.SetStencilTestValue(stencilValue);
|
||||
args.SetTexture(tex);
|
||||
args.SetTexture(tex, thing->RenderStyle);
|
||||
args.SetClipPlane(0, clipPlane);
|
||||
args.SetDepthTest(true);
|
||||
args.SetWriteDepth(false);
|
||||
|
|
|
@ -53,23 +53,17 @@
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
class FVoxelTexture : public FTexture
|
||||
class FVoxelTexture : public FWorldTexture
|
||||
{
|
||||
public:
|
||||
|
||||
FVoxelTexture(FVoxel *voxel);
|
||||
~FVoxelTexture();
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
void Unload ();
|
||||
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf);
|
||||
bool UseBasePalette() { return false; }
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override;
|
||||
bool UseBasePalette() override { return false; }
|
||||
uint8_t *MakeTexture(FRenderStyle style) override;
|
||||
|
||||
protected:
|
||||
FVoxel *SourceVox;
|
||||
uint8_t *Pixels;
|
||||
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
|
@ -86,7 +80,6 @@ FVoxelTexture::FVoxelTexture(FVoxel *vox)
|
|||
WidthBits = 4;
|
||||
HeightBits = 4;
|
||||
WidthMask = 15;
|
||||
Pixels = NULL;
|
||||
gl_info.bNoFilter = true;
|
||||
gl_info.bNoCompress = true;
|
||||
}
|
||||
|
@ -97,54 +90,32 @@ FVoxelTexture::FVoxelTexture(FVoxel *vox)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
FVoxelTexture::~FVoxelTexture()
|
||||
{
|
||||
}
|
||||
|
||||
const uint8_t *FVoxelTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
{
|
||||
// not needed
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const uint8_t *FVoxelTexture::GetPixels ()
|
||||
uint8_t *FVoxelTexture::MakeTexture (FRenderStyle style)
|
||||
{
|
||||
// GetPixels gets called when a translated palette is used so we still need to implement it here.
|
||||
if (Pixels == NULL)
|
||||
auto Pixels = new uint8_t[256];
|
||||
uint8_t *pp = SourceVox->Palette;
|
||||
|
||||
if(pp != NULL)
|
||||
{
|
||||
Pixels = new uint8_t[256];
|
||||
|
||||
uint8_t *pp = SourceVox->Palette;
|
||||
|
||||
if(pp != NULL)
|
||||
for(int i=0;i<256;i++, pp+=3)
|
||||
{
|
||||
for(int i=0;i<256;i++, pp+=3)
|
||||
{
|
||||
PalEntry pe;
|
||||
pe.r = (pp[0] << 2) | (pp[0] >> 4);
|
||||
pe.g = (pp[1] << 2) | (pp[1] >> 4);
|
||||
pe.b = (pp[2] << 2) | (pp[2] >> 4);
|
||||
Pixels[i] = ColorMatcher.Pick(pe);
|
||||
}
|
||||
PalEntry pe;
|
||||
pe.r = (pp[0] << 2) | (pp[0] >> 4);
|
||||
pe.g = (pp[1] << 2) | (pp[1] >> 4);
|
||||
pe.b = (pp[2] << 2) | (pp[2] >> 4);
|
||||
// Alphatexture handling is just for completeness, but rather unlikely to be used ever.
|
||||
Pixels[i] = (style.Flags & STYLEF_RedIsAlpha)? pe.r : ColorMatcher.Pick(pe);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i=0;i<256;i++, pp+=3)
|
||||
{
|
||||
Pixels[i] = (uint8_t)i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
void FVoxelTexture::Unload ()
|
||||
{
|
||||
if (Pixels != NULL)
|
||||
else
|
||||
{
|
||||
delete[] Pixels;
|
||||
Pixels = NULL;
|
||||
}
|
||||
for(int i=0;i<256;i++, pp+=3)
|
||||
{
|
||||
Pixels[i] = (uint8_t)i;
|
||||
}
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -133,20 +133,28 @@ union FRenderStyle
|
|||
uint32_t AsDWORD;
|
||||
|
||||
inline FRenderStyle &operator= (ERenderStyle legacy);
|
||||
operator uint32_t() const { return AsDWORD; }
|
||||
bool operator==(const FRenderStyle &o) const { return AsDWORD == o.AsDWORD; }
|
||||
void CheckFuzz();
|
||||
bool IsVisible(double alpha) const throw();
|
||||
private:
|
||||
// Code that compares an actor's render style with a legacy render
|
||||
// style value should be updated. Making these conversion operators
|
||||
// private will catch those cases.
|
||||
operator ERenderStyle() const { return STYLE_Normal; }
|
||||
operator int() const { return STYLE_Normal; }
|
||||
// style value should be updated.
|
||||
operator ERenderStyle() = delete;
|
||||
operator int() const = delete;
|
||||
};
|
||||
|
||||
extern FRenderStyle LegacyRenderStyles[STYLE_Count];
|
||||
|
||||
inline FRenderStyle DefaultRenderStyle()
|
||||
{
|
||||
return LegacyRenderStyles[STYLE_Normal];
|
||||
}
|
||||
|
||||
inline FRenderStyle BadRenderStyle() // This is just a marker to find places where work is still needed.
|
||||
{
|
||||
return LegacyRenderStyles[STYLE_Normal];
|
||||
}
|
||||
|
||||
inline FRenderStyle &FRenderStyle::operator= (ERenderStyle legacy)
|
||||
{
|
||||
if (legacy < STYLE_None || legacy >= STYLE_Count)
|
||||
|
|
|
@ -280,6 +280,8 @@ bool FZipFile::Open(bool quiet)
|
|||
}
|
||||
}
|
||||
}
|
||||
// If it ran through the list without finding anything it should not attempt any path remapping.
|
||||
if (!foundspeciallump) name0 = "";
|
||||
|
||||
dirptr = (char*)directory;
|
||||
lump_p = Lumps;
|
||||
|
|
|
@ -2743,6 +2743,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
if (parentfunc->Variants[0].Implementation->DefaultArgs.Size() > 0)
|
||||
{
|
||||
sym->Variants[0].Implementation->DefaultArgs = parentfunc->Variants[0].Implementation->DefaultArgs;
|
||||
sym->Variants[0].ArgFlags = parentfunc->Variants[0].ArgFlags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -298,8 +298,9 @@ SndFileSong::SndFileSong(FileReader &reader, SoundDecoder *decoder, uint32_t loo
|
|||
if (!startass) loop_start = Scale(loop_start, SampleRate, 1000);
|
||||
if (!endass) loop_end = Scale(loop_end, SampleRate, 1000);
|
||||
|
||||
const uint32_t sampleLength = (uint32_t)decoder->getSampleLength();
|
||||
Loop_Start = loop_start;
|
||||
Loop_End = clamp<uint32_t>(loop_end, 0, (uint32_t)decoder->getSampleLength());
|
||||
Loop_End = sampleLength == 0 ? loop_end : clamp<uint32_t>(loop_end, 0, sampleLength);
|
||||
Reader = std::move(reader);
|
||||
Decoder = decoder;
|
||||
Channels = iChannels == ChannelConfig_Stereo? 2:1;
|
||||
|
@ -419,12 +420,17 @@ bool SndFileSong::Read(SoundStream *stream, void *vbuff, int ilen, void *userdat
|
|||
// This looks a bit more complicated than necessary because libmpg123 will not read the full requested length for the last block in the file.
|
||||
if (currentpos + framestoread > song->Loop_End)
|
||||
{
|
||||
size_t endblock = (song->Loop_End - currentpos) * song->Channels * 2;
|
||||
size_t endlen = song->Decoder->read(buff, endblock);
|
||||
// Loop can be very short, make sure the current position doesn't exceed it
|
||||
if (currentpos < song->Loop_End)
|
||||
{
|
||||
size_t endblock = (song->Loop_End - currentpos) * song->Channels * 2;
|
||||
size_t endlen = song->Decoder->read(buff, endblock);
|
||||
|
||||
// Even if zero bytes was read give it a chance to start from the beginning
|
||||
buff += endlen;
|
||||
len -= endlen;
|
||||
}
|
||||
|
||||
// Even if zero bytes was read give it a chance to start from the beginning
|
||||
buff = buff + endlen;
|
||||
len -= endlen;
|
||||
song->Decoder->seek(song->Loop_Start, false, true);
|
||||
}
|
||||
while (len > 0)
|
||||
|
|
|
@ -155,6 +155,7 @@ namespace swrenderer
|
|||
|
||||
bool RenderDrawSegment::RenderWall(DrawSegment *ds, int x1, int x2, WallDrawerArgs &walldrawerargs, SpriteDrawerArgs &columndrawerargs, bool visible, FDynamicColormap *basecolormap, int wallshade)
|
||||
{
|
||||
auto renderstyle = DefaultRenderStyle();
|
||||
auto viewport = Thread->Viewport.get();
|
||||
Clip3DFloors *clip3d = Thread->Clip3D.get();
|
||||
|
||||
|
@ -314,7 +315,7 @@ namespace swrenderer
|
|||
// draw the columns one at a time
|
||||
if (visible)
|
||||
{
|
||||
Thread->PrepareTexture(tex);
|
||||
Thread->PrepareTexture(tex, renderstyle);
|
||||
for (int x = x1; x < x2; ++x)
|
||||
{
|
||||
if (cameraLight->FixedColormap() == nullptr && cameraLight->FixedLightLevel() < 0)
|
||||
|
@ -329,7 +330,7 @@ namespace swrenderer
|
|||
else
|
||||
sprtopscreen = viewport->CenterY - texturemid * spryscale;
|
||||
|
||||
columndrawerargs.DrawMaskedColumn(Thread, x, iscale, tex, maskedtexturecol[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip);
|
||||
columndrawerargs.DrawMaskedColumn(Thread, x, iscale, tex, maskedtexturecol[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, renderstyle);
|
||||
|
||||
rw_light += rw_lightstep;
|
||||
spryscale += rw_scalestep;
|
||||
|
|
|
@ -97,7 +97,7 @@ namespace swrenderer
|
|||
col = width + (col % width);
|
||||
}
|
||||
|
||||
source = texture->GetColumn(col, nullptr);
|
||||
source = texture->GetColumn(DefaultRenderStyle(), col, nullptr);
|
||||
source2 = nullptr;
|
||||
texturefracx = 0;
|
||||
}
|
||||
|
@ -330,7 +330,6 @@ namespace swrenderer
|
|||
if (rw_pic->UseType == FTexture::TEX_Null)
|
||||
return;
|
||||
|
||||
rw_pic->GetHeight(); // To ensure that rw_pic->HeightBits has been set
|
||||
int fracbits = 32 - rw_pic->HeightBits;
|
||||
if (fracbits == 32)
|
||||
{ // Hack for one pixel tall textures
|
||||
|
@ -531,7 +530,7 @@ namespace swrenderer
|
|||
this->rw_pic = pic;
|
||||
this->mask = mask;
|
||||
|
||||
Thread->PrepareTexture(pic);
|
||||
Thread->PrepareTexture(pic, DefaultRenderStyle()); // Get correct render style? Shaded won't get here.
|
||||
|
||||
if (rw_pic->GetHeight() != 1 << rw_pic->HeightBits)
|
||||
{
|
||||
|
|
|
@ -172,8 +172,8 @@ namespace swrenderer
|
|||
drawerargs.SetLight(&NormalLight, 0, 0);
|
||||
}
|
||||
|
||||
Thread->PrepareTexture(frontskytex);
|
||||
Thread->PrepareTexture(backskytex);
|
||||
Thread->PrepareTexture(frontskytex, DefaultRenderStyle());
|
||||
Thread->PrepareTexture(backskytex, DefaultRenderStyle());
|
||||
|
||||
DrawSky(pl);
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ namespace swrenderer
|
|||
return pal_drawers.get();
|
||||
}
|
||||
|
||||
void RenderThread::PrepareTexture(FTexture *texture)
|
||||
void RenderThread::PrepareTexture(FTexture *texture, FRenderStyle style)
|
||||
{
|
||||
if (texture == nullptr)
|
||||
return;
|
||||
|
@ -106,9 +106,9 @@ namespace swrenderer
|
|||
|
||||
std::unique_lock<std::mutex> lock(loadmutex);
|
||||
|
||||
texture->GetPixels();
|
||||
texture->GetPixels(style);
|
||||
const FTexture::Span *spans;
|
||||
texture->GetColumn(0, &spans);
|
||||
texture->GetColumn(style, 0, &spans);
|
||||
if (Viewport->RenderTarget->IsBgra())
|
||||
{
|
||||
texture->GetPixelsBgra();
|
||||
|
|
|
@ -84,7 +84,7 @@ namespace swrenderer
|
|||
SWPixelFormatDrawers *Drawers(RenderViewport *viewport);
|
||||
|
||||
// Make sure texture can accessed safely
|
||||
void PrepareTexture(FTexture *texture);
|
||||
void PrepareTexture(FTexture *texture, FRenderStyle style);
|
||||
|
||||
// Setup poly object in a threadsafe manner
|
||||
void PreparePolyObject(subsector_t *sub);
|
||||
|
|
|
@ -196,7 +196,7 @@ void SWCanvas::DrawTexture(DCanvas *canvas, FTexture *img, DrawParms &parms)
|
|||
|
||||
while (x < x2_i)
|
||||
{
|
||||
drawerargs.DrawMaskedColumn(&thread, x, iscale, img, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, !parms.masked);
|
||||
drawerargs.DrawMaskedColumn(&thread, x, iscale, img, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, parms.style, !parms.masked);
|
||||
x++;
|
||||
frac += xiscale_i;
|
||||
}
|
||||
|
|
|
@ -105,14 +105,14 @@ void FSoftwareRenderer::PrecacheTexture(FTexture *tex, int cache)
|
|||
if (isbgra)
|
||||
tex->GetColumnBgra(0, &spanp);
|
||||
else
|
||||
tex->GetColumn(0, &spanp);
|
||||
tex->GetColumn(DefaultRenderStyle(), 0, &spanp);
|
||||
}
|
||||
else if (cache != 0)
|
||||
{
|
||||
if (isbgra)
|
||||
tex->GetPixelsBgra();
|
||||
else
|
||||
tex->GetPixels ();
|
||||
tex->GetPixels (DefaultRenderStyle());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -282,7 +282,7 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin
|
|||
cameraViewpoint = r_viewpoint;
|
||||
cameraViewwindow = r_viewwindow;
|
||||
|
||||
uint8_t *Pixels = renderTarget->IsBgra() ? (uint8_t*)tex->GetPixelsBgra() : (uint8_t*)tex->GetPixels();
|
||||
uint8_t *Pixels = renderTarget->IsBgra() ? (uint8_t*)tex->GetPixelsBgra() : (uint8_t*)tex->GetPixels(DefaultRenderStyle());
|
||||
DSimpleCanvas *Canvas = renderTarget->IsBgra() ? tex->GetCanvasBgra() : tex->GetCanvas();
|
||||
|
||||
// curse Doom's overuse of global variables in the renderer.
|
||||
|
@ -328,7 +328,7 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin
|
|||
// We need to make sure that both pixel buffers contain data:
|
||||
int width = tex->GetWidth();
|
||||
int height = tex->GetHeight();
|
||||
uint8_t *palbuffer = (uint8_t *)tex->GetPixels();
|
||||
uint8_t *palbuffer = (uint8_t *)tex->GetPixels(DefaultRenderStyle());
|
||||
uint32_t *bgrabuffer = (uint32_t*)tex->GetPixelsBgra();
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
|
|
|
@ -312,14 +312,14 @@ namespace swrenderer
|
|||
|
||||
if (visible)
|
||||
{
|
||||
thread->PrepareTexture(WallSpriteTile);
|
||||
thread->PrepareTexture(WallSpriteTile, decal->RenderStyle);
|
||||
while (x < x2)
|
||||
{
|
||||
if (calclighting)
|
||||
{ // calculate lighting
|
||||
drawerargs.SetLight(usecolormap, light, wallshade);
|
||||
}
|
||||
DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip);
|
||||
DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, decal->RenderStyle);
|
||||
light += lightstep;
|
||||
x++;
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ namespace swrenderer
|
|||
} while (needrepeat--);
|
||||
}
|
||||
|
||||
void RenderDecal::DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip)
|
||||
void RenderDecal::DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style)
|
||||
{
|
||||
auto viewport = thread->Viewport.get();
|
||||
|
||||
|
@ -345,6 +345,6 @@ namespace swrenderer
|
|||
else
|
||||
sprtopscreen = viewport->CenterY - texturemid * spryscale;
|
||||
|
||||
drawerargs.DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip);
|
||||
drawerargs.DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, style);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@ namespace swrenderer
|
|||
|
||||
private:
|
||||
static void Render(RenderThread *thread, side_t *wall, DBaseDecal *first, DrawSegment *clipper, int wallshade, float lightleft, float lightstep, seg_t *curline, const FWallCoords &wallC, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, bool drawsegPass);
|
||||
static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip);
|
||||
static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -199,7 +199,7 @@ namespace swrenderer
|
|||
if (Thread->Viewport->RenderTarget->IsBgra())
|
||||
args.SetTexture((const uint8_t *)SkinTexture->GetPixelsBgra(), SkinTexture->GetWidth(), SkinTexture->GetHeight());
|
||||
else
|
||||
args.SetTexture(SkinTexture->GetPixels(), SkinTexture->GetWidth(), SkinTexture->GetHeight());
|
||||
args.SetTexture(SkinTexture->GetPixels(DefaultRenderStyle()), SkinTexture->GetWidth(), SkinTexture->GetHeight());
|
||||
|
||||
args.SetDepthTest(true);
|
||||
args.SetWriteDepth(true);
|
||||
|
@ -237,7 +237,7 @@ namespace swrenderer
|
|||
if (Thread->Viewport->RenderTarget->IsBgra())
|
||||
args.SetTexture((const uint8_t *)SkinTexture->GetPixelsBgra(), SkinTexture->GetWidth(), SkinTexture->GetHeight());
|
||||
else
|
||||
args.SetTexture(SkinTexture->GetPixels(), SkinTexture->GetWidth(), SkinTexture->GetHeight());
|
||||
args.SetTexture(SkinTexture->GetPixels(DefaultRenderStyle()), SkinTexture->GetWidth(), SkinTexture->GetHeight());
|
||||
|
||||
args.SetDepthTest(true);
|
||||
args.SetWriteDepth(true);
|
||||
|
|
|
@ -545,10 +545,10 @@ namespace swrenderer
|
|||
short *mceilingclip = zeroarray;
|
||||
|
||||
fixed_t frac = startfrac;
|
||||
thread->PrepareTexture(pic);
|
||||
thread->PrepareTexture(pic, RenderStyle);
|
||||
for (int x = x1; x < x2; x++)
|
||||
{
|
||||
drawerargs.DrawMaskedColumn(thread, x, iscale, pic, frac + xiscale / 2, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, false);
|
||||
drawerargs.DrawMaskedColumn(thread, x, iscale, pic, frac + xiscale / 2, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, RenderStyle, false);
|
||||
frac += xiscale;
|
||||
}
|
||||
|
||||
|
|
|
@ -361,11 +361,11 @@ namespace swrenderer
|
|||
{
|
||||
RenderTranslucentPass *translucentPass = thread->TranslucentPass.get();
|
||||
|
||||
thread->PrepareTexture(tex);
|
||||
thread->PrepareTexture(tex, vis->RenderStyle);
|
||||
while (x < x2)
|
||||
{
|
||||
if (!translucentPass->ClipSpriteColumnWithPortals(x, vis))
|
||||
drawerargs.DrawMaskedColumn(thread, x, iscale, tex, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, false);
|
||||
drawerargs.DrawMaskedColumn(thread, x, iscale, tex, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, vis->RenderStyle, false);
|
||||
x++;
|
||||
frac += xiscale;
|
||||
}
|
||||
|
|
|
@ -239,7 +239,7 @@ namespace swrenderer
|
|||
{
|
||||
RenderTranslucentPass *translucentPass = thread->TranslucentPass.get();
|
||||
|
||||
thread->PrepareTexture(WallSpriteTile);
|
||||
thread->PrepareTexture(WallSpriteTile, spr->RenderStyle);
|
||||
while (x < x2)
|
||||
{
|
||||
if (calclighting)
|
||||
|
@ -247,14 +247,14 @@ namespace swrenderer
|
|||
drawerargs.SetLight(usecolormap, light, shade);
|
||||
}
|
||||
if (!translucentPass->ClipSpriteColumnWithPortals(x, spr))
|
||||
DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip);
|
||||
DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, spr->RenderStyle);
|
||||
light += lightstep;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderWallSprite::DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip)
|
||||
void RenderWallSprite::DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style)
|
||||
{
|
||||
auto viewport = thread->Viewport.get();
|
||||
|
||||
|
@ -266,6 +266,6 @@ namespace swrenderer
|
|||
else
|
||||
sprtopscreen = viewport->CenterY - texturemid * spryscale;
|
||||
|
||||
drawerargs.DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip);
|
||||
drawerargs.DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, style);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace swrenderer
|
|||
void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override;
|
||||
|
||||
private:
|
||||
static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip);
|
||||
static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style);
|
||||
|
||||
FWallCoords wallc;
|
||||
uint32_t Translation = 0;
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace swrenderer
|
|||
}
|
||||
else
|
||||
{
|
||||
dc_source = texture->GetColumn(column, nullptr);
|
||||
dc_source = texture->GetColumn(DefaultRenderStyle(), column, nullptr);
|
||||
dc_sourceheight = texture->GetHeight();
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ namespace swrenderer
|
|||
}
|
||||
else
|
||||
{
|
||||
dc_source2 = texture->GetColumn(column, nullptr);
|
||||
dc_source2 = texture->GetColumn(DefaultRenderStyle(), column, nullptr);
|
||||
dc_sourceheight2 = texture->GetHeight();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace swrenderer
|
|||
|
||||
void SpanDrawerArgs::SetTexture(RenderThread *thread, FTexture *tex)
|
||||
{
|
||||
thread->PrepareTexture(tex);
|
||||
thread->PrepareTexture(tex, DefaultRenderStyle());
|
||||
|
||||
ds_texwidth = tex->GetWidth();
|
||||
ds_texheight = tex->GetHeight();
|
||||
|
@ -47,7 +47,7 @@ namespace swrenderer
|
|||
ds_ybits--;
|
||||
}
|
||||
|
||||
ds_source = thread->Viewport->RenderTarget->IsBgra() ? (const uint8_t*)tex->GetPixelsBgra() : tex->GetPixels();
|
||||
ds_source = thread->Viewport->RenderTarget->IsBgra() ? (const uint8_t*)tex->GetPixelsBgra() : tex->GetPixels(DefaultRenderStyle()); // Get correct render style? Shaded won't get here.
|
||||
ds_source_mipmapped = tex->Mipmapped() && tex->GetWidth() > 1 && tex->GetHeight() > 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace swrenderer
|
|||
colfunc = &SWPixelFormatDrawers::DrawColumn;
|
||||
}
|
||||
|
||||
void SpriteDrawerArgs::DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FTexture *tex, fixed_t col, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked)
|
||||
void SpriteDrawerArgs::DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FTexture *tex, fixed_t col, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style, bool unmasked)
|
||||
{
|
||||
if (x < thread->X1 || x >= thread->X2)
|
||||
return;
|
||||
|
@ -67,7 +67,7 @@ namespace swrenderer
|
|||
if (viewport->RenderTarget->IsBgra() && !drawer_needs_pal_input)
|
||||
column = (const uint8_t *)tex->GetColumnBgra(col >> FRACBITS, &span);
|
||||
else
|
||||
column = tex->GetColumn(col >> FRACBITS, &span);
|
||||
column = tex->GetColumn(style, col >> FRACBITS, &span);
|
||||
|
||||
FTexture::Span unmaskedSpan[2];
|
||||
if (unmasked)
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace swrenderer
|
|||
void SetSolidColor(int color) { dc_color = color; dc_color_bgra = GPalette.BaseColors[color]; }
|
||||
void SetDynamicLight(uint32_t color) { dynlightcolor = color; }
|
||||
|
||||
void DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FTexture *texture, fixed_t column, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked = false);
|
||||
void DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FTexture *texture, fixed_t column, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style, bool unmasked = false);
|
||||
void FillColumn(RenderThread *thread);
|
||||
void DrawVoxelBlocks(RenderThread *thread, const VoxelBlock *blocks, int blockcount);
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "doomtype.h"
|
||||
#include "files.h"
|
||||
#include "w_wad.h"
|
||||
#include "v_palette.h"
|
||||
#include "textures/textures.h"
|
||||
|
||||
//==========================================================================
|
||||
|
@ -46,21 +47,11 @@
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
class FAutomapTexture : public FTexture
|
||||
class FAutomapTexture : public FWorldTexture
|
||||
{
|
||||
public:
|
||||
~FAutomapTexture ();
|
||||
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
void Unload ();
|
||||
void MakeTexture ();
|
||||
|
||||
FAutomapTexture (int lumpnum);
|
||||
|
||||
private:
|
||||
uint8_t *Pixels;
|
||||
Span DummySpan[2];
|
||||
FAutomapTexture(int lumpnum);
|
||||
uint8_t *MakeTexture (FRenderStyle style);
|
||||
};
|
||||
|
||||
|
||||
|
@ -86,16 +77,11 @@ FTexture *AutomapTexture_TryCreate(FileReader &data, int lumpnum)
|
|||
//==========================================================================
|
||||
|
||||
FAutomapTexture::FAutomapTexture (int lumpnum)
|
||||
: FTexture(NULL, lumpnum), Pixels(NULL)
|
||||
: FWorldTexture(NULL, lumpnum)
|
||||
{
|
||||
Width = 320;
|
||||
Height = uint16_t(Wads.LumpLength(lumpnum) / 320);
|
||||
CalcBitSize ();
|
||||
|
||||
DummySpan[0].TopOffset = 0;
|
||||
DummySpan[0].Length = Height;
|
||||
DummySpan[1].TopOffset = 0;
|
||||
DummySpan[1].Length = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -104,84 +90,22 @@ FAutomapTexture::FAutomapTexture (int lumpnum)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FAutomapTexture::~FAutomapTexture ()
|
||||
{
|
||||
Unload ();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FAutomapTexture::Unload ()
|
||||
{
|
||||
if (Pixels != NULL)
|
||||
{
|
||||
delete[] Pixels;
|
||||
Pixels = NULL;
|
||||
}
|
||||
FTexture::Unload();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FAutomapTexture::MakeTexture ()
|
||||
uint8_t *FAutomapTexture::MakeTexture (FRenderStyle style)
|
||||
{
|
||||
int x, y;
|
||||
FMemLump data = Wads.ReadLump (SourceLump);
|
||||
const uint8_t *indata = (const uint8_t *)data.GetMem();
|
||||
|
||||
Pixels = new uint8_t[Width * Height];
|
||||
auto Pixels = new uint8_t[Width * Height];
|
||||
|
||||
for (x = 0; x < Width; ++x)
|
||||
{
|
||||
for (y = 0; y < Height; ++y)
|
||||
{
|
||||
Pixels[x*Height+y] = indata[x+320*y];
|
||||
auto p = indata[x + 320 * y];
|
||||
Pixels[x*Height + y] = (style.Flags & STYLEF_RedIsAlpha) ? p : GPalette.Remap[p];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FAutomapTexture::GetPixels ()
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FAutomapTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
if ((unsigned)column >= (unsigned)Width)
|
||||
{
|
||||
column %= Width;
|
||||
}
|
||||
if (spans_out != NULL)
|
||||
{
|
||||
*spans_out = DummySpan;
|
||||
}
|
||||
return Pixels + column*Height;
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
struct FBackdropTexture : public FTexture
|
||||
class FBackdropTexture : public FWorldTexture
|
||||
{
|
||||
enum
|
||||
{
|
||||
|
@ -77,15 +77,12 @@ struct FBackdropTexture : public FTexture
|
|||
public:
|
||||
FBackdropTexture();
|
||||
|
||||
const uint8_t *GetColumn(unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels();
|
||||
void Unload();
|
||||
bool CheckModified();
|
||||
bool CheckModified(FRenderStyle style) override;
|
||||
uint8_t *MakeTexture(FRenderStyle style) override;
|
||||
|
||||
protected:
|
||||
uint32_t costab[COS_SIZE];
|
||||
uint8_t *Pixels;
|
||||
static const Span DummySpan[2];
|
||||
uint8_t Pixels[160*144];
|
||||
int LastRenderTic;
|
||||
|
||||
uint32_t time1, time2, time3, time4;
|
||||
|
@ -170,8 +167,6 @@ static uint8_t pattern2[1024] =
|
|||
7, 7, 0, 5, 1, 6, 7, 9,12, 9,12,21,22,25,24,22,23,25,24,18,24,22,17,13,10, 9,10, 9, 6,11, 6, 5,
|
||||
};
|
||||
|
||||
const FTexture::Span FBackdropTexture::DummySpan[2] = { { 0, 160 }, { 0, 0 } };
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
|
@ -180,7 +175,7 @@ const FTexture::Span FBackdropTexture::DummySpan[2] = { { 0, 160 }, { 0, 0 } };
|
|||
|
||||
FBackdropTexture::FBackdropTexture()
|
||||
{
|
||||
Pixels = nullptr;
|
||||
PixelsAreStatic = 3;
|
||||
Width = 144;
|
||||
Height = 160;
|
||||
WidthBits = 8;
|
||||
|
@ -209,44 +204,19 @@ FBackdropTexture::FBackdropTexture()
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
bool FBackdropTexture::CheckModified()
|
||||
bool FBackdropTexture::CheckModified(FRenderStyle)
|
||||
{
|
||||
return LastRenderTic != gametic;
|
||||
}
|
||||
|
||||
void FBackdropTexture::Unload()
|
||||
{
|
||||
if (Pixels != nullptr) delete[] Pixels;
|
||||
Pixels = nullptr;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
// There's no point making this work as a regular texture as it is made to
|
||||
// work with special translations. As an alpha texture it should be fine.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
const uint8_t *FBackdropTexture::GetColumn(unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (LastRenderTic != gametic)
|
||||
{
|
||||
Render();
|
||||
}
|
||||
column = clamp(column, 0u, 143u);
|
||||
if (spans_out != nullptr)
|
||||
{
|
||||
*spans_out = DummySpan;
|
||||
}
|
||||
return Pixels + column*160;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
const uint8_t *FBackdropTexture::GetPixels()
|
||||
uint8_t *FBackdropTexture::MakeTexture(FRenderStyle style)
|
||||
{
|
||||
if (LastRenderTic != gametic)
|
||||
{
|
||||
|
@ -266,7 +236,6 @@ void FBackdropTexture::Render()
|
|||
uint8_t *from;
|
||||
int width, height, pitch;
|
||||
|
||||
if (Pixels == nullptr) Pixels = new uint8_t[160 * 144];
|
||||
width = 160;
|
||||
height = 144;
|
||||
pitch = width;
|
||||
|
|
|
@ -193,13 +193,14 @@ typedef void (*CopyFunc)(uint8_t *pout, const uint8_t *pin, int count, int step,
|
|||
iCopyColors<cRGBA, cBGRA, op>, \
|
||||
iCopyColors<cIA, cBGRA, op>, \
|
||||
iCopyColors<cCMYK, cBGRA, op>, \
|
||||
iCopyColors<cYCbCr, cBGRA, op>, \
|
||||
iCopyColors<cBGR, cBGRA, op>, \
|
||||
iCopyColors<cBGRA, cBGRA, op>, \
|
||||
iCopyColors<cI16, cBGRA, op>, \
|
||||
iCopyColors<cRGB555, cBGRA, op>, \
|
||||
iCopyColors<cPalEntry, cBGRA, op> \
|
||||
}
|
||||
static const CopyFunc copyfuncs[][10]={
|
||||
static const CopyFunc copyfuncs[][11]={
|
||||
COPY_FUNCS(bCopy),
|
||||
COPY_FUNCS(bBlend),
|
||||
COPY_FUNCS(bAdd),
|
||||
|
|
|
@ -235,6 +235,15 @@ struct cCMYK
|
|||
static __forceinline int Gray(const unsigned char * p) { return (R(p)*77 + G(p)*143 + B(p)*36)>>8; }
|
||||
};
|
||||
|
||||
struct cYCbCr
|
||||
{
|
||||
static __forceinline unsigned char R(const unsigned char * p) { return clamp((int)(p[0] + 1.40200 * (int(p[2]) - 0x80)), 0, 255); }
|
||||
static __forceinline unsigned char G(const unsigned char * p) { return clamp((int)(p[0] - 0.34414 * (int(p[1] - 0x80)) - 0.71414 * (int(p[2]) - 0x80)), 0, 255); }
|
||||
static __forceinline unsigned char B(const unsigned char * p) { return clamp((int)(p[0] + 1.77200 * (int(p[1]) - 0x80)), 0, 255); }
|
||||
static __forceinline unsigned char A(const unsigned char * p, uint8_t x, uint8_t y, uint8_t z) { return 255; }
|
||||
static __forceinline int Gray(const unsigned char * p) { return (R(p) * 77 + G(p) * 143 + B(p) * 36) >> 8; }
|
||||
};
|
||||
|
||||
struct cBGR
|
||||
{
|
||||
static __forceinline unsigned char R(const unsigned char * p) { return p[2]; }
|
||||
|
@ -310,6 +319,7 @@ enum ColorType
|
|||
CF_RGBA,
|
||||
CF_IA,
|
||||
CF_CMYK,
|
||||
CF_YCbCr,
|
||||
CF_BGR,
|
||||
CF_BGRA,
|
||||
CF_I16,
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
/*
|
||||
** buildtexture.cpp
|
||||
** Handling Build textures
|
||||
** Handling Build textures (now as a usable editing feature!)
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2004-2006 Randy Heit
|
||||
** Copyright 2018 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
|
@ -39,8 +40,13 @@
|
|||
#include "templates.h"
|
||||
#include "cmdlib.h"
|
||||
#include "st_start.h"
|
||||
#include "colormatcher.h"
|
||||
#include "bitmap.h"
|
||||
#include "textures/textures.h"
|
||||
#include "r_data/sprites.h"
|
||||
#include "r_data/r_translate.h"
|
||||
#include "resourcefiles/resourcefile.h"
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -48,18 +54,18 @@
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
class FBuildTexture : public FTexture
|
||||
class FBuildTexture : public FWorldTexture
|
||||
{
|
||||
public:
|
||||
FBuildTexture (int tilenum, const uint8_t *pixels, int width, int height, int left, int top);
|
||||
~FBuildTexture ();
|
||||
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
FBuildTexture (const FString &pathprefix, int tilenum, const uint8_t *pixels, int translation, int width, int height, int left, int top);
|
||||
uint8_t *MakeTexture(FRenderStyle style) override;
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override;
|
||||
bool UseBasePalette() override { return false; }
|
||||
FTextureFormat GetFormat() override { return TEX_RGB; }
|
||||
|
||||
protected:
|
||||
const uint8_t *Pixels;
|
||||
Span **Spans;
|
||||
const uint8_t *RawPixels;
|
||||
int Translation;
|
||||
};
|
||||
|
||||
|
||||
|
@ -69,72 +75,37 @@ protected:
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FBuildTexture::FBuildTexture (int tilenum, const uint8_t *pixels, int width, int height, int left, int top)
|
||||
: Pixels (pixels), Spans (NULL)
|
||||
FBuildTexture::FBuildTexture(const FString &pathprefix, int tilenum, const uint8_t *pixels, int translation, int width, int height, int left, int top)
|
||||
: RawPixels (pixels), Translation(translation)
|
||||
{
|
||||
PixelsAreStatic = 3;
|
||||
Width = width;
|
||||
Height = height;
|
||||
LeftOffset = left;
|
||||
TopOffset = top;
|
||||
CalcBitSize ();
|
||||
Name.Format("BTIL%04d", tilenum);
|
||||
UseType = TEX_Build;
|
||||
Name.Format("%sBTIL%04d", pathprefix.GetChars(), tilenum);
|
||||
UseType = TEX_Override;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FBuildTexture::~FBuildTexture ()
|
||||
uint8_t *FBuildTexture::MakeTexture(FRenderStyle style)
|
||||
{
|
||||
if (Spans != NULL)
|
||||
auto Pixels = new uint8_t[Width * Height];
|
||||
FRemapTable *Remap = translationtables[TRANSLATION_Standard][Translation];
|
||||
for (int i = 0; i < Width*Height; i++)
|
||||
{
|
||||
FreeSpans (Spans);
|
||||
Spans = NULL;
|
||||
auto c = RawPixels[i];
|
||||
Pixels[i] = (style.Flags & STYLEF_RedIsAlpha) ? Remap->Palette[c].r : Remap->Remap[c];
|
||||
}
|
||||
return (uint8_t*)RawPixels;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FBuildTexture::GetPixels ()
|
||||
int FBuildTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf)
|
||||
{
|
||||
return Pixels;
|
||||
}
|
||||
PalEntry *Remap = translationtables[TRANSLATION_Standard][Translation]->Palette;
|
||||
bmp->CopyPixelData(x, y, RawPixels, Width, Height, Height, 1, rotate, Remap, inf);
|
||||
return 0;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FBuildTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (column >= Width)
|
||||
{
|
||||
if (WidthMask + 1 == Width)
|
||||
{
|
||||
column &= WidthMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
column %= Width;
|
||||
}
|
||||
}
|
||||
if (spans_out != NULL)
|
||||
{
|
||||
if (Spans == NULL)
|
||||
{
|
||||
Spans = CreateSpans (Pixels);
|
||||
}
|
||||
*spans_out = Spans[column];
|
||||
}
|
||||
return Pixels + column*Height;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -145,15 +116,16 @@ const uint8_t *FBuildTexture::GetColumn (unsigned int column, const Span **spans
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void FTextureManager::AddTiles (void *tiles)
|
||||
void FTextureManager::AddTiles (const FString &pathprefix, const void *tiles, int translation)
|
||||
{
|
||||
|
||||
// int numtiles = LittleLong(((uint32_t *)tiles)[1]); // This value is not reliable
|
||||
int tilestart = LittleLong(((uint32_t *)tiles)[2]);
|
||||
int tileend = LittleLong(((uint32_t *)tiles)[3]);
|
||||
const uint16_t *tilesizx = &((const uint16_t *)tiles)[8];
|
||||
const uint16_t *tilesizy = &tilesizx[tileend - tilestart + 1];
|
||||
const uint32_t *picanm = (const uint32_t *)&tilesizy[tileend - tilestart + 1];
|
||||
uint8_t *tiledata = (uint8_t *)&picanm[tileend - tilestart + 1];
|
||||
const uint8_t *tiledata = (const uint8_t *)&picanm[tileend - tilestart + 1];
|
||||
|
||||
for (int i = tilestart; i <= tileend; ++i)
|
||||
{
|
||||
|
@ -169,15 +141,12 @@ void FTextureManager::AddTiles (void *tiles)
|
|||
|
||||
if (width <= 0 || height <= 0) continue;
|
||||
|
||||
tex = new FBuildTexture (i, tiledata, width, height, xoffs, yoffs);
|
||||
tex = new FBuildTexture (pathprefix, i, tiledata, translation, width, height, xoffs, yoffs);
|
||||
texnum = AddTexture (tex);
|
||||
while (size > 0)
|
||||
{
|
||||
*tiledata = 255 - *tiledata;
|
||||
tiledata++;
|
||||
size--;
|
||||
}
|
||||
StartScreen->Progress();
|
||||
tiledata += size;
|
||||
|
||||
// reactivate only if the texture counter works here.
|
||||
//StartScreen->Progress();
|
||||
|
||||
if ((picanm[pic] & 63) && (picanm[pic] & 192))
|
||||
{
|
||||
|
@ -251,7 +220,7 @@ void FTextureManager::AddTiles (void *tiles)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
int FTextureManager::CountTiles (void *tiles)
|
||||
static int CountTiles (const void *tiles)
|
||||
{
|
||||
int version = LittleLong(*(uint32_t *)tiles);
|
||||
if (version != 1)
|
||||
|
@ -265,6 +234,60 @@ int FTextureManager::CountTiles (void *tiles)
|
|||
return tileend >= tilestart ? tileend - tilestart + 1 : 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Create palette data and remap table for the tile set's palette
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
static int BuildPaletteTranslation(int lump)
|
||||
{
|
||||
if (Wads.LumpLength(lump) < 768)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
FMemLump data = Wads.ReadLump(lump);
|
||||
const uint8_t *ipal = (const uint8_t *)data.GetMem();
|
||||
FRemapTable opal;
|
||||
|
||||
bool blood = false;
|
||||
for (int c = 0; c < 765; c++) // Build used VGA palettes (color values 0..63), Blood used full palettes (0..255) Let's hope this doesn't screw up...
|
||||
{
|
||||
if (ipal[c] >= 64)
|
||||
{
|
||||
blood = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int c = 0; c < 255; c++)
|
||||
{
|
||||
int r, g, b;
|
||||
if (!blood)
|
||||
{
|
||||
r = (ipal[3*c ] << 2) | (ipal[3 * c ] >> 4);
|
||||
g = (ipal[3*c + 1] << 2) | (ipal[3 * c + 1] >> 4);
|
||||
b = (ipal[3*c + 2] << 2) | (ipal[3 * c + 2] >> 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = ipal[3 * c] << 2;
|
||||
g = ipal[3 * c + 1] << 2;
|
||||
b = ipal[3 * c + 2] << 2;
|
||||
}
|
||||
opal.Palette[c] = PalEntry(255, r, g, b);
|
||||
opal.Remap[c] = ColorMatcher.Pick(r, g, b);
|
||||
}
|
||||
// The last entry is transparent.
|
||||
opal.Palette[255] = 0;
|
||||
opal.Remap[255] = 0;
|
||||
// Store the remap table in the translation manager so that we do not need to keep track of it ourselves.
|
||||
// Slot 0 for internal translations is a convenient location because normally it only contains a small number of translations.
|
||||
return GetTranslationIndex(opal.StoreTranslation(TRANSLATION_Standard));
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// R_CountBuildTiles
|
||||
|
@ -274,98 +297,59 @@ int FTextureManager::CountTiles (void *tiles)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
int FTextureManager::CountBuildTiles ()
|
||||
void FTextureManager::InitBuildTiles()
|
||||
{
|
||||
int numartfiles = 0;
|
||||
char artfile[] = "tilesXXX.art";
|
||||
int lumpnum;
|
||||
int numtiles;
|
||||
int totaltiles = 0;
|
||||
|
||||
lumpnum = Wads.CheckNumForFullName ("blood.pal");
|
||||
if (lumpnum >= 0)
|
||||
// The search rules are as follows:
|
||||
// - scan the entire lump directory for palette.dat files.
|
||||
// - if one is found, process the directory for .ART files and add textures for them.
|
||||
// - once all have been found, process all directories that may contain Build data.
|
||||
// - the root is not excluded which allows to read this from .GRP files as well.
|
||||
// - Blood support has been removed because it is not useful for modding to have loose .ART files.
|
||||
//
|
||||
// Unfortunately neither the palettes nor the .ART files contain any usable identifying marker
|
||||
// so this can only go by the file names.
|
||||
|
||||
int numlumps = Wads.GetNumLumps();
|
||||
for (int i = 0; i < numlumps; i++)
|
||||
{
|
||||
// Blood's tiles are external resources. (Why did they do it like that?)
|
||||
FString rffpath = Wads.GetWadFullName (Wads.GetLumpFile (lumpnum));
|
||||
int slashat = rffpath.LastIndexOf ('/');
|
||||
if (slashat >= 0)
|
||||
const char *name = Wads.GetLumpFullName(i);
|
||||
if (Wads.CheckNumForFullName(name) != i) continue; // This palette is hidden by a later one. Do not process
|
||||
FString base = ExtractFileBase(name, true);
|
||||
base.ToLower();
|
||||
if (base.Compare("palette.dat") == 0 && Wads.LumpLength(i) >= 768) // must be a valid palette, i.e. at least 256 colors.
|
||||
{
|
||||
rffpath.Truncate (slashat + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
rffpath += '/';
|
||||
}
|
||||
FString path = ExtractFilePath(name);
|
||||
if (path.IsNotEmpty() && path.Back() != '/') path += '/';
|
||||
|
||||
for (; numartfiles < 1000; numartfiles++)
|
||||
{
|
||||
artfile[5] = numartfiles / 100 + '0';
|
||||
artfile[6] = numartfiles / 10 % 10 + '0';
|
||||
artfile[7] = numartfiles % 10 + '0';
|
||||
|
||||
FString artpath = rffpath;
|
||||
artpath += artfile;
|
||||
|
||||
FileReader fr;
|
||||
|
||||
if (!fr.OpenFile(artpath))
|
||||
int translation = BuildPaletteTranslation(i);
|
||||
for (int numartfiles = 0; numartfiles < 1000; numartfiles++)
|
||||
{
|
||||
break;
|
||||
}
|
||||
FStringf artpath("%stiles%03d.art", path.GetChars(), numartfiles);
|
||||
// only read from the same source as the palette.
|
||||
// The entire format here is just too volatile to allow liberal mixing.
|
||||
// An .ART set must be treated as one unit.
|
||||
lumpnum = Wads.CheckNumForFullName(artpath, Wads.GetLumpFile(i));
|
||||
if (lumpnum < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
auto len = fr.GetLength();
|
||||
uint8_t *art = new uint8_t[len];
|
||||
if (fr.Read (art, len) != len || (numtiles = CountTiles(art)) == 0)
|
||||
{
|
||||
delete[] art;
|
||||
}
|
||||
else
|
||||
{
|
||||
BuildTileFiles.Push (art);
|
||||
totaltiles += numtiles;
|
||||
BuildTileData.Reserve(1);
|
||||
auto &artdata = BuildTileData.Last();
|
||||
artdata.Resize(Wads.LumpLength(lumpnum));
|
||||
Wads.ReadLump(lumpnum, &artdata[0]);
|
||||
|
||||
if ((numtiles = CountTiles(&artdata[0])) > 0)
|
||||
{
|
||||
AddTiles(path, &artdata[0], translation);
|
||||
totaltiles += numtiles;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (; numartfiles < 1000; numartfiles++)
|
||||
{
|
||||
artfile[5] = numartfiles / 100 + '0';
|
||||
artfile[6] = numartfiles / 10 % 10 + '0';
|
||||
artfile[7] = numartfiles % 10 + '0';
|
||||
lumpnum = Wads.CheckNumForFullName (artfile);
|
||||
if (lumpnum < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t *art = new uint8_t[Wads.LumpLength (lumpnum)];
|
||||
Wads.ReadLump (lumpnum, art);
|
||||
|
||||
if ((numtiles = CountTiles(art)) == 0)
|
||||
{
|
||||
delete[] art;
|
||||
}
|
||||
else
|
||||
{
|
||||
BuildTileFiles.Push (art);
|
||||
totaltiles += numtiles;
|
||||
}
|
||||
}
|
||||
return totaltiles;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// R_InitBuildTiles
|
||||
//
|
||||
// [RH] Support Build tiles!
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FTextureManager::InitBuildTiles ()
|
||||
{
|
||||
for (unsigned int i = 0; i < BuildTileFiles.Size(); ++i)
|
||||
{
|
||||
AddTiles (BuildTileFiles[i]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,12 +65,12 @@ FCanvasTexture::~FCanvasTexture ()
|
|||
Unload ();
|
||||
}
|
||||
|
||||
const uint8_t *FCanvasTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
const uint8_t *FCanvasTexture::GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out)
|
||||
{
|
||||
bNeedsUpdate = true;
|
||||
if (Canvas == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
MakeTexture (style);
|
||||
}
|
||||
if ((unsigned)column >= (unsigned)Width)
|
||||
{
|
||||
|
@ -90,12 +90,12 @@ const uint8_t *FCanvasTexture::GetColumn (unsigned int column, const Span **span
|
|||
return Pixels + column*Height;
|
||||
}
|
||||
|
||||
const uint8_t *FCanvasTexture::GetPixels ()
|
||||
const uint8_t *FCanvasTexture::GetPixels (FRenderStyle style)
|
||||
{
|
||||
bNeedsUpdate = true;
|
||||
if (Canvas == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
MakeTexture (style);
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ const uint32_t *FCanvasTexture::GetPixelsBgra()
|
|||
return PixelsBgra;
|
||||
}
|
||||
|
||||
void FCanvasTexture::MakeTexture ()
|
||||
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->Lock ();
|
||||
|
@ -183,7 +183,7 @@ void FCanvasTexture::Unload ()
|
|||
FTexture::Unload();
|
||||
}
|
||||
|
||||
bool FCanvasTexture::CheckModified ()
|
||||
bool FCanvasTexture::CheckModified (FRenderStyle)
|
||||
{
|
||||
if (bDidUpdate)
|
||||
{
|
||||
|
|
|
@ -153,22 +153,21 @@ struct DDSFileHeader
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
class FDDSTexture : public FTexture
|
||||
class FDDSTexture : public FWorldTexture
|
||||
{
|
||||
enum
|
||||
{
|
||||
PIX_Palette = 0,
|
||||
PIX_Alphatex = 1,
|
||||
PIX_ARGB = 2
|
||||
};
|
||||
public:
|
||||
FDDSTexture (FileReader &lump, int lumpnum, void *surfdesc);
|
||||
~FDDSTexture ();
|
||||
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
void Unload ();
|
||||
FTextureFormat GetFormat ();
|
||||
FTextureFormat GetFormat () override;
|
||||
uint8_t *MakeTexture(FRenderStyle style) override;
|
||||
|
||||
protected:
|
||||
|
||||
uint8_t *Pixels;
|
||||
Span **Spans;
|
||||
|
||||
uint32_t Format;
|
||||
|
||||
uint32_t RMask, GMask, BMask, AMask;
|
||||
|
@ -180,11 +179,10 @@ protected:
|
|||
|
||||
static void CalcBitShift (uint32_t mask, uint8_t *lshift, uint8_t *rshift);
|
||||
|
||||
void MakeTexture ();
|
||||
void ReadRGB (FileReader &lump, uint8_t *tcbuf = NULL);
|
||||
void DecompressDXT1 (FileReader &lump, uint8_t *tcbuf = NULL);
|
||||
void DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t *tcbuf = NULL);
|
||||
void DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t *tcbuf = NULL);
|
||||
void ReadRGB (FileReader &lump, uint8_t *buffer, int pixelmode);
|
||||
void DecompressDXT1 (FileReader &lump, uint8_t *buffer, int pixelmode);
|
||||
void DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t *buffer, int pixelmode);
|
||||
void DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t *buffer, int pixelmode);
|
||||
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL);
|
||||
bool UseBasePalette();
|
||||
|
@ -287,7 +285,7 @@ FTexture *DDSTexture_TryCreate (FileReader &data, int lumpnum)
|
|||
//==========================================================================
|
||||
|
||||
FDDSTexture::FDDSTexture (FileReader &lump, int lumpnum, void *vsurfdesc)
|
||||
: FTexture(NULL, lumpnum), Pixels(0), Spans(0)
|
||||
: FWorldTexture(NULL, lumpnum)
|
||||
{
|
||||
DDSURFACEDESC2 *surf = (DDSURFACEDESC2 *)vsurfdesc;
|
||||
|
||||
|
@ -381,38 +379,6 @@ void FDDSTexture::CalcBitShift (uint32_t mask, uint8_t *lshiftp, uint8_t *rshift
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FDDSTexture::~FDDSTexture ()
|
||||
{
|
||||
Unload ();
|
||||
if (Spans != NULL)
|
||||
{
|
||||
FreeSpans (Spans);
|
||||
Spans = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FDDSTexture::Unload ()
|
||||
{
|
||||
if (Pixels != NULL)
|
||||
{
|
||||
delete[] Pixels;
|
||||
Pixels = NULL;
|
||||
}
|
||||
FTexture::Unload();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FTextureFormat FDDSTexture::GetFormat()
|
||||
{
|
||||
#if 0
|
||||
|
@ -437,88 +403,41 @@ FTextureFormat FDDSTexture::GetFormat()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FDDSTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
uint8_t *FDDSTexture::MakeTexture (FRenderStyle style)
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
if ((unsigned)column >= (unsigned)Width)
|
||||
{
|
||||
if (WidthMask + 1 == Width)
|
||||
{
|
||||
column &= WidthMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
column %= Width;
|
||||
}
|
||||
}
|
||||
if (spans_out != NULL)
|
||||
{
|
||||
if (Spans == NULL)
|
||||
{
|
||||
Spans = CreateSpans (Pixels);
|
||||
}
|
||||
*spans_out = Spans[column];
|
||||
}
|
||||
return Pixels + column*Height;
|
||||
}
|
||||
auto lump = Wads.OpenLumpReader (SourceLump);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
auto Pixels = new uint8_t[Width*Height];
|
||||
|
||||
const uint8_t *FDDSTexture::GetPixels ()
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
lump.Seek (sizeof(DDSURFACEDESC2) + 4, FileReader::SeekSet);
|
||||
|
||||
int pmode = (style.Flags & STYLEF_RedIsAlpha) ? PIX_Alphatex : PIX_Palette;
|
||||
if (Format >= 1 && Format <= 4) // RGB: Format is # of bytes per pixel
|
||||
{
|
||||
MakeTexture ();
|
||||
ReadRGB (lump, Pixels, pmode);
|
||||
}
|
||||
else if (Format == ID_DXT1)
|
||||
{
|
||||
DecompressDXT1 (lump, Pixels, pmode);
|
||||
}
|
||||
else if (Format == ID_DXT3 || Format == ID_DXT2)
|
||||
{
|
||||
DecompressDXT3 (lump, Format == ID_DXT2, Pixels, pmode);
|
||||
}
|
||||
else if (Format == ID_DXT5 || Format == ID_DXT4)
|
||||
{
|
||||
DecompressDXT5 (lump, Format == ID_DXT4, Pixels, pmode);
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
// Note that pixel size == 8 is column-major, but 32 is row-major!
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FDDSTexture::MakeTexture ()
|
||||
{
|
||||
auto lump = Wads.OpenLumpReader (SourceLump);
|
||||
|
||||
Pixels = new uint8_t[Width*Height];
|
||||
|
||||
lump.Seek (sizeof(DDSURFACEDESC2) + 4, FileReader::SeekSet);
|
||||
|
||||
if (Format >= 1 && Format <= 4) // RGB: Format is # of bytes per pixel
|
||||
{
|
||||
ReadRGB (lump);
|
||||
}
|
||||
else if (Format == ID_DXT1)
|
||||
{
|
||||
DecompressDXT1 (lump);
|
||||
}
|
||||
else if (Format == ID_DXT3 || Format == ID_DXT2)
|
||||
{
|
||||
DecompressDXT3 (lump, Format == ID_DXT2);
|
||||
}
|
||||
else if (Format == ID_DXT5 || Format == ID_DXT4)
|
||||
{
|
||||
DecompressDXT5 (lump, Format == ID_DXT4);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FDDSTexture::ReadRGB (FileReader &lump, uint8_t *tcbuf)
|
||||
void FDDSTexture::ReadRGB (FileReader &lump, uint8_t *buffer, int pixelmode)
|
||||
{
|
||||
uint32_t x, y;
|
||||
uint32_t amask = AMask == 0 ? 0 : 0x80000000 >> AShiftL;
|
||||
|
@ -527,7 +446,7 @@ void FDDSTexture::ReadRGB (FileReader &lump, uint8_t *tcbuf)
|
|||
for (y = Height; y > 0; --y)
|
||||
{
|
||||
uint8_t *buffp = linebuff;
|
||||
uint8_t *pixelp = tcbuf? tcbuf + 4*y*Height : Pixels + y;
|
||||
uint8_t *pixelp = pixelmode == PIX_ARGB? buffer + 4*y*Height : buffer + y;
|
||||
lump.Read (linebuff, Pitch);
|
||||
for (x = Width; x > 0; --x)
|
||||
{
|
||||
|
@ -548,14 +467,21 @@ void FDDSTexture::ReadRGB (FileReader &lump, uint8_t *tcbuf)
|
|||
{
|
||||
c = *buffp++;
|
||||
}
|
||||
if (!tcbuf)
|
||||
if (pixelmode != PIX_ARGB)
|
||||
{
|
||||
if (amask == 0 || (c & amask))
|
||||
{
|
||||
uint32_t r = (c & RMask) << RShiftL; r |= r >> RShiftR;
|
||||
uint32_t g = (c & GMask) << GShiftL; g |= g >> GShiftR;
|
||||
uint32_t b = (c & BMask) << BShiftL; b |= b >> BShiftR;
|
||||
*pixelp = RGB256k.RGB[r >> 26][g >> 26][b >> 26];
|
||||
if (pixelmode == PIX_Palette)
|
||||
{
|
||||
uint32_t g = (c & GMask) << GShiftL; g |= g >> GShiftR;
|
||||
uint32_t b = (c & BMask) << BShiftL; b |= b >> BShiftR;
|
||||
*pixelp = RGB256k.RGB[r >> 26][g >> 26][b >> 26];
|
||||
}
|
||||
else
|
||||
{
|
||||
*pixelp = uint8_t(r >> 24);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -587,13 +513,13 @@ void FDDSTexture::ReadRGB (FileReader &lump, uint8_t *tcbuf)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FDDSTexture::DecompressDXT1 (FileReader &lump, uint8_t *tcbuf)
|
||||
void FDDSTexture::DecompressDXT1 (FileReader &lump, uint8_t *buffer, int pixelmode)
|
||||
{
|
||||
const long blocklinelen = ((Width + 3) >> 2) << 3;
|
||||
uint8_t *blockbuff = new uint8_t[blocklinelen];
|
||||
uint8_t *block;
|
||||
PalEntry color[4];
|
||||
uint8_t palcol[4];
|
||||
uint8_t palcol[4] = { 0,0,0,0 }; // shut up compiler warnings.
|
||||
int ox, oy, x, y, i;
|
||||
|
||||
color[0].a = 255;
|
||||
|
@ -639,9 +565,12 @@ void FDDSTexture::DecompressDXT1 (FileReader &lump, uint8_t *tcbuf)
|
|||
bMasked = true;
|
||||
}
|
||||
// Pick colors from the palette for each of the four colors.
|
||||
/*if (!tcbuf)*/ for (i = 3; i >= 0; --i)
|
||||
if (pixelmode != PIX_ARGB) for (i = 3; i >= 0; --i)
|
||||
{
|
||||
palcol[i] = color[i].a ? RGB256k.RGB[color[i].r >> 2][color[i].g >> 2][color[i].b >> 2] : 0;
|
||||
if (pixelmode == PIX_Palette)
|
||||
palcol[i] = color[i].a ? RGB256k.RGB[color[i].r >> 2][color[i].g >> 2][color[i].b >> 2] : 0;
|
||||
else
|
||||
palcol[i] = (color[i].a * color[i].r) / 255; // use the same logic as the hardware renderer.
|
||||
}
|
||||
// Now decode this 4x4 block to the pixel buffer.
|
||||
for (y = 0; y < 4; ++y)
|
||||
|
@ -658,13 +587,13 @@ void FDDSTexture::DecompressDXT1 (FileReader &lump, uint8_t *tcbuf)
|
|||
break;
|
||||
}
|
||||
int ci = (yslice >> (x + x)) & 3;
|
||||
if (!tcbuf)
|
||||
if (pixelmode != PIX_ARGB)
|
||||
{
|
||||
Pixels[oy + y + (ox + x) * Height] = palcol[ci];
|
||||
buffer[oy + y + (ox + x) * Height] = palcol[ci];
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t * tcp = &tcbuf[(ox + x)*4 + (oy + y) * Width*4];
|
||||
uint8_t * tcp = &buffer[(ox + x)*4 + (oy + y) * Width*4];
|
||||
tcp[0] = color[ci].r;
|
||||
tcp[1] = color[ci].g;
|
||||
tcp[2] = color[ci].b;
|
||||
|
@ -685,13 +614,13 @@ void FDDSTexture::DecompressDXT1 (FileReader &lump, uint8_t *tcbuf)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FDDSTexture::DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t *tcbuf)
|
||||
void FDDSTexture::DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t *buffer, int pixelmode)
|
||||
{
|
||||
const long blocklinelen = ((Width + 3) >> 2) << 4;
|
||||
uint8_t *blockbuff = new uint8_t[blocklinelen];
|
||||
uint8_t *block;
|
||||
PalEntry color[4];
|
||||
uint8_t palcol[4];
|
||||
uint8_t palcol[4] = { 0,0,0,0 };
|
||||
int ox, oy, x, y, i;
|
||||
|
||||
for (oy = 0; oy < Height; oy += 4)
|
||||
|
@ -719,10 +648,14 @@ void FDDSTexture::DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t
|
|||
color[3].b = (color[0].b + color[1].b + color[1].b + 1) / 3;
|
||||
|
||||
// Pick colors from the palette for each of the four colors.
|
||||
if (!tcbuf) for (i = 3; i >= 0; --i)
|
||||
if (pixelmode != PIX_ARGB) for (i = 3; i >= 0; --i)
|
||||
{
|
||||
palcol[i] = RGB256k.RGB[color[i].r >> 2][color[i].g >> 2][color[i].b >> 2];
|
||||
if (pixelmode == PIX_Palette)
|
||||
palcol[i] = color[i].a ? RGB256k.RGB[color[i].r >> 2][color[i].g >> 2][color[i].b >> 2] : 0;
|
||||
else
|
||||
palcol[i] = (color[i].a * color[i].r) / 255; // use the same logic as the hardware renderer.
|
||||
}
|
||||
|
||||
// Now decode this 4x4 block to the pixel buffer.
|
||||
for (y = 0; y < 4; ++y)
|
||||
{
|
||||
|
@ -738,14 +671,14 @@ void FDDSTexture::DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t
|
|||
{
|
||||
break;
|
||||
}
|
||||
if (!tcbuf)
|
||||
if (pixelmode != PIX_ARGB)
|
||||
{
|
||||
Pixels[oy + y + (ox + x) * Height] = ((yalphaslice >> (x*4)) & 15) < 8 ?
|
||||
buffer[oy + y + (ox + x) * Height] = ((yalphaslice >> (x*4)) & 15) < 8 ?
|
||||
(bMasked = true, 0) : palcol[(yslice >> (x + x)) & 3];
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t * tcp = &tcbuf[(ox + x)*4 + (oy + y) * Width*4];
|
||||
uint8_t * tcp = &buffer[(ox + x)*4 + (oy + y) * Width*4];
|
||||
int c = (yslice >> (x + x)) & 3;
|
||||
tcp[0] = color[c].r;
|
||||
tcp[1] = color[c].g;
|
||||
|
@ -767,13 +700,13 @@ void FDDSTexture::DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FDDSTexture::DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t *tcbuf)
|
||||
void FDDSTexture::DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t *buffer, int pixelmode)
|
||||
{
|
||||
const long blocklinelen = ((Width + 3) >> 2) << 4;
|
||||
uint8_t *blockbuff = new uint8_t[blocklinelen];
|
||||
uint8_t *block;
|
||||
PalEntry color[4];
|
||||
uint8_t palcol[4];
|
||||
uint8_t palcol[4] = { 0,0,0,0 };
|
||||
uint32_t yalphaslice = 0;
|
||||
int ox, oy, x, y, i;
|
||||
|
||||
|
@ -824,9 +757,12 @@ void FDDSTexture::DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t
|
|||
color[3].b = (color[0].b + color[1].b + color[1].b + 1) / 3;
|
||||
|
||||
// Pick colors from the palette for each of the four colors.
|
||||
if (!tcbuf) for (i = 3; i >= 0; --i)
|
||||
if (pixelmode != PIX_ARGB) for (i = 3; i >= 0; --i)
|
||||
{
|
||||
palcol[i] = RGB256k.RGB[color[i].r >> 2][color[i].g >> 2][color[i].b >> 2];
|
||||
if (pixelmode == PIX_Palette)
|
||||
palcol[i] = color[i].a ? RGB256k.RGB[color[i].r >> 2][color[i].g >> 2][color[i].b >> 2] : 0;
|
||||
else
|
||||
palcol[i] = (color[i].a * color[i].r) / 255; // use the same logic as the hardware renderer.
|
||||
}
|
||||
// Now decode this 4x4 block to the pixel buffer.
|
||||
for (y = 0; y < 4; ++y)
|
||||
|
@ -851,14 +787,14 @@ void FDDSTexture::DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t
|
|||
{
|
||||
break;
|
||||
}
|
||||
if (!tcbuf)
|
||||
if (pixelmode == 8)
|
||||
{
|
||||
Pixels[oy + y + (ox + x) * Height] = alpha[((yalphaslice >> (x*3)) & 7)] < 128 ?
|
||||
buffer[oy + y + (ox + x) * Height] = alpha[((yalphaslice >> (x*3)) & 7)] < 128 ?
|
||||
(bMasked = true, 0) : palcol[(yslice >> (x + x)) & 3];
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t * tcp = &tcbuf[(ox + x)*4 + (oy + y) * Width*4];
|
||||
uint8_t * tcp = &buffer[(ox + x)*4 + (oy + y) * Width*4];
|
||||
int c = (yslice >> (x + x)) & 3;
|
||||
tcp[0] = color[c].r;
|
||||
tcp[1] = color[c].g;
|
||||
|
@ -889,19 +825,19 @@ int FDDSTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo
|
|||
|
||||
if (Format >= 1 && Format <= 4) // RGB: Format is # of bytes per pixel
|
||||
{
|
||||
ReadRGB (lump, TexBuffer);
|
||||
ReadRGB (lump, TexBuffer, PIX_ARGB);
|
||||
}
|
||||
else if (Format == ID_DXT1)
|
||||
{
|
||||
DecompressDXT1 (lump, TexBuffer);
|
||||
DecompressDXT1 (lump, TexBuffer, PIX_ARGB);
|
||||
}
|
||||
else if (Format == ID_DXT3 || Format == ID_DXT2)
|
||||
{
|
||||
DecompressDXT3 (lump, Format == ID_DXT2, TexBuffer);
|
||||
DecompressDXT3 (lump, Format == ID_DXT2, TexBuffer, PIX_ARGB);
|
||||
}
|
||||
else if (Format == ID_DXT5 || Format == ID_DXT4)
|
||||
{
|
||||
DecompressDXT5 (lump, Format == ID_DXT4, TexBuffer);
|
||||
DecompressDXT5 (lump, Format == ID_DXT4, TexBuffer, PIX_ARGB);
|
||||
}
|
||||
|
||||
// All formats decompress to RGBA.
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
** flattexture.cpp
|
||||
** emptytexture.cpp
|
||||
** Texture class for empty placeholder textures
|
||||
** (essentially patches with dimensions and offsets of (0,0) )
|
||||
** These need special treatment because a texture size of 0 is illegal
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2009 Christoph Oelckers
|
||||
|
@ -41,30 +42,21 @@
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// A texture defined between F_START and F_END markers
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FEmptyTexture : public FTexture
|
||||
class FEmptyTexture : public FWorldTexture
|
||||
{
|
||||
uint8_t Pixel = 0;
|
||||
public:
|
||||
FEmptyTexture (int lumpnum);
|
||||
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
void Unload() {}
|
||||
|
||||
protected:
|
||||
uint8_t Pixels[1];
|
||||
Span DummySpans[1];
|
||||
uint8_t *MakeTexture(FRenderStyle style) override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Since there is no way to detect the validity of a flat
|
||||
// they can't be used anywhere else but between F_START and F_END
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
@ -86,15 +78,13 @@ FTexture *EmptyTexture_TryCreate(FileReader & file, int lumpnum)
|
|||
//==========================================================================
|
||||
|
||||
FEmptyTexture::FEmptyTexture (int lumpnum)
|
||||
: FTexture(NULL, lumpnum)
|
||||
: FWorldTexture(NULL, lumpnum)
|
||||
{
|
||||
bMasked = true;
|
||||
WidthBits = HeightBits = 1;
|
||||
Width = Height = 1;
|
||||
WidthMask = 0;
|
||||
DummySpans[0].TopOffset = 0;
|
||||
DummySpans[0].Length = 0;
|
||||
Pixels[0] = 0;
|
||||
PixelsAreStatic = 3;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -103,23 +93,8 @@ FEmptyTexture::FEmptyTexture (int lumpnum)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FEmptyTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
uint8_t *FEmptyTexture::MakeTexture(FRenderStyle style)
|
||||
{
|
||||
if (spans_out != NULL)
|
||||
{
|
||||
*spans_out = DummySpans;
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FEmptyTexture::GetPixels ()
|
||||
{
|
||||
return Pixels;
|
||||
return &Pixel;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,24 +45,11 @@
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
class FFlatTexture : public FTexture
|
||||
class FFlatTexture : public FWorldTexture
|
||||
{
|
||||
public:
|
||||
FFlatTexture (int lumpnum);
|
||||
~FFlatTexture ();
|
||||
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
void Unload ();
|
||||
|
||||
protected:
|
||||
uint8_t *Pixels;
|
||||
Span DummySpans[2];
|
||||
|
||||
|
||||
void MakeTexture ();
|
||||
|
||||
friend class FTexture;
|
||||
uint8_t *MakeTexture (FRenderStyle style) override;
|
||||
};
|
||||
|
||||
|
||||
|
@ -86,7 +73,7 @@ FTexture *FlatTexture_TryCreate(FileReader & file, int lumpnum)
|
|||
//==========================================================================
|
||||
|
||||
FFlatTexture::FFlatTexture (int lumpnum)
|
||||
: FTexture(NULL, lumpnum), Pixels(0)
|
||||
: FWorldTexture(NULL, lumpnum)
|
||||
{
|
||||
int area;
|
||||
int bits;
|
||||
|
@ -108,10 +95,6 @@ FFlatTexture::FFlatTexture (int lumpnum)
|
|||
WidthBits = HeightBits = bits;
|
||||
Width = Height = 1 << bits;
|
||||
WidthMask = (1 << bits) - 1;
|
||||
DummySpans[0].TopOffset = 0;
|
||||
DummySpans[0].Length = Height;
|
||||
DummySpans[1].TopOffset = 0;
|
||||
DummySpans[1].Length = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -120,87 +103,17 @@ FFlatTexture::FFlatTexture (int lumpnum)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FFlatTexture::~FFlatTexture ()
|
||||
{
|
||||
Unload ();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FFlatTexture::Unload ()
|
||||
{
|
||||
if (Pixels != NULL)
|
||||
{
|
||||
delete[] Pixels;
|
||||
Pixels = NULL;
|
||||
}
|
||||
FTexture::Unload();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FFlatTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
if ((unsigned)column >= (unsigned)Width)
|
||||
{
|
||||
if (WidthMask + 1 == Width)
|
||||
{
|
||||
column &= WidthMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
column %= Width;
|
||||
}
|
||||
}
|
||||
if (spans_out != NULL)
|
||||
{
|
||||
*spans_out = DummySpans;
|
||||
}
|
||||
return Pixels + column*Height;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FFlatTexture::GetPixels ()
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FFlatTexture::MakeTexture ()
|
||||
uint8_t *FFlatTexture::MakeTexture (FRenderStyle style)
|
||||
{
|
||||
auto lump = Wads.OpenLumpReader (SourceLump);
|
||||
Pixels = new uint8_t[Width*Height];
|
||||
auto Pixels = new uint8_t[Width*Height];
|
||||
auto numread = lump.Read (Pixels, Width*Height);
|
||||
if (numread < Width*Height)
|
||||
{
|
||||
memset (Pixels + numread, 0xBB, Width*Height - numread);
|
||||
}
|
||||
FlipSquareBlockRemap (Pixels, Width, Height, GPalette.Remap);
|
||||
if (!(style.Flags & STYLEF_RedIsAlpha)) FTexture::FlipSquareBlockRemap (Pixels, Width, Height, GPalette.Remap);
|
||||
else FTexture::FlipSquareBlock(Pixels, Width, Height);
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "doomtype.h"
|
||||
#include "files.h"
|
||||
#include "w_wad.h"
|
||||
#include "v_palette.h"
|
||||
#include "textures/textures.h"
|
||||
|
||||
|
||||
|
@ -47,7 +48,7 @@
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
class FIMGZTexture : public FTexture
|
||||
class FIMGZTexture : public FWorldTexture
|
||||
{
|
||||
struct ImageHeader
|
||||
{
|
||||
|
@ -62,18 +63,7 @@ class FIMGZTexture : public FTexture
|
|||
|
||||
public:
|
||||
FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int16_t t);
|
||||
~FIMGZTexture ();
|
||||
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
void Unload ();
|
||||
|
||||
protected:
|
||||
|
||||
uint8_t *Pixels;
|
||||
Span **Spans;
|
||||
|
||||
void MakeTexture ();
|
||||
uint8_t *MakeTexture (FRenderStyle style) override;
|
||||
};
|
||||
|
||||
|
||||
|
@ -106,7 +96,7 @@ FTexture *IMGZTexture_TryCreate(FileReader & file, int lumpnum)
|
|||
//==========================================================================
|
||||
|
||||
FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int16_t t)
|
||||
: FTexture(NULL, lumpnum), Pixels(0), Spans(0)
|
||||
: FWorldTexture(NULL, lumpnum)
|
||||
{
|
||||
Wads.GetLumpName (Name, lumpnum);
|
||||
Width = w;
|
||||
|
@ -122,88 +112,7 @@ FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int1
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FIMGZTexture::~FIMGZTexture ()
|
||||
{
|
||||
Unload ();
|
||||
if (Spans != NULL)
|
||||
{
|
||||
FreeSpans (Spans);
|
||||
Spans = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FIMGZTexture::Unload ()
|
||||
{
|
||||
if (Pixels != NULL)
|
||||
{
|
||||
delete[] Pixels;
|
||||
Pixels = NULL;
|
||||
}
|
||||
FTexture::Unload();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FIMGZTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
if ((unsigned)column >= (unsigned)Width)
|
||||
{
|
||||
if (WidthMask + 1 == Width)
|
||||
{
|
||||
column &= WidthMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
column %= Width;
|
||||
}
|
||||
}
|
||||
if (spans_out != NULL)
|
||||
{
|
||||
if (Spans == NULL)
|
||||
{
|
||||
Spans = CreateSpans (Pixels);
|
||||
}
|
||||
*spans_out = Spans[column];
|
||||
}
|
||||
return Pixels + column*Height;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FIMGZTexture::GetPixels ()
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FIMGZTexture::MakeTexture ()
|
||||
uint8_t *FIMGZTexture::MakeTexture (FRenderStyle style)
|
||||
{
|
||||
FMemLump lump = Wads.ReadLump (SourceLump);
|
||||
const ImageHeader *imgz = (const ImageHeader *)lump.GetMem();
|
||||
|
@ -222,7 +131,7 @@ void FIMGZTexture::MakeTexture ()
|
|||
int dest_rew = Width * Height - 1;
|
||||
|
||||
CalcBitSize ();
|
||||
Pixels = new uint8_t[Width*Height];
|
||||
auto Pixels = new uint8_t[Width*Height];
|
||||
dest_p = Pixels;
|
||||
|
||||
// Convert the source image from row-major to column-major format
|
||||
|
@ -232,7 +141,8 @@ void FIMGZTexture::MakeTexture ()
|
|||
{
|
||||
for (int x = Width; x != 0; --x)
|
||||
{
|
||||
*dest_p = *data;
|
||||
auto p = *data;
|
||||
*dest_p = (style.Flags & STYLEF_RedIsAlpha) ? p : GPalette.Remap[p];
|
||||
dest_p += dest_adv;
|
||||
data++;
|
||||
}
|
||||
|
@ -251,8 +161,8 @@ void FIMGZTexture::MakeTexture ()
|
|||
{
|
||||
if (runlen != 0)
|
||||
{
|
||||
uint8_t color = *data;
|
||||
*dest_p = color;
|
||||
auto p = *data;
|
||||
*dest_p = (style.Flags & STYLEF_RedIsAlpha) ? p : GPalette.Remap[p];
|
||||
dest_p += dest_adv;
|
||||
data++;
|
||||
x--;
|
||||
|
@ -282,5 +192,6 @@ void FIMGZTexture::MakeTexture ()
|
|||
dest_p -= dest_rew;
|
||||
}
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
|
|
|
@ -179,27 +179,15 @@ void JPEG_OutputMessage (j_common_ptr cinfo)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
class FJPEGTexture : public FTexture
|
||||
class FJPEGTexture : public FWorldTexture
|
||||
{
|
||||
public:
|
||||
FJPEGTexture (int lumpnum, int width, int height);
|
||||
~FJPEGTexture ();
|
||||
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
void Unload ();
|
||||
FTextureFormat GetFormat ();
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL);
|
||||
bool UseBasePalette();
|
||||
|
||||
protected:
|
||||
|
||||
uint8_t *Pixels;
|
||||
Span DummySpans[2];
|
||||
|
||||
void MakeTexture ();
|
||||
|
||||
friend class FTexture;
|
||||
FTextureFormat GetFormat () override;
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override;
|
||||
bool UseBasePalette() override;
|
||||
uint8_t *MakeTexture (FRenderStyle style) override;
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
@ -259,7 +247,7 @@ FTexture *JPEGTexture_TryCreate(FileReader & data, int lumpnum)
|
|||
//==========================================================================
|
||||
|
||||
FJPEGTexture::FJPEGTexture (int lumpnum, int width, int height)
|
||||
: FTexture(NULL, lumpnum), Pixels(0)
|
||||
: FWorldTexture(NULL, lumpnum)
|
||||
{
|
||||
UseType = TEX_MiscPatch;
|
||||
LeftOffset = 0;
|
||||
|
@ -269,35 +257,6 @@ FJPEGTexture::FJPEGTexture (int lumpnum, int width, int height)
|
|||
Width = width;
|
||||
Height = height;
|
||||
CalcBitSize ();
|
||||
|
||||
DummySpans[0].TopOffset = 0;
|
||||
DummySpans[0].Length = Height;
|
||||
DummySpans[1].TopOffset = 0;
|
||||
DummySpans[1].Length = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FJPEGTexture::~FJPEGTexture ()
|
||||
{
|
||||
Unload ();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FJPEGTexture::Unload ()
|
||||
{
|
||||
delete[] Pixels;
|
||||
Pixels = NULL;
|
||||
FTexture::Unload();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -317,142 +276,123 @@ FTextureFormat FJPEGTexture::GetFormat()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FJPEGTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
if ((unsigned)column >= (unsigned)Width)
|
||||
{
|
||||
if (WidthMask + 1 == Width)
|
||||
{
|
||||
column &= WidthMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
column %= Width;
|
||||
}
|
||||
}
|
||||
if (spans_out != NULL)
|
||||
{
|
||||
*spans_out = DummySpans;
|
||||
}
|
||||
return Pixels + column*Height;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FJPEGTexture::GetPixels ()
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FJPEGTexture::MakeTexture ()
|
||||
uint8_t *FJPEGTexture::MakeTexture (FRenderStyle style)
|
||||
{
|
||||
auto lump = Wads.OpenLumpReader (SourceLump);
|
||||
JSAMPLE *buff = NULL;
|
||||
bool doalpha = !!(style.Flags & STYLEF_RedIsAlpha);
|
||||
|
||||
jpeg_decompress_struct cinfo;
|
||||
jpeg_error_mgr jerr;
|
||||
|
||||
Pixels = new uint8_t[Width * Height];
|
||||
auto Pixels = new uint8_t[Width * Height];
|
||||
memset (Pixels, 0xBA, Width * Height);
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
cinfo.err->output_message = JPEG_OutputMessage;
|
||||
cinfo.err->error_exit = JPEG_ErrorExit;
|
||||
jpeg_create_decompress(&cinfo);
|
||||
|
||||
FLumpSourceMgr sourcemgr(&lump, &cinfo);
|
||||
try
|
||||
{
|
||||
FLumpSourceMgr sourcemgr(&lump, &cinfo);
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
if (!((cinfo.out_color_space == JCS_RGB && cinfo.num_components == 3) ||
|
||||
(cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) ||
|
||||
(cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1)))
|
||||
(cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) ||
|
||||
(cinfo.out_color_space == JCS_YCbCr && cinfo.num_components == 3) ||
|
||||
(cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1)))
|
||||
{
|
||||
Printf (TEXTCOLOR_ORANGE "Unsupported color format\n");
|
||||
throw -1;
|
||||
Printf(TEXTCOLOR_ORANGE "Unsupported color format in %s\n", Wads.GetLumpFullPath(SourceLump).GetChars());
|
||||
}
|
||||
|
||||
jpeg_start_decompress(&cinfo);
|
||||
|
||||
int y = 0;
|
||||
buff = new uint8_t[cinfo.output_width * cinfo.output_components];
|
||||
|
||||
while (cinfo.output_scanline < cinfo.output_height)
|
||||
else
|
||||
{
|
||||
int num_scanlines = jpeg_read_scanlines(&cinfo, &buff, 1);
|
||||
uint8_t *in = buff;
|
||||
uint8_t *out = Pixels + y;
|
||||
switch (cinfo.out_color_space)
|
||||
jpeg_start_decompress(&cinfo);
|
||||
|
||||
int y = 0;
|
||||
buff = new uint8_t[cinfo.output_width * cinfo.output_components];
|
||||
|
||||
while (cinfo.output_scanline < cinfo.output_height)
|
||||
{
|
||||
case JCS_RGB:
|
||||
for (int x = Width; x > 0; --x)
|
||||
int num_scanlines = jpeg_read_scanlines(&cinfo, &buff, 1);
|
||||
uint8_t *in = buff;
|
||||
uint8_t *out = Pixels + y;
|
||||
switch (cinfo.out_color_space)
|
||||
{
|
||||
*out = RGB256k.RGB[in[0]>>2][in[1]>>2][in[2]>>2];
|
||||
out += Height;
|
||||
in += 3;
|
||||
}
|
||||
break;
|
||||
case JCS_RGB:
|
||||
for (int x = Width; x > 0; --x)
|
||||
{
|
||||
*out = !doalpha? RGB256k.RGB[in[0] >> 2][in[1] >> 2][in[2] >> 2] : in[0];
|
||||
out += Height;
|
||||
in += 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case JCS_GRAYSCALE:
|
||||
for (int x = Width; x > 0; --x)
|
||||
{
|
||||
*out = GrayMap[in[0]];
|
||||
out += Height;
|
||||
in += 1;
|
||||
}
|
||||
break;
|
||||
case JCS_GRAYSCALE:
|
||||
for (int x = Width; x > 0; --x)
|
||||
{
|
||||
*out = !doalpha ? FTexture::GrayMap[in[0]] : in[0];
|
||||
out += Height;
|
||||
in += 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case JCS_CMYK:
|
||||
// What are you doing using a CMYK image? :)
|
||||
for (int x = Width; x > 0; --x)
|
||||
{
|
||||
// To be precise, these calculations should use 255, but
|
||||
// 256 is much faster and virtually indistinguishable.
|
||||
int r = in[3] - (((256-in[0])*in[3]) >> 8);
|
||||
int g = in[3] - (((256-in[1])*in[3]) >> 8);
|
||||
int b = in[3] - (((256-in[2])*in[3]) >> 8);
|
||||
*out = RGB256k.RGB[r >> 2][g >> 2][b >> 2];
|
||||
out += Height;
|
||||
in += 4;
|
||||
}
|
||||
break;
|
||||
case JCS_CMYK:
|
||||
// What are you doing using a CMYK image? :)
|
||||
for (int x = Width; x > 0; --x)
|
||||
{
|
||||
// To be precise, these calculations should use 255, but
|
||||
// 256 is much faster and virtually indistinguishable.
|
||||
int r = in[3] - (((256 - in[0])*in[3]) >> 8);
|
||||
if (!doalpha)
|
||||
{
|
||||
int g = in[3] - (((256 - in[1])*in[3]) >> 8);
|
||||
int b = in[3] - (((256 - in[2])*in[3]) >> 8);
|
||||
*out = RGB256k.RGB[r >> 2][g >> 2][b >> 2];
|
||||
}
|
||||
else *out = (uint8_t)r;
|
||||
out += Height;
|
||||
in += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// The other colorspaces were considered above and discarded,
|
||||
// but GCC will complain without a default for them here.
|
||||
break;
|
||||
case JCS_YCbCr:
|
||||
// Probably useless but since I had the formula available...
|
||||
for (int x = Width; x > 0; --x)
|
||||
{
|
||||
double Y = in[0], Cb = in[1], Cr = in[2];
|
||||
int r = clamp((int)(Y + 1.40200 * (Cr - 0x80)), 0, 255);
|
||||
if (!doalpha)
|
||||
{
|
||||
int g = clamp((int)(Y - 0.34414 * (Cb - 0x80) - 0.71414 * (Cr - 0x80)), 0, 255);
|
||||
int b = clamp((int)(Y + 1.77200 * (Cb - 0x80)), 0, 255);
|
||||
*out = RGB256k.RGB[r >> 2][g >> 2][b >> 2];
|
||||
}
|
||||
else *out = (uint8_t)r;
|
||||
out += Height;
|
||||
in += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// The other colorspaces were considered above and discarded,
|
||||
// but GCC will complain without a default for them here.
|
||||
break;
|
||||
}
|
||||
y++;
|
||||
}
|
||||
y++;
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
}
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
}
|
||||
catch (int)
|
||||
{
|
||||
Printf (TEXTCOLOR_ORANGE " in texture %s\n", Name.GetChars());
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
Printf(TEXTCOLOR_ORANGE "JPEG error in %s\n", Wads.GetLumpFullPath(SourceLump).GetChars());
|
||||
}
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
if (buff != NULL)
|
||||
{
|
||||
delete[] buff;
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
|
||||
|
@ -479,58 +419,66 @@ int FJPEGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FC
|
|||
cinfo.err->error_exit = JPEG_ErrorExit;
|
||||
jpeg_create_decompress(&cinfo);
|
||||
|
||||
FLumpSourceMgr sourcemgr(&lump, &cinfo);
|
||||
try
|
||||
{
|
||||
FLumpSourceMgr sourcemgr(&lump, &cinfo);
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
|
||||
if (!((cinfo.out_color_space == JCS_RGB && cinfo.num_components == 3) ||
|
||||
(cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) ||
|
||||
(cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1)))
|
||||
(cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) ||
|
||||
(cinfo.out_color_space == JCS_YCbCr && cinfo.num_components == 3) ||
|
||||
(cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1)))
|
||||
{
|
||||
Printf (TEXTCOLOR_ORANGE "Unsupported color format\n");
|
||||
throw -1;
|
||||
Printf(TEXTCOLOR_ORANGE "Unsupported color format in %s\n", Wads.GetLumpFullPath(SourceLump).GetChars());
|
||||
}
|
||||
jpeg_start_decompress(&cinfo);
|
||||
|
||||
int yc = 0;
|
||||
buff = new uint8_t[cinfo.output_height * cinfo.output_width * cinfo.output_components];
|
||||
|
||||
|
||||
while (cinfo.output_scanline < cinfo.output_height)
|
||||
else
|
||||
{
|
||||
uint8_t * ptr = buff + cinfo.output_width * cinfo.output_components * yc;
|
||||
jpeg_read_scanlines(&cinfo, &ptr, 1);
|
||||
yc++;
|
||||
jpeg_start_decompress(&cinfo);
|
||||
|
||||
int yc = 0;
|
||||
buff = new uint8_t[cinfo.output_height * cinfo.output_width * cinfo.output_components];
|
||||
|
||||
|
||||
while (cinfo.output_scanline < cinfo.output_height)
|
||||
{
|
||||
uint8_t * ptr = buff + cinfo.output_width * cinfo.output_components * yc;
|
||||
jpeg_read_scanlines(&cinfo, &ptr, 1);
|
||||
yc++;
|
||||
}
|
||||
|
||||
switch (cinfo.out_color_space)
|
||||
{
|
||||
case JCS_RGB:
|
||||
bmp->CopyPixelDataRGB(x, y, buff, cinfo.output_width, cinfo.output_height,
|
||||
3, cinfo.output_width * cinfo.output_components, rotate, CF_RGB, inf);
|
||||
break;
|
||||
|
||||
case JCS_GRAYSCALE:
|
||||
for (int i = 0; i < 256; i++) pe[i] = PalEntry(255, i, i, i); // default to a gray map
|
||||
bmp->CopyPixelData(x, y, buff, cinfo.output_width, cinfo.output_height,
|
||||
1, cinfo.output_width, rotate, pe, inf);
|
||||
break;
|
||||
|
||||
case JCS_CMYK:
|
||||
bmp->CopyPixelDataRGB(x, y, buff, cinfo.output_width, cinfo.output_height,
|
||||
4, cinfo.output_width * cinfo.output_components, rotate, CF_CMYK, inf);
|
||||
break;
|
||||
|
||||
case JCS_YCbCr:
|
||||
bmp->CopyPixelDataRGB(x, y, buff, cinfo.output_width, cinfo.output_height,
|
||||
4, cinfo.output_width * cinfo.output_components, rotate, CF_YCbCr, inf);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
}
|
||||
|
||||
switch (cinfo.out_color_space)
|
||||
{
|
||||
case JCS_RGB:
|
||||
bmp->CopyPixelDataRGB(x, y, buff, cinfo.output_width, cinfo.output_height,
|
||||
3, cinfo.output_width * cinfo.output_components, rotate, CF_RGB, inf);
|
||||
break;
|
||||
|
||||
case JCS_GRAYSCALE:
|
||||
for(int i=0;i<256;i++) pe[i]=PalEntry(255,i,i,i); // default to a gray map
|
||||
bmp->CopyPixelData(x, y, buff, cinfo.output_width, cinfo.output_height,
|
||||
1, cinfo.output_width, rotate, pe, inf);
|
||||
break;
|
||||
|
||||
case JCS_CMYK:
|
||||
bmp->CopyPixelDataRGB(x, y, buff, cinfo.output_width, cinfo.output_height,
|
||||
4, cinfo.output_width * cinfo.output_components, rotate, CF_CMYK, inf);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
}
|
||||
catch(int)
|
||||
catch (int)
|
||||
{
|
||||
Printf (TEXTCOLOR_ORANGE " in JPEG texture %s\n", Name.GetChars());
|
||||
Printf(TEXTCOLOR_ORANGE "JPEG error in %s\n", Wads.GetLumpFullPath(SourceLump).GetChars());
|
||||
}
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
if (buff != NULL) delete [] buff;
|
||||
|
|
|
@ -148,24 +148,21 @@ struct FPatchLookup
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
class FMultiPatchTexture : public FTexture
|
||||
class FMultiPatchTexture : public FWorldTexture
|
||||
{
|
||||
public:
|
||||
FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflump);
|
||||
FMultiPatchTexture (FScanner &sc, int usetype);
|
||||
~FMultiPatchTexture ();
|
||||
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
FTextureFormat GetFormat();
|
||||
bool UseBasePalette() ;
|
||||
void Unload ();
|
||||
virtual void SetFrontSkyLayer ();
|
||||
FTextureFormat GetFormat() override;
|
||||
bool UseBasePalette() override;
|
||||
virtual void SetFrontSkyLayer () override;
|
||||
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL);
|
||||
int GetSourceLump() { return DefinitionLump; }
|
||||
FTexture *GetRedirect(bool wantwarped);
|
||||
FTexture *GetRawTexture();
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override;
|
||||
int GetSourceLump() override { return DefinitionLump; }
|
||||
FTexture *GetRedirect(bool wantwarped) override;
|
||||
FTexture *GetRawTexture() override;
|
||||
void ResolvePatches();
|
||||
|
||||
protected:
|
||||
|
@ -198,10 +195,16 @@ protected:
|
|||
int NumParts;
|
||||
TexPart *Parts;
|
||||
TexInit *Inits;
|
||||
bool bRedirect:1;
|
||||
bool bTranslucentPatches:1;
|
||||
bool bRedirect;
|
||||
bool bTranslucentPatches;
|
||||
|
||||
uint8_t *MakeTexture (FRenderStyle style);
|
||||
|
||||
// The getters must optionally redirect if it's a simple one-patch texture.
|
||||
const uint8_t *GetPixels(FRenderStyle style) override { return bRedirect ? Parts->Texture->GetPixels(style) : FWorldTexture::GetPixels(style); }
|
||||
const uint8_t *GetColumn(FRenderStyle style, unsigned int col, const Span **out) override
|
||||
{ return bRedirect ? Parts->Texture->GetColumn(style, col, out) : FWorldTexture::GetColumn(style, col, out); }
|
||||
|
||||
void MakeTexture ();
|
||||
|
||||
private:
|
||||
void CheckForHacks ();
|
||||
|
@ -323,11 +326,6 @@ FMultiPatchTexture::~FMultiPatchTexture ()
|
|||
delete[] Inits;
|
||||
Inits = nullptr;
|
||||
}
|
||||
if (Spans != NULL)
|
||||
{
|
||||
FreeSpans (Spans);
|
||||
Spans = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -345,80 +343,6 @@ void FMultiPatchTexture::SetFrontSkyLayer ()
|
|||
bNoRemap0 = true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FMultiPatchTexture :: Unload
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FMultiPatchTexture::Unload ()
|
||||
{
|
||||
if (Pixels != NULL)
|
||||
{
|
||||
delete[] Pixels;
|
||||
Pixels = NULL;
|
||||
}
|
||||
FTexture::Unload();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FMultiPatchTexture :: GetPixels
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FMultiPatchTexture::GetPixels ()
|
||||
{
|
||||
if (bRedirect)
|
||||
{
|
||||
return Parts->Texture->GetPixels ();
|
||||
}
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FMultiPatchTexture :: GetColumn
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FMultiPatchTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (bRedirect)
|
||||
{
|
||||
return Parts->Texture->GetColumn (column, spans_out);
|
||||
}
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
if ((unsigned)column >= (unsigned)Width)
|
||||
{
|
||||
if (WidthMask + 1 == Width)
|
||||
{
|
||||
column &= WidthMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
column %= Width;
|
||||
}
|
||||
}
|
||||
if (spans_out != NULL)
|
||||
{
|
||||
if (Spans == NULL)
|
||||
{
|
||||
Spans = CreateSpans (Pixels);
|
||||
}
|
||||
*spans_out = Spans[column];
|
||||
}
|
||||
return Pixels + column*Height;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetBlendMap
|
||||
|
@ -427,7 +351,6 @@ const uint8_t *FMultiPatchTexture::GetColumn (unsigned int column, const Span **
|
|||
|
||||
uint8_t *GetBlendMap(PalEntry blend, uint8_t *blendwork)
|
||||
{
|
||||
|
||||
switch (blend.a==0 ? int(blend) : -1)
|
||||
{
|
||||
case BLEND_ICEMAP:
|
||||
|
@ -480,39 +403,54 @@ uint8_t *GetBlendMap(PalEntry blend, uint8_t *blendwork)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FMultiPatchTexture::MakeTexture ()
|
||||
uint8_t *FMultiPatchTexture::MakeTexture (FRenderStyle style)
|
||||
{
|
||||
// Add a little extra space at the end if the texture's height is not
|
||||
// a power of 2, in case somebody accidentally makes it repeat vertically.
|
||||
int numpix = Width * Height + (1 << HeightBits) - Height;
|
||||
uint8_t blendwork[256];
|
||||
bool hasTranslucent = false;
|
||||
bool buildrgb = bComplex;
|
||||
|
||||
Pixels = new uint8_t[numpix];
|
||||
auto Pixels = new uint8_t[numpix];
|
||||
memset (Pixels, 0, numpix);
|
||||
|
||||
for (int i = 0; i < NumParts; ++i)
|
||||
if (style.Flags & STYLEF_RedIsAlpha)
|
||||
{
|
||||
if (Parts[i].op != OP_COPY)
|
||||
// The rules here are as follows:
|
||||
// A texture uses its palette index as alpha only if it reports to use the base palette.
|
||||
// In summary this means:
|
||||
// If a texture is marked 'complex', it will use the red channel.
|
||||
// If a texture uses non-base-palette patches, it will use the red channel for all pixels, even those coming from a base palette patch.
|
||||
// If a texture only uses base-palette patches and no compositing effects it will use the palette index.
|
||||
//
|
||||
buildrgb = !UseBasePalette();
|
||||
}
|
||||
else
|
||||
{
|
||||
// For regular textures we can use paletted compositing if all patches are just being copied because they all can create a paletted buffer.
|
||||
if (!buildrgb) for (int i = 0; i < NumParts; ++i)
|
||||
{
|
||||
hasTranslucent = true;
|
||||
if (Parts[i].op != OP_COPY)
|
||||
{
|
||||
buildrgb = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasTranslucent)
|
||||
{
|
||||
if (!buildrgb)
|
||||
{
|
||||
for (int i = 0; i < NumParts; ++i)
|
||||
{
|
||||
if (Parts[i].Texture->bHasCanvas) continue; // cannot use camera textures as patch.
|
||||
|
||||
uint8_t *trans = Parts[i].Translation ? Parts[i].Translation->Remap : NULL;
|
||||
uint8_t *trans = Parts[i].Translation? Parts[i].Translation->Remap : nullptr;
|
||||
{
|
||||
if (Parts[i].Blend != 0)
|
||||
{
|
||||
trans = GetBlendMap(Parts[i].Blend, blendwork);
|
||||
}
|
||||
Parts[i].Texture->CopyToBlock (Pixels, Width, Height,
|
||||
Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans);
|
||||
Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans, style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -531,7 +469,7 @@ void FMultiPatchTexture::MakeTexture ()
|
|||
{
|
||||
if (*out == 0 && in[3] != 0)
|
||||
{
|
||||
*out = RGB256k.RGB[in[2]>>2][in[1]>>2][in[0]>>2];
|
||||
*out = (style.Flags & STYLEF_RedIsAlpha)? in[2]*in[3] : RGB256k.RGB[in[2]>>2][in[1]>>2][in[0]>>2];
|
||||
}
|
||||
out += Height;
|
||||
in += 4;
|
||||
|
@ -539,6 +477,7 @@ void FMultiPatchTexture::MakeTexture ()
|
|||
}
|
||||
delete [] buffer;
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -755,14 +694,6 @@ void FMultiPatchTexture::CheckForHacks ()
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == NumParts)
|
||||
{
|
||||
for (i = 0; i < NumParts; ++i)
|
||||
{
|
||||
Parts[i].Texture->HackHack(256);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "templates.h"
|
||||
#include "v_palette.h"
|
||||
#include "textures/textures.h"
|
||||
#include "r_data/r_translate.h"
|
||||
|
||||
|
||||
// posts are runs of non masked source pixels
|
||||
|
@ -55,24 +56,13 @@ struct column_t
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
class FPatchTexture : public FTexture
|
||||
class FPatchTexture : public FWorldTexture
|
||||
{
|
||||
bool badflag = false;
|
||||
public:
|
||||
FPatchTexture (int lumpnum, patch_t *header);
|
||||
~FPatchTexture ();
|
||||
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
void Unload ();
|
||||
|
||||
protected:
|
||||
uint8_t *Pixels;
|
||||
Span **Spans;
|
||||
bool hackflag;
|
||||
|
||||
|
||||
virtual void MakeTexture ();
|
||||
void HackHack (int newheight);
|
||||
uint8_t *MakeTexture (FRenderStyle style) override;
|
||||
void DetectBadPatches();
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
@ -149,12 +139,13 @@ FTexture *PatchTexture_TryCreate(FileReader & file, int lumpnum)
|
|||
//==========================================================================
|
||||
|
||||
FPatchTexture::FPatchTexture (int lumpnum, patch_t * header)
|
||||
: FTexture(NULL, lumpnum), Pixels(0), Spans(0), hackflag(false)
|
||||
: FWorldTexture(NULL, lumpnum)
|
||||
{
|
||||
Width = header->width;
|
||||
Height = header->height;
|
||||
LeftOffset = header->leftoffset;
|
||||
TopOffset = header->topoffset;
|
||||
DetectBadPatches();
|
||||
CalcBitSize ();
|
||||
}
|
||||
|
||||
|
@ -164,89 +155,7 @@ FPatchTexture::FPatchTexture (int lumpnum, patch_t * header)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FPatchTexture::~FPatchTexture ()
|
||||
{
|
||||
Unload ();
|
||||
if (Spans != NULL)
|
||||
{
|
||||
FreeSpans (Spans);
|
||||
Spans = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FPatchTexture::Unload ()
|
||||
{
|
||||
if (Pixels != NULL)
|
||||
{
|
||||
delete[] Pixels;
|
||||
Pixels = NULL;
|
||||
}
|
||||
FTexture::Unload();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FPatchTexture::GetPixels ()
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FPatchTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
if ((unsigned)column >= (unsigned)Width)
|
||||
{
|
||||
if (WidthMask + 1 == Width)
|
||||
{
|
||||
column &= WidthMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
column %= Width;
|
||||
}
|
||||
}
|
||||
if (spans_out != NULL)
|
||||
{
|
||||
if (Spans == NULL)
|
||||
{
|
||||
Spans = CreateSpans(Pixels);
|
||||
}
|
||||
*spans_out = Spans[column];
|
||||
}
|
||||
return Pixels + column*Height;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FPatchTexture::MakeTexture ()
|
||||
uint8_t *FPatchTexture::MakeTexture (FRenderStyle style)
|
||||
{
|
||||
uint8_t *remap, remaptable[256];
|
||||
int numspans;
|
||||
|
@ -258,23 +167,11 @@ void FPatchTexture::MakeTexture ()
|
|||
|
||||
maxcol = (const column_t *)((const uint8_t *)patch + Wads.LumpLength (SourceLump) - 3);
|
||||
|
||||
// Check for badly-sized patches
|
||||
#if 0 // Such textures won't be created so there's no need to check here
|
||||
if (LittleShort(patch->width) <= 0 || LittleShort(patch->height) <= 0)
|
||||
if (style.Flags & STYLEF_RedIsAlpha)
|
||||
{
|
||||
lump = Wads.ReadLump ("-BADPATC");
|
||||
patch = (const patch_t *)lump.GetMem();
|
||||
Printf (PRINT_BOLD, "Patch %s has a non-positive size.\n", Name);
|
||||
remap = translationtables[TRANSLATION_Standard][8]->Remap;
|
||||
}
|
||||
else if (LittleShort(patch->width) > 2048 || LittleShort(patch->height) > 2048)
|
||||
{
|
||||
lump = Wads.ReadLump ("-BADPATC");
|
||||
patch = (const patch_t *)lump.GetMem();
|
||||
Printf (PRINT_BOLD, "Patch %s is too big.\n", Name);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (bNoRemap0)
|
||||
else if (bNoRemap0)
|
||||
{
|
||||
memcpy (remaptable, GPalette.Remap, 256);
|
||||
remaptable[0] = 0;
|
||||
|
@ -286,9 +183,9 @@ void FPatchTexture::MakeTexture ()
|
|||
}
|
||||
|
||||
|
||||
if (hackflag)
|
||||
if (badflag)
|
||||
{
|
||||
Pixels = new uint8_t[Width * Height];
|
||||
auto Pixels = new uint8_t[Width * Height];
|
||||
uint8_t *out;
|
||||
|
||||
// Draw the image to the buffer
|
||||
|
@ -302,7 +199,7 @@ void FPatchTexture::MakeTexture ()
|
|||
out++, in++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
// Add a little extra space at the end if the texture's height is not
|
||||
|
@ -311,7 +208,7 @@ void FPatchTexture::MakeTexture ()
|
|||
|
||||
numspans = Width;
|
||||
|
||||
Pixels = new uint8_t[numpix];
|
||||
auto Pixels = new uint8_t[numpix];
|
||||
memset (Pixels, 0, numpix);
|
||||
|
||||
// Draw the image to the buffer
|
||||
|
@ -355,6 +252,7 @@ void FPatchTexture::MakeTexture ()
|
|||
column = (const column_t *)((const uint8_t *)column + column->length + 4);
|
||||
}
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
|
||||
|
@ -364,8 +262,11 @@ void FPatchTexture::MakeTexture ()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FPatchTexture::HackHack (int newheight)
|
||||
void FPatchTexture::DetectBadPatches ()
|
||||
{
|
||||
// The patch must look like it is large enough for the rules to apply to avoid using this on truly empty patches.
|
||||
if (Wads.LumpLength(SourceLump) < Width * Height / 2) return;
|
||||
|
||||
// Check if this patch is likely to be a problem.
|
||||
// It must be 256 pixels tall, and all its columns must have exactly
|
||||
// one post, where each post has a supposed length of 0.
|
||||
|
@ -381,29 +282,17 @@ void FPatchTexture::HackHack (int newheight)
|
|||
const column_t *col = (column_t*)((uint8_t*)realpatch+LittleLong(cofs[x]));
|
||||
if (col->topdelta != 0 || col->length != 0)
|
||||
{
|
||||
break; // It's not bad!
|
||||
return; // It's not bad!
|
||||
}
|
||||
col = (column_t *)((uint8_t *)col + 256 + 4);
|
||||
if (col->topdelta != 0xFF)
|
||||
{
|
||||
break; // More than one post in a column!
|
||||
return; // More than one post in a column!
|
||||
}
|
||||
}
|
||||
if (x == x2)
|
||||
{
|
||||
// If all the columns were checked, it needs fixing.
|
||||
Unload ();
|
||||
if (Spans != NULL)
|
||||
{
|
||||
FreeSpans (Spans);
|
||||
}
|
||||
|
||||
Height = newheight;
|
||||
LeftOffset = 0;
|
||||
TopOffset = 0;
|
||||
|
||||
hackflag = true;
|
||||
bMasked = false; // Hacked textures don't have transparent parts.
|
||||
}
|
||||
LeftOffset = 0;
|
||||
TopOffset = 0;
|
||||
badflag = true;
|
||||
bMasked = false; // Hacked textures don't have transparent parts.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,32 +81,23 @@ struct PCXHeader
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
class FPCXTexture : public FTexture
|
||||
class FPCXTexture : public FWorldTexture
|
||||
{
|
||||
public:
|
||||
FPCXTexture (int lumpnum, PCXHeader &);
|
||||
~FPCXTexture ();
|
||||
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
void Unload ();
|
||||
FTextureFormat GetFormat ();
|
||||
FTextureFormat GetFormat () override;
|
||||
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL);
|
||||
bool UseBasePalette();
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override;
|
||||
bool UseBasePalette() override;
|
||||
|
||||
protected:
|
||||
uint8_t *Pixels;
|
||||
Span DummySpans[2];
|
||||
|
||||
void ReadPCX1bit (uint8_t *dst, FileReader & lump, PCXHeader *hdr);
|
||||
void ReadPCX4bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr);
|
||||
void ReadPCX8bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr);
|
||||
void ReadPCX24bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr, int planes);
|
||||
|
||||
virtual void MakeTexture ();
|
||||
|
||||
friend class FTexture;
|
||||
uint8_t *MakeTexture (FRenderStyle style) override;
|
||||
};
|
||||
|
||||
|
||||
|
@ -154,44 +145,12 @@ FTexture * PCXTexture_TryCreate(FileReader & file, int lumpnum)
|
|||
//==========================================================================
|
||||
|
||||
FPCXTexture::FPCXTexture(int lumpnum, PCXHeader & hdr)
|
||||
: FTexture(NULL, lumpnum), Pixels(0)
|
||||
: FWorldTexture(NULL, lumpnum)
|
||||
{
|
||||
bMasked = false;
|
||||
Width = LittleShort(hdr.xmax) - LittleShort(hdr.xmin) + 1;
|
||||
Height = LittleShort(hdr.ymax) - LittleShort(hdr.ymin) + 1;
|
||||
CalcBitSize();
|
||||
|
||||
DummySpans[0].TopOffset = 0;
|
||||
DummySpans[0].Length = Height;
|
||||
DummySpans[1].TopOffset = 0;
|
||||
DummySpans[1].Length = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FPCXTexture::~FPCXTexture ()
|
||||
{
|
||||
Unload ();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FPCXTexture::Unload ()
|
||||
{
|
||||
if (Pixels != NULL)
|
||||
{
|
||||
delete[] Pixels;
|
||||
Pixels = NULL;
|
||||
}
|
||||
FTexture::Unload();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -211,51 +170,6 @@ FTextureFormat FPCXTexture::GetFormat()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FPCXTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
if ((unsigned)column >= (unsigned)Width)
|
||||
{
|
||||
if (WidthMask + 1 == Width)
|
||||
{
|
||||
column &= WidthMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
column %= Width;
|
||||
}
|
||||
}
|
||||
if (spans_out != NULL)
|
||||
{
|
||||
*spans_out = DummySpans;
|
||||
}
|
||||
return Pixels + column*Height;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FPCXTexture::GetPixels ()
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FPCXTexture::ReadPCX1bit (uint8_t *dst, FileReader & lump, PCXHeader *hdr)
|
||||
{
|
||||
int y, i, bytes;
|
||||
|
@ -457,18 +371,19 @@ void FPCXTexture::ReadPCX24bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FPCXTexture::MakeTexture()
|
||||
uint8_t *FPCXTexture::MakeTexture(FRenderStyle style)
|
||||
{
|
||||
uint8_t PaletteMap[256];
|
||||
PCXHeader header;
|
||||
int bitcount;
|
||||
bool alphatex = !!(style.Flags & STYLEF_RedIsAlpha);
|
||||
|
||||
auto lump = Wads.OpenLumpReader(SourceLump);
|
||||
|
||||
lump.Read(&header, sizeof(header));
|
||||
|
||||
bitcount = header.bitsPerPixel * header.numColorPlanes;
|
||||
Pixels = new uint8_t[Width*Height];
|
||||
auto Pixels = new uint8_t[Width*Height];
|
||||
|
||||
if (bitcount < 24)
|
||||
{
|
||||
|
@ -476,7 +391,8 @@ void FPCXTexture::MakeTexture()
|
|||
{
|
||||
for (int i=0;i<16;i++)
|
||||
{
|
||||
PaletteMap[i] = ColorMatcher.Pick(header.palette[i*3],header.palette[i*3+1],header.palette[i*3+2]);
|
||||
if (!alphatex) PaletteMap[i] = ColorMatcher.Pick(header.palette[i * 3], header.palette[i * 3 + 1], header.palette[i * 3 + 2]);
|
||||
else PaletteMap[i] = header.palette[i * 3];
|
||||
}
|
||||
|
||||
switch (bitcount)
|
||||
|
@ -502,7 +418,7 @@ void FPCXTexture::MakeTexture()
|
|||
uint8_t r = lump.ReadUInt8();
|
||||
uint8_t g = lump.ReadUInt8();
|
||||
uint8_t b = lump.ReadUInt8();
|
||||
PaletteMap[i] = ColorMatcher.Pick(r,g,b);
|
||||
PaletteMap[i] = !alphatex? ColorMatcher.Pick(r,g,b) : r;
|
||||
}
|
||||
lump.Seek(sizeof(header), FileReader::SeekSet);
|
||||
ReadPCX8bits (Pixels, lump, &header);
|
||||
|
@ -529,12 +445,13 @@ void FPCXTexture::MakeTexture()
|
|||
{
|
||||
for(int x=0; x < Width; x++)
|
||||
{
|
||||
Pixels[y+Height*x] = RGB256k.RGB[row[0]>>2][row[1]>>2][row[2]>>2];
|
||||
Pixels[y + Height * x] = !alphatex? RGB256k.RGB[row[0] >> 2][row[1] >> 2][row[2] >> 2] : row[0];
|
||||
row+=3;
|
||||
}
|
||||
}
|
||||
delete [] buffer;
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -48,24 +48,21 @@
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
class FPNGTexture : public FTexture
|
||||
class FPNGTexture : public FWorldTexture
|
||||
{
|
||||
public:
|
||||
FPNGTexture (FileReader &lump, int lumpnum, const FString &filename, int width, int height, uint8_t bitdepth, uint8_t colortype, uint8_t interlace);
|
||||
~FPNGTexture ();
|
||||
~FPNGTexture();
|
||||
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
void Unload ();
|
||||
FTextureFormat GetFormat ();
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL);
|
||||
bool UseBasePalette();
|
||||
FTextureFormat GetFormat () override;
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override;
|
||||
bool UseBasePalette() override;
|
||||
uint8_t *MakeTexture(FRenderStyle style) override;
|
||||
|
||||
protected:
|
||||
void ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap);
|
||||
|
||||
FString SourceFile;
|
||||
uint8_t *Pixels;
|
||||
Span **Spans;
|
||||
FileReader fr;
|
||||
|
||||
uint8_t BitDepth;
|
||||
|
@ -74,13 +71,10 @@ protected:
|
|||
bool HaveTrans;
|
||||
uint16_t NonPaletteTrans[3];
|
||||
|
||||
uint8_t *PaletteMap;
|
||||
int PaletteSize;
|
||||
uint32_t StartOfIDAT;
|
||||
|
||||
void MakeTexture ();
|
||||
|
||||
friend class FTexture;
|
||||
uint8_t *PaletteMap = nullptr;
|
||||
int PaletteSize = 0;
|
||||
uint32_t StartOfIDAT = 0;
|
||||
uint32_t StartOfPalette = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -200,9 +194,8 @@ FTexture *PNGTexture_CreateFromFile(PNGHandle *png, const FString &filename)
|
|||
|
||||
FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename, int width, int height,
|
||||
uint8_t depth, uint8_t colortype, uint8_t interlace)
|
||||
: FTexture(NULL, lumpnum), SourceFile(filename), Pixels(0), Spans(0),
|
||||
BitDepth(depth), ColorType(colortype), Interlace(interlace), HaveTrans(false),
|
||||
PaletteMap(0), PaletteSize(0), StartOfIDAT(0)
|
||||
: FWorldTexture(NULL, lumpnum), SourceFile(filename),
|
||||
BitDepth(depth), ColorType(colortype), Interlace(interlace), HaveTrans(false)
|
||||
{
|
||||
union
|
||||
{
|
||||
|
@ -265,6 +258,7 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename
|
|||
|
||||
case MAKE_ID('P','L','T','E'):
|
||||
PaletteSize = MIN<int> (len / 3, 256);
|
||||
StartOfPalette = (uint32_t)lump.Tell();
|
||||
lump.Read (p.pngpal, PaletteSize * 3);
|
||||
if (PaletteSize * 3 != (int)len)
|
||||
{
|
||||
|
@ -284,11 +278,6 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename
|
|||
NonPaletteTrans[1] = uint16_t(trans[2] * 256 + trans[3]);
|
||||
NonPaletteTrans[2] = uint16_t(trans[4] * 256 + trans[5]);
|
||||
break;
|
||||
|
||||
case MAKE_ID('a','l','P','h'):
|
||||
bAlphaTexture = true;
|
||||
bMasked = true;
|
||||
break;
|
||||
}
|
||||
lump.Seek(4, FileReader::SeekCur); // Skip CRC
|
||||
lump.Read(&len, 4);
|
||||
|
@ -304,20 +293,17 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename
|
|||
// intentional fall-through
|
||||
|
||||
case 0: // Grayscale
|
||||
if (!bAlphaTexture)
|
||||
if (colortype == 0 && HaveTrans && NonPaletteTrans[0] < 256)
|
||||
{
|
||||
if (colortype == 0 && HaveTrans && NonPaletteTrans[0] < 256)
|
||||
{
|
||||
bMasked = true;
|
||||
PaletteSize = 256;
|
||||
PaletteMap = new uint8_t[256];
|
||||
memcpy (PaletteMap, GrayMap, 256);
|
||||
PaletteMap[NonPaletteTrans[0]] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
PaletteMap = GrayMap;
|
||||
}
|
||||
bMasked = true;
|
||||
PaletteSize = 256;
|
||||
PaletteMap = new uint8_t[256];
|
||||
memcpy (PaletteMap, GrayMap, 256);
|
||||
PaletteMap[NonPaletteTrans[0]] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
PaletteMap = GrayMap;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -354,16 +340,10 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename
|
|||
|
||||
FPNGTexture::~FPNGTexture ()
|
||||
{
|
||||
Unload ();
|
||||
if (Spans != NULL)
|
||||
{
|
||||
FreeSpans (Spans);
|
||||
Spans = NULL;
|
||||
}
|
||||
if (PaletteMap != NULL && PaletteMap != GrayMap)
|
||||
if (PaletteMap != nullptr && PaletteMap != FTexture::GrayMap)
|
||||
{
|
||||
delete[] PaletteMap;
|
||||
PaletteMap = NULL;
|
||||
PaletteMap = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -373,19 +353,6 @@ FPNGTexture::~FPNGTexture ()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FPNGTexture::Unload ()
|
||||
{
|
||||
delete[] Pixels;
|
||||
Pixels = NULL;
|
||||
FTexture::Unload();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FTextureFormat FPNGTexture::GetFormat()
|
||||
{
|
||||
#if 0
|
||||
|
@ -407,32 +374,18 @@ FTextureFormat FPNGTexture::GetFormat()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FPNGTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
void FPNGTexture::ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap)
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
auto p = lump->Tell();
|
||||
lump->Seek(StartOfPalette, FileReader::SeekSet);
|
||||
for (int i = 0; i < PaletteSize; i++)
|
||||
{
|
||||
MakeTexture ();
|
||||
uint8_t r = lump->ReadUInt8();
|
||||
lump->ReadUInt8(); // Skip g and b.
|
||||
lump->ReadUInt8();
|
||||
alpharemap[i] = PaletteMap[i] == 0? 0 : r;
|
||||
}
|
||||
if ((unsigned)column >= (unsigned)Width)
|
||||
{
|
||||
if (WidthMask + 1 == Width)
|
||||
{
|
||||
column &= WidthMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
column %= Width;
|
||||
}
|
||||
}
|
||||
if (spans_out != NULL)
|
||||
{
|
||||
if (Spans == NULL)
|
||||
{
|
||||
Spans = CreateSpans (Pixels);
|
||||
}
|
||||
*spans_out = Spans[column];
|
||||
}
|
||||
return Pixels + column*Height;
|
||||
lump->Seek(p, FileReader::SeekSet);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -441,26 +394,11 @@ const uint8_t *FPNGTexture::GetColumn (unsigned int column, const Span **spans_o
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FPNGTexture::GetPixels ()
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FPNGTexture::MakeTexture ()
|
||||
uint8_t *FPNGTexture::MakeTexture (FRenderStyle style)
|
||||
{
|
||||
FileReader *lump;
|
||||
FileReader lfr;
|
||||
bool alphatex = !!(style.Flags & STYLEF_RedIsAlpha);
|
||||
|
||||
if (SourceLump >= 0)
|
||||
{
|
||||
|
@ -472,7 +410,7 @@ void FPNGTexture::MakeTexture ()
|
|||
lump = &fr;
|
||||
}
|
||||
|
||||
Pixels = new uint8_t[Width*Height];
|
||||
auto Pixels = new uint8_t[Width*Height];
|
||||
if (StartOfIDAT == 0)
|
||||
{
|
||||
memset (Pixels, 0x99, Width*Height);
|
||||
|
@ -490,25 +428,37 @@ void FPNGTexture::MakeTexture ()
|
|||
|
||||
if (Width == Height)
|
||||
{
|
||||
if (PaletteMap != NULL)
|
||||
if (!alphatex)
|
||||
{
|
||||
FlipSquareBlockRemap (Pixels, Width, Height, PaletteMap);
|
||||
FTexture::FlipSquareBlockRemap (Pixels, Width, Height, PaletteMap);
|
||||
}
|
||||
else if (ColorType == 0)
|
||||
{
|
||||
FTexture::FlipSquareBlock (Pixels, Width, Height);
|
||||
}
|
||||
else
|
||||
{
|
||||
FlipSquareBlock (Pixels, Width, Height);
|
||||
uint8_t alpharemap[256];
|
||||
ReadAlphaRemap(lump, alpharemap);
|
||||
FTexture::FlipSquareBlockRemap(Pixels, Width, Height, alpharemap);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *newpix = new uint8_t[Width*Height];
|
||||
if (PaletteMap != NULL)
|
||||
if (!alphatex)
|
||||
{
|
||||
FlipNonSquareBlockRemap (newpix, Pixels, Width, Height, Width, PaletteMap);
|
||||
FTexture::FlipNonSquareBlockRemap (newpix, Pixels, Width, Height, Width, PaletteMap);
|
||||
}
|
||||
else if (ColorType == 0)
|
||||
{
|
||||
FTexture::FlipNonSquareBlock (newpix, Pixels, Width, Height, Width);
|
||||
}
|
||||
else
|
||||
{
|
||||
FlipNonSquareBlock (newpix, Pixels, Width, Height, Width);
|
||||
uint8_t alpharemap[256];
|
||||
ReadAlphaRemap(lump, alpharemap);
|
||||
FTexture::FlipNonSquareBlockRemap(newpix, Pixels, Width, Height, Width, alpharemap);
|
||||
}
|
||||
uint8_t *oldpix = Pixels;
|
||||
Pixels = newpix;
|
||||
|
@ -537,22 +487,13 @@ void FPNGTexture::MakeTexture ()
|
|||
{
|
||||
for (y = Height; y > 0; --y)
|
||||
{
|
||||
if (!HaveTrans)
|
||||
if (HaveTrans && in[0] == NonPaletteTrans[0] && in[1] == NonPaletteTrans[1] && in[2] == NonPaletteTrans[2])
|
||||
{
|
||||
*out++ = RGB256k.RGB[in[0]>>2][in[1]>>2][in[2]>>2];
|
||||
*out++ = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (in[0] == NonPaletteTrans[0] &&
|
||||
in[1] == NonPaletteTrans[1] &&
|
||||
in[2] == NonPaletteTrans[2])
|
||||
{
|
||||
*out++ = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*out++ = RGB256k.RGB[in[0]>>2][in[1]>>2][in[2]>>2];
|
||||
}
|
||||
*out++ = alphatex? in[0] : RGB256k.RGB[in[0]>>2][in[1]>>2][in[2]>>2];
|
||||
}
|
||||
in += pitch;
|
||||
}
|
||||
|
@ -563,29 +504,14 @@ void FPNGTexture::MakeTexture ()
|
|||
case 4: // Grayscale + Alpha
|
||||
pitch = Width * 2;
|
||||
backstep = Height * pitch - 2;
|
||||
if (PaletteMap != NULL)
|
||||
for (x = Width; x > 0; --x)
|
||||
{
|
||||
for (x = Width; x > 0; --x)
|
||||
for (y = Height; y > 0; --y)
|
||||
{
|
||||
for (y = Height; y > 0; --y)
|
||||
{
|
||||
*out++ = in[1] < 128 ? 0 : PaletteMap[in[0]];
|
||||
in += pitch;
|
||||
}
|
||||
in -= backstep;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (x = Width; x > 0; --x)
|
||||
{
|
||||
for (y = Height; y > 0; --y)
|
||||
{
|
||||
*out++ = in[1] < 128 ? 0 : in[0];
|
||||
in += pitch;
|
||||
}
|
||||
in -= backstep;
|
||||
*out++ = alphatex? ((in[0] * in[1]) >> 8) : in[1] < 128 ? 0 : PaletteMap[in[0]];
|
||||
in += pitch;
|
||||
}
|
||||
in -= backstep;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -596,7 +522,7 @@ void FPNGTexture::MakeTexture ()
|
|||
{
|
||||
for (y = Height; y > 0; --y)
|
||||
{
|
||||
*out++ = in[3] < 128 ? 0 : RGB256k.RGB[in[0]>>2][in[1]>>2][in[2]>>2];
|
||||
*out++ = alphatex? ((in[0] * in[3]) >> 8) : in[3] < 128 ? 0 : RGB256k.RGB[in[0]>>2][in[1]>>2][in[2]>>2];
|
||||
in += pitch;
|
||||
}
|
||||
in -= backstep;
|
||||
|
@ -606,6 +532,7 @@ void FPNGTexture::MakeTexture ()
|
|||
delete[] tempix;
|
||||
}
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -46,21 +46,11 @@
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
class FRawPageTexture : public FTexture
|
||||
class FRawPageTexture : public FWorldTexture
|
||||
{
|
||||
public:
|
||||
FRawPageTexture (int lumpnum);
|
||||
~FRawPageTexture ();
|
||||
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
void Unload ();
|
||||
|
||||
protected:
|
||||
uint8_t *Pixels;
|
||||
static const Span DummySpans[2];
|
||||
|
||||
void MakeTexture ();
|
||||
uint8_t *MakeTexture (FRenderStyle style) override;
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
@ -155,17 +145,6 @@ FTexture *RawPageTexture_TryCreate(FileReader & file, int lumpnum)
|
|||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const FTexture::Span FRawPageTexture::DummySpans[2] =
|
||||
{
|
||||
{ 0, 200 }, { 0, 0 }
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -173,7 +152,7 @@ const FTexture::Span FRawPageTexture::DummySpans[2] =
|
|||
//==========================================================================
|
||||
|
||||
FRawPageTexture::FRawPageTexture (int lumpnum)
|
||||
: FTexture(NULL, lumpnum), Pixels(0)
|
||||
: FWorldTexture(NULL, lumpnum)
|
||||
{
|
||||
Width = 320;
|
||||
Height = 200;
|
||||
|
@ -188,79 +167,14 @@ FRawPageTexture::FRawPageTexture (int lumpnum)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FRawPageTexture::~FRawPageTexture ()
|
||||
{
|
||||
Unload ();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FRawPageTexture::Unload ()
|
||||
{
|
||||
if (Pixels != NULL)
|
||||
{
|
||||
delete[] Pixels;
|
||||
Pixels = NULL;
|
||||
}
|
||||
FTexture::Unload();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FRawPageTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
if ((unsigned)column >= (unsigned)Width)
|
||||
{
|
||||
column %= 320;
|
||||
}
|
||||
if (spans_out != NULL)
|
||||
{
|
||||
*spans_out = DummySpans;
|
||||
}
|
||||
return Pixels + column*Height;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FRawPageTexture::GetPixels ()
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FRawPageTexture::MakeTexture ()
|
||||
uint8_t *FRawPageTexture::MakeTexture (FRenderStyle style)
|
||||
{
|
||||
FMemLump lump = Wads.ReadLump (SourceLump);
|
||||
const uint8_t *source = (const uint8_t *)lump.GetMem();
|
||||
const uint8_t *source_p = source;
|
||||
uint8_t *dest_p;
|
||||
|
||||
Pixels = new uint8_t[Width*Height];
|
||||
auto Pixels = new uint8_t[Width*Height];
|
||||
dest_p = Pixels;
|
||||
|
||||
// Convert the source image from row-major to column-major format
|
||||
|
@ -268,11 +182,12 @@ void FRawPageTexture::MakeTexture ()
|
|||
{
|
||||
for (int x = 320; x != 0; --x)
|
||||
{
|
||||
*dest_p = GPalette.Remap[*source_p];
|
||||
*dest_p = (style.Flags & STYLEF_RedIsAlpha)? *source_p : GPalette.Remap[*source_p];
|
||||
dest_p += 200;
|
||||
source_p++;
|
||||
}
|
||||
dest_p -= 200*320-1;
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,9 +49,11 @@
|
|||
#include "r_defs.h"
|
||||
#include "r_state.h"
|
||||
#include "r_data/r_translate.h"
|
||||
#include "r_data/renderstyle.h"
|
||||
#include "bitmap.h"
|
||||
|
||||
|
||||
class FBarShader : public FTexture
|
||||
class FBarShader : public FWorldTexture
|
||||
{
|
||||
public:
|
||||
FBarShader(bool vertical, bool reverse)
|
||||
|
@ -62,6 +64,7 @@ public:
|
|||
Width = vertical ? 2 : 256;
|
||||
Height = vertical ? 256 : 2;
|
||||
CalcBitSize();
|
||||
PixelsAreStatic = 2; // The alpha buffer is static, but if this gets used as a regular texture, a separate buffer needs to be made.
|
||||
|
||||
// Fill the column/row with shading values.
|
||||
// Vertical shaders have have minimum alpha at the top
|
||||
|
@ -106,24 +109,42 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
DummySpan[0].TopOffset = 0;
|
||||
DummySpan[0].Length = vertical ? 256 : 2;
|
||||
DummySpan[1].TopOffset = 0;
|
||||
DummySpan[1].Length = 0;
|
||||
}
|
||||
const uint8_t *GetColumn(unsigned int column, const Span **spans_out)
|
||||
|
||||
uint8_t *MakeTexture(FRenderStyle style) override
|
||||
{
|
||||
if (spans_out != NULL)
|
||||
if (style.Flags & STYLEF_RedIsAlpha)
|
||||
{
|
||||
*spans_out = DummySpan;
|
||||
return Pixels;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Since this presents itself to the game as a regular named texture
|
||||
// it can easily be used on walls and flats and should work as such,
|
||||
// even if it makes little sense.
|
||||
auto Pix = new uint8_t[512];
|
||||
for (int i = 0; i < 512; i++)
|
||||
{
|
||||
Pix[i] = GrayMap[Pixels[i]];
|
||||
}
|
||||
return Pix;
|
||||
}
|
||||
return Pixels + ((column & WidthMask) << HeightBits);
|
||||
}
|
||||
const uint8_t *GetPixels() { return Pixels; }
|
||||
void Unload() {}
|
||||
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override
|
||||
{
|
||||
bmp->CopyPixelData(x, y, Pixels, Width, Height, Height, 1, rotate, translationtables[TRANSLATION_Standard][8]->Palette, inf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool UseBasePalette() override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
uint8_t Pixels[512];
|
||||
Span DummySpan[2];
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -59,9 +59,9 @@ FSkyBox::~FSkyBox()
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const uint8_t *FSkyBox::GetColumn (unsigned int column, const Span **spans_out)
|
||||
const uint8_t *FSkyBox::GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (faces[0]) return faces[0]->GetColumn(column, spans_out);
|
||||
if (faces[0]) return faces[0]->GetColumn(style, column, spans_out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -71,9 +71,9 @@ const uint8_t *FSkyBox::GetColumn (unsigned int column, const Span **spans_out)
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const uint8_t *FSkyBox::GetPixels ()
|
||||
const uint8_t *FSkyBox::GetPixels (FRenderStyle style)
|
||||
{
|
||||
if (faces[0]) return faces[0]->GetPixels();
|
||||
if (faces[0]) return faces[0]->GetPixels(style);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ public:
|
|||
|
||||
FSkyBox();
|
||||
~FSkyBox();
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels (FRenderStyle style);
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf);
|
||||
bool UseBasePalette();
|
||||
void Unload ();
|
||||
|
|
|
@ -183,19 +183,20 @@ void FTexture::Unload()
|
|||
const uint32_t *FTexture::GetColumnBgra(unsigned int column, const Span **spans_out)
|
||||
{
|
||||
const uint32_t *pixels = GetPixelsBgra();
|
||||
if (pixels == nullptr) return nullptr;
|
||||
|
||||
column %= Width;
|
||||
|
||||
if (spans_out != nullptr)
|
||||
GetColumn(column, spans_out);
|
||||
GetColumn(DefaultRenderStyle(), column, spans_out); // This isn't the right way to create the spans.
|
||||
return pixels + column * Height;
|
||||
}
|
||||
|
||||
const uint32_t *FTexture::GetPixelsBgra()
|
||||
{
|
||||
if (PixelsBgra.empty() || CheckModified())
|
||||
if (PixelsBgra.empty() || CheckModified(DefaultRenderStyle()))
|
||||
{
|
||||
if (!GetColumn(0, nullptr))
|
||||
if (!GetColumn(DefaultRenderStyle(), 0, nullptr))
|
||||
return nullptr;
|
||||
|
||||
FBitmap bitmap;
|
||||
|
@ -206,7 +207,7 @@ const uint32_t *FTexture::GetPixelsBgra()
|
|||
return PixelsBgra.data();
|
||||
}
|
||||
|
||||
bool FTexture::CheckModified ()
|
||||
bool FTexture::CheckModified (FRenderStyle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -248,10 +249,6 @@ void FTexture::CalcBitSize ()
|
|||
HeightBits = i;
|
||||
}
|
||||
|
||||
void FTexture::HackHack (int newheight)
|
||||
{
|
||||
}
|
||||
|
||||
FTexture::Span **FTexture::CreateSpans (const uint8_t *pixels) const
|
||||
{
|
||||
Span **spans, *span;
|
||||
|
@ -286,6 +283,7 @@ FTexture::Span **FTexture::CreateSpans (const uint8_t *pixels) const
|
|||
newspan = true;
|
||||
for (y = numrows; y > 0; --y)
|
||||
{
|
||||
|
||||
if (*data_p++ == 0)
|
||||
{
|
||||
if (!newspan)
|
||||
|
@ -554,14 +552,15 @@ void FTexture::GenerateBgraMipmapsFast()
|
|||
}
|
||||
}
|
||||
|
||||
void FTexture::CopyToBlock (uint8_t *dest, int dwidth, int dheight, int xpos, int ypos, int rotate, const uint8_t *translation)
|
||||
void FTexture::CopyToBlock (uint8_t *dest, int dwidth, int dheight, int xpos, int ypos, int rotate, const uint8_t *translation, FRenderStyle style)
|
||||
{
|
||||
const uint8_t *pixels = GetPixels();
|
||||
const uint8_t *pixels = GetPixels(style);
|
||||
int srcwidth = Width;
|
||||
int srcheight = Height;
|
||||
int step_x = Height;
|
||||
int step_y = 1;
|
||||
FClipRect cr = {0, 0, dwidth, dheight};
|
||||
if (style.Flags & STYLEF_RedIsAlpha) translation = nullptr; // do not apply translations to alpha textures.
|
||||
|
||||
if (ClipCopyPixelRect(&cr, xpos, ypos, pixels, srcwidth, srcheight, step_x, step_y, rotate))
|
||||
{
|
||||
|
@ -723,7 +722,7 @@ FNativeTexture *FTexture::GetNative(bool wrapping)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (CheckModified())
|
||||
if (CheckModified(DefaultRenderStyle()))
|
||||
{
|
||||
Native->Update();
|
||||
}
|
||||
|
@ -743,12 +742,6 @@ void FTexture::KillNative()
|
|||
}
|
||||
}
|
||||
|
||||
// For this generic implementation, we just call GetPixels and copy that data
|
||||
// to the buffer. Texture formats that can do better than paletted images
|
||||
// should provide their own implementation that may preserve the original
|
||||
// color data. Note that the buffer expects row-major data, since that's
|
||||
// generally more convenient for any non-Doom image formats, and it doesn't
|
||||
// need to be used by any of Doom's column drawing routines.
|
||||
void FTexture::FillBuffer(uint8_t *buff, int pitch, int height, FTextureFormat fmt)
|
||||
{
|
||||
const uint8_t *pix;
|
||||
|
@ -761,7 +754,7 @@ void FTexture::FillBuffer(uint8_t *buff, int pitch, int height, FTextureFormat f
|
|||
{
|
||||
case TEX_Pal:
|
||||
case TEX_Gray:
|
||||
pix = GetPixels();
|
||||
pix = GetPixels(DefaultRenderStyle());
|
||||
stride = pitch - w;
|
||||
for (y = 0; y < h; ++y)
|
||||
{
|
||||
|
@ -805,14 +798,14 @@ int FTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyI
|
|||
{
|
||||
PalEntry *palette = screen->GetPalette();
|
||||
for(int i=1;i<256;i++) palette[i].a = 255; // set proper alpha values
|
||||
bmp->CopyPixelData(x, y, GetPixels(), Width, Height, Height, 1, rotate, palette, inf);
|
||||
bmp->CopyPixelData(x, y, GetPixels(DefaultRenderStyle()), Width, Height, Height, 1, rotate, palette, inf);
|
||||
for(int i=1;i<256;i++) palette[i].a = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FTexture::CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, PalEntry *remap, FCopyInfo *inf)
|
||||
{
|
||||
bmp->CopyPixelData(x, y, GetPixels(), Width, Height, Height, 1, rotate, remap, inf);
|
||||
bmp->CopyPixelData(x, y, GetPixels(DefaultRenderStyle()), Width, Height, Height, 1, rotate, remap, inf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -923,7 +916,7 @@ int FTexture::CheckRealHeight()
|
|||
|
||||
for (int i = 0; i < GetWidth(); ++i)
|
||||
{
|
||||
GetColumn(i, &span);
|
||||
GetColumn(DefaultRenderStyle(), i, &span);
|
||||
while (span->Length != 0)
|
||||
{
|
||||
if (span->TopOffset < miny)
|
||||
|
@ -963,16 +956,15 @@ void FDummyTexture::SetSize (int width, int height)
|
|||
CalcBitSize ();
|
||||
}
|
||||
|
||||
// This must never be called
|
||||
const uint8_t *FDummyTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
// These only get called from the texture precacher which discards the result.
|
||||
const uint8_t *FDummyTexture::GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out)
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// And this also must never be called
|
||||
const uint8_t *FDummyTexture::GetPixels ()
|
||||
const uint8_t *FDummyTexture::GetPixels(FRenderStyle style)
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -999,7 +991,7 @@ CCMD (printspans)
|
|||
{
|
||||
const FTexture::Span *spans;
|
||||
Printf ("%4d:", x);
|
||||
tex->GetColumn (x, &spans);
|
||||
tex->GetColumn(DefaultRenderStyle(), x, &spans);
|
||||
while (spans->Length != 0)
|
||||
{
|
||||
Printf (" (%4d,%4d)", spans->TopOffset, spans->TopOffset+spans->Length-1);
|
||||
|
|
|
@ -137,12 +137,7 @@ void FTextureManager::DeleteAll()
|
|||
}
|
||||
}
|
||||
mAnimatedDoors.Clear();
|
||||
|
||||
for (unsigned int i = 0; i < BuildTileFiles.Size(); ++i)
|
||||
{
|
||||
delete[] BuildTileFiles[i];
|
||||
}
|
||||
BuildTileFiles.Clear();
|
||||
BuildTileData.Clear();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -982,8 +977,7 @@ void FTextureManager::Init()
|
|||
{
|
||||
DeleteAll();
|
||||
SpriteFrames.Clear();
|
||||
// Init Build Tile data if it hasn't been done already
|
||||
if (BuildTileFiles.Size() == 0) CountBuildTiles ();
|
||||
//if (BuildTileFiles.Size() == 0) CountBuildTiles ();
|
||||
FTexture::InitGrayMap();
|
||||
|
||||
// Texture 0 is a dummy texture used to indicate "no texture"
|
||||
|
@ -1131,7 +1125,7 @@ int FTextureManager::GuesstimateNumTextures ()
|
|||
}
|
||||
}
|
||||
|
||||
numtex += CountBuildTiles ();
|
||||
//numtex += CountBuildTiles (); // this cannot be done with a lot of overhead so just leave it out.
|
||||
numtex += CountTexturesX ();
|
||||
return numtex;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include "doomtype.h"
|
||||
#include "vectors.h"
|
||||
#include "r_data/renderstyle.h"
|
||||
#include <vector>
|
||||
|
||||
struct FloatRect
|
||||
|
@ -206,7 +207,6 @@ public:
|
|||
TEX_Flat,
|
||||
TEX_Sprite,
|
||||
TEX_WallPatch,
|
||||
TEX_Build,
|
||||
TEX_SkinSprite,
|
||||
TEX_Decal,
|
||||
TEX_MiscPatch,
|
||||
|
@ -225,13 +225,13 @@ public:
|
|||
};
|
||||
|
||||
// Returns a single column of the texture
|
||||
virtual const uint8_t *GetColumn (unsigned int column, const Span **spans_out) = 0;
|
||||
virtual const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) = 0;
|
||||
|
||||
// Returns a single column of the texture, in BGRA8 format
|
||||
virtual const uint32_t *GetColumnBgra(unsigned int column, const Span **spans_out);
|
||||
|
||||
// Returns the whole texture, stored in column-major order
|
||||
virtual const uint8_t *GetPixels () = 0;
|
||||
virtual const uint8_t *GetPixels(FRenderStyle style) = 0;
|
||||
|
||||
// Returns the whole texture, stored in column-major order, in BGRA8 format
|
||||
virtual const uint32_t *GetPixelsBgra();
|
||||
|
@ -277,17 +277,12 @@ public:
|
|||
|
||||
virtual void SetFrontSkyLayer();
|
||||
|
||||
void CopyToBlock (uint8_t *dest, int dwidth, int dheight, int x, int y, const uint8_t *translation=NULL)
|
||||
{
|
||||
CopyToBlock(dest, dwidth, dheight, x, y, 0, translation);
|
||||
}
|
||||
|
||||
void CopyToBlock (uint8_t *dest, int dwidth, int dheight, int x, int y, int rotate, const uint8_t *translation=NULL);
|
||||
void CopyToBlock (uint8_t *dest, int dwidth, int dheight, int x, int y, int rotate, const uint8_t *translation, FRenderStyle style);
|
||||
|
||||
// Returns true if the next call to GetPixels() will return an image different from the
|
||||
// last call to GetPixels(). This should be considered valid only if a call to CheckModified()
|
||||
// is immediately followed by a call to GetPixels().
|
||||
virtual bool CheckModified ();
|
||||
virtual bool CheckModified (FRenderStyle style);
|
||||
|
||||
static void InitGrayMap();
|
||||
|
||||
|
@ -307,8 +302,6 @@ public:
|
|||
PalEntry GetSkyCapColor(bool bottom);
|
||||
static PalEntry averageColor(const uint32_t *data, int size, int maxout);
|
||||
|
||||
virtual void HackHack (int newheight); // called by FMultipatchTexture to discover corrupt patches.
|
||||
|
||||
protected:
|
||||
uint16_t Width, Height, WidthMask;
|
||||
static uint8_t GrayMap[256];
|
||||
|
@ -528,9 +521,8 @@ private:
|
|||
int CountLumpTextures (int lumpnum);
|
||||
|
||||
// Build tiles
|
||||
void AddTiles (void *tiles);
|
||||
int CountTiles (void *tiles);
|
||||
int CountBuildTiles ();
|
||||
void AddTiles (const FString &pathprefix, const void *, int translation);
|
||||
//int CountBuildTiles ();
|
||||
void InitBuildTiles ();
|
||||
|
||||
// Animation stuff
|
||||
|
@ -572,11 +564,12 @@ private:
|
|||
FTextureID DefaultTexture;
|
||||
TArray<int> FirstTextureForFile;
|
||||
TMap<int,int> PalettedVersions; // maps from normal -> paletted version
|
||||
TArray<TArray<uint8_t> > BuildTileData;
|
||||
|
||||
TArray<FAnimDef *> mAnimations;
|
||||
TArray<FSwitchDef *> mSwitchDefs;
|
||||
TArray<FDoorAnimation> mAnimatedDoors;
|
||||
TArray<uint8_t *> BuildTileFiles;
|
||||
|
||||
public:
|
||||
short sintable[2048]; // for texture warping
|
||||
enum
|
||||
|
@ -585,45 +578,60 @@ public:
|
|||
};
|
||||
};
|
||||
|
||||
// base class for everything that can be used as a world texture.
|
||||
// This intermediate class encapsulates the buffers for the software renderer.
|
||||
class FWorldTexture : public FTexture
|
||||
{
|
||||
protected:
|
||||
uint8_t *Pixeldata[2] = { nullptr, nullptr };
|
||||
Span **Spandata[2] = { nullptr, nullptr };
|
||||
uint8_t PixelsAreStatic = 0; // can be set by subclasses which provide static pixel buffers.
|
||||
|
||||
FWorldTexture(const char *name = nullptr, int lumpnum = -1);
|
||||
~FWorldTexture();
|
||||
|
||||
const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) override;
|
||||
const uint8_t *GetPixels(FRenderStyle style) override;
|
||||
void Unload() override;
|
||||
virtual uint8_t *MakeTexture(FRenderStyle style) = 0;
|
||||
void FreeAllSpans();
|
||||
};
|
||||
|
||||
// A texture that doesn't really exist
|
||||
class FDummyTexture : public FTexture
|
||||
{
|
||||
public:
|
||||
FDummyTexture ();
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) override;
|
||||
const uint8_t *GetPixels(FRenderStyle style) override;
|
||||
void SetSize (int width, int height);
|
||||
};
|
||||
|
||||
// A texture that returns a wiggly version of another texture.
|
||||
class FWarpTexture : public FTexture
|
||||
class FWarpTexture : public FWorldTexture
|
||||
{
|
||||
public:
|
||||
FWarpTexture (FTexture *source, int warptype);
|
||||
~FWarpTexture ();
|
||||
void Unload() override;
|
||||
|
||||
virtual int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate=0, FCopyInfo *inf = NULL);
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
virtual int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate=0, FCopyInfo *inf = NULL) override;
|
||||
const uint32_t *GetPixelsBgra() override;
|
||||
void Unload ();
|
||||
bool CheckModified ();
|
||||
bool CheckModified (FRenderStyle) override;
|
||||
|
||||
float GetSpeed() const { return Speed; }
|
||||
int GetSourceLump() { return SourcePic->GetSourceLump(); }
|
||||
void SetSpeed(float fac) { Speed = fac; }
|
||||
FTexture *GetRedirect(bool wantwarped);
|
||||
|
||||
uint64_t GenTime;
|
||||
uint64_t GenTimeBgra;
|
||||
float Speed;
|
||||
uint64_t GenTime[2] = { 0, 0 };
|
||||
uint64_t GenTimeBgra = 0;
|
||||
float Speed = 1.f;
|
||||
int WidthOffsetMultiplier, HeightOffsetMultiplier; // [mxd]
|
||||
protected:
|
||||
FTexture *SourcePic;
|
||||
uint8_t *Pixels;
|
||||
Span **Spans;
|
||||
|
||||
virtual void MakeTexture (uint64_t time);
|
||||
uint8_t *MakeTexture (FRenderStyle style) override;
|
||||
int NextPo2 (int v); // [mxd]
|
||||
void SetupMultipliers (int width, int height); // [mxd]
|
||||
};
|
||||
|
@ -638,17 +646,17 @@ public:
|
|||
FCanvasTexture (const char *name, int width, int height);
|
||||
~FCanvasTexture ();
|
||||
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels (FRenderStyle style);
|
||||
const uint32_t *GetPixelsBgra() override;
|
||||
void Unload ();
|
||||
bool CheckModified ();
|
||||
bool CheckModified (FRenderStyle) override;
|
||||
void NeedUpdate() { bNeedsUpdate=true; }
|
||||
void SetUpdated() { bNeedsUpdate = false; bDidUpdate = true; bFirstUpdate = false; }
|
||||
DSimpleCanvas *GetCanvas() { return Canvas; }
|
||||
DSimpleCanvas *GetCanvasBgra() { return CanvasBgra; }
|
||||
bool Mipmapped() override { return false; }
|
||||
void MakeTexture ();
|
||||
void MakeTexture (FRenderStyle style);
|
||||
void MakeTextureBgra ();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -76,29 +76,18 @@ struct TGAHeader
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
class FTGATexture : public FTexture
|
||||
class FTGATexture : public FWorldTexture
|
||||
{
|
||||
public:
|
||||
FTGATexture (int lumpnum, TGAHeader *);
|
||||
~FTGATexture ();
|
||||
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
void Unload ();
|
||||
FTextureFormat GetFormat ();
|
||||
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL);
|
||||
bool UseBasePalette();
|
||||
FTextureFormat GetFormat () override;
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override;
|
||||
bool UseBasePalette() override;
|
||||
|
||||
protected:
|
||||
uint8_t *Pixels;
|
||||
Span **Spans;
|
||||
|
||||
void ReadCompressed(FileReader &lump, uint8_t * buffer, int bytesperpixel);
|
||||
|
||||
virtual void MakeTexture ();
|
||||
|
||||
friend class FTexture;
|
||||
uint8_t *MakeTexture (FRenderStyle style) override;
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
@ -142,7 +131,7 @@ FTexture *TGATexture_TryCreate(FileReader & file, int lumpnum)
|
|||
//==========================================================================
|
||||
|
||||
FTGATexture::FTGATexture (int lumpnum, TGAHeader * hdr)
|
||||
: FTexture(NULL, lumpnum), Pixels(0), Spans(0)
|
||||
: FWorldTexture(NULL, lumpnum)
|
||||
{
|
||||
Wads.GetLumpName (Name, lumpnum);
|
||||
Width = hdr->width;
|
||||
|
@ -158,38 +147,6 @@ FTGATexture::FTGATexture (int lumpnum, TGAHeader * hdr)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FTGATexture::~FTGATexture ()
|
||||
{
|
||||
Unload ();
|
||||
if (Spans != NULL)
|
||||
{
|
||||
FreeSpans (Spans);
|
||||
Spans = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FTGATexture::Unload ()
|
||||
{
|
||||
if (Pixels != NULL)
|
||||
{
|
||||
delete[] Pixels;
|
||||
Pixels = NULL;
|
||||
}
|
||||
FTexture::Unload();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FTextureFormat FTGATexture::GetFormat()
|
||||
{
|
||||
return TEX_RGB;
|
||||
|
@ -201,55 +158,6 @@ FTextureFormat FTGATexture::GetFormat()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FTGATexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
if ((unsigned)column >= (unsigned)Width)
|
||||
{
|
||||
if (WidthMask + 1 == Width)
|
||||
{
|
||||
column &= WidthMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
column %= Width;
|
||||
}
|
||||
}
|
||||
if (spans_out != NULL)
|
||||
{
|
||||
if (Spans == NULL)
|
||||
{
|
||||
Spans = CreateSpans (Pixels);
|
||||
}
|
||||
*spans_out = Spans[column];
|
||||
}
|
||||
return Pixels + column*Height;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FTGATexture::GetPixels ()
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FTGATexture::ReadCompressed(FileReader &lump, uint8_t * buffer, int bytesperpixel)
|
||||
{
|
||||
uint8_t data[4];
|
||||
|
@ -286,7 +194,7 @@ void FTGATexture::ReadCompressed(FileReader &lump, uint8_t * buffer, int bytespe
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FTGATexture::MakeTexture ()
|
||||
uint8_t *FTGATexture::MakeTexture (FRenderStyle style)
|
||||
{
|
||||
uint8_t PaletteMap[256];
|
||||
auto lump = Wads.OpenLumpReader (SourceLump);
|
||||
|
@ -294,8 +202,9 @@ void FTGATexture::MakeTexture ()
|
|||
uint16_t w;
|
||||
uint8_t r,g,b,a;
|
||||
uint8_t * buffer;
|
||||
bool alphatex = !!(style.Flags & STYLEF_RedIsAlpha);
|
||||
|
||||
Pixels = new uint8_t[Width*Height];
|
||||
auto Pixels = new uint8_t[Width*Height];
|
||||
lump.Read(&hdr, sizeof(hdr));
|
||||
lump.Seek(hdr.id_len, FileReader::SeekCur);
|
||||
|
||||
|
@ -339,7 +248,7 @@ void FTGATexture::MakeTexture ()
|
|||
r=g=b=a=0;
|
||||
break;
|
||||
}
|
||||
PaletteMap[i] = a>=128? ColorMatcher.Pick(r, g, b) : 0;
|
||||
PaletteMap[i] = !alphatex? (a>=128? ColorMatcher.Pick(r, g, b) : 0) : (r * a) >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -397,8 +306,8 @@ void FTGATexture::MakeTexture ()
|
|||
uint16_t * p = (uint16_t*)(ptr + y * Pitch);
|
||||
for(int x=0;x<Width;x++)
|
||||
{
|
||||
int v = LittleLong(*p);
|
||||
Pixels[x*Height+y] = RGB256k.RGB[((v>>10) & 0x1f)*2][((v>>5) & 0x1f)*2][(v & 0x1f)*2];
|
||||
int v = LittleShort(*p);
|
||||
Pixels[x*Height + y] = !alphatex ? RGB256k.RGB[((v >> 10) & 0x1f) * 2][((v >> 5) & 0x1f) * 2][(v & 0x1f) * 2] : ((v >> 10) & 0x1f) * 8;
|
||||
p+=step_x;
|
||||
}
|
||||
}
|
||||
|
@ -410,7 +319,7 @@ void FTGATexture::MakeTexture ()
|
|||
uint8_t * p = ptr + y * Pitch;
|
||||
for(int x=0;x<Width;x++)
|
||||
{
|
||||
Pixels[x*Height+y] = RGB256k.RGB[p[2]>>2][p[1]>>2][p[0]>>2];
|
||||
Pixels[x*Height + y] = !alphatex ? RGB256k.RGB[p[2] >> 2][p[1] >> 2][p[0] >> 2] : p[2];
|
||||
p+=step_x;
|
||||
}
|
||||
}
|
||||
|
@ -424,7 +333,7 @@ void FTGATexture::MakeTexture ()
|
|||
uint8_t * p = ptr + y * Pitch;
|
||||
for(int x=0;x<Width;x++)
|
||||
{
|
||||
Pixels[x*Height+y] = RGB256k.RGB[p[2]>>2][p[1]>>2][p[0]>>2];
|
||||
Pixels[x*Height + y] = !alphatex ? RGB256k.RGB[p[2] >> 2][p[1] >> 2][p[0] >> 2] : p[2];
|
||||
p+=step_x;
|
||||
}
|
||||
}
|
||||
|
@ -436,7 +345,7 @@ void FTGATexture::MakeTexture ()
|
|||
uint8_t * p = ptr + y * Pitch;
|
||||
for(int x=0;x<Width;x++)
|
||||
{
|
||||
Pixels[x*Height+y] = p[3] >= 128? RGB256k.RGB[p[2]>>2][p[1]>>2][p[0]>>2] : 0;
|
||||
Pixels[x*Height + y] = !alphatex ? (p[3] >= 128 ? RGB256k.RGB[p[2] >> 2][p[1] >> 2][p[0] >> 2] : 0) : (p[2] * p[3]) >> 8;
|
||||
p+=step_x;
|
||||
}
|
||||
}
|
||||
|
@ -457,7 +366,7 @@ void FTGATexture::MakeTexture ()
|
|||
uint8_t * p = ptr + y * Pitch;
|
||||
for(int x=0;x<Width;x++)
|
||||
{
|
||||
Pixels[x*Height+y] = GrayMap[*p];
|
||||
Pixels[x*Height+y] = !alphatex? FTexture::GrayMap[*p] : *p;
|
||||
p+=step_x;
|
||||
}
|
||||
}
|
||||
|
@ -469,7 +378,7 @@ void FTGATexture::MakeTexture ()
|
|||
uint8_t * p = ptr + y * Pitch;
|
||||
for(int x=0;x<Width;x++)
|
||||
{
|
||||
Pixels[x*Height+y] = GrayMap[p[1]]; // only use the high byte
|
||||
Pixels[x*Height+y] = !alphatex ? FTexture::GrayMap[p[1]] : p[1]; // only use the high byte
|
||||
p+=step_x;
|
||||
}
|
||||
}
|
||||
|
@ -484,6 +393,7 @@ void FTGATexture::MakeTexture ()
|
|||
break;
|
||||
}
|
||||
delete [] buffer;
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
|
||||
FWarpTexture::FWarpTexture (FTexture *source, int warptype)
|
||||
: GenTime (0), GenTimeBgra(0), Speed (1.f), SourcePic (source), Pixels (0), Spans (0)
|
||||
: SourcePic (source)
|
||||
{
|
||||
CopyInfo(source);
|
||||
if (warptype == 2) SetupMultipliers(256, 128);
|
||||
|
@ -55,53 +55,25 @@ FWarpTexture::FWarpTexture (FTexture *source, int warptype)
|
|||
FWarpTexture::~FWarpTexture ()
|
||||
{
|
||||
Unload ();
|
||||
if (Spans != NULL)
|
||||
{
|
||||
FreeSpans (Spans);
|
||||
Spans = NULL;
|
||||
}
|
||||
delete SourcePic;
|
||||
}
|
||||
|
||||
void FWarpTexture::Unload ()
|
||||
{
|
||||
if (Pixels != NULL)
|
||||
{
|
||||
delete[] Pixels;
|
||||
Pixels = NULL;
|
||||
}
|
||||
if (Spans != NULL)
|
||||
{
|
||||
FreeSpans (Spans);
|
||||
Spans = NULL;
|
||||
}
|
||||
SourcePic->Unload ();
|
||||
FTexture::Unload();
|
||||
FWorldTexture::Unload();
|
||||
FreeAllSpans();
|
||||
}
|
||||
|
||||
bool FWarpTexture::CheckModified ()
|
||||
bool FWarpTexture::CheckModified (FRenderStyle style)
|
||||
{
|
||||
return screen->FrameTime != GenTime;
|
||||
}
|
||||
|
||||
const uint8_t *FWarpTexture::GetPixels ()
|
||||
{
|
||||
uint64_t time = screen->FrameTime;
|
||||
|
||||
if (Pixels == NULL || time != GenTime)
|
||||
{
|
||||
MakeTexture (time);
|
||||
}
|
||||
return Pixels;
|
||||
return screen->FrameTime != GenTime[!!(style.Flags & STYLEF_RedIsAlpha)];
|
||||
}
|
||||
|
||||
const uint32_t *FWarpTexture::GetPixelsBgra()
|
||||
{
|
||||
uint64_t time = screen->FrameTime;
|
||||
if (Pixels == NULL || time != GenTime)
|
||||
MakeTexture(time);
|
||||
|
||||
if (PixelsBgra.empty() || time != GenTimeBgra)
|
||||
auto Pixels = GetPixels(DefaultRenderStyle());
|
||||
if (PixelsBgra.empty() || GenTime[0] != GenTimeBgra)
|
||||
{
|
||||
CreatePixelsBgraWithMipmaps();
|
||||
for (int i = 0; i < Width * Height; i++)
|
||||
|
@ -112,58 +84,21 @@ const uint32_t *FWarpTexture::GetPixelsBgra()
|
|||
PixelsBgra[i] = 0;
|
||||
}
|
||||
GenerateBgraMipmapsFast();
|
||||
GenTimeBgra = time;
|
||||
GenTimeBgra = GenTime[0];
|
||||
}
|
||||
return PixelsBgra.data();
|
||||
}
|
||||
|
||||
const uint8_t *FWarpTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
|
||||
uint8_t *FWarpTexture::MakeTexture(FRenderStyle style)
|
||||
{
|
||||
uint64_t time =screen->FrameTime;
|
||||
|
||||
if (Pixels == NULL || time != GenTime)
|
||||
{
|
||||
MakeTexture (time);
|
||||
}
|
||||
if ((unsigned)column >= (unsigned)Width)
|
||||
{
|
||||
if (WidthMask + 1 == Width)
|
||||
{
|
||||
column &= WidthMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
column %= Width;
|
||||
}
|
||||
}
|
||||
if (spans_out != NULL)
|
||||
{
|
||||
if (Spans == NULL)
|
||||
{
|
||||
Spans = CreateSpans (Pixels);
|
||||
}
|
||||
*spans_out = Spans[column];
|
||||
}
|
||||
return Pixels + column*Height;
|
||||
}
|
||||
|
||||
|
||||
void FWarpTexture::MakeTexture(uint64_t time)
|
||||
{
|
||||
const uint8_t *otherpix = SourcePic->GetPixels();
|
||||
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
Pixels = new uint8_t[Width * Height];
|
||||
}
|
||||
if (Spans != NULL)
|
||||
{
|
||||
FreeSpans(Spans);
|
||||
Spans = NULL;
|
||||
}
|
||||
|
||||
GenTime = time;
|
||||
uint64_t time = screen->FrameTime;
|
||||
const uint8_t *otherpix = SourcePic->GetPixels(style);
|
||||
auto Pixels = new uint8_t[Width * Height];
|
||||
WarpBuffer(Pixels, otherpix, Width, Height, WidthOffsetMultiplier, HeightOffsetMultiplier, time, Speed, bWarped);
|
||||
FreeAllSpans();
|
||||
GenTime[!!(style.Flags & STYLEF_RedIsAlpha)] = time;
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
// [mxd] Non power of 2 textures need different offset multipliers, otherwise warp animation won't sync across texture
|
||||
|
|
150
src/textures/worldtexture.cpp
Normal file
150
src/textures/worldtexture.cpp
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
** worldtexture.cpp
|
||||
** Intermediate class for some common code for several classes
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2018 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
**
|
||||
*/
|
||||
|
||||
#include "textures.h"
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FWorldTexture::FWorldTexture(const char *name, int lumpnum)
|
||||
: FTexture(name, lumpnum)
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FWorldTexture::~FWorldTexture()
|
||||
{
|
||||
Unload();
|
||||
FreeAllSpans();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FWorldTexture::FreeAllSpans()
|
||||
{
|
||||
for(int i = 0; i < 2; i++)
|
||||
{
|
||||
if (Spandata[i] != nullptr)
|
||||
{
|
||||
FreeSpans (Spandata[i]);
|
||||
Spandata[i] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FWorldTexture::Unload ()
|
||||
{
|
||||
for(int i = 0; i < 2; i++)
|
||||
{
|
||||
if (!(PixelsAreStatic & (1 << i)))
|
||||
{
|
||||
delete[] Pixeldata[i];
|
||||
}
|
||||
Pixeldata[i] = nullptr;
|
||||
}
|
||||
FTexture::Unload();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FWorldTexture::GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out)
|
||||
{
|
||||
int index = !!(style.Flags & STYLEF_RedIsAlpha);
|
||||
GetPixels(style);
|
||||
if ((unsigned)column >= (unsigned)Width)
|
||||
{
|
||||
if (WidthMask + 1 == Width)
|
||||
{
|
||||
column &= WidthMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
column %= Width;
|
||||
}
|
||||
}
|
||||
if (spans_out != nullptr)
|
||||
{
|
||||
if (Spandata[index] == nullptr)
|
||||
{
|
||||
Spandata[index] = CreateSpans (Pixeldata[index]);
|
||||
}
|
||||
*spans_out = Spandata[index][column];
|
||||
}
|
||||
return Pixeldata[index] + column*Height;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FWorldTexture::GetPixels (FRenderStyle style)
|
||||
{
|
||||
if (CheckModified(style))
|
||||
{
|
||||
Unload();
|
||||
}
|
||||
int index = !!(style.Flags & STYLEF_RedIsAlpha);
|
||||
if (Pixeldata[index] == nullptr)
|
||||
{
|
||||
Pixeldata[index] = MakeTexture (style);
|
||||
}
|
||||
return Pixeldata[index];
|
||||
}
|
||||
|
|
@ -177,8 +177,8 @@ class FFontChar1 : public FTexture
|
|||
{
|
||||
public:
|
||||
FFontChar1 (FTexture *sourcelump);
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels (FRenderStyle style);
|
||||
void SetSourceRemap(const uint8_t *sourceremap);
|
||||
void Unload ();
|
||||
~FFontChar1 ();
|
||||
|
@ -198,8 +198,8 @@ public:
|
|||
FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0);
|
||||
~FFontChar2 ();
|
||||
|
||||
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels ();
|
||||
const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels (FRenderStyle style);
|
||||
void SetSourceRemap(const uint8_t *sourceremap);
|
||||
void Unload ();
|
||||
|
||||
|
@ -559,7 +559,7 @@ void RecordTextureColors (FTexture *pic, uint8_t *usedcolors)
|
|||
for (x = pic->GetWidth() - 1; x >= 0; x--)
|
||||
{
|
||||
const FTexture::Span *spans;
|
||||
const uint8_t *column = pic->GetColumn (x, &spans);
|
||||
const uint8_t *column = pic->GetColumn(DefaultRenderStyle(), x, &spans); // This shouldn't use the spans...
|
||||
|
||||
while (spans->Length != 0)
|
||||
{
|
||||
|
@ -1649,9 +1649,11 @@ FFontChar1::FFontChar1 (FTexture *sourcelump)
|
|||
//
|
||||
// FFontChar1 :: GetPixels
|
||||
//
|
||||
// Render style is not relevant for fonts. This must not use it!
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FFontChar1::GetPixels ()
|
||||
const uint8_t *FFontChar1::GetPixels (FRenderStyle)
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
|
@ -1666,12 +1668,12 @@ const uint8_t *FFontChar1::GetPixels ()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FFontChar1::MakeTexture ()
|
||||
void FFontChar1::MakeTexture ()
|
||||
{
|
||||
// Make the texture as normal, then remap it so that all the colors
|
||||
// are at the low end of the palette
|
||||
Pixels = new uint8_t[Width*Height];
|
||||
const uint8_t *pix = BaseTexture->GetPixels();
|
||||
const uint8_t *pix = BaseTexture->GetPixels(DefaultRenderStyle());
|
||||
|
||||
if (!SourceRemap)
|
||||
{
|
||||
|
@ -1692,14 +1694,14 @@ void FFontChar1::MakeTexture ()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FFontChar1::GetColumn (unsigned int column, const Span **spans_out)
|
||||
const uint8_t *FFontChar1::GetColumn(FRenderStyle, unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
MakeTexture ();
|
||||
}
|
||||
|
||||
BaseTexture->GetColumn(column, spans_out);
|
||||
BaseTexture->GetColumn(DefaultRenderStyle(), column, spans_out);
|
||||
return Pixels + column*Height;
|
||||
}
|
||||
|
||||
|
@ -1797,9 +1799,11 @@ void FFontChar2::Unload ()
|
|||
//
|
||||
// FFontChar2 :: GetPixels
|
||||
//
|
||||
// Like for FontChar1, the render style has no relevance here as well.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FFontChar2::GetPixels ()
|
||||
const uint8_t *FFontChar2::GetPixels (FRenderStyle)
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
|
@ -1814,7 +1818,7 @@ const uint8_t *FFontChar2::GetPixels ()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FFontChar2::GetColumn (unsigned int column, const Span **spans_out)
|
||||
const uint8_t *FFontChar2::GetColumn(FRenderStyle, unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
|
|
|
@ -340,69 +340,20 @@ void ReadPalette(int lumpnum, uint8_t *buffer)
|
|||
}
|
||||
}
|
||||
|
||||
static bool FixBuildPalette (uint8_t *opal, int lump, bool blood)
|
||||
{
|
||||
if (Wads.LumpLength (lump) < 768)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
FMemLump data = Wads.ReadLump (lump);
|
||||
const uint8_t *ipal = (const uint8_t *)data.GetMem();
|
||||
|
||||
// Reverse the palette because BUILD used entry 255 as
|
||||
// transparent, but we use 0 as transparent.
|
||||
|
||||
for (int c = 0; c < 768; c += 3)
|
||||
{
|
||||
if (!blood)
|
||||
{
|
||||
opal[c] = (ipal[765-c] << 2) | (ipal[765-c] >> 4);
|
||||
opal[c+1] = (ipal[766-c] << 2) | (ipal[766-c] >> 4);
|
||||
opal[c+2] = (ipal[767-c] << 2) | (ipal[767-c] >> 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
opal[c] = ipal[765-c];
|
||||
opal[c+1] = ipal[766-c];
|
||||
opal[c+2] = ipal[767-c];
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void InitPalette ()
|
||||
{
|
||||
uint8_t pal[768];
|
||||
bool usingBuild = false;
|
||||
int lump;
|
||||
|
||||
if ((lump = Wads.CheckNumForFullName ("palette.dat")) >= 0 && Wads.LumpLength (lump) >= 768)
|
||||
{
|
||||
usingBuild = FixBuildPalette (pal, lump, false);
|
||||
}
|
||||
else if ((lump = Wads.CheckNumForFullName ("blood.pal")) >= 0 && Wads.LumpLength (lump) >= 768)
|
||||
{
|
||||
usingBuild = FixBuildPalette (pal, lump, true);
|
||||
}
|
||||
|
||||
if (!usingBuild)
|
||||
{
|
||||
ReadPalette(Wads.CheckNumForName("PLAYPAL"), pal);
|
||||
}
|
||||
|
||||
ReadPalette(Wads.CheckNumForName("PLAYPAL"), pal);
|
||||
|
||||
GPalette.SetPalette (pal);
|
||||
GPalette.MakeGoodRemap ();
|
||||
ColorMatcher.SetPalette ((uint32_t *)GPalette.BaseColors);
|
||||
|
||||
// The BUILD engine already has a transparent color, so it doesn't need any remapping.
|
||||
if (!usingBuild)
|
||||
{
|
||||
if (GPalette.Remap[0] == 0)
|
||||
{ // No duplicates, so settle for something close to color 0
|
||||
GPalette.Remap[0] = BestColor ((uint32_t *)GPalette.BaseColors,
|
||||
GPalette.BaseColors[0].r, GPalette.BaseColors[0].g, GPalette.BaseColors[0].b, 1, 255);
|
||||
}
|
||||
if (GPalette.Remap[0] == 0)
|
||||
{ // No duplicates, so settle for something close to color 0
|
||||
GPalette.Remap[0] = BestColor ((uint32_t *)GPalette.BaseColors,
|
||||
GPalette.BaseColors[0].r, GPalette.BaseColors[0].g, GPalette.BaseColors[0].b, 1, 255);
|
||||
}
|
||||
|
||||
// Colormaps have to be initialized before actors are loaded,
|
||||
|
|
|
@ -135,9 +135,9 @@ class FPaletteTester : public FTexture
|
|||
public:
|
||||
FPaletteTester ();
|
||||
|
||||
const uint8_t *GetColumn(unsigned int column, const Span **spans_out);
|
||||
const uint8_t *GetPixels();
|
||||
bool CheckModified();
|
||||
const uint8_t *GetColumn(FRenderStyle, unsigned int column, const Span **spans_out) override;
|
||||
const uint8_t *GetPixels(FRenderStyle);
|
||||
bool CheckModified(FRenderStyle);
|
||||
void SetTranslation(int num);
|
||||
|
||||
protected:
|
||||
|
@ -983,7 +983,7 @@ FPaletteTester::FPaletteTester()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FPaletteTester::CheckModified()
|
||||
bool FPaletteTester::CheckModified(FRenderStyle)
|
||||
{
|
||||
return CurTranslation != WantTranslation;
|
||||
}
|
||||
|
@ -1008,7 +1008,7 @@ void FPaletteTester::SetTranslation(int num)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FPaletteTester::GetColumn (unsigned int column, const Span **spans_out)
|
||||
const uint8_t *FPaletteTester::GetColumn(FRenderStyle, unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (CurTranslation != WantTranslation)
|
||||
{
|
||||
|
@ -1028,7 +1028,7 @@ const uint8_t *FPaletteTester::GetColumn (unsigned int column, const Span **span
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
const uint8_t *FPaletteTester::GetPixels ()
|
||||
const uint8_t *FPaletteTester::GetPixels (FRenderStyle)
|
||||
{
|
||||
if (CurTranslation != WantTranslation)
|
||||
{
|
||||
|
|
|
@ -1255,6 +1255,19 @@ int FWadCollection::GetLumpFile (int lump) const
|
|||
return LumpInfo[lump].wadnum;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_GetLumpFile
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FResourceLump *FWadCollection::GetLumpRecord(int lump) const
|
||||
{
|
||||
if ((size_t)lump >= LumpInfo.Size())
|
||||
return nullptr;
|
||||
return LumpInfo[lump].lump;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_ReadLump
|
||||
|
|
|
@ -170,6 +170,7 @@ public:
|
|||
int GetLumpFile (int lump) const; // [RH] Returns wadnum for a specified lump
|
||||
int GetLumpNamespace (int lump) const; // [RH] Returns the namespace a lump belongs to
|
||||
int GetLumpIndexNum (int lump) const; // Returns the RFF index number for this lump
|
||||
FResourceLump *GetLumpRecord(int lump) const; // Returns the FResourceLump, in case the caller wants to have direct access to the lump cache.
|
||||
bool CheckLumpName (int lump, const char *name) const; // [RH] Returns true if the names match
|
||||
|
||||
bool IsEncryptedFile(int lump) const;
|
||||
|
|
|
@ -16,6 +16,7 @@ class Inventory : Actor native
|
|||
native int InterHubAmount; // Amount of item that can be kept between hubs or levels
|
||||
native int RespawnTics; // Tics from pickup time to respawn time
|
||||
native TextureID Icon; // Icon to show on status bar or HUD
|
||||
native TextureID AltHUDIcon;
|
||||
native int DropTime; // Countdown after dropping
|
||||
native Class<Actor> SpawnPointClass; // For respawning like Heretic's mace
|
||||
native Class<Actor> PickupFlash; // actor to spawn as pickup flash
|
||||
|
|
|
@ -6,6 +6,7 @@ class HereticStatusBar : BaseStatusBar
|
|||
HUDFont mBigFont;
|
||||
InventoryBarState diparms;
|
||||
InventoryBarState diparms_sbar;
|
||||
private int wiggle;
|
||||
|
||||
|
||||
override void Init()
|
||||
|
@ -40,6 +41,12 @@ class HereticStatusBar : BaseStatusBar
|
|||
{
|
||||
Super.Tick();
|
||||
mHealthInterpolator.Update(CPlayer.health);
|
||||
|
||||
// wiggle the chain if it moves
|
||||
if (level.time & 1)
|
||||
{
|
||||
wiggle = (mHealthInterpolator.GetValue() != CPlayer.health) && Random[ChainWiggle](0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
override void Draw (int state, double TicFrac)
|
||||
|
@ -73,7 +80,6 @@ class HereticStatusBar : BaseStatusBar
|
|||
DrawImage("CHAINCAC", (0, 190), DI_ITEM_OFFSETS);
|
||||
// wiggle the chain if it moves
|
||||
int inthealth = mHealthInterpolator.GetValue();
|
||||
int wiggle = (inthealth != CPlayer.health) && Random[ChainWiggle](0, 1);
|
||||
DrawGem("CHAIN", "LIFEGEM2",inthealth, CPlayer.mo.GetMaxHealth(true), (2, 191 + wiggle), 15, 25, 16, (multiplayer? DI_TRANSLATABLE : 0) | DI_ITEM_LEFT_TOP);
|
||||
DrawImage("LTFACE", (0, 190), DI_ITEM_OFFSETS);
|
||||
DrawImage("RTFACE", (276, 190), DI_ITEM_OFFSETS);
|
||||
|
|
Loading…
Reference in a new issue