- added a texture format for single frame ANMs so that they can be handled like normal images.

The intermission code is doing weird things with them that isn't really portable.
This commit is contained in:
Christoph Oelckers 2020-06-28 14:41:44 +02:00
parent 924816ac8d
commit 2ddec37098
9 changed files with 185 additions and 6 deletions

View file

@ -783,7 +783,6 @@ set (PCH_SOURCES
build/src/timer.cpp
build/src/voxmodel.cpp
core/animlib.cpp
core/mathutil.cpp
core/rts.cpp
core/ct_chat.cpp
@ -846,6 +845,7 @@ set (PCH_SOURCES
common/textures/skyboxtexture.cpp
common/textures/animtexture.cpp
common/textures/v_collection.cpp
common/textures/animlib.cpp
common/textures/formats/automaptexture.cpp
common/textures/formats/brightmaptexture.cpp
common/textures/formats/buildtexture.cpp
@ -864,6 +864,7 @@ set (PCH_SOURCES
common/textures/formats/shadertexture.cpp
common/textures/formats/tgatexture.cpp
common/textures/formats/stbtexture.cpp
common/textures/formats/anmtexture.cpp
common/textures/hires/hqresize.cpp
common/models/models_md3.cpp
common/models/models_md2.cpp

View file

@ -187,6 +187,7 @@ void DrawTexture(F2DDrawer *drawer, FGameTexture* img, double x, double y, int t
va_start(tags.list, tags_first);
DrawParms parms;
if (!img || !img->isValid()) return;
bool res = ParseDrawTextureTags(drawer, img, x, y, tags_first, tags, &parms, false);
va_end(tags.list);
if (!res)
@ -208,6 +209,7 @@ static void DrawTexture(F2DDrawer *drawer, FGameTexture *img, double x, double y
{
DrawParms parms;
uint32_t tag = ListGetInt(args);
if (!img || !img->isValid()) return;
bool res = ParseDrawTextureTags(drawer, img, x, y, tag, args, &parms, false);
if (!res) return;
drawer->AddTexture(img, parms);

View file

@ -78,7 +78,8 @@ DEFINE_ACTION_FUNCTION(_TexMan, GetName)
static int CheckForTexture(const FString& name, int type, int flags)
{
return TexMan.CheckForTexture(name, static_cast<ETextureType>(type), flags).GetIndex();
// ForceLookup is intentionally blocked here, this flag is for internal use only.
return TexMan.CheckForTexture(name, static_cast<ETextureType>(type), (flags & ~FTextureManager::TEXMAN_ForceLookup)).GetIndex();
}
DEFINE_ACTION_FUNCTION_NATIVE(_TexMan, CheckForTexture, CheckForTexture)

View file

@ -0,0 +1,172 @@
/*
** anmtexture.cpp
** Texture class for reading the first frame of Build ANM files
**
**---------------------------------------------------------------------------
** Copyright 2020 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 "bitmap.h"
#include "imagehelpers.h"
#include "image.h"
#include "animlib.h"
//==========================================================================
//
//
//==========================================================================
class FAnmTexture : public FImageSource
{
public:
FAnmTexture (int lumpnum, int w, int h);
void ReadFrame(uint8_t *buffer, uint8_t *palette);
TArray<uint8_t> CreatePalettedPixels(int conversion) override;
int CopyPixels(FBitmap *bmp, int conversion) override;
};
//==========================================================================
//
//
//
//==========================================================================
FImageSource *AnmImage_TryCreate(FileReader & file, int lumpnum)
{
int x, y, comp;
file.Seek(0, FileReader::SeekSet);
char check[4];
file.Read(check, 4);
if (memcmp(check, "LPF ", 4)) return nullptr;
file.Seek(0, FileReader::SeekSet);
auto buffer = file.ReadPadded(1);
anim_t anim;
if (ANIM_LoadAnim(&anim, buffer.Data(), buffer.Size() - 1) < 0)
{
return nullptr;
}
numframes = ANIM_NumFrames(&anim);
if (result >= 1)
{
return new FAnmTexture(lumpnum, 320, 200);
}
return nullptr;
}
//==========================================================================
//
//
//
//==========================================================================
FAnmTexture::FAnmTexture (int lumpnum, int w, int h)
: FImageSource(lumpnum)
{
Width = w;
Height = h;
LeftOffset = 0;
TopOffset = 0;
}
void FAnmTexture::ReadFrame(uint8_t *pixels, uint8_t *palette)
{
FileData lump = fileSystem.ReadFile (SourceLump);
const uint8_t *source = (const uint8_t *)lump.GetMem();
anim_t anim;
if (ANIM_LoadAnim(&anim, source, lump.GetSize()) >= 0)
{
numframes = ANIM_NumFrames(&anim);
if (result >= 1)
{
memcpy(palette, ANIM_GetPalette(anim), 768);
memcpy(pixels, ANIM_DrawFrame(1), Width*Height);
return;
}
}
memset(pixels, 0, Width*Height);
memset(palette, 0, 768);
}
//==========================================================================
//
//
//
//==========================================================================
TArray<uint8_t> FAnmTexture::CreatePalettedPixels(int conversion)
{
TArray<uint8_t> pixels(Width*Height, true);
uint8_t buffer[64000];
uint8_t palette[768];
uint8_t remap[256];
ReadFrame(buffer, palette);
for(int i=0;i<256;i++)
{
remap[i] = ColorMatcher.Pick(palette[i*3], palette[i*3+1], palette[i*3+2]);
}
ImageHelpers::FlipNonSquareBlockRemap (pixels.Data(), buffer, Width, Height, Width, remap);
return Pixels;
}
//==========================================================================
//
//
//
//==========================================================================
int FAnmTexture::CopyPixels(FBitmap *bmp, int conversion)
{
uint8_t buffer[64000];
uint8_t palette[768];
ReadFrame(buffer, palette);
auto dpix = bmp.GetPixels();
for (int i = 0; i < Width * Height; i++)
{
int p = i * 4;
int index = buffer[i];
dpix[p + 0] = Palette[index * 3 + 2];
dpix[p + 1] = Palette[index * 3 + 1];
dpix[p + 2] = Palette[index * 3];
dpix[p + 3] = 255;
}
return -1;
}

View file

@ -331,6 +331,7 @@ 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 *AnmImage_TryCreate(FileReader &, int lumpnum);
FImageSource *RawPageImage_TryCreate(FileReader &, int lumpnum);
FImageSource *FlatImage_TryCreate(FileReader &, int lumpnum);
FImageSource *PatchImage_TryCreate(FileReader &, int lumpnum);
@ -350,6 +351,7 @@ FImageSource * FImageSource::GetImage(int lumpnum, bool isflat)
{ PCXImage_TryCreate, false },
{ StbImage_TryCreate, false },
{ TGAImage_TryCreate, false },
{ AnmImage_TryCreate, false },
{ RawPageImage_TryCreate, false },
{ FlatImage_TryCreate, true }, // flat detection is not reliable, so only consider this for real flats.
{ PatchImage_TryCreate, false },

View file

@ -240,7 +240,7 @@ FTextureID FTextureManager::CheckForTexture (const char *name, ETextureType uset
{
// We intentionally only look for textures in subdirectories.
// Any graphic being placed in the zip's root directory can not be found by this.
if (strchr(name, '/'))
if (strchr(name, '/') || (flags & TEXMAN_ForceLookup))
{
FGameTexture *const NO_TEXTURE = (FGameTexture*)-1;
int lump = fileSystem.CheckNumForFullName(name);

View file

@ -47,9 +47,9 @@ public:
}
// This only gets used in UI code so we do not need PALVERS handling.
FGameTexture* GetGameTextureByName(const char *name, bool animate = false)
FGameTexture* GetGameTextureByName(const char *name, bool animate = false, int flags = 0)
{
FTextureID texnum = GetTextureID(name, ETextureType::MiscPatch);
FTextureID texnum = GetTextureID(name, ETextureType::MiscPatch, flags);
return InternalGetTexture(texnum.GetIndex(), animate, true);
}
@ -88,7 +88,8 @@ public:
TEXMAN_AllowSkins = 8,
TEXMAN_ShortNameOnly = 16,
TEXMAN_DontCreate = 32,
TEXMAN_Localize = 64
TEXMAN_Localize = 64,
TEXMAN_ForceLookup = 128
};
enum