Store all channels of a color together in CStdPalette

This mostly simplifies things, since most other places use an 32 bit
integer to store colors, but might even improve performance through better
cache locality.
Günther Brammer 2012-08-16 00:45:27 +02:00
parent 4b096d71a0
commit a5b83665af
9 changed files with 31 additions and 50 deletions

View File

@ -131,6 +131,7 @@ class C4ViewportList;
class C4ViewportWindow;
class C4Markup;
class CStdFont;
struct CStdPalette;
class CStdStream;
class CStdVectorFont;
class CSurface8;

View File

@ -21,6 +21,7 @@
#include "C4Include.h"
#include <Bitmap256.h>
#include <StdColors.h>
C4BMPInfo::C4BMPInfo()
{
@ -73,7 +74,7 @@ int C4BMP256Info::FileBitsOffset()
return Head.bfOffBits-sizeof(C4BMP256Info);
}
void C4BMP256Info::Set(int iWdt, int iHgt, BYTE *bypPalette)
void C4BMP256Info::Set(int iWdt, int iHgt, CStdPalette *Palette)
{
Default();
// Set header
@ -92,9 +93,9 @@ void C4BMP256Info::Set(int iWdt, int iHgt, BYTE *bypPalette)
// Set palette
for (int cnt=0; cnt<256; cnt++)
{
Colors[cnt].rgbRed = bypPalette[cnt*3+0];
Colors[cnt].rgbGreen = bypPalette[cnt*3+1];
Colors[cnt].rgbBlue = bypPalette[cnt*3+2];
Colors[cnt].rgbRed = GetRedValue(Palette->Colors[cnt]);
Colors[cnt].rgbGreen = GetGreenValue(Palette->Colors[cnt]);
Colors[cnt].rgbBlue = GetBlueValue(Palette->Colors[cnt]);
}
}

View File

@ -82,7 +82,7 @@ public:
RGBQUAD Colors[256];
public:
void Default();
void Set(int iWdt, int iHgt, BYTE *bypPalette);
void Set(int iWdt, int iHgt, CStdPalette *);
bool Valid();
int FileBitsOffset();

View File

@ -131,10 +131,9 @@ bool CSurface8::Read(CStdStream &hGroup)
// Copy palette
for (cnt=0; cnt<256; cnt++)
{
pPal->Colors[cnt*3+0]=BitmapInfo.Colors[cnt].rgbRed;
pPal->Colors[cnt*3+1]=BitmapInfo.Colors[cnt].rgbGreen;
pPal->Colors[cnt*3+2]=BitmapInfo.Colors[cnt].rgbBlue;
pPal->Alpha[cnt]=0xff;
pPal->Colors[cnt] = C4RGB(BitmapInfo.Colors[cnt].rgbRed,
BitmapInfo.Colors[cnt].rgbGreen,
BitmapInfo.Colors[cnt].rgbBlue);
}
}
@ -164,10 +163,10 @@ bool CSurface8::Read(CStdStream &hGroup)
return true;
}
bool CSurface8::Save(const char *szFilename, BYTE *bpPalette)
bool CSurface8::Save(const char *szFilename, CStdPalette *bpPalette)
{
C4BMP256Info BitmapInfo;
BitmapInfo.Set(Wdt,Hgt,bpPalette ? bpPalette : pPal->Colors);
BitmapInfo.Set(Wdt,Hgt, bpPalette ? bpPalette : pPal);
// Create file & write info
CStdFile hFile;

View File

@ -60,7 +60,7 @@ public:
void Clip(int iX, int iY, int iX2, int iY2);
void NoClip();
bool Read(class CStdStream &hGroup);
bool Save(const char *szFilename, BYTE *bpPalette = NULL);
bool Save(const char *szFilename, CStdPalette * = NULL);
void GetSurfaceSize(int &irX, int &irY); // get surface size
void AllowColor(BYTE iRngLo, BYTE iRngHi, bool fAllowZero=false);
void SetBuffer(BYTE *pbyToBuf, int Wdt, int Hgt, int Pitch);

View File

@ -1478,11 +1478,11 @@ bool C4Landscape::SaveMap(C4Group &hGroup)
if (!Map) return false;
// Create map palette
BYTE bypPalette[3*256];
::TextureMap.StoreMapPalette(bypPalette,::MaterialMap);
CStdPalette Palette;
::TextureMap.StoreMapPalette(&Palette,::MaterialMap);
// Save map surface
if (!Map->Save(Config.AtTempPath(C4CFN_TempMap), bypPalette))
if (!Map->Save(Config.AtTempPath(C4CFN_TempMap), &Palette))
return false;
// Move temp file to group
@ -3245,13 +3245,8 @@ bool C4Landscape::Mat2Pal()
continue;
// colors
DWORD dwPix = pTex->GetPattern().PatternClr(0, 0);
for (rgb=0; rgb<3; rgb++)
Surface8->pPal->Colors[MatTex2PixCol(tex)*3+rgb]
= Surface8->pPal->Colors[(MatTex2PixCol(tex)+IFT)*3+rgb]
= uint8_t(dwPix >> ((2-rgb) * 8));
// alpha
Surface8->pPal->Alpha[MatTex2PixCol(tex)] = 0xff;
Surface8->pPal->Alpha[MatTex2PixCol(tex)+IFT] = 0xff;
Surface8->pPal->Colors[MatTex2PixCol(tex)] = dwPix;
Surface8->pPal->Colors[MatTex2PixCol(tex) + IFT] = dwPix;
}
// success
return true;

