diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 5277f6fb2..f63ce05f9 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -982,6 +982,7 @@ set (PCH_SOURCES common/textures/formats/pcxtexture.cpp common/textures/formats/pngtexture.cpp common/textures/formats/tgatexture.cpp + common/textures/formats/arttexture.cpp ) diff --git a/source/build/include/build.h b/source/build/include/build.h index 3a60775c7..f02cb6edf 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -1086,7 +1086,6 @@ void artSetupMapArt(const char *filename); bool tileLoad(int16_t tilenume); void tileLoadData(int16_t tilenume, int32_t dasiz, char *buffer); int32_t tileCRC(int16_t tileNum); -void artConvertRGB(palette_t *pic, uint8_t const *buf, int32_t bufsizx, int32_t sizx, int32_t sizy); void tileUpdatePicSiz(int32_t picnum); int32_t qloadkvx(int32_t voxindex, const char *filename); diff --git a/source/build/src/defs.cpp b/source/build/src/defs.cpp index f3b90864b..59297c7aa 100644 --- a/source/build/src/defs.cpp +++ b/source/build/src/defs.cpp @@ -17,6 +17,7 @@ #include "mdsprite.h" // md3model_t #include "colmatch.h" #include "textures.h" +#include "bitmap.h" #ifdef USE_OPENGL # include "hightile.h" @@ -252,52 +253,9 @@ static int32_t Defs_ImportTileFromTexture(char const * const fn, int32_t const t if (check_file_exist(fn)) return -1; - int32_t xsiz = 0, ysiz = 0; - palette_t *picptr = NULL; FTexture* tex = FTexture::GetTexture(fn); - - // This should be implemented as a separate texture type to avoid maintenance problems elsewhere. - if (!tex) - { - auto fr = kopenFileReader(fn, 0); - auto data = fr.Read(); - int32_t const artstatus = artCheckUnitFileHeader(data.Data(), data.Size()); - if (artstatus < 0) - return artstatus<<8; - - int32_t picanmdisk; - Bmemcpy(&picanmdisk, &kpzbuf[20], sizeof(int32_t)); - picanmdisk = B_LITTLE32(picanmdisk); - tileConvertAnimFormat(tile, picanmdisk); - - int32_t const xsiz = B_LITTLE16(B_UNBUF16(&kpzbuf[16])); - int32_t const ysiz = B_LITTLE16(B_UNBUF16(&kpzbuf[18])); - - if (EDUKE32_PREDICT_FALSE(xsiz <= 0 || ysiz <= 0)) - { - tileDelete(tile); - return 2; - } - - tileSetSize(tile, xsiz, ysiz); - int32_t const dasiz = xsiz * ysiz; - - if (EDUKE32_PREDICT_FALSE(ARTv1_UNITOFFSET + dasiz > (int)data.Size())) - { - tileSetupDummy(tile); - return 3; - } - - tileSetData(tile, dasiz, &kpzbuf[ARTv1_UNITOFFSET]); - -#ifdef USE_OPENGL - if (istexture) - hicsetsubsttex(tile, 0, fn, (float)(255-alphacut) * (1.f/255.f), 1.0f, 1.0f, 1.0f, 1.0f, HICR_ARTIMMUNITY); -#endif - - return 1; - } + int32_t xsiz = tex->GetWidth(), ysiz = tex->GetHeight(); if (EDUKE32_PREDICT_FALSE(xsiz <= 0 || ysiz <= 0)) return -2; @@ -305,11 +263,12 @@ static int32_t Defs_ImportTileFromTexture(char const * const fn, int32_t const t if (!(paletteloaded & PALETTE_MAIN)) return -3; - tileSetSize(tile, tex->GetWidth(), tex->GetHeight()); - - tile_from_truecolpic(tile, picptr, alphacut); - - Xfree(picptr); + if (videoGetRenderMode() < REND_POLYMOST) + { + tileSetSize(tile, tex->GetWidth(), tex->GetHeight()); + auto image = tex->GetBgraBitmap(nullptr, nullptr); + tile_from_truecolpic(tile, (const palette_t*)image.GetPixels(), alphacut); + } #ifdef USE_OPENGL if (istexture) diff --git a/source/build/src/tiles.cpp b/source/build/src/tiles.cpp index 10f4b0f22..f71b8cce4 100644 --- a/source/build/src/tiles.cpp +++ b/source/build/src/tiles.cpp @@ -796,31 +796,6 @@ int32_t tileCRC(int16_t tileNum) return crc; } -// Assumes pic has been initialized to zero. -void artConvertRGB(palette_t * const pic, uint8_t const * const buf, int32_t const bufsizx, int32_t const sizx, int32_t const sizy) -{ - for (bssize_t y = 0; y < sizy; ++y) - { - palette_t * const picrow = &pic[bufsizx * y]; - - for (bssize_t x = 0; x < sizx; ++x) - { - uint8_t index = buf[sizy * x + y]; - - if (index == 255) - continue; - - index *= 3; - - // pic is BGRA - picrow[x].r = palette[index+2]; - picrow[x].g = palette[index+1]; - picrow[x].b = palette[index]; - picrow[x].f = 255; - } - } -} - // // allocatepermanenttile // diff --git a/source/common/textures/formats/arttexture.cpp b/source/common/textures/formats/arttexture.cpp new file mode 100644 index 000000000..0092b32b2 --- /dev/null +++ b/source/common/textures/formats/arttexture.cpp @@ -0,0 +1,146 @@ +/* +** arttexture.cpp +** Texture class for ART-based hightiles +** +**--------------------------------------------------------------------------- +** Copyright 2019 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 "templates.h" +#include "bitmap.h" +#include "image.h" +#include "cache1d.h" +#include "build.h" + + +//========================================================================== +// +// an AET texture +// +//========================================================================== + +class FArtTexture : public FImageSource +{ + +public: + FArtTexture (int width, int height, int p); + int CopyPixels(FBitmap *bmp, int conversion) override; + int32_t picanmdisk; // Todo: Get this out again on the other side. +}; + +//========================================================================== +// +// +// +//========================================================================== + +FImageSource *ArtImage_TryCreate(FileReader & file) +{ + auto buffer = file.Read(); + int32_t const artstatus = artCheckUnitFileHeader(buffer.Data(), buffer.Size()); + if (artstatus < 0) return nullptr; + + int32_t picanmdisk; + memcpy(&picanmdisk, &buffer[20], sizeof(int32_t)); + picanmdisk = B_LITTLE32(picanmdisk); + //tileConvertAnimFormat(tile, picanmdisk); + + int Width = B_LITTLE16(B_UNBUF16(&buffer[16])); + int Height = B_LITTLE16(B_UNBUF16(&buffer[18])); + + if (Width <= 0 || Height <= 0) + { + return nullptr; + } + + int32_t NumPixels = Width * Height; + + if (ARTv1_UNITOFFSET + NumPixels > (int)buffer.Size()) + { + return nullptr; + } + + return new FArtTexture(Width, Height, picanmdisk); +} + +//========================================================================== +// +// +// +//========================================================================== + +FArtTexture::FArtTexture(int width, int height, int p) +{ + Width = width; + Height = height; + picanmdisk = p; +} + +//=========================================================================== +// +// FArtTexture::CopyPixels +// +// This format is special because it ignores the game palettes and +// only outputs a true color image with the primary palette. +// +//=========================================================================== + +int FArtTexture::CopyPixels(FBitmap *bmp, int conversion) +{ + // Treat both buffer as linear contiguous blocks. + // Both Src and Dst are ordered the same with no padding. + int numpixels = Width * Height; + bool hasalpha = false; + FileReader fr = kopenFileReader(Name, 0); + if (!fr.isOpen()) return 0; + TArray source(numpixels, true); + fr.Read(source.Data(), numpixels); + auto dest = bmp->GetPixels(); + + for (int y = 0; y < numpixels; ++y) + { + int index = source[y]; + if (index == 255) + { + hasalpha = true; + continue; + } + + dest[0] = palette[index]; + dest[1] = palette[index+1]; + dest[2] = palette[index+2]; + dest[3] = 255; + dest += 4; + } + bMasked = hasalpha; + return 0; +} + diff --git a/source/common/textures/image.cpp b/source/common/textures/image.cpp index 6ea28820c..a13d3837c 100644 --- a/source/common/textures/image.cpp +++ b/source/common/textures/image.cpp @@ -99,6 +99,7 @@ FImageSource *JPEGImage_TryCreate(FileReader &); FImageSource *DDSImage_TryCreate(FileReader &); FImageSource *PCXImage_TryCreate(FileReader &); FImageSource *TGAImage_TryCreate(FileReader &); +FImageSource *ArtImage_TryCreate(FileReader &); // Examines the lump contents to decide what type of texture to create, @@ -110,7 +111,7 @@ FImageSource * FImageSource::GetImage(const char *name) { JPEGImage_TryCreate }, { DDSImage_TryCreate }, { PCXImage_TryCreate }, - { TGAImage_TryCreate }, + { ArtImage_TryCreate }, { nullptr } };