- Added translation support to multipatch textures. Incomplete and not tested yet!

- Added Martin Howe's morph weapon update.


SVN r916 (trunk)
This commit is contained in:
Christoph Oelckers 2008-04-15 22:17:30 +00:00
commit b2bfad0c50
19 changed files with 645 additions and 142 deletions

View file

@ -44,6 +44,8 @@
#include "sc_man.h"
#include "templates.h"
#include "vectors.h"
#include "r_translate.h"
#include "bitmap.h"
// On the Alpha, accessing the shorts directly if they aren't aligned on a
// 4-byte boundary causes unaligned access warnings. Why it does this at
@ -274,6 +276,70 @@ const BYTE *FMultiPatchTexture::GetColumn (unsigned int column, const Span **spa
return Pixels + column*Height;
}
//==========================================================================
//
// FMultiPatchTexture :: GetColumn
//
//==========================================================================
BYTE * GetBlendMap(PalEntry blend, BYTE *blendwork)
{
switch (blend)
{
case BLEND_INVERSEMAP:
return InverseColormap;
case BLEND_GOLDMAP:
return GoldColormap;
case BLEND_REDMAP:
return RedColormap;
case BLEND_GREENMAP:
return GreenColormap;
case BLEND_ICEMAP:
return TranslationToTable(TRANSLATION(TRANSLATION_Standard, 7))->Remap;
default:
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 NULL;
}
//==========================================================================
//
// FMultiPatchTexture :: MakeTexture
@ -285,14 +351,20 @@ void FMultiPatchTexture::MakeTexture ()
// 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;
BYTE blendwork[256];
Pixels = new BYTE[numpix];
memset (Pixels, 0, numpix);
for (int i = 0; i < NumParts; ++i)
{
BYTE *trans = Parts[i].Translation? Parts[i].Translation->Remap : NULL;
if (Parts[i].Blend != BLEND_NONE)
{
trans = GetBlendMap(Parts[i].Blend, blendwork);
}
Parts[i].Texture->CopyToBlock (Pixels, Width, Height,
Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate);
Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans);
}
}
@ -310,7 +382,29 @@ int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rota
for(int i=0;i<NumParts;i++)
{
int ret = Parts[i].Texture->CopyTrueColorPixels(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate);
int ret;
if (!Parts[i].Texture->bComplex)
{
if (Parts[i].Translation != NULL)
{
// Using a translation forces downconversion to the base palette
ret = Parts[i].Texture->CopyTrueColorTranslated(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, Parts[i].Translation);
}
else
{
if (Parts[i].Blend != BLEND_NONE)
{
}
ret = Parts[i].Texture->CopyTrueColorPixels(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate);
}
}
else
{
// If the patch is a texture with some kind of processing involved
// the copying must be done in 2 steps: First create a complete image of the patch
// including all processing and then copy from that intermediate image to the destination
}
if (ret > retv) retv = ret;
}
@ -327,6 +421,7 @@ int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rota
FTextureFormat FMultiPatchTexture::GetFormat()
{
if (bComplex) return TEX_RGB;
if (NumParts == 1) return Parts[0].Texture->GetFormat();
return UseBasePalette() ? TEX_Pal : TEX_RGB;
}
@ -343,6 +438,7 @@ FTextureFormat FMultiPatchTexture::GetFormat()
bool FMultiPatchTexture::UseBasePalette()
{
if (bComplex) return false;
for(int i=0;i<NumParts;i++)
{
if (!Parts[i].Texture->UseBasePalette()) return false;
@ -489,6 +585,8 @@ FMultiPatchTexture::TexPart::TexPart()
Rotate = 0;
textureOwned = false;
Texture = NULL;
Translation = NULL;
Blend = 0;
}
//==========================================================================
@ -501,6 +599,7 @@ FMultiPatchTexture::TexPart::~TexPart()
{
if (textureOwned && Texture != NULL) delete Texture;
Texture = NULL;
if (Translation != NULL) delete Translation;
}
//==========================================================================
@ -673,6 +772,17 @@ void FTextureManager::AddTexturesLumps (int lump1, int lump2, int patcheslump)
}
static bool Check(char *& range, char c)
{
while (isspace(*range)) range++;
if (*range==c)
{
range++;
return true;
}
return false;
}
void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part)
{
FString patchname;
@ -727,6 +837,110 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part)
}
part.Rotate = (sc.Number / 90) & 3;
}
else if (sc.Compare("Translation"))
{
bComplex = true;
if (part.Translation != NULL) delete part.Translation;
part.Translation = NULL;
part.Blend = 0;
static const char *maps[] = { "inverse", "gold", "red", "green", "ice", "desaturate", NULL };
int match = sc.MatchString(maps);
if (match >= 0)
{
part.Blend.r = 1 + match;
if (part.Blend.r == BLEND_DESATURATE1)
{
sc.MustGetStringName(",");
sc.MustGetNumber();
part.Blend.r += clamp(sc.Number-1, 0, 30);
}
}
else
{
part.Translation = new FRemapTable;
part.Translation->MakeIdentity();
do
{
sc.MustGetString();
char *range = sc.String;
int start,end;
start=strtol(range, &range, 10);
if (!Check(range, ':')) return;
end=strtol(range, &range, 10);
if (!Check(range, '=')) return;
if (!Check(range, '['))
{
int pal1,pal2;
pal1=strtol(range, &range, 10);
if (!Check(range, ':')) return;
pal2=strtol(range, &range, 10);
part.Translation->AddIndexRange(start, end, pal1, pal2);
}
else
{
// translation using RGB values
int r1,g1,b1,r2,g2,b2;
r1=strtol(range, &range, 10);
if (!Check(range, ',')) return;
g1=strtol(range, &range, 10);
if (!Check(range, ',')) return;
b1=strtol(range, &range, 10);
if (!Check(range, ']')) return;
if (!Check(range, ':')) return;
if (!Check(range, '[')) return;
r2=strtol(range, &range, 10);
if (!Check(range, ',')) return;
g2=strtol(range, &range, 10);
if (!Check(range, ',')) return;
b2=strtol(range, &range, 10);
if (!Check(range, ']')) return;
part.Translation->AddColorRange(start, end, r1, g1, b1, r2, g2, b2);
}
}
while (sc.CheckString(","));
}
}
else if (sc.Compare("Blend"))
{
bComplex = true;
if (part.Translation != NULL) delete part.Translation;
part.Translation = NULL;
part.Blend = 0;
if (!sc.CheckNumber())
{
part.Blend = V_GetColor(NULL, sc.String);
}
else
{
int r,g,b;
sc.MustGetNumber();
sc.MustGetStringName(",");
r = sc.Number;
sc.MustGetNumber();
sc.MustGetStringName(",");
g = sc.Number;
sc.MustGetNumber();
sc.MustGetStringName(",");
b = sc.Number;
part.Blend = MAKERGB(r, g, b);
}
if (sc.CheckString(","))
{
sc.MustGetFloat();
part.Blend.a = clamp<int>(int(sc.Float*255), 1, 254);
}
else part.Blend.a = 255;
bComplex = true;
}
}
}
if (Mirror & 2)