- added the other image formats from GZDoom.

This commit is contained in:
Christoph Oelckers 2020-05-24 00:15:38 +02:00
parent 50ab68b53b
commit 1954ac0374
14 changed files with 2108 additions and 0 deletions

View file

@ -753,10 +753,21 @@ set (PCH_SOURCES
common/textures/bitmap.cpp
common/textures/m_png.cpp
common/textures/image.cpp
common/textures/formats/automaptexture.cpp
common/textures/formats/brightmaptexture.cpp
common/textures/formats/buildtexture.cpp
common/textures/formats/ddstexture.cpp
common/textures/formats/flattexture.cpp
common/textures/formats/imgztexture.cpp
common/textures/formats/jpegtexture.cpp
common/textures/formats/md5check.cpp
common/textures/formats/multipatchtexture.cpp
common/textures/formats/patchtexture.cpp
common/textures/formats/pcxtexture.cpp
common/textures/formats/pngtexture.cpp
common/textures/formats/rawpagetexture.cpp
common/textures/formats/emptytexture.cpp
common/textures/formats/shadertexture.cpp
common/textures/formats/tgatexture.cpp
common/textures/formats/stbtexture.cpp
common/console/c_commandline.cpp
@ -969,6 +980,7 @@ include_directories(
common/audio/music
common/thirdparty
common/textures
common/textures/formats
common/filesystem
common/utility
common/console

View file

@ -0,0 +1,111 @@
/*
** automaptexture.cpp
** Texture class for Raven's automap parchment
**
**---------------------------------------------------------------------------
** Copyright 2004-2006 Randy Heit
** 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.
**---------------------------------------------------------------------------
**
** This texture type is only used as a last resort when everything else has failed for creating
** the AUTOPAGE texture. That's because Raven used a raw lump of non-standard proportions to define it.
**
*/
#include "files.h"
#include "filesystem.h"
#include "imagehelpers.h"
#include "image.h"
//==========================================================================
//
// A raw 320x? graphic used by Heretic and Hexen for the automap parchment
//
//==========================================================================
class FAutomapTexture : public FImageSource
{
public:
FAutomapTexture(int lumpnum);
TArray<uint8_t> CreatePalettedPixels(int conversion) override;
};
//==========================================================================
//
// This texture type will only be used for the AUTOPAGE lump if no other
// format matches.
//
//==========================================================================
FImageSource *AutomapImage_TryCreate(FileReader &data, int lumpnum)
{
if (data.GetLength() < 320) return nullptr;
if (!fileSystem.CheckFileName(lumpnum, "AUTOPAGE")) return nullptr;
return new FAutomapTexture(lumpnum);
}
//==========================================================================
//
//
//
//==========================================================================
FAutomapTexture::FAutomapTexture (int lumpnum)
: FImageSource(lumpnum)
{
Width = 320;
Height = uint16_t(fileSystem.FileLength(lumpnum) / 320);
bUseGamePalette = true;
}
//==========================================================================
//
//
//
//==========================================================================
TArray<uint8_t> FAutomapTexture::CreatePalettedPixels(int conversion)
{
int x, y;
FileData data = fileSystem.ReadFile (SourceLump);
const uint8_t *indata = (const uint8_t *)data.GetMem();
TArray<uint8_t> Pixels(Width * Height, true);
const uint8_t *remap = ImageHelpers::GetRemap(conversion == luminance);
for (x = 0; x < Width; ++x)
{
for (y = 0; y < Height; ++y)
{
auto p = indata[x + 320 * y];
Pixels[x*Height + y] = remap[p];
}
}
return Pixels;
}

View file

@ -0,0 +1,79 @@
/*
** brightmaptexture.cpp
** The texture class for colormap based brightmaps.
**
**---------------------------------------------------------------------------
** Copyright 2006-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 "filesystem.h"
#include "palettecontainer.h"
#include "bitmap.h"
#include "image.h"
class FBrightmapTexture : public FImageSource
{
public:
FBrightmapTexture (FImageSource *source);
int CopyPixels(FBitmap *bmp, int conversion) override;
protected:
FImageSource *SourcePic;
};
//===========================================================================
//
// fake brightness maps
// These are generated for textures affected by a colormap with
// fullbright entries.
//
//===========================================================================
FBrightmapTexture::FBrightmapTexture (FImageSource *source)
{
SourcePic = source;
Width = source->GetWidth();
Height = source->GetHeight();
bMasked = false;
}
int FBrightmapTexture::CopyPixels(FBitmap *bmp, int conversion)
{
SourcePic->CopyTranslatedPixels(bmp, GPalette.GlobalBrightmap.Palette);
return 0;
}
#if 0
FTexture *CreateBrightmapTexture(FImageSource *tex)
{
return CreateImageTexture(new FBrightmapTexture(tex));
}
#endif

View file

@ -0,0 +1,78 @@
/*
** buildtexture.cpp
** 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
** 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 "files.h"
#include "bitmap.h"
#include "image.h"
#include "palettecontainer.h"
#if 0
//==========================================================================
//
//
//
//==========================================================================
FBuildTexture::FBuildTexture(const FString &pathprefix, int tilenum, const uint8_t *pixels, FRemapTable *translation, int width, int height, int left, int top)
: RawPixels (pixels), Translation(translation)
{
Width = width;
Height = height;
LeftOffset = left;
TopOffset = top;
}
TArray<uint8_t> FBuildTexture::CreatePalettedPixels(int conversion)
{
TArray<uint8_t> Pixels(Width * Height, true);
FRemapTable *Remap = Translation;
for (int i = 0; i < Width*Height; i++)
{
auto c = RawPixels[i];
Pixels[i] = conversion == luminance ? Remap->Palette[c].Luminance() : Remap->Remap[c];
}
return Pixels;
}
int FBuildTexture::CopyPixels(FBitmap *bmp, int conversion)
{
PalEntry *Remap = Translation->Palette;
bmp->CopyPixelData(0, 0, RawPixels, Width, Height, Height, 1, 0, Remap);
return -1;
}
#endif

View file

@ -0,0 +1,98 @@
/*
** 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
** 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 "files.h"
#include "filesystem.h"
#include "image.h"
//==========================================================================
//
//
//
//==========================================================================
class FEmptyTexture : public FImageSource
{
public:
FEmptyTexture (int lumpnum);
TArray<uint8_t> CreatePalettedPixels(int conversion) override;
};
//==========================================================================
//
//
//
//==========================================================================
FImageSource *EmptyImage_TryCreate(FileReader & file, int lumpnum)
{
char check[8];
if (file.GetLength() != 8) return NULL;
file.Seek(0, FileReader::SeekSet);
if (file.Read(check, 8) != 8) return NULL;
if (memcmp(check, "\0\0\0\0\0\0\0\0", 8)) return NULL;
return new FEmptyTexture(lumpnum);
}
//==========================================================================
//
//
//
//==========================================================================
FEmptyTexture::FEmptyTexture (int lumpnum)
: FImageSource(lumpnum)
{
bMasked = true;
Width = Height = 1;
bUseGamePalette = true;
}
//==========================================================================
//
//
//
//==========================================================================
TArray<uint8_t> FEmptyTexture::CreatePalettedPixels(int conversion)
{
TArray<uint8_t> Pixel(1, true);
Pixel[0] = 0;
return Pixel;
}

View file

@ -0,0 +1,117 @@
/*
** flattexture.cpp
** Texture class for standard Doom flats
**
**---------------------------------------------------------------------------
** Copyright 2004-2006 Randy Heit
** 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 "files.h"
#include "filesystem.h"
#include "imagehelpers.h"
#include "image.h"
//==========================================================================
//
// A texture defined between F_START and F_END markers
//
//==========================================================================
class FFlatTexture : public FImageSource
{
public:
FFlatTexture (int lumpnum);
TArray<uint8_t> CreatePalettedPixels(int conversion) 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
//
//==========================================================================
FImageSource *FlatImage_TryCreate(FileReader & file, int lumpnum)
{
return new FFlatTexture(lumpnum);
}
//==========================================================================
//
//
//
//==========================================================================
FFlatTexture::FFlatTexture (int lumpnum)
: FImageSource(lumpnum)
{
int area;
int bits;
area = fileSystem.FileLength (lumpnum);
switch (area)
{
default:
case 64*64: bits = 6; break;
case 8*8: bits = 3; break;
case 16*16: bits = 4; break;
case 32*32: bits = 5; break;
case 128*128: bits = 7; break;
case 256*256: bits = 8; break;
}
bUseGamePalette = true;
bMasked = false;
bTranslucent = false;
Width = Height = 1 << bits;
}
//==========================================================================
//
//
//
//==========================================================================
TArray<uint8_t> FFlatTexture::CreatePalettedPixels(int conversion)
{
auto lump = fileSystem.OpenFileReader (SourceLump);
TArray<uint8_t> Pixels(Width*Height, true);
auto numread = lump.Read (Pixels.Data(), Width*Height);
if (numread < Width*Height)
{
memset (Pixels.Data() + numread, 0xBB, Width*Height - numread);
}
ImageHelpers::FlipSquareBlockRemap(Pixels.Data(), Width, ImageHelpers::GetRemap(conversion == luminance));
return Pixels;
}

View file

@ -0,0 +1,206 @@
/*
** imgztexture.cpp
** Texture class for IMGZ style images
**
**---------------------------------------------------------------------------
** Copyright 2004-2006 Randy Heit
** 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 "files.h"
#include "filesystem.h"
#include "bitmap.h"
#include "imagehelpers.h"
#include "image.h"
bool checkIMGZPalette(FileReader &file);
//==========================================================================
//
// An IMGZ image (mostly just crosshairs)
// [RH] Just a format I invented to avoid WinTex's palette remapping
// when I wanted to insert some alpha maps.
//
//==========================================================================
class FIMGZTexture : public FImageSource
{
struct ImageHeader
{
uint8_t Magic[4];
uint16_t Width;
uint16_t Height;
int16_t LeftOffset;
int16_t TopOffset;
uint8_t Compression;
uint8_t Reserved[11];
};
bool isalpha = true;
public:
FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int16_t t, bool isalpha);
TArray<uint8_t> CreatePalettedPixels(int conversion) override;
int CopyPixels(FBitmap *bmp, int conversion) override;
};
//==========================================================================
//
//
//
//==========================================================================
FImageSource *IMGZImage_TryCreate(FileReader & file, int lumpnum)
{
uint32_t magic = 0;
uint16_t w, h;
int16_t l, t;
bool ispalette;
file.Seek(0, FileReader::SeekSet);
if (file.Read(&magic, 4) != 4) return NULL;
if (magic != MAKE_ID('I','M','G','Z')) return NULL;
w = file.ReadUInt16();
h = file.ReadUInt16();
l = file.ReadInt16();
t = file.ReadInt16();
ispalette = checkIMGZPalette(file);
return new FIMGZTexture(lumpnum, w, h, l, t, !ispalette);
}
//==========================================================================
//
//
//
//==========================================================================
FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int16_t t, bool _isalpha)
: FImageSource(lumpnum)
{
Width = w;
Height = h;
LeftOffset = l;
TopOffset = t;
isalpha = _isalpha;
bUseGamePalette = !isalpha;
}
//==========================================================================
//
//
//
//==========================================================================
TArray<uint8_t> FIMGZTexture::CreatePalettedPixels(int conversion)
{
FileData lump = fileSystem.ReadFile (SourceLump);
const ImageHeader *imgz = (const ImageHeader *)lump.GetMem();
const uint8_t *data = (const uint8_t *)&imgz[1];
uint8_t *dest_p;
int dest_adv = Height;
int dest_rew = Width * Height - 1;
TArray<uint8_t> Pixels(Width*Height, true);
dest_p = Pixels.Data();
const uint8_t *remap = ImageHelpers::GetRemap(conversion == luminance, isalpha);
// Convert the source image from row-major to column-major format and remap it
if (!imgz->Compression)
{
for (int y = Height; y != 0; --y)
{
for (int x = Width; x != 0; --x)
{
*dest_p = remap[*data];
dest_p += dest_adv;
data++;
}
dest_p -= dest_rew;
}
}
else
{
// IMGZ compression is the same RLE used by IFF ILBM files
int runlen = 0, setlen = 0;
uint8_t setval = 0; // Shut up, GCC
for (int y = Height; y != 0; --y)
{
for (int x = Width; x != 0; )
{
if (runlen != 0)
{
*dest_p = remap[*data];
dest_p += dest_adv;
data++;
x--;
runlen--;
}
else if (setlen != 0)
{
*dest_p = setval;
dest_p += dest_adv;
x--;
setlen--;
}
else
{
int8_t code = *data++;
if (code >= 0)
{
runlen = code + 1;
}
else if (code != -128)
{
setlen = (-code) + 1;
setval = remap[*data++];
}
}
}
dest_p -= dest_rew;
}
}
return Pixels;
}
//==========================================================================
//
//
//
//==========================================================================
int FIMGZTexture::CopyPixels(FBitmap *bmp, int conversion)
{
if (!isalpha) return FImageSource::CopyPixels(bmp, conversion);
else return CopyTranslatedPixels(bmp, GPalette.GrayscaleMap.Palette);
}

View file

@ -0,0 +1,272 @@
/*
** md5check.cpp
** Checksums for textures that need special treatment
**
**---------------------------------------------------------------------------
** 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 <stdint.h>
#include "files.h"
#include "md5.h"
#include "printf.h"
struct MD5Check
{
int length;
const char *md5;
};
// If these lists grow they should maybe put in gzdoom.pk3.
// The first list is alpha textures in patch format.
// Patches are normally paletted but for these it needs to be treated
// as a grayscale ramp.
static const MD5Check alphapatches[] =
{
{ 18, "fb1472adb34ce1de7a40156d484dd3fc"}, // xhair5.gfx
{ 59, "7149115092f5e8f01f84dacc120aae94"}, // xhairs9.gfx
{ 62, "7a8d11c24b51e7daff2ab0ffbe3641d9"}, // xhair1.gfx
{ 75, "53ca06706de386ec440a501156dd4bc6"}, // xhair2.gfx
{ 78, "299bd69e46b4ba3632e8bf5a96f1b0cb"}, // xhair3.gfx
{ 86, "643535b5db4361db4177978152294a01"}, // xhairs14.gfx
{ 89, "773bb976dd343266bfe2fc11c1d2a2aa"}, // xhairs13.gfx
{ 100, "493dd248c2cb0d45635ef9cc995db952"}, // xhair4.gfx
{ 105, "257a140b3533713fb59d9be493ba6803"}, // chip4.gfx
{ 105, "7e4b578c7217b7f0c7120d62177dd5bc"}, // xhairs8.gfx
{ 111, "fd9fec58b188284ece38e43c823abd73"}, // chip2.gfx
{ 119, "d6fd267eb249ce01d06fe3e2361eab64"}, // chip3.gfx
{ 122, "4daba1da79b0a009b46e2949a2f8c6f8"}, // chip5.gfx
{ 128, "ed83d41bcf4a91968ffc3ca5cad6a383"}, // chip1.gfx
{ 133, "ca55c89aac30bc8f7e5722520389209e"}, // chip2(2).gfx
{ 134, "2b00983c62e69cad182a5204df163701"}, // xhairb9.gfx
{ 137, "4fb1b26ac278de9ef382e8268cc7e7bb"}, // xhairb8.gfx
{ 138, "b3b69ce27c4b57912232bf718768390a"}, // chip3(2).gfx
{ 147, "ae5625169660aaf44ddffe5553be3e28"}, // xhairs11.gfx
{ 149, "e594798cfad078a553cd21ea6544abac"}, // chip1(2).gfx
{ 152, "bd30eccd4e6afe596af8823d4f8ccf40"}, // xhairb14.gfx
{ 153, "5f2111f1b44cc8cd153e6c08eec3f68c"}, // xhairs10.gfx
{ 160, "27682ca38c949072848c186f499bf027"}, // chip4(2).gfx
{ 168, "7f3d0cf78df24473ffa98ff41d8c93ce"}, // xhairs15.gfx
{ 169, "a0df55d2aee6f72c9164127f8fc9f0dd"}, // ahit.gfx
{ 171, "08c3d1b4bcb5643ae133938778e74c6f"}, // xhairb11.gfx
{ 171, "603355244602e830a2fa9949711a7e83"}, // xhairs12.gfx
{ 177, "6dae9b9bd34805cb066309679f9aaf81"}, // bal7scr1.gfx
{ 177, "a3312ae7011faf08e7903c753e7108b0"}, // xhair6.gfx
{ 183, "142acb37f179aff6e91b430415189c5f"}, // xhair7.gfx
{ 185, "ce1428acd24ced861aa628b4fcefc761"}, // xhairb13.gfx
{ 194, "ab742500964a2298076a4e3ca5f8d8dc"}, // chip5(2).gfx
{ 196, "36e6dd0c675ceb94304954fb1d321f87"}, // xhair8(2).gfx
{ 196, "48ef0cdb8c25e6993e38ddedb0b1a69d"}, // xhairb10.gfx
{ 239, "72384cc34d4345de824e9b775e185155"}, // xhair8.gfx
{ 251, "f3ba8dc69906efee68e27bc37ad8b164"}, // bsplat08_2.gfx
{ 251, "f9138bed705dd05b7ac925751f2173c8"}, // bsplat08.gfx
{ 261, "c6325f4f79f3e36d00eced5d4a160e50"}, // xhairs17.gfx
{ 268, "319f297738ecd5b8e9c32d635c5dc781"}, // bsplat14.gfx
{ 268, "b6e71e5e2a5df85f5a1496ff322cda76"}, // bsplat14_2.gfx
{ 270, "5fe0a8e06182c155fb0508aae1e2c661"}, // xhairb1.gfx
{ 288, "ceb3a910c338fe4f7cdc6c3b49bcb986"}, // xhairb15.gfx
{ 290, "5c8810d3be4b27fdbb7660af04ef91ce"}, // xhairb12.gfx
{ 307, "53564f95e3bcd9f84f463cdb06d4c959"}, // xhairs18.gfx
{ 329, "943cda6f9fbc13bef59c02d38481c1b9"}, // xhairs19.gfx
{ 330, "397071348b313cbf4631e16e292a2816"}, // xhair8(3).gfx
{ 334, "a7efbab516ae51271d7dece02ee7a3da"}, // xhairs16.gfx
{ 341, "ae1f343cbea6ab7892bcc25bd544b149"}, // xhairs20.gfx
{ 359, "3828fb4462f3c559d6a1d5659d736d38"}, // Ascrd1.gfx
{ 397, "3a3a887506a77d812f07ddb46e13d828"}, // Ascrd2.gfx
{ 399, "80a0b9b54618a94fdbd9ff907eb69f2c"}, // Ascrd3.gfx
{ 412, "78cef7b3872c4a47bc47155e3fdc2f45"}, // Ascrd4.gfx
{ 438, "2c08ca266a7df57d609d85b774fb589f"}, // xhairb2.gfx
{ 480, "1f84994c04f4a4941ffc183bda3d9ce3"}, // xhairb17.gfx
{ 521, "833d10c6a1b0ed1cf76ce0012628415d"}, // bsplat07_2.gfx
{ 521, "8658b919b52228d740c057c50038eaac"}, // bsplat07.gfx
{ 521, "c9650cf2f9564b149fbc8c1bbd13c157"}, // Bsplat6.GFX
{ 542, "ddc08f004ee63eeec2fbb474393ec5ed"}, // xhairb19.gfx
{ 569, "3baa1f2b6c05ceb60e5a7ed5f8990263"}, // bsplat13_2.gfx
{ 569, "a1951138cfa47d4ee1033ae088f7ed04"}, // bsplat13.gfx
{ 642, "0f4320a0c53f645d2c3551eeea5ba898"}, // Bsplat5.GFX
{ 642, "968c486e2f2880a3a8d5c7df87a3d8ad"}, // bsplat06.gfx
{ 642, "c41089a518b28be1db182a9d1e7fa7de"}, // bsplat06_2.gfx
{ 653, "7bd11e17dd6672680f5325a4f5496c98"}, // bsplat11.gfx
{ 653, "b57e64f5f98b1fea132a5d6572f24724"}, // bsplat11_2.gfx
{ 653, "e53b9967ef7f93f2ea069b30d6b42444"}, // Bsplat9.GFX
{ 780, "0f95bd26c68d0f3180527aa8dc539d28"}, // Ascra2.gfx
{ 780, "3e0075c2e707083e83c0b897a20d6089"}, // Fdbal2.gfx
{ 801, "3dd3a4bb095deffd70489b9bb6636c96"}, // bsplat12_2.gfx
{ 801, "44703476a6702522047fe0ff0831cc31"}, // bsplat12.gfx
{ 801, "c4a348a488d948dcc70faa6a396b6625"}, // Fdbal1.gfx
{ 801, "f22f176a5e0e2d608c33e2572b28a841"}, // Ascra1.gfx
{ 855, "5385652621b2df49fedd6d970b1d582f"}, // bsplat10_2.gfx
{ 855, "559817e4658047519abbc58a14b2c97c"}, // Bsplat8.GFX
{ 855, "6dee11141dbedff291b9393677276b54"}, // bsplat10.gfx
{ 864, "0300a526b884a27d68d22291b926c1d1"}, // xhairb20.gfx
{ 900, "0fca1f72e22661c39ba0f4e4e9a39c87"}, // bsplat05.gfx
{ 900, "700c0e4cbf0087392e026ac8ab01283d"}, // bsplat05_2.gfx
{ 900, "f414ff86af1611bb90043ca859eb2eda"}, // Bsplat4.GFX
{ 970, "b9ebf0a5895fd2fcadb3304a8f7351b1"}, // xhairb16.gfx
{ 1020, "08d4691ac72069c5a0897650e91a34b8"}, // bsplat04_2.gfx
{ 1020, "3559fb14d0a30f5fae9705f67c9e2b83"}, // bsplat04.gfx
{ 1020, "afe88bbb055060e39e6e757aebd29a96"}, // Bsplat3.GFX
{ 1034, "8671f2be0d2be65340b7a3b819d57933"}, // xhairb18.gfx
{ 1124, "4ec6d839eb2c10a33dfa0191b2200ede"}, // splat.gfx
{ 1149, "5a0040d28c3f84ef895806a3e80d49a6"}, // bsplat01_2.gfx
{ 1149, "783e85a5195ba91667491002a80e03a3"}, // bsplat01.gfx
{ 1189, "295e144b6318abe47b14d1e6bcc7a7fa"}, // bsplat02_2.gfx
{ 1189, "78606aefd9807b51760b4e6dd9203afa"}, // Bsplat1.GFX
{ 1189, "892d3a9fc35e14fd97f526c8b6ea9a3f"}, // bsplat02.gfx
{ 1218, "3bafcd6672b95d1e4fc92367ed10732d"}, // bsplat03_2.gfx
{ 1218, "916964ed55798ebfd288a65ffb09bb02"}, // bsplat03.gfx
{ 1218, "a3f4fca1e8050d7e5d8e64f48bc16515"}, // Bsplat2.GFX
{ 1235, "7927d6dd72ff5dd3b4b0f538fe78d7b9"}, // bsplat09_2.gfx
{ 1235, "d62f324008e74bfea74efd160b668872"}, // bsplat09.gfx
{ 1235, "f6a0df424b064ed6f6744d5891936ab2"}, // Bsplat7.GFX
{ 1717, "df6d834ad357b48feaa9e9d2b0a1f449"}, // bsplat3(2).gfx
{ 1856, "9a9a2cc871a0dec902c8c91e631bc9c8"}, // Snbal2.gfx
{ 1856, "c1e539d6a93a952a5752018d65d577f4"}, // plasma1.gfx
{ 1856, "e60306eefd66bceef1c802732b9163e3"}, // Snbal4.gfx
{ 1942, "84974f010afdabd9351163175b19bb49"}, // Ascrg2.gfx
{ 1942, "a4caf2b9ade6467ea0018bd78321ff50"}, // uscrch2.gfx
{ 1952, "3ee4ddc539059b533c0e31afbf07bb7f"}, // uscrch1.gfx
{ 1952, "e868f1c2bab9752a6cd819b7a7ce6487"}, // Ascrg1.gfx
{ 2035, "36b4e593a7a60d100e4ec081a7d2f809"}, // Ascrc1.gfx
{ 2080, "ebb5c3017a9beb76258f7d374e99a339"}, // bsplat2(2).gfx
{ 2092, "5461be1e0b02d00ff2204ee457fc5d7c"}, // Ascrc2.gfx
{ 2247, "35f936c271a190e3f67aaea1f02dee57"}, // Snbal3.gfx
{ 2247, "3e237bb101d4e3236a5052a1bc5c80d2"}, // plasma2.gfx
{ 2247, "58b4e240b1c5d41e6150df6e320c1349"}, // Snbal1.gfx
{ 2280, "4e1369d2d683d757445a3d78ace82e98"}, // Ascrh2.gfx
{ 2302, "351c1d1cd32637a1d0b4e0168165b266"}, // Ascrh1.gfx
{ 2821, "8c822e94db02cc9d6c851a189c77123e"}, // xhairs51.gfx
{ 2834, "d0099d0fc5aebcdd3994a45ff2560dbc"}, // xhairs50.gfx
{ 2865, "5c0350860fcb89ed28041d6ab0d023a8"}, // xhairs52.gfx
{ 4370, "bda605422fb9144f9671c03405e7c73b"}, // bsmear2_2.gfx
{ 4370, "f3862fb4f336506542e7e9a91bc88261"}, // bsmear2.gfx
{ 4483, "d05e14fbce5864b2df4b92599c48a4c5"}, // Ascre1.gfx
{ 4506, "230ee2c1a8c5baeafbea7248659da3f4"}, // bsplat1(2).gfx
{ 4855, "d27a510aa0285f1c74cb12c7f8ac6d25"}, // bsplat4(2).gfx
{ 6232, "9e7f0b2c6ca50aa8335929c959ba8c51"}, // Ascrf1.gfx
{ 6858, "876c130f90700587b1a71d1aab095746"}, // bsmear1_2.gfx
{ 6858, "c72d6f4c3a0ff3a2d2db1082aea1c884"}, // bsmear1.gfx
{ 7444, "81e4a147ce264394fad80cfd04965d5d"}, // xhairb50.gfx
{ 7452, "aa3f72a47fe2b7c3e353ea62c75d6b42"}, // xhairb51.gfx
{ 7576, "ac2b9c1b53e91bbb0cb260665189291b"}, // xhairb52.gfx
{10164, "3c8908619cd5b357de701a0c6b04f408"}, // splat1.gfx
{ -1, nullptr}
};
// These are IMGZ images that use the game palette.
// Normally IMGZ is only used for crosshairs, i.e grayscale images.
static const MD5Check palimgzs[] =
{
{ 1728, "9ffdd749b414a1d34c74650828ad6504"}, // scodef.imgz
{64024, "bee2a3ddec08bf975353b3dc139bb956"}, // interpic.imgz
{ -1, nullptr}
};
//==========================================================================
//
//
//
//==========================================================================
void makeMD5(const void *buffer, unsigned length, char *md5out)
{
MD5Context md5;
uint8_t cksum[16];
md5.Update((uint8_t*)buffer, length);
md5.Final(cksum);
for (int i = 0; i < 16; i++)
{
mysnprintf(md5out + 2*i, 3, "%02x", cksum[i]);
}
}
//==========================================================================
//
//
//
//==========================================================================
bool checkPatchForAlpha(const void *buffer, uint32_t length)
{
if (length > 10164) return false; // shortcut for anything too large
char md5[33];
bool done = false;
for(int i=0; alphapatches[i].length > 0; i++)
{
if (alphapatches[i].length == (int)length) // length check
{
if (!done) makeMD5(buffer, length, md5);
done = true;
if (!memcmp(md5, alphapatches[i].md5, 32))
{
return true;
}
}
}
return false;
}
//==========================================================================
//
//
//
//==========================================================================
bool checkIMGZPalette(FileReader &file)
{
uint32_t length = (uint32_t)file.GetLength();
char md5[33];
bool done = false;
for(int i=0; palimgzs[i].length > 0; i++)
{
if (palimgzs[i].length ==(int) length)
{
if (!done)
{
uint8_t *buffer = new uint8_t[length];
file.Seek(0, FileReader::SeekSet);
file.Read(buffer, length);
makeMD5(buffer, length, md5);
done = true;
delete[] buffer;
}
if (!memcmp(md5, palimgzs[i].md5, 32))
{
return true;
}
}
}
return false;
}

View file

@ -0,0 +1,339 @@
/*
** multipatchtexture.cpp
** Texture class for standard Doom multipatch textures
**
**---------------------------------------------------------------------------
** Copyright 2004-2006 Randy Heit
** 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 <ctype.h>
#include "files.h"
#include "filesystem.h"
#include "image.h"
#include "multipatchtexture.h"
#include "imagehelpers.h"
//==========================================================================
//
// FMultiPatchTexture :: FMultiPatchTexture
//
//==========================================================================
FMultiPatchTexture::FMultiPatchTexture(int w, int h, const TArray<TexPart> &parts, bool complex, bool textual)
{
Width = w;
Height = h;
bComplex = complex;
bTextual = textual;
Parts = (TexPart*)ImageArena.Alloc(sizeof(TexPart) * parts.Size());
NumParts = parts.Size();
memcpy(Parts, parts.Data(), sizeof(TexPart) * parts.Size());
bUseGamePalette = false;
if (!bComplex)
{
for (int i = 0; i < NumParts; i++)
{
if (!Parts[i].Image->UseGamePalette()) return;
}
bUseGamePalette = true; // only if all patches use the game palette.
}
}
//==========================================================================
//
// GetBlendMap
//
//==========================================================================
static uint8_t *GetBlendMap(PalEntry blend, uint8_t *blendwork)
{
switch (blend.a==0 ? int(blend) : -1)
{
case BLEND_ICEMAP:
return GPalette.IceMap.Remap;
default:
if (blend >= BLEND_SPECIALCOLORMAP1 && blend < BLEND_SPECIALCOLORMAP1 + SpecialColormaps.Size())
{
return SpecialColormaps[blend - BLEND_SPECIALCOLORMAP1].Colormap;
}
else if (blend >= BLEND_DESATURATE1 && blend <= BLEND_DESATURATE31)
{
return DesaturateColormap[blend - BLEND_DESATURATE1];
}
else
{
blendwork[0]=0;
if (blend.a == 255)
{
for(int i=1;i<256;i++)
{
int rr = (blend.r * GPalette.BaseColors[i].r) / 255;
int gg = (blend.g * GPalette.BaseColors[i].g) / 255;
int bb = (blend.b * GPalette.BaseColors[i].b) / 255;
blendwork[i] = ColorMatcher.Pick(rr, gg, bb);
}
return blendwork;
}
else if (blend.a != 0)
{
for(int i=1;i<256;i++)
{
int rr = (blend.r * blend.a + GPalette.BaseColors[i].r * (255-blend.a)) / 255;
int gg = (blend.g * blend.a + GPalette.BaseColors[i].g * (255-blend.a)) / 255;
int bb = (blend.b * blend.a + GPalette.BaseColors[i].b * (255-blend.a)) / 255;
blendwork[i] = ColorMatcher.Pick(rr, gg, bb);
}
return blendwork;
}
}
}
return nullptr;
}
//==========================================================================
//
//
//
//==========================================================================
void FMultiPatchTexture::CopyToBlock(uint8_t *dest, int dwidth, int dheight, FImageSource *source, int xpos, int ypos, int rotate, const uint8_t *translation, int style)
{
auto cimage = source->GetCachedPalettedPixels(style); // should use composition cache
auto &image = cimage.Pixels;
const uint8_t *pixels = image.Data();
int srcwidth = source->GetWidth();
int srcheight = source->GetHeight();
int step_x = source->GetHeight();
int step_y = 1;
FClipRect cr = { 0, 0, dwidth, dheight };
if (style) translation = nullptr; // do not apply translations to alpha textures.
if (ClipCopyPixelRect(&cr, xpos, ypos, pixels, srcwidth, srcheight, step_x, step_y, rotate))
{
dest += ypos + dheight * xpos;
if (translation == NULL)
{
for (int x = 0; x < srcwidth; x++)
{
int pos = x * dheight;
for (int y = 0; y < srcheight; y++, pos++)
{
// the optimizer is doing a good enough job here so there's no need to optimize this by hand
uint8_t v = pixels[y * step_y + x * step_x];
if (v != 0) dest[pos] = v;
}
}
}
else
{
for (int x = 0; x < srcwidth; x++)
{
int pos = x * dheight;
for (int y = 0; y < srcheight; y++, pos++)
{
uint8_t v = pixels[y * step_y + x * step_x];
if (v != 0) dest[pos] = translation[v];
}
}
}
}
}
//==========================================================================
//
// FMultiPatchTexture :: MakeTexture
//
//==========================================================================
TArray<uint8_t> FMultiPatchTexture::CreatePalettedPixels(int conversion)
{
int numpix = Width * Height;
uint8_t blendwork[256];
bool buildrgb = bComplex;
TArray<uint8_t> Pixels(numpix, true);
memset (Pixels.Data(), 0, numpix);
if (conversion == luminance)
{
// For alpha textures, downconversion to the palette would lose too much precision if not all patches use the palette.
buildrgb = !UseGamePalette();
}
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)
{
if (Parts[i].op != OP_COPY)
{
buildrgb = true;
}
}
}
if (conversion == noremap0)
{
// sky remapping will only happen if
// - the texture was defined through a TEXTUREx lump (this implies only trivial copies)
// - all patches use the base palette.
// All other cases would not be able to properly deal with this special case.
// For textual definitions this hack isn't necessary.
if (bTextual || !UseGamePalette()) conversion = normal;
}
if (!buildrgb)
{
for (int i = 0; i < NumParts; ++i)
{
uint8_t *trans = Parts[i].Translation? Parts[i].Translation->Remap : nullptr;
{
if (Parts[i].Blend != 0)
{
trans = GetBlendMap(Parts[i].Blend, blendwork);
}
CopyToBlock (Pixels.Data(), Width, Height, Parts[i].Image, Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans, conversion);
}
}
}
else
{
// In case there are translucent patches let's do the composition in
// True color to keep as much precision as possible before downconverting to the palette.
FBitmap PixelsIn;
PixelsIn.Create(Width, Height);
CopyPixels(&PixelsIn, normal);
for(int y = 0; y < Height; y++)
{
uint8_t *in = PixelsIn.GetPixels() + Width * y * 4;
uint8_t *out = Pixels.Data() + y;
for (int x = 0; x < Width; x++)
{
if (*out == 0 && in[3] != 0)
{
*out = ImageHelpers::RGBToPalette(conversion == luminance, in[2], in[1], in[0]);
}
out += Height;
in += 4;
}
}
}
return Pixels;
}
//===========================================================================
//
// FMultipatchTexture::CopyTrueColorPixels
//
// Preserves the palettes of each individual patch
//
//===========================================================================
int FMultiPatchTexture::CopyPixels(FBitmap *bmp, int conversion)
{
int retv = -1;
if (conversion == noremap0)
{
if (bTextual || !UseGamePalette()) conversion = normal;
}
for(int i = 0; i < NumParts; i++)
{
int ret = -1;
FCopyInfo info;
memset (&info, 0, sizeof(info));
info.alpha = Parts[i].Alpha;
info.invalpha = BLENDUNIT - info.alpha;
info.op = ECopyOp(Parts[i].op);
PalEntry b = Parts[i].Blend;
if (b.a == 0 && b != BLEND_NONE)
{
info.blend = EBlend(b.d);
}
else if (b.a != 0)
{
if (b.a == 255)
{
info.blendcolor[0] = b.r * BLENDUNIT / 255;
info.blendcolor[1] = b.g * BLENDUNIT / 255;
info.blendcolor[2] = b.b * BLENDUNIT / 255;
info.blend = BLEND_MODULATE;
}
else
{
blend_t blendalpha = b.a * BLENDUNIT / 255;
info.blendcolor[0] = b.r * blendalpha;
info.blendcolor[1] = b.g * blendalpha;
info.blendcolor[2] = b.b * blendalpha;
info.blendcolor[3] = FRACUNIT - blendalpha;
info.blend = BLEND_OVERLAY;
}
}
auto trans = Parts[i].Translation ? Parts[i].Translation->Palette : nullptr;
FBitmap Pixels = Parts[i].Image->GetCachedBitmap(trans, conversion, &ret);
bmp->Blit(Parts[i].OriginX, Parts[i].OriginY, Pixels, Pixels.GetWidth(), Pixels.GetHeight(), Parts[i].Rotate, &info);
// treat -1 (i.e. unknown) as absolute. We have no idea if this may have overwritten previous info so a real check needs to be done.
if (ret == -1) retv = ret;
else if (retv != -1 && ret > retv) retv = ret;
}
return retv;
}
//==========================================================================
//
//
//
//==========================================================================
void FMultiPatchTexture::CollectForPrecache(PrecacheInfo &info, bool requiretruecolor)
{
FImageSource::CollectForPrecache(info, requiretruecolor);
if (!requiretruecolor)
{
requiretruecolor = bComplex;
if (!requiretruecolor) for (int i = 0; i < NumParts; ++i)
{
if (Parts[i].op != OP_COPY) requiretruecolor = true;
}
}
for (int i = 0; i < NumParts; ++i)
{
Parts[i].Image->CollectForPrecache(info, requiretruecolor);
}
}

View file

@ -0,0 +1,120 @@
#pragma once
#include "sc_man.h"
#include "palettecontainer.h"
#include "textureid.h"
#include "vectors.h"
#include "bitmap.h"
#include "image.h"
class FImageTexture;
//==========================================================================
//
// TexPart is the data that will get passed to the final texture.
//
//==========================================================================
struct TexPart
{
FRemapTable *Translation = nullptr;
FImageSource *Image = nullptr;
PalEntry Blend = 0;
blend_t Alpha = FRACUNIT;
int16_t OriginX = 0;
int16_t OriginY = 0;
uint8_t Rotate = 0;
uint8_t op = OP_COPY;
};
//==========================================================================
//
// A texture defined in a TEXTURE1 or TEXTURE2 lump
//
//==========================================================================
class FMultiPatchTexture : public FImageSource
{
friend class FTexture;
public:
FMultiPatchTexture(int w, int h, const TArray<TexPart> &parts, bool complex, bool textual);
protected:
int NumParts;
bool bComplex;
bool bTextual;
TexPart *Parts;
// The getters must optionally redirect if it's a simple one-patch texture.
int CopyPixels(FBitmap *bmp, int conversion) override;
TArray<uint8_t> CreatePalettedPixels(int conversion) override;
void CopyToBlock(uint8_t *dest, int dwidth, int dheight, FImageSource *source, int xpos, int ypos, int rotate, const uint8_t *translation, int style);
void CollectForPrecache(PrecacheInfo &info, bool requiretruecolor);
};
//==========================================================================
//
// Additional data per patch which is needed for initialization
//
//==========================================================================
struct TexInit
{
FString TexName;
//ETextureType UseType = ETextureType::Null;
FTexture *Texture = nullptr;
bool Silent = false;
bool HasLine = false;
bool UseOffsets = false;
FScriptPosition sc;
};
//==========================================================================
//
// All build info only needed to construct the multipatch textures
//
//==========================================================================
struct FPatchLookup;
struct BuildInfo
{
FString Name;
TArray<TexPart> Parts;
TArray<TexInit> Inits;
int Width = 0;
int Height = 0;
DVector2 Scale = { 1, 1 };
bool bWorldPanning = false; // This sucks!
int DefinitionLump = 0;
bool bComplex = false;
bool textual = false;
bool bNoDecals = false;
int LeftOffset[2] = {};
int TopOffset[2] = {};
FImageTexture *tex = nullptr;
void swap(BuildInfo &other)
{
Name.Swap(other.Name);
Parts.Swap(other.Parts);
Inits.Swap(other.Inits);
std::swap(Width, other.Width);
std::swap(Height, other.Height);
std::swap(Scale, other.Scale);
std::swap(bWorldPanning, other.bWorldPanning);
std::swap(DefinitionLump, other.DefinitionLump);
std::swap(bComplex, other.bComplex);
std::swap(textual, other.textual);
std::swap(bNoDecals, other.bNoDecals);
std::swap(LeftOffset[0], other.LeftOffset[0]);
std::swap(LeftOffset[1], other.LeftOffset[1]);
std::swap(TopOffset[0], other.TopOffset[0]);
std::swap(TopOffset[1], other.TopOffset[1]);
std::swap(tex, other.tex);
}
};

View file

@ -0,0 +1,304 @@
/*
** patchtexture.cpp
** Texture class for single Doom patches
**
**---------------------------------------------------------------------------
** Copyright 2004-2006 Randy Heit
** 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 "files.h"
#include "filesystem.h"
#include "bitmap.h"
#include "image.h"
#include "imagehelpers.h"
// posts are runs of non masked source pixels
struct column_t
{
uint8_t topdelta; // -1 is the last post in a column
uint8_t length; // length data bytes follows
};
bool checkPatchForAlpha(const void *buffer, uint32_t length);
//==========================================================================
//
// A texture that is just a single Doom format patch
//
//==========================================================================
class FPatchTexture : public FImageSource
{
bool badflag = false;
bool isalpha = false;
public:
FPatchTexture (int lumpnum, int w, int h, int lo, int to, bool isalphatex);
TArray<uint8_t> CreatePalettedPixels(int conversion) override;
int CopyPixels(FBitmap *bmp, int conversion) override;
void DetectBadPatches();
};
//==========================================================================
//
// Checks if the currently open lump can be a Doom patch
//
//==========================================================================
static bool CheckIfPatch(FileReader & file, bool &isalpha)
{
if (file.GetLength() < 13) return false; // minimum length of a valid Doom patch
file.Seek(0, FileReader::SeekSet);
auto data = file.Read(file.GetLength());
const patch_t *foo = (const patch_t *)data.Data();
int height = LittleShort(foo->height);
int width = LittleShort(foo->width);
if (height > 0 && height <= 2048 && width > 0 && width <= 2048 && width < file.GetLength()/4)
{
// The dimensions seem like they might be valid for a patch, so
// check the column directory for extra security. At least one
// column must begin exactly at the end of the column directory,
// and none of them must point past the end of the patch.
bool gapAtStart = true;
int x;
for (x = 0; x < width; ++x)
{
uint32_t ofs = LittleLong(foo->columnofs[x]);
if (ofs == (uint32_t)width * 4 + 8)
{
gapAtStart = false;
}
else if (ofs >= (uint32_t)(file.GetLength())) // Need one byte for an empty column (but there's patches that don't know that!)
{
return false;
}
}
if (!gapAtStart)
{
// only check this if the texture passed validation.
// Here is a good point because we already have a valid buffer of the lump's data.
isalpha = checkPatchForAlpha(data.Data(), (uint32_t)file.GetLength());
}
return !gapAtStart;
}
return false;
}
//==========================================================================
//
//
//
//==========================================================================
FImageSource *PatchImage_TryCreate(FileReader & file, int lumpnum)
{
bool isalpha;
if (!CheckIfPatch(file, isalpha)) return NULL;
file.Seek(0, FileReader::SeekSet);
int width = file.ReadUInt16();
int height = file.ReadUInt16();
int leftoffset = file.ReadInt16();
int topoffset = file.ReadInt16();
return new FPatchTexture(lumpnum, width, height, leftoffset, topoffset, isalpha);
}
//==========================================================================
//
//
//
//==========================================================================
FPatchTexture::FPatchTexture (int lumpnum, int w, int h, int lo, int to, bool isalphatex)
: FImageSource(lumpnum)
{
bUseGamePalette = !isalphatex;
isalpha = isalphatex;
Width = w;
Height = h;
LeftOffset = lo;
TopOffset = to;
DetectBadPatches();
}
//==========================================================================
//
//
//
//==========================================================================
TArray<uint8_t> FPatchTexture::CreatePalettedPixels(int conversion)
{
uint8_t *remap, remaptable[256];
int numspans;
const column_t *maxcol;
int x;
FileData lump = fileSystem.ReadFile (SourceLump);
const patch_t *patch = (const patch_t *)lump.GetMem();
maxcol = (const column_t *)((const uint8_t *)patch + fileSystem.FileLength (SourceLump) - 3);
remap = ImageHelpers::GetRemap(conversion == luminance, isalpha);
// Special case for skies
if (conversion == noremap0 && remap == GPalette.Remap)
{
memcpy(remaptable, GPalette.Remap, 256);
remaptable[0] = 0;
remap = remaptable;
}
if (badflag)
{
TArray<uint8_t> Pixels(Width * Height, true);
uint8_t *out;
// Draw the image to the buffer
for (x = 0, out = Pixels.Data(); x < Width; ++x)
{
const uint8_t *in = (const uint8_t *)patch + LittleLong(patch->columnofs[x]) + 3;
for (int y = Height; y > 0; --y)
{
*out = remap[*in];
out++, in++;
}
}
return Pixels;
}
int numpix = Width * Height;
numspans = Width;
TArray<uint8_t> Pixels(numpix, true);
memset (Pixels.Data(), 0, numpix);
// Draw the image to the buffer
for (x = 0; x < Width; ++x)
{
uint8_t *outtop = Pixels.Data() + x*Height;
const column_t *column = (const column_t *)((const uint8_t *)patch + LittleLong(patch->columnofs[x]));
int top = -1;
while (column < maxcol && column->topdelta != 0xFF)
{
if (column->topdelta <= top)
{
top += column->topdelta;
}
else
{
top = column->topdelta;
}
int len = column->length;
uint8_t *out = outtop + top;
if (len != 0)
{
if (top + len > Height) // Clip posts that extend past the bottom
{
len = Height - top;
}
if (len > 0)
{
numspans++;
const uint8_t *in = (const uint8_t *)column + 3;
for (int i = 0; i < len; ++i)
{
out[i] = remap[in[i]];
}
}
}
column = (const column_t *)((const uint8_t *)column + column->length + 4);
}
}
return Pixels;
}
//==========================================================================
//
//
//
//==========================================================================
int FPatchTexture::CopyPixels(FBitmap *bmp, int conversion)
{
if (!isalpha) return FImageSource::CopyPixels(bmp, conversion);
else return CopyTranslatedPixels(bmp, GPalette.GrayscaleMap.Palette);
}
//==========================================================================
//
// Fix for certain special patches on single-patch textures.
//
//==========================================================================
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 (fileSystem.FileLength(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.
FileData lump = fileSystem.ReadFile (SourceLump);
const patch_t *realpatch = (patch_t *)lump.GetMem();
const uint32_t *cofs = realpatch->columnofs;
int x, x2 = LittleShort(realpatch->width);
if (LittleShort(realpatch->height) == 256)
{
for (x = 0; x < x2; ++x)
{
const column_t *col = (column_t*)((uint8_t*)realpatch+LittleLong(cofs[x]));
if (col->topdelta != 0 || col->length != 0)
{
return; // It's not bad!
}
col = (column_t *)((uint8_t *)col + 256 + 4);
if (col->topdelta != 0xFF)
{
return; // More than one post in a column!
}
}
LeftOffset = 0;
TopOffset = 0;
badflag = true;
bMasked = false; // Hacked textures don't have transparent parts.
}
}

View file

@ -0,0 +1,222 @@
/*
** rawpagetexture.cpp
** Texture class for Raven's raw fullscreen pages
**
**---------------------------------------------------------------------------
** Copyright 2004-2006 Randy Heit
** 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 "files.h"
#include "filesystem.h"
#include "bitmap.h"
#include "imagehelpers.h"
#include "image.h"
//==========================================================================
//
// A raw 320x200 graphic used by Heretic and Hexen fullscreen images
//
//==========================================================================
class FRawPageTexture : public FImageSource
{
int mPaletteLump = -1;
public:
FRawPageTexture (int lumpnum);
TArray<uint8_t> CreatePalettedPixels(int conversion) override;
int CopyPixels(FBitmap *bmp, int conversion) override;
};
//==========================================================================
//
// RAW textures must be exactly 64000 bytes long and not be identifiable
// as Doom patch
//
//==========================================================================
static bool CheckIfRaw(FileReader & data)
{
if (data.GetLength() != 64000) return false;
// This is probably a raw page graphic, but do some checking to be sure
patch_t *foo;
int height;
int width;
data.Seek(0, FileReader::SeekSet);
auto bits = data.Read(data.GetLength());
foo = (patch_t *)bits.Data();;
height = LittleShort(foo->height);
width = LittleShort(foo->width);
if (height > 0 && height < 510 && width > 0 && width < 15997)
{
// The dimensions seem like they might be valid for a patch, so
// check the column directory for extra security. At least one
// column must begin exactly at the end of the column directory,
// and none of them must point past the end of the patch.
bool gapAtStart = true;
int x;
for (x = 0; x < width; ++x)
{
uint32_t ofs = LittleLong(foo->columnofs[x]);
if (ofs == (uint32_t)width * 4 + 8)
{
gapAtStart = false;
}
else if (ofs >= 64000-1) // Need one byte for an empty column
{
return true;
}
else
{
// Ensure this column does not extend beyond the end of the patch
const uint8_t *foo2 = (const uint8_t *)foo;
while (ofs < 64000)
{
if (foo2[ofs] == 255)
{
return true;
}
ofs += foo2[ofs+1] + 4;
}
if (ofs >= 64000)
{
return true;
}
}
}
if (gapAtStart || (x != width))
{
return true;
}
return false;
}
else
{
return true;
}
}
//==========================================================================
//
//
//
//==========================================================================
FImageSource *RawPageImage_TryCreate(FileReader & file, int lumpnum)
{
if (!CheckIfRaw(file)) return nullptr;
return new FRawPageTexture(lumpnum);
}
//==========================================================================
//
//
//
//==========================================================================
FRawPageTexture::FRawPageTexture (int lumpnum)
: FImageSource(lumpnum)
{
Width = 320;
Height = 200;
// Special case hack for Heretic's E2 end pic. This is not going to be exposed as an editing feature because the implications would be horrible.
FString Name;
fileSystem.GetFileShortName(Name, lumpnum);
if (Name.CompareNoCase("E2END") == 0)
{
mPaletteLump = fileSystem.CheckNumForName("E2PAL");
if (fileSystem.FileLength(mPaletteLump) < 768) mPaletteLump = -1;
}
else bUseGamePalette = true;
}
//==========================================================================
//
//
//
//==========================================================================
TArray<uint8_t> FRawPageTexture::CreatePalettedPixels(int conversion)
{
FileData lump = fileSystem.ReadFile (SourceLump);
const uint8_t *source = (const uint8_t *)lump.GetMem();
const uint8_t *source_p = source;
uint8_t *dest_p;
TArray<uint8_t> Pixels(Width*Height, true);
dest_p = Pixels.Data();
const uint8_t *remap = ImageHelpers::GetRemap(conversion == luminance);
// This does not handle the custom palette.
// User maps are encouraged to use a real image format when replacing E2END and the original could never be used anywhere else.
// Convert the source image from row-major to column-major format
for (int y = 200; y != 0; --y)
{
for (int x = 320; x != 0; --x)
{
*dest_p = remap[*source_p];
dest_p += 200;
source_p++;
}
dest_p -= 200 * 320 - 1;
}
return Pixels;
}
int FRawPageTexture::CopyPixels(FBitmap *bmp, int conversion)
{
if (mPaletteLump < 0) return FImageSource::CopyPixels(bmp, conversion);
else
{
FileData lump = fileSystem.ReadFile(SourceLump);
FileData plump = fileSystem.ReadFile(mPaletteLump);
const uint8_t *source = (const uint8_t *)lump.GetMem();
const uint8_t *psource = (const uint8_t *)plump.GetMem();
PalEntry paldata[256];
for (auto & pe : paldata)
{
pe.r = *psource++;
pe.g = *psource++;
pe.b = *psource++;
pe.a = 255;
}
bmp->CopyPixelData(0, 0, source, 320, 200, 1, 320, 0, paldata);
}
return 0;
}

View file

@ -0,0 +1,138 @@
/*
** shadertexture.cpp
**
** simple shader gradient textures, used by the status bars.
**
**---------------------------------------------------------------------------
** Copyright 2008 Braden Obrzut
** Copyright 2017 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 "filesystem.h"
#include "bitmap.h"
#include "imagehelpers.h"
#include "image.h"
class FBarShader : public FImageSource
{
public:
FBarShader(bool vertical, bool reverse)
{
int i;
Width = vertical ? 2 : 256;
Height = vertical ? 256 : 2;
bMasked = false;
bTranslucent = false;
// Fill the column/row with shading values.
// Vertical shaders have have minimum alpha at the top
// and maximum alpha at the bottom, unless flipped by
// setting reverse to true. Horizontal shaders are just
// the opposite.
if (vertical)
{
if (!reverse)
{
for (i = 0; i < 256; ++i)
{
Pixels[i] = i;
Pixels[256+i] = i;
}
}
else
{
for (i = 0; i < 256; ++i)
{
Pixels[i] = 255 - i;
Pixels[256+i] = 255 -i;
}
}
}
else
{
if (!reverse)
{
for (i = 0; i < 256; ++i)
{
Pixels[i*2] = 255 - i;
Pixels[i*2+1] = 255 - i;
}
}
else
{
for (i = 0; i < 256; ++i)
{
Pixels[i*2] = i;
Pixels[i*2+1] = i;
}
}
}
}
TArray<uint8_t> CreatePalettedPixels(int conversion) override
{
TArray<uint8_t> Pix(512, true);
if (conversion == luminance)
{
memcpy(Pix.Data(), Pixels, 512);
}
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.
for (int i = 0; i < 512; i++)
{
Pix[i] = GPalette.GrayMap[Pixels[i]];
}
}
return Pix;
}
int CopyPixels(FBitmap *bmp, int conversion) override
{
bmp->CopyPixelData(0, 0, Pixels, Width, Height, Height, 1, 0, GPalette.GrayRamp.Palette);
return 0;
}
private:
uint8_t Pixels[512];
};
#if 0
FTexture *CreateShaderTexture(bool vertical, bool reverse)
{
FStringf name("BarShader%c%c", vertical ? 'v' : 'h', reverse ? 'r' : 'f');
return CreateImageTexture(new FBarShader(vertical, reverse), name.GetChars());
}
#endif

View file

@ -326,12 +326,18 @@ struct TexCreateInfo
bool checkflat;
};
FImageSource *IMGZImage_TryCreate(FileReader &, int lumpnum);
FImageSource *PNGImage_TryCreate(FileReader &, int lumpnum);
FImageSource *JPEGImage_TryCreate(FileReader &, int lumpnum);
FImageSource *DDSImage_TryCreate(FileReader &, int lumpnum);
FImageSource *PCXImage_TryCreate(FileReader &, int lumpnum);
FImageSource *TGAImage_TryCreate(FileReader &, int lumpnum);
FImageSource *StbImage_TryCreate(FileReader &, int lumpnum);
FImageSource *RawPageImage_TryCreate(FileReader &, int lumpnum);
FImageSource *FlatImage_TryCreate(FileReader &, int lumpnum);
FImageSource *PatchImage_TryCreate(FileReader &, int lumpnum);
FImageSource *EmptyImage_TryCreate(FileReader &, int lumpnum);
FImageSource *AutomapImage_TryCreate(FileReader &, int lumpnum);
// Examines the lump contents to decide what type of texture to create,
@ -339,12 +345,18 @@ FImageSource *StbImage_TryCreate(FileReader &, int lumpnum);
FImageSource * FImageSource::GetImage(int lumpnum, bool isflat)
{
static TexCreateInfo CreateInfo[] = {
{ IMGZImage_TryCreate, false },
{ PNGImage_TryCreate, false },
{ JPEGImage_TryCreate, false },
{ DDSImage_TryCreate, false },
{ PCXImage_TryCreate, false },
{ StbImage_TryCreate, false },
{ TGAImage_TryCreate, false },
{ RawPageImage_TryCreate, false },
{ FlatImage_TryCreate, true }, // flat detection is not reliable, so only consider this for real flats.
{ PatchImage_TryCreate, false },
{ EmptyImage_TryCreate, false },
{ AutomapImage_TryCreate, false },
};
if (lumpnum == -1) return nullptr;