View File

@ -422,14 +422,10 @@ void C4TextureMap::Default()
fInitialized = false;
}
void C4TextureMap::StoreMapPalette(BYTE *bypPalette, C4MaterialMap &rMaterial)
void C4TextureMap::StoreMapPalette(CStdPalette *Palette, C4MaterialMap &rMaterial)
{
// Zero palette
ZeroMem(bypPalette,256*3);
// Sky color
bypPalette[0]=192;
bypPalette[1]=196;
bypPalette[2]=252;
Palette->Colors[0] = C4RGB(192, 196, 252);
// Material colors by texture map entries
bool fSet[256];
ZeroMem(&fSet, sizeof (fSet));
@ -438,12 +434,8 @@ void C4TextureMap::StoreMapPalette(BYTE *bypPalette, C4MaterialMap &rMaterial)
{
// Find material
DWORD dwPix = Entry[i].GetPattern().PatternClr(0, 0);
bypPalette[3*i+0]=dwPix >> 16;
bypPalette[3*i+1]=dwPix >> 8;
bypPalette[3*i+2]=dwPix;
bypPalette[3*(i+IFT)+0]=dwPix >> 16;
bypPalette[3*(i+IFT)+1]=dwPix >> 8;
bypPalette[3*(i+IFT)+2]=dwPix | 0x0F; // IFT arbitrarily gets more blue
Palette->Colors[i] = dwPix;
Palette->Colors[i + IFT] = dwPix | 0x0F; // IFT arbitrarily gets more blue
fSet[i] = fSet[i + IFT] = true;
}
// Crosscheck colors, change equal palette entries
@ -452,17 +444,16 @@ void C4TextureMap::StoreMapPalette(BYTE *bypPalette, C4MaterialMap &rMaterial)
{
// search equal entry
int32_t j = 0;
for (; j < i; j++) if (fSet[j])
if (bypPalette[3*i+0] == bypPalette[3*j+0] &&
bypPalette[3*i+1] == bypPalette[3*j+1] &&
bypPalette[3*i+2] == bypPalette[3*j+2])
for (; j < i; j++)
if (fSet[j] && Palette->Colors[i] == Palette->Colors[j])
break;
// not found? ok then
if (j >= i) break;
// change randomly
if (rand() < RAND_MAX / 2) bypPalette[3*i+0] += 3; else bypPalette[3*i+0] -= 3;
if (rand() < RAND_MAX / 2) bypPalette[3*i+1] += 3; else bypPalette[3*i+1] -= 3;
if (rand() < RAND_MAX / 2) bypPalette[3*i+2] += 3; else bypPalette[3*i+2] -= 3;
Palette->Colors[i] = C4RGB(
(rand() < RAND_MAX / 2) ? GetRedValue(Palette->Colors[i]) + 3 : GetRedValue(Palette->Colors[i]) - 3,
(rand() < RAND_MAX / 2) ? GetGreenValue(Palette->Colors[i]) + 3 : GetGreenValue(Palette->Colors[i]) - 3,
(rand() < RAND_MAX / 2) ? GetBlueValue(Palette->Colors[i]) + 3 : GetBlueValue(Palette->Colors[i]) - 3);
}
}

View File

@ -83,7 +83,7 @@ public:
void RemoveEntry(int32_t iIndex) { if (Inside<int32_t>(iIndex, 1, C4M_MaxTexIndex-1)) Entry[iIndex].Clear(); }
void Default();
void Clear();
void StoreMapPalette(BYTE *bypPalette, C4MaterialMap &rMaterials);
void StoreMapPalette(CStdPalette *, C4MaterialMap &rMaterials);
static bool LoadFlags(C4Group &hGroup, const char *szEntryName, bool *pOverloadMaterials, bool *pOverloadTextures);
int32_t LoadMap(C4Group &hGroup, const char *szEntryName, bool *pOverloadMaterials, bool *pOverloadTextures);
int32_t Init();

View File

@ -297,16 +297,10 @@ inline bool RGB2rgb(int R, int G, int B, double *pr, double *pg, double *pb, dou
// a standard pal
struct CStdPalette
{
BYTE Colors[3*256];
BYTE Alpha[3*256]; // TODO: alphapal: Why 3*? Isn't Alpha[256] enough?
DWORD Colors[256];
DWORD GetClr(BYTE byCol)
{ return C4RGB(Colors[byCol*3], Colors[byCol*3+1], Colors[byCol*3+2])+(Alpha[byCol]<<24); }
void EnforceC0Transparency()
{
Colors[0]=Colors[1]=Colors[2]=0; Alpha[0]=0;
}
{ return Colors[byCol]; }
};
// clrmod-add-map to cover a drawing range in which all draws shall be adjusted by the map