split out palette management, preparing for custom palette support .

This commit is contained in:
Zero Fanker 2024-05-13 21:37:30 -04:00
parent fb64321a28
commit 981059c2b4
6 changed files with 645 additions and 655 deletions

View file

@ -1029,60 +1029,6 @@ const Vec3f lightDirection = Vec3f(1.0f, 0.0f, -1.0f).normalize();
#endif
HTSPALETTE CLoading::GetIsoPalette(char theat)
{
HTSPALETTE isoPalette = m_hPalIsoTemp;
switch (theat) {
case 'T':
case 'G':
isoPalette = m_hPalIsoTemp;
break;
case 'A':
isoPalette = m_hPalIsoSnow;
break;
case 'U':
isoPalette = m_hPalIsoUrb;
break;
case 'N':
isoPalette = m_hPalIsoUbn;
break;
case 'D':
isoPalette = m_hPalIsoDes;
break;
case 'L':
isoPalette = m_hPalIsoLun;
break;
}
return isoPalette;
}
HTSPALETTE CLoading::GetUnitPalette(char theat)
{
HTSPALETTE isoPalette = m_hPalUnitTemp;
switch (theat) {
case 'T':
case 'G':
isoPalette = m_hPalUnitTemp;
break;
case 'A':
isoPalette = m_hPalUnitSnow;
break;
case 'U':
isoPalette = m_hPalUnitUrb;
break;
case 'N':
isoPalette = m_hPalUnitUbn;
break;
case 'D':
isoPalette = m_hPalUnitDes;
break;
case 'L':
isoPalette = m_hPalUnitLun;
break;
}
return isoPalette;
}
CString theatToSuffix(char theat)
{
if (theat == 'T') return ".tem";
@ -1126,20 +1072,20 @@ std::optional<FindShpResult> CLoading::FindUnitShp(const CString& image, char pr
const auto& unitPalettePrefixes = g_data["ForceUnitPalettePrefix"];
if (unitPalettePrefixes.end() != std::find_if(unitPalettePrefixes.begin(), unitPalettePrefixes.end(),
[&image](const auto& pair) {return image.Find(pair.second) == 0; })) {
forcedPalette = GetUnitPalette(preferred_theat);
forcedPalette = m_palettes.GetUnitPalette(preferred_theat);
}
const auto& isoPalettePrefixes = g_data["ForceIsoPalettePrefix"];
if (isoPalettePrefixes.end() != std::find_if(isoPalettePrefixes.begin(), isoPalettePrefixes.end(),
[&image](const auto& pair) {return image.Find(pair.second) == 0; })) {
forcedPalette = GetIsoPalette(preferred_theat);
forcedPalette = m_palettes.GetIsoPalette(preferred_theat);
}
const bool isTheater = artSection.GetBool("Theater");
const bool isNewTheater = artSection.GetBool("NewTheater");
const bool terrainPalette = artSection.GetBool("TerrainPalette");
auto unitOrIsoPalette = terrainPalette ? GetIsoPalette(preferred_theat) : GetUnitPalette(preferred_theat);
auto unitOrIsoPalette = terrainPalette ? m_palettes.GetIsoPalette(preferred_theat) : m_palettes.GetUnitPalette(preferred_theat);
HMIXFILE curMixFile = 0;
CString curFilename = image + ".shp";
@ -1154,7 +1100,7 @@ std::optional<FindShpResult> CLoading::FindUnitShp(const CString& image, char pr
curFilename.MakeLower();
curMixFile = FindFileInMix(curFilename, &curMixTheater);
if (curMixFile)
return FindShpResult(curMixFile, curMixTheater, curFilename, toTheaterChar(suffixToTheat(curSuffix)), forcedPalette ? forcedPalette : GetIsoPalette(suffixToTheat(curSuffix)));
return FindShpResult(curMixFile, curMixTheater, curFilename, toTheaterChar(suffixToTheat(curSuffix)), forcedPalette ? forcedPalette : m_palettes.GetIsoPalette(suffixToTheat(curSuffix)));
}
}
// Phase 1: if NewTheater is enabled and first character indicates support, try with real theater, then in order of kTheatersToTry
@ -1203,7 +1149,7 @@ std::optional<FindShpResult> CLoading::FindUnitShp(const CString& image, char pr
curFilename.MakeLower();
curMixFile = FindFileInMix(curFilename, &curMixTheater);
if (curMixFile)
return FindShpResult(curMixFile, curMixTheater, curFilename, toTheaterChar(suffixToTheat(curSuffix)), forcedPalette ? forcedPalette : GetIsoPalette(suffixToTheat(curSuffix)));
return FindShpResult(curMixFile, curMixTheater, curFilename, toTheaterChar(suffixToTheat(curSuffix)), forcedPalette ? forcedPalette : m_palettes.GetIsoPalette(suffixToTheat(curSuffix)));
}
// Phase 6: try with theater in 2nd char even if first char does not indicate support
curFilename = image + ".shp";
@ -1211,7 +1157,7 @@ std::optional<FindShpResult> CLoading::FindUnitShp(const CString& image, char pr
curFilename.SetAt(1, curTheater);
curMixFile = FindFileInMix(curFilename, &curMixTheater);
if (curMixFile)
return FindShpResult(curMixFile, curMixTheater, curFilename, toTheaterChar(curTheater), forcedPalette ? forcedPalette : GetIsoPalette(curTheater));
return FindShpResult(curMixFile, curMixTheater, curFilename, toTheaterChar(curTheater), forcedPalette ? forcedPalette : m_palettes.GetIsoPalette(curTheater));
}
return std::nullopt;
@ -2770,117 +2716,16 @@ HMIXFILE CLoading::FindFileInMix(LPCTSTR lpFilename, TheaterChar* pTheaterChar)
void CLoading::InitPalettes()
{
errstream << "InitPalettes() called\n";
if (!FSunPackLib::XCC_ExtractFile("isotem.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache))
errstream << "IsoTem.pal failed\n";
m_hPalIsoTemp = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("isosno.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache))
errstream << "IsoSno.pal failed\n";
m_hPalIsoSnow = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("isourb.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache))
errstream << "IsoUrb.pal failed\n";
m_hPalIsoUrb = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
HMIXFILE m_hCache2 = m_hExpand[100].hECache;
if (!FSunPackLib::XCC_ExtractFile("isolun.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache2))
errstream << "IsoLun.pal failed\n";
m_hPalIsoLun = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("isodes.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache2))
errstream << "IsoDes.pal failed\n";
m_hPalIsoDes = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("isoubn.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache2))
errstream << "IsoUbn.pal failed\n";
m_hPalIsoUbn = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("unittem.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache))
errstream << "UnitTem.pal failed";
m_hPalUnitTemp = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("unitsno.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache))
errstream << "UnitSno.pal failed\n";
m_hPalUnitSnow = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("uniturb.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache))
errstream << "UnitUrb.pal failed\n";
m_hPalUnitUrb = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("unitlun.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache2))
errstream << "UnitLun.pal failed\n";
m_hPalUnitLun = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("unitdes.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache2))
errstream << "UnitDes.pal failed\n";
m_hPalUnitDes = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("unitubn.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache2))
errstream << "UnitUbn.pal failed\n";
m_hPalUnitUbn = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("snow.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache))
errstream << "Snow.pal failed\n";
m_hPalSnow = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("temperat.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache))
errstream << "Temperat.pal failed\n";
m_hPalTemp = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("urban.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache))
errstream << "Urban.pal failed\n";
m_hPalUrb = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("lunar.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache2))
errstream << "lunar.pal failed\n";
m_hPalLun = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("desert.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache2))
errstream << "desert.pal failed\n";
m_hPalDes = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("urbann.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache2))
errstream << "urbann.pal failed\n";
m_hPalUbn = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("_ID2124019542", u8AppDataPath + "\\TmpPalette.pal", m_hCache))
errstream << "lib.pal failed\n";
m_hPalLib = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
m_palettes.Init();
errstream << "\n";
errstream.flush();
}
void CLoading::InitTMPs(CProgressCtrl* prog)
{
FetchPalettes();
m_palettes.FetchPalettes();
MEMORYSTATUS ms;
@ -2991,17 +2836,33 @@ void CLoading::InitTMPs(CProgressCtrl* prog)
if (tiles == &tiles_d) suffix = ".des";
filename += suffix;
HTSPALETTE hPalette = m_hPalIsoTemp;
if (tiles == &tiles_s) hPalette = m_hPalIsoSnow;
if (tiles == &tiles_u) hPalette = m_hPalIsoUrb;
if (tiles == &tiles_t) hPalette = m_hPalIsoTemp;
if (tiles == &tiles_un) hPalette = m_hPalIsoUbn;
if (tiles == &tiles_d) hPalette = m_hPalIsoDes;
if (tiles == &tiles_l) hPalette = m_hPalIsoLun;
HTSPALETTE hPalette = m_palettes.m_hPalIsoTemp;
if (tiles == &tiles_s) {
hPalette = m_palettes.m_hPalIsoSnow; }
if (tiles == &tiles_u) {
hPalette = m_palettes.m_hPalIsoUrb; }
if (tiles == &tiles_t) {
hPalette = m_palettes.m_hPalIsoTemp;
}
if (tiles == &tiles_un) {
hPalette = m_palettes.m_hPalIsoUbn;
}
if (tiles == &tiles_d) {
hPalette = m_palettes.m_hPalIsoDes;
}
if (tiles == &tiles_l) {
hPalette = m_palettes.m_hPalIsoLun;
}
// MW add: use other...
if (FindFileInMix(filename) == NULL && tiles == &tiles_un) { filename = bas_f + ".urb"; hPalette = m_hPalIsoUrb; }
if (FindFileInMix(filename) == NULL) { filename = bas_f + ".tem"; hPalette = m_hPalIsoTemp; }
if (FindFileInMix(filename) == NULL && tiles == &tiles_un) {
filename = bas_f + ".urb";
hPalette = m_palettes.m_hPalIsoUrb;
}
if (FindFileInMix(filename) == NULL) {
filename = bas_f + ".tem";
hPalette = m_palettes.m_hPalIsoTemp;
}
(*tiledata)[tilecount].bAllowTiberium = bTib;
(*tiledata)[tilecount].bAllowToPlace = bPlace;
@ -3304,7 +3165,6 @@ void CLoading::LoadOverlayGraphic(const CString& lpOvrlName_, int iOvrlNum)
last_succeeded_operation = 11;
CString image; // the image used
CString filename; // filename of the image
SHPHEADER head;
char theat = cur_theat;
BYTE** lpT = NULL;
@ -3312,41 +3172,41 @@ void CLoading::LoadOverlayGraphic(const CString& lpOvrlName_, int iOvrlNum)
char OvrlID[50];
itoa(iOvrlNum, OvrlID, 10);
HTSPALETTE hPalette = m_hPalIsoTemp;
HTSPALETTE hPalette = m_palettes.m_hPalIsoTemp;
if (cur_theat == 'T') {
hPalette = m_hPalIsoTemp;
hPalette = m_palettes.m_hPalIsoTemp;
#ifdef RA2_MODE
hPalette = m_hPalIsoTemp;
hPalette = m_palettes.m_hPalIsoTemp;
#endif
}
if (cur_theat == 'A') {
hPalette = m_hPalIsoSnow;
hPalette = m_palettes.m_hPalIsoSnow;
#ifdef RA2_MODE
hPalette = m_hPalIsoSnow;
hPalette = m_palettes.m_hPalIsoSnow;
#endif
}
if (cur_theat == 'U' && m_hPalIsoUrb) {
hPalette = m_hPalIsoUrb;
if (cur_theat == 'U' && m_palettes.m_hPalIsoUrb) {
hPalette = m_palettes.m_hPalIsoUrb;
#ifdef RA2_MODE
hPalette = m_hPalIsoUrb;
hPalette = m_palettes.m_hPalIsoUrb;
#endif
}
if (cur_theat == 'N' && m_hPalIsoUbn) {
hPalette = m_hPalIsoUbn;
if (cur_theat == 'N' && m_palettes.m_hPalIsoUbn) {
hPalette = m_palettes.m_hPalIsoUbn;
#ifdef RA2_MODE
hPalette = m_hPalIsoUbn;
hPalette = m_palettes.m_hPalIsoUbn;
#endif
}
if (cur_theat == 'L' && m_hPalIsoLun) {
hPalette = m_hPalIsoLun;
if (cur_theat == 'L' && m_palettes.m_hPalIsoLun) {
hPalette = m_palettes.m_hPalIsoLun;
#ifdef RA2_MODE
hPalette = m_hPalIsoLun;
hPalette = m_palettes.m_hPalIsoLun;
#endif
}
if (cur_theat == 'D' && m_hPalIsoDes) {
hPalette = m_hPalIsoDes;
if (cur_theat == 'D' && m_palettes.m_hPalIsoDes) {
hPalette = m_palettes.m_hPalIsoDes;
#ifdef RA2_MODE
hPalette = m_hPalIsoDes;
hPalette = m_palettes.m_hPalIsoDes;
#endif
}
@ -3355,10 +3215,10 @@ void CLoading::LoadOverlayGraphic(const CString& lpOvrlName_, int iOvrlNum)
const auto& unitPalettePrefixes = g_data["ForceOvrlUnitPalettePrefix"];
const CString sOvrlName(lpOvrlName_);
if (unitPalettePrefixes.end() != std::find_if(unitPalettePrefixes.begin(), unitPalettePrefixes.end(), [&sOvrlName](const auto& pair) {return sOvrlName.Find(pair.second) == 0; })) {
forcedPalette = GetUnitPalette(cur_theat);
forcedPalette = m_palettes.GetUnitPalette(cur_theat);
}
if (isoPalettePrefixes.end() != std::find_if(isoPalettePrefixes.begin(), isoPalettePrefixes.end(), [&sOvrlName](const auto& pair) {return sOvrlName.Find(pair.second) == 0; })) {
forcedPalette = GetIsoPalette(cur_theat);
forcedPalette = m_palettes.GetIsoPalette(cur_theat);
}
HMIXFILE hMix;
@ -3386,20 +3246,7 @@ void CLoading::LoadOverlayGraphic(const CString& lpOvrlName_, int iOvrlNum)
TruncSpace(image);
if (cur_theat == 'T') {
filename = image + ".tem";
} else if (cur_theat == 'A') {
filename = image + ".sno";
} else if (cur_theat == 'U') {
filename = image + ".urb";
} else if (cur_theat == 'N') {
filename = image + ".ubn";
} else if (cur_theat == 'L') {
filename = image + ".lun";
} else if (cur_theat == 'D') {
filename = image + ".des";
}
CString filename = image + theatToSuffix(cur_theat);
hMix = FindFileInMix(filename);
@ -3411,12 +3258,24 @@ void CLoading::LoadOverlayGraphic(const CString& lpOvrlName_, int iOvrlNum)
filename.SetAt(1, theat);
}
if (cur_theat == 'U' && m_hPalUnitUrb) hPalette = m_hPalUnitUrb;
if (cur_theat == 'T') hPalette = m_hPalUnitTemp;
if (cur_theat == 'A') hPalette = m_hPalUnitSnow;
if (cur_theat == 'N') hPalette = m_hPalUnitUbn;
if (cur_theat == 'L') hPalette = m_hPalUnitLun;
if (cur_theat == 'D') hPalette = m_hPalUnitDes;
if (cur_theat == 'U' && m_palettes.m_hPalUnitUrb) {
hPalette = m_palettes.m_hPalUnitUrb;
}
if (cur_theat == 'T') {
hPalette = m_palettes.m_hPalUnitTemp;
}
if (cur_theat == 'A') {
hPalette = m_palettes.m_hPalUnitSnow;
}
if (cur_theat == 'N') {
hPalette = m_palettes.m_hPalUnitUbn;
}
if (cur_theat == 'L') {
hPalette = m_palettes.m_hPalUnitLun;
}
if (cur_theat == 'D') {
hPalette = m_palettes.m_hPalUnitDes;
}
hMix = FindFileInMix(filename);
@ -3449,47 +3308,59 @@ void CLoading::LoadOverlayGraphic(const CString& lpOvrlName_, int iOvrlNum)
}
if (cur_theat == 'T' || cur_theat == 'U') {
hPalette = m_hPalUnitTemp;
hPalette = m_palettes.m_hPalUnitTemp;
} else
hPalette = m_hPalUnitSnow;
hPalette = m_palettes.m_hPalUnitSnow;
}
if (hMix == NULL) {
filename = image + ".tem";
hMix = FindFileInMix(filename);
if (hMix) hPalette = m_hPalIsoTemp;
if (hMix) {
hPalette = m_palettes.m_hPalIsoTemp;
}
}
if (hMix == NULL) {
filename = image + ".sno";
hMix = FindFileInMix(filename);
if (hMix) hPalette = m_hPalIsoSnow;
if (hMix) {
hPalette = m_palettes.m_hPalIsoSnow;
}
}
if (hMix == NULL) {
filename = image + ".urb";
hMix = FindFileInMix(filename);
if (hMix && m_hPalIsoUrb) hPalette = m_hPalIsoUrb;
if (hMix && m_palettes.m_hPalIsoUrb) {
hPalette = m_palettes.m_hPalIsoUrb;
}
}
if (hMix == NULL) {
filename = image + ".ubn";
hMix = FindFileInMix(filename);
if (hMix && m_hPalIsoUbn) hPalette = m_hPalIsoUbn;
if (hMix && m_palettes.m_hPalIsoUbn) {
hPalette = m_palettes.m_hPalIsoUbn;
}
}
if (hMix == NULL) {
filename = image + ".lun";
hMix = FindFileInMix(filename);
if (hMix && m_hPalIsoLun) hPalette = m_hPalIsoLun;
if (hMix && m_palettes.m_hPalIsoLun) {
hPalette = m_palettes.m_hPalIsoLun;
}
}
if (hMix == NULL) {
filename = image + ".des";
hMix = FindFileInMix(filename);
if (hMix && m_hPalIsoDes) hPalette = m_hPalIsoDes;
if (hMix && m_palettes.m_hPalIsoDes) {
hPalette = m_palettes.m_hPalIsoDes;
}
}
if (isveinhole == TRUE || isveins == TRUE || istiberium == TRUE) {
hPalette = m_hPalTemp;
hPalette = m_palettes.m_hPalTemp;
#ifndef RA2_MODE
hPalette = m_hPalUnitTemp;
hPalette = m_palettes.m_hPalUnitTemp;
#endif
}
@ -3582,9 +3453,30 @@ void CLoading::LoadOverlayGraphic(const CString& lpOvrlName_, int iOvrlNum)
PICDATA p;
p.pic = lpT[i];
if (hPalette == m_hPalIsoTemp || hPalette == m_hPalIsoUrb || hPalette == m_hPalIsoSnow || hPalette == m_hPalIsoDes || hPalette == m_hPalIsoLun || hPalette == m_hPalIsoUbn) p.pal = iPalIso;
if (hPalette == m_hPalTemp || hPalette == m_hPalUrb || hPalette == m_hPalSnow || hPalette == m_hPalDes || hPalette == m_hPalLun || hPalette == m_hPalUbn) p.pal = iPalTheater;
if (hPalette == m_hPalUnitTemp || hPalette == m_hPalUnitUrb || hPalette == m_hPalUnitSnow || hPalette == m_hPalUnitDes || hPalette == m_hPalUnitLun || hPalette == m_hPalUnitUbn) p.pal = iPalUnit;
if (hPalette == m_palettes.m_hPalIsoTemp
|| hPalette == m_palettes.m_hPalIsoUrb
|| hPalette == m_palettes.m_hPalIsoSnow
|| hPalette == m_palettes.m_hPalIsoDes
|| hPalette == m_palettes.m_hPalIsoLun
|| hPalette == m_palettes.m_hPalIsoUbn) {
p.pal = iPalIso;
}
if (hPalette == m_palettes.m_hPalTemp
|| hPalette == m_palettes.m_hPalUrb
|| hPalette == m_palettes.m_hPalSnow
|| hPalette == m_palettes.m_hPalDes
|| hPalette == m_palettes.m_hPalLun
|| hPalette == m_palettes.m_hPalUbn) {
p.pal = iPalTheater;
}
if (hPalette == m_palettes.m_hPalUnitTemp
|| hPalette == m_palettes.m_hPalUnitUrb
|| hPalette == m_palettes.m_hPalUnitSnow
|| hPalette == m_palettes.m_hPalUnitDes
|| hPalette == m_palettes.m_hPalUnitLun
|| hPalette == m_palettes.m_hPalUnitUbn) {
p.pal = iPalUnit;
}
p.vborder = new(VBORDER[head.cy]);
int k;
@ -3624,257 +3516,6 @@ void CLoading::LoadOverlayGraphic(const CString& lpOvrlName_, int iOvrlNum)
}
}
#else // surfaces
void CLoading::LoadOverlayGraphic(LPCTSTR lpOvrlName_, int iOvrlNum)
{
last_succeeded_operation = 11;
CString image; // the image used
CString filename; // filename of the image
SHPHEADER head;
char theat = cur_theat;
LPDIRECTDRAWSURFACE4* lpT = NULL;
char OvrlID[50];
itoa(iOvrlNum, OvrlID, 10);
HTSPALETTE hPalette;
if (cur_theat == 'T') {
hPalette = m_hPalIsoTemp;
#ifdef RA2_MODE
hPalette = m_hPalIsoTemp;
#endif
}
if (cur_theat == 'A') {
hPalette = m_hPalIsoSnow;
#ifdef RA2_MODE
hPalette = m_hPalIsoSnow;
#endif
}
if (cur_theat == 'U' && m_hPalIsoUrb) {
hPalette = m_hPalIsoUrb;
#ifdef RA2_MODE
hPalette = m_hPalIsoUrb;
#endif
}
HMIXFILE hMix;
CIsoView& v = *((CFinalSunDlg*)theApp.m_pMainWnd)->m_view.m_isoview;
CString lpOvrlName = lpOvrlName_;
if (lpOvrlName.Find(' ') >= 0) lpOvrlName = lpOvrlName.Left(lpOvrlName.Find(' '));
CString isveinhole_t = rules.sections[lpOvrlName].values["IsVeinholeMonster"];
CString istiberium_t = rules.sections[lpOvrlName].values["Tiberium"];
CString isveins_t = rules.sections[lpOvrlName].values["IsVeins"];
isveinhole_t.MakeLower();
istiberium_t.MakeLower();
isveins_t.MakeLower();
BOOL isveinhole = FALSE, istiberium = FALSE, isveins = FALSE;
if (isTrue(isveinhole_t)) isveinhole = TRUE;
if (isTrue(istiberium_t)) istiberium = TRUE;
if (isTrue(isveins_t)) isveins = TRUE;
image = lpOvrlName;
if (rules.sections[lpOvrlName].values.find("Image") != rules.sections[lpOvrlName].values.end())
image = rules.sections[lpOvrlName].values["Image"];
TruncSpace(image);
CString imagerules = image;
if (art.sections[image].values.find("Image") != art.sections[image].values.end())
image = art.sections[image].values["Image"];
TruncSpace(image);
if (cur_theat == 'T') filename = image + ".tem";
if (cur_theat == 'A') filename = image + ".sno";
if (cur_theat == 'U') filename = image + ".urb";
hMix = FindFileInMix(filename);
if (hMix == NULL) {
filename = image + ".shp";
if (isTrue(art.sections[image].values["NewTheater"]))
filename.SetAt(1, theat);
if (cur_theat == 'U' && m_hPalUnitUrb) hPalette = m_hPalUnitUrb;
if (cur_theat == 'T') hPalette = m_hPalUnitTemp;
if (cur_theat == 'A') hPalette = m_hPalUnitSnow;
hMix = FindFileInMix(filename);
// errstream << (LPCSTR)filename << " " << hMix;
if (hMix == NULL) {
filename.SetAt(1, 'T');
hMix = FindFileInMix(filename);
}
if (hMix == NULL) {
filename.SetAt(1, 'A');
hMix = FindFileInMix(filename);
}
if (hMix == NULL) {
filename.SetAt(1, 'U');
hMix = FindFileInMix(filename);
}
if (cur_theat == 'T' || cur_theat == 'U') {
hPalette = m_hPalUnitTemp;
} else
hPalette = m_hPalUnitSnow;
}
if (hMix == NULL) {
filename = image + ".tem";
hMix = FindFileInMix(filename);
if (hMix) hPalette = m_hPalIsoTemp;
}
if (hMix == NULL) {
filename = image + ".sno";
hMix = FindFileInMix(filename);
if (hMix) hPalette = m_hPalIsoSnow;
}
if (hMix == NULL) {
filename = image + ".urb";
hMix = FindFileInMix(filename);
if (hMix && m_hPalIsoUrb) hPalette = m_hPalIsoUrb;
}
if (isveinhole == TRUE || isveins == TRUE || istiberium == TRUE) {
hPalette = m_hPalTemp;
#ifndef RA2_MODE
hPalette = m_hPalUnitTemp;
#endif
}
if (hMix != NULL) {
FSunPackLib::SetCurrentSHP(filename, hMix);
{
FSunPackLib::XCC_GetSHPHeader(&head);
int i;
int maxPics = head.c_images;
if (maxPics > max_ovrl_img) maxPics = max_ovrl_img; // max may_ovrl_img pictures (memory usage!)
//errstream << ", loading " << maxPics << " of " << head.c_images << " pictures. ";
//errstream.flush();
// create an array of pointers to directdraw surfaces
lpT = new(LPDIRECTDRAWSURFACE4[maxPics]);
memset(lpT, 0, sizeof(LPDIRECTDRAWSURFACE4) * maxPics);
// if tiberium, change color
BOOL bIsBlueTib = FALSE;
BOOL bIsGreenTib = FALSE;
RGBTRIPLE rgbOld[16], rgbNew;
#ifndef RA2_MODE
if (istiberium) {
if (lpOvrlName[4] == '_') // other than green!
bIsBlueTib = TRUE;
else
bIsGreenTib = TRUE;
int i;
for (i = 0; i < 16; i++) {
if (bIsGreenTib) {
rgbNew.rgbtBlue = 0;
if (i != 0)
rgbNew.rgbtGreen = 255 - i * 16 + 1;
else
rgbNew.rgbtGreen = 255;
rgbNew.rgbtRed = 0;
} else if (bIsBlueTib) {
if (i != 0)
rgbNew.rgbtBlue = 255 - i * 16 + 1;
else
rgbNew.rgbtBlue = 255;
rgbNew.rgbtGreen = 0;
rgbNew.rgbtRed = 0;
}
FSunPackLib::SetTSPaletteEntry(hPalette, 0x10 + i, &rgbNew, &rgbOld[i]);
}
}
#endif
FSunPackLib::LoadSHPImageInSurface(v.dd, hPalette, 0, maxPics, lpT);
#ifndef RA2_MODE
if (istiberium)
for (i = 0; i < 16; i++)
FSunPackLib::SetTSPaletteEntry(hPalette, 0x10 + i, &rgbOld[i], NULL);
#endif
for (i = 0; i < maxPics; i++) {
SHPIMAGEHEADER imghead;
FSunPackLib::XCC_GetSHPImageHeader(i, &imghead);
if (imghead.unknown == 0) // is it a shadow or not used image?
if (lpT[i]) lpT[i]->Release();
if (imghead.unknown && lpT[i]) {
char ic[50];
itoa(i, ic, 10);
PICDATA p;
p.pic = lpT[i];
p.x = imghead.x;
p.y = imghead.y;
p.wHeight = imghead.cy;
p.wWidth = imghead.cx;
p.wMaxWidth = head.cx;
p.wMaxHeight = head.cy;
p.bType = PICDATA_TYPE_SHP;
pics[(CString)"OVRL" + OvrlID + "_" + ic] = p;
}
}
delete[] lpT;
//errstream << " --> Finished" << endl;
//errstream.flush();
}
/*else
{
errstream << " failed";
errstream.flush();
}*/
}
else {
//errstream << "File not found: " << (LPCTSTR)filename << endl;
//errstream.flush();
}
int i;
for (i = 0; i < 0xFF; i++) {
char ic[50];
itoa(i, ic, 10);
pics[(CString)"OVRL" + OvrlID + "_" + ic].bTried = TRUE;
}
}
#endif
@ -4727,12 +4368,12 @@ void CLoading::PrepareUnitGraphic(LPCSTR lpUnittype)
auto const bPowerUp = !rules.GetString(lpUnittype, "PowersUpBuilding").IsEmpty();
HTSPALETTE hPalette;
if (theat == 'T') hPalette = m_hPalIsoTemp;
if (theat == 'A') hPalette = m_hPalIsoSnow;
if (theat == 'U') hPalette = m_hPalIsoUrb;
if (theat == 'L') hPalette = m_hPalIsoLun;
if (theat == 'D') hPalette = m_hPalIsoDes;
if (theat == 'N') hPalette = m_hPalIsoUbn;
if (theat == 'T') hPalette = m_palettes.m_hPalIsoTemp;
if (theat == 'A') hPalette = m_palettes.m_hPalIsoSnow;
if (theat == 'U') hPalette = m_palettes.m_hPalIsoUrb;
if (theat == 'L') hPalette = m_palettes.m_hPalIsoLun;
if (theat == 'D') hPalette = m_palettes.m_hPalIsoDes;
if (theat == 'N') hPalette = m_palettes.m_hPalIsoUbn;
CIsoView& v = *((CFinalSunDlg*)theApp.m_pMainWnd)->m_view.m_isoview;
@ -4978,7 +4619,7 @@ void CLoading::PrepareUnitGraphic(LPCSTR lpUnittype)
auto limited_to_theater = artSection.GetBool("TerrainPalette") ? shp->mixfile_theater : TheaterChar::None;
if (filename == "tibtre01.tem" || filename == "tibtre02.tem" || filename == "tibtre03.tem" || filename == "veinhole.tem") {
hPalette = m_hPalUnitTemp;
hPalette = m_palettes.m_hPalUnitTemp;
}
if (shp->mixfile > 0) {
@ -4986,7 +4627,7 @@ void CLoading::PrepareUnitGraphic(LPCSTR lpUnittype)
BOOL bSuccess = FSunPackLib::SetCurrentSHP(filename, shp->mixfile);
if (!bSuccess) {
filename = image + ".sno";
if (cur_theat == 'T' || cur_theat == 'U') hPalette = m_hPalIsoTemp;
if (cur_theat == 'T' || cur_theat == 'U') hPalette = m_palettes.m_hPalIsoTemp;
HMIXFILE hShpMix = FindFileInMix(filename);
bSuccess = FSunPackLib::SetCurrentSHP(filename, hShpMix);
@ -5030,112 +4671,4 @@ void CLoading::PrepareUnitGraphic(LPCSTR lpUnittype)
}
}
/*
Helper function that fetches the palette data from FsunPackLib
FSunPackLib doesn´t provide any special function to retrieve a color table entry,
so we have to build it ourself
Also builds color_conv
*/
void CLoading::FetchPalettes()
{
// SetTSPaletteEntry(HTSPALETTE hPalette, BYTE bIndex, RGBTRIPLE* rgb, RGBTRIPLE* orig);
// SetTSPaletteEntry can retrieve the current color table entry without modifying it!
// iso palette
HTSPALETTE hCur = 0;
if (Map->GetTheater() == THEATER0) hCur = m_hPalIsoTemp;
if (Map->GetTheater() == THEATER1) hCur = m_hPalIsoSnow;
if (Map->GetTheater() == THEATER2) hCur = m_hPalIsoUrb;
if (Map->GetTheater() == THEATER3) hCur = m_hPalIsoUbn;
if (Map->GetTheater() == THEATER4) hCur = m_hPalIsoLun;
if (Map->GetTheater() == THEATER5) hCur = m_hPalIsoDes;
int i;
for (i = 0; i < 256; i++) {
FSunPackLib::SetTSPaletteEntry(hCur, i, NULL /* don´t modify it!*/, &palIso[i] /*but retrieve it!*/);
}
// unit palette
if (Map->GetTheater() == THEATER0) hCur = m_hPalUnitTemp;
if (Map->GetTheater() == THEATER1) hCur = m_hPalUnitSnow;
if (Map->GetTheater() == THEATER2) hCur = m_hPalUnitUrb;
if (Map->GetTheater() == THEATER3) hCur = m_hPalUnitUbn;
if (Map->GetTheater() == THEATER4) hCur = m_hPalUnitLun;
if (Map->GetTheater() == THEATER5) hCur = m_hPalUnitDes;
for (i = 0; i < 256; i++) {
FSunPackLib::SetTSPaletteEntry(hCur, i, NULL /* don´t modify it!*/, &palUnit[i] /*but retrieve it!*/);
}
// theater palette
if (Map->GetTheater() == THEATER0) hCur = m_hPalTemp;
if (Map->GetTheater() == THEATER1) hCur = m_hPalSnow;
if (Map->GetTheater() == THEATER2) hCur = m_hPalUrb;
if (Map->GetTheater() == THEATER3) hCur = m_hPalUbn;
if (Map->GetTheater() == THEATER4) hCur = m_hPalLun;
if (Map->GetTheater() == THEATER5) hCur = m_hPalDes;
for (i = 0; i < 256; i++) {
FSunPackLib::SetTSPaletteEntry(hCur, i, NULL /* don´t modify it!*/, &palTheater[i] /*but retrieve it!*/);
}
// lib palette
hCur = m_hPalLib;
for (i = 0; i < 256; i++) {
FSunPackLib::SetTSPaletteEntry(hCur, i, NULL /* don´t modify it!*/, &palLib[i] /*but retrieve it!*/);
}
CreateConvTable(palIso, iPalIso);
CreateConvTable(palLib, iPalLib);
CreateConvTable(palUnit, iPalUnit);
CreateConvTable(palTheater, iPalTheater);
CIsoView& v = *((CFinalSunDlg*)theApp.m_pMainWnd)->m_view.m_isoview;
DDPIXELFORMAT pf;
memset(&pf, 0, sizeof(DDPIXELFORMAT));
pf.dwSize = sizeof(DDPIXELFORMAT);
v.lpds->GetPixelFormat(&pf);
v.pf = pf;
v.m_color_converter.reset(new FSunPackLib::ColorConverter(v.pf));
FSunPackLib::ColorConverter conf(pf);
for (auto const& [name, col] : rules["Colors"]) {
COLORREF cref = v.GetColor("", col);
color_conv[col] = conf.GetColor(GetRValue(cref), GetGValue(cref), GetBValue(cref));
colorref_conv[cref] = color_conv[col];
}
}
void CLoading::CreateConvTable(RGBTRIPLE* pal, int* iPal)
{
CIsoView& v = *((CFinalSunDlg*)theApp.m_pMainWnd)->m_view.m_isoview;
DDPIXELFORMAT pf;
memset(&pf, 0, sizeof(DDPIXELFORMAT));
pf.dwSize = sizeof(DDPIXELFORMAT);
v.lpds->GetPixelFormat(&pf);
FSunPackLib::ColorConverter conf(pf);
int i;
for (i = 0; i < 256; i++) {
iPal[i] = conf.GetColor(pal[i].rgbtRed, pal[i].rgbtGreen, pal[i].rgbtBlue);
}
}
}

View file

@ -23,6 +23,7 @@
#include "FinalSunDlg.h"
#include "MissionEditorPackLib.h"
#include "Palettes.h"
#include <memory>
#include <optional>
@ -90,8 +91,6 @@ class CLoading : public CDialog
{
// Construction
public:
void CreateConvTable(RGBTRIPLE* pal, int* iPal);
void FetchPalettes();
void PrepareUnitGraphic(LPCSTR lpUnittype);
void LoadStrings();
void FreeAll();
@ -114,11 +113,17 @@ public:
void LoadBuildingSubGraphic(const CString& subkey, const CIniFileSection& artSection, BOOL bAlwaysSetChar, char theat, HMIXFILE hShpMix, SHPHEADER& shp_h, BYTE*& shp);
void LoadOverlayGraphic(const CString& lpOvrlName, int iOvrlNum);
void InitVoxelNormalTables();
HTSPALETTE GetIsoPalette(char theat);
HTSPALETTE GetUnitPalette(char theat);
std::optional<FindShpResult> FindUnitShp(const CString& image, char preferred_theat, const CIniFileSection& artSection);
char cur_theat;
HMIXFILE FindFileInMix(LPCTSTR lpFilename, TheaterChar* pTheaterChar = NULL);
const HMIXFILE CacheMix() const {
return m_hCache;
}
const EXPANDMIX* ExpandMixes() const {
return m_hExpand;
}
// Dialog data
//{{AFX_DATA(CLoading)
@ -156,29 +161,9 @@ private:
int m_pic_count;
int m_bmp_count;
BOOL LoadTile(LPCSTR lpFilename, HMIXFILE hOwner, HTSPALETTE hPalette, DWORD dwID, BOOL bReplacement);
HTSPALETTE m_hPalIsoTemp;
HTSPALETTE m_hPalIsoSnow;
HTSPALETTE m_hPalIsoUrb;
HTSPALETTE m_hPalUnitTemp;
HTSPALETTE m_hPalUnitSnow;
HTSPALETTE m_hPalUnitUrb;
HTSPALETTE m_hPalTemp;
HTSPALETTE m_hPalSnow;
HTSPALETTE m_hPalUrb;
HTSPALETTE m_hPalLib;
// YR pals:
HTSPALETTE m_hPalLun;
HTSPALETTE m_hPalDes;
HTSPALETTE m_hPalUbn;
HTSPALETTE m_hPalIsoLun;
HTSPALETTE m_hPalIsoDes;
HTSPALETTE m_hPalIsoUbn;
HTSPALETTE m_hPalUnitLun;
HTSPALETTE m_hPalUnitDes;
HTSPALETTE m_hPalUnitUbn;
Palettes m_palettes;
HMIXFILE FindFileInMix(LPCTSTR lpFilename, TheaterChar* pTheaterChar = NULL);
HMIXFILE m_hLocal;
HMIXFILE m_hSno;
HMIXFILE m_hTem;

349
MissionEditor/Palettes.cpp Normal file
View file

@ -0,0 +1,349 @@
#include "Palettes.h"
#include "variables.h"
#include "functions.h"
void Palettes::Init()
{
if (!FSunPackLib::XCC_ExtractFile("isotem.pal", u8AppDataPath + "\\TmpPalette.pal", loading.CacheMix()))
errstream << "IsoTem.pal failed\n";
m_hPalIsoTemp = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("isosno.pal", u8AppDataPath + "\\TmpPalette.pal", loading.CacheMix()))
errstream << "IsoSno.pal failed\n";
m_hPalIsoSnow = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("isourb.pal", u8AppDataPath + "\\TmpPalette.pal", loading.CacheMix()))
errstream << "IsoUrb.pal failed\n";
m_hPalIsoUrb = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
HMIXFILE m_hCache2 = loading.ExpandMixes()[100].hECache;
if (!FSunPackLib::XCC_ExtractFile("isolun.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache2))
errstream << "IsoLun.pal failed\n";
m_hPalIsoLun = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("isodes.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache2))
errstream << "IsoDes.pal failed\n";
m_hPalIsoDes = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("isoubn.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache2))
errstream << "IsoUbn.pal failed\n";
m_hPalIsoUbn = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("unittem.pal", u8AppDataPath + "\\TmpPalette.pal", loading.CacheMix()))
errstream << "UnitTem.pal failed";
m_hPalUnitTemp = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("unitsno.pal", u8AppDataPath + "\\TmpPalette.pal", loading.CacheMix()))
errstream << "UnitSno.pal failed\n";
m_hPalUnitSnow = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("uniturb.pal", u8AppDataPath + "\\TmpPalette.pal", loading.CacheMix()))
errstream << "UnitUrb.pal failed\n";
m_hPalUnitUrb = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("unitlun.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache2))
errstream << "UnitLun.pal failed\n";
m_hPalUnitLun = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("unitdes.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache2))
errstream << "UnitDes.pal failed\n";
m_hPalUnitDes = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("unitubn.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache2))
errstream << "UnitUbn.pal failed\n";
m_hPalUnitUbn = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("snow.pal", u8AppDataPath + "\\TmpPalette.pal", loading.CacheMix()))
errstream << "Snow.pal failed\n";
m_hPalSnow = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("temperat.pal", u8AppDataPath + "\\TmpPalette.pal", loading.CacheMix()))
errstream << "Temperat.pal failed\n";
m_hPalTemp = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("urban.pal", u8AppDataPath + "\\TmpPalette.pal", loading.CacheMix()))
errstream << "Urban.pal failed\n";
m_hPalUrb = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("lunar.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache2))
errstream << "lunar.pal failed\n";
m_hPalLun = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("desert.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache2))
errstream << "desert.pal failed\n";
m_hPalDes = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("urbann.pal", u8AppDataPath + "\\TmpPalette.pal", m_hCache2))
errstream << "urbann.pal failed\n";
m_hPalUbn = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
if (!FSunPackLib::XCC_ExtractFile("_ID2124019542", u8AppDataPath + "\\TmpPalette.pal", loading.CacheMix()))
errstream << "lib.pal failed\n";
m_hPalLib = FSunPackLib::LoadTSPalette(u8AppDataPath + "\\TmpPalette.pal", NULL);
deleteFile(u8AppDataPath + "\\TmpPalette.pal");
LoadedPalettes["isotem.pal"] = new Palette(m_hPalIsoTemp);
LoadedPalettes["isosno.pal"] = new Palette(m_hPalIsoSnow);
LoadedPalettes["isourb.pal"] = new Palette(m_hPalIsoUrb);
LoadedPalettes["isoubn.pal"] = new Palette(m_hPalIsoUbn);
LoadedPalettes["isolun.pal"] = new Palette(m_hPalIsoLun);
LoadedPalettes["isodes.pal"] = new Palette(m_hPalIsoDes);
LoadedPalettes["unittem.pal"] = new Palette(m_hPalUnitTemp);
LoadedPalettes["unitsno.pal"] = new Palette(m_hPalUnitSnow);
LoadedPalettes["uniturb.pal"] = new Palette(m_hPalUnitUrb);
LoadedPalettes["unitubn.pal"] = new Palette(m_hPalUnitUbn);
LoadedPalettes["unitlun.pal"] = new Palette(m_hPalUnitLun);
LoadedPalettes["unitdes.pal"] = new Palette(m_hPalUnitDes);
LoadedPalettes["temperat.pal"] = new Palette(m_hPalTemp);
LoadedPalettes["snow.pal"] = new Palette(m_hPalSnow);
LoadedPalettes["urban.pal"] = new Palette(m_hPalUrb);
LoadedPalettes["urbann.pal"] = new Palette(m_hPalUbn);
LoadedPalettes["lunar.pal"] = new Palette(m_hPalLun);
LoadedPalettes["desert.pal"] = new Palette(m_hPalDes);
LoadedPalettes["lib.pal"] = new Palette(m_hPalLib);
}
HTSPALETTE Palettes::GetIsoPalette(char theat)
{
HTSPALETTE isoPalette = m_hPalIsoTemp;
switch (theat) {
case 'T':
case 'G':
isoPalette = m_hPalIsoTemp;
break;
case 'A':
isoPalette = m_hPalIsoSnow;
break;
case 'U':
isoPalette = m_hPalIsoUrb;
break;
case 'N':
isoPalette = m_hPalIsoUbn;
break;
case 'D':
isoPalette = m_hPalIsoDes;
break;
case 'L':
isoPalette = m_hPalIsoLun;
break;
}
return isoPalette;
}
HTSPALETTE Palettes::GetUnitPalette(char theat)
{
HTSPALETTE isoPalette = m_hPalUnitTemp;
switch (theat) {
case 'T':
case 'G':
isoPalette = m_hPalUnitTemp;
break;
case 'A':
isoPalette = m_hPalUnitSnow;
break;
case 'U':
isoPalette = m_hPalUnitUrb;
break;
case 'N':
isoPalette = m_hPalUnitUbn;
break;
case 'D':
isoPalette = m_hPalUnitDes;
break;
case 'L':
isoPalette = m_hPalUnitLun;
break;
}
return isoPalette;
}
/*
Helper function that fetches the palette data from FsunPackLib
FSunPackLib doesn´t provide any special function to retrieve a color table entry,
so we have to build it ourself
Also builds color_conv
*/
void Palettes::FetchPalettes()
{
// SetTSPaletteEntry(HTSPALETTE hPalette, BYTE bIndex, RGBTRIPLE* rgb, RGBTRIPLE* orig);
// SetTSPaletteEntry can retrieve the current color table entry without modifying it!
// iso palette
HTSPALETTE hCur = 0;
if (Map->GetTheater() == THEATER0) hCur = m_hPalIsoTemp;
if (Map->GetTheater() == THEATER1) hCur = m_hPalIsoSnow;
if (Map->GetTheater() == THEATER2) hCur = m_hPalIsoUrb;
if (Map->GetTheater() == THEATER3) hCur = m_hPalIsoUbn;
if (Map->GetTheater() == THEATER4) hCur = m_hPalIsoLun;
if (Map->GetTheater() == THEATER5) hCur = m_hPalIsoDes;
int i;
for (i = 0; i < 256; i++) {
FSunPackLib::SetTSPaletteEntry(hCur, i, NULL /* don´t modify it!*/, &palIso[i] /*but retrieve it!*/);
}
// unit palette
if (Map->GetTheater() == THEATER0) hCur = m_hPalUnitTemp;
if (Map->GetTheater() == THEATER1) hCur = m_hPalUnitSnow;
if (Map->GetTheater() == THEATER2) hCur = m_hPalUnitUrb;
if (Map->GetTheater() == THEATER3) hCur = m_hPalUnitUbn;
if (Map->GetTheater() == THEATER4) hCur = m_hPalUnitLun;
if (Map->GetTheater() == THEATER5) hCur = m_hPalUnitDes;
for (i = 0; i < 256; i++) {
FSunPackLib::SetTSPaletteEntry(hCur, i, NULL /* don´t modify it!*/, &palUnit[i] /*but retrieve it!*/);
}
// theater palette
if (Map->GetTheater() == THEATER0) hCur = m_hPalTemp;
if (Map->GetTheater() == THEATER1) hCur = m_hPalSnow;
if (Map->GetTheater() == THEATER2) hCur = m_hPalUrb;
if (Map->GetTheater() == THEATER3) hCur = m_hPalUbn;
if (Map->GetTheater() == THEATER4) hCur = m_hPalLun;
if (Map->GetTheater() == THEATER5) hCur = m_hPalDes;
for (i = 0; i < 256; i++) {
FSunPackLib::SetTSPaletteEntry(hCur, i, NULL /* don´t modify it!*/, &palTheater[i] /*but retrieve it!*/);
}
// lib palette
hCur = m_hPalLib;
for (i = 0; i < 256; i++) {
FSunPackLib::SetTSPaletteEntry(hCur, i, NULL /* don´t modify it!*/, &palLib[i] /*but retrieve it!*/);
}
CreateConvTable(palIso, iPalIso);
CreateConvTable(palLib, iPalLib);
CreateConvTable(palUnit, iPalUnit);
CreateConvTable(palTheater, iPalTheater);
CIsoView& v = *((CFinalSunDlg*)theApp.m_pMainWnd)->m_view.m_isoview;
DDPIXELFORMAT pf;
memset(&pf, 0, sizeof(DDPIXELFORMAT));
pf.dwSize = sizeof(DDPIXELFORMAT);
v.lpds->GetPixelFormat(&pf);
v.pf = pf;
v.m_color_converter.reset(new FSunPackLib::ColorConverter(v.pf));
FSunPackLib::ColorConverter conf(pf);
for (auto const& [name, col] : rules["Colors"]) {
COLORREF cref = v.GetColor("", col);
color_conv[col] = conf.GetColor(GetRValue(cref), GetGValue(cref), GetBValue(cref));
colorref_conv[cref] = color_conv[col];
}
}
void Palettes::CreateConvTable(RGBTRIPLE* pal, int* iPal)
{
CIsoView& v = *((CFinalSunDlg*)theApp.m_pMainWnd)->m_view.m_isoview;
DDPIXELFORMAT pf;
memset(&pf, 0, sizeof(DDPIXELFORMAT));
pf.dwSize = sizeof(DDPIXELFORMAT);
v.lpds->GetPixelFormat(&pf);
FSunPackLib::ColorConverter conf(pf);
int i;
for (i = 0; i < 256; i++) {
iPal[i] = conf.GetColor(pal[i].rgbtRed, pal[i].rgbtGreen, pal[i].rgbtBlue);
}
}
Palette* Palettes::LoadPalette(const CString& palName)
{
if (LoadedPalettes.size() == 0) {
Palettes::Init();
}
auto it = LoadedPalettes.find(palName);
if (it != LoadedPalettes.end()) {
return it->second;
}
BytePalette buffer;
HMIXFILE mixIdx = loading.FindFileInMix(palName);
if (FSunPackLib::LoadTSPalette(reinterpret_cast<RGBTRIPLE*>(buffer.Data), palName, mixIdx)) {
auto pal = new Palette(buffer);
LoadedPalettes[palName] = pal;
return pal;
}
return nullptr;
}
void Palettes::Clear()
{
for (auto& pair : LoadedPalettes) {
delete(pair.second);
}
LoadedPalettes.clear();
RemappedPalettes.clear();
Init();
}
Palette::Palette(const BytePalette& bytes)
{
for (auto idx = 0; idx < 256; idx++) {
Data[idx].R = bytes.Data[idx].red;
Data[idx].G = bytes.Data[idx].green;
Data[idx].B = bytes.Data[idx].blue;
Data[idx].Zero = 0;
}
}
Palette::Palette(HTSPALETTE indexer)
{
for (auto idx = 0; idx < 256; idx++) {
RGBTRIPLE ret;
FSunPackLib::SetTSPaletteEntry(indexer, idx, NULL /* don´t modify it!*/, &ret /*but retrieve it!*/);
Data[idx].R = ret.rgbtRed;
Data[idx].G = ret.rgbtGreen;
Data[idx].B = ret.rgbtBlue;
Data[idx].Zero = 0;
}
}

89
MissionEditor/Palettes.h Normal file
View file

@ -0,0 +1,89 @@
#pragma once
#include <afxcview.h>
#include <map>
#include "MissionEditorPackLib.h"
struct BGRStruct
{
unsigned char B, G, R, Zero;
bool operator< (const BGRStruct& rhs) const { return *(int*)this < *(int*)&rhs; }
bool operator==(const BGRStruct& rhs) const { return *(int*)this == *(int*)&rhs; }
};
struct ColorStruct
{
unsigned char red, green, blue;
};
class BytePalette
{
public:
ColorStruct Data[256];
ColorStruct& operator[](int index) { return Data[index]; }
};
class Palette
{
public:
Palette(const BytePalette& bytes);
Palette(HTSPALETTE raw);
BGRStruct& operator[](int index) { return Data[index]; }
ColorStruct GetByteColor(int index) {
ColorStruct ret;
BGRStruct& tmp = Data[index];
ret.red = tmp.R;
ret.green = tmp.G;
ret.blue = tmp.B;
return ret;
}
private:
BGRStruct Data[256];
};
class Palettes
{
public:
Palettes(CLoading& loading) :
loading(loading)
{}
void Init();
HTSPALETTE GetIsoPalette(char theat);
HTSPALETTE GetUnitPalette(char theat);
void FetchPalettes();
void CreateConvTable(RGBTRIPLE* pal, int* iPal);
Palette* LoadPalette(const CString& palName);
void Clear();
HTSPALETTE m_hPalIsoTemp;
HTSPALETTE m_hPalIsoSnow;
HTSPALETTE m_hPalIsoUrb;
HTSPALETTE m_hPalUnitTemp;
HTSPALETTE m_hPalUnitSnow;
HTSPALETTE m_hPalUnitUrb;
HTSPALETTE m_hPalTemp;
HTSPALETTE m_hPalSnow;
HTSPALETTE m_hPalUrb;
HTSPALETTE m_hPalLib;
// YR pals:
HTSPALETTE m_hPalLun;
HTSPALETTE m_hPalDes;
HTSPALETTE m_hPalUbn;
HTSPALETTE m_hPalIsoLun;
HTSPALETTE m_hPalIsoDes;
HTSPALETTE m_hPalIsoUbn;
HTSPALETTE m_hPalUnitLun;
HTSPALETTE m_hPalUnitDes;
HTSPALETTE m_hPalUnitUbn;
private:
CLoading& loading;
std::map<CString, Palette*> LoadedPalettes;
std::map<Palette*, std::map<BGRStruct, Palette>> RemappedPalettes;
};

View file

@ -25,6 +25,7 @@ struct IUnknown;
#include <map>
#include <vector>
#include <optional>
#include "mix_file.h"
#include "cc_file.h"
@ -1934,46 +1935,78 @@ namespace FSunPackLib
return TRUE;
}
bool loadTSPaletteRaw(Cpal_file& pal, const std::string& szPalette)
{
return open_read(pal, szPalette) == 0;
}
bool loadTSPaletteFromMix(Cpal_file& pal, const std::string& szPalette, HMIXFILE hPaletteOwner)
{
if (szPalette[0] == '_' && szPalette[1] == 'I' && szPalette[2] == 'D') {
char id[256];
strcpy_s(id, &szPalette[3]);
int iId = atoi(id);
return pal.open(iId, mixfiles[hPaletteOwner - 1]) == 0;
}
return pal.open(szPalette, mixfiles[hPaletteOwner - 1]) == 0;
}
std::optional<Cpal_file> loadTSPalette(const std::string& szPalette, HMIXFILE hPaletteOwner)
{
Cpal_file pal;
if (hPaletteOwner == NULL) {
if (!loadTSPaletteRaw(pal, szPalette)) {
return std::nullopt;
}
} else {
if (!loadTSPaletteFromMix(pal, szPalette, hPaletteOwner)) {
return std::nullopt;
}
}
if (!pal.is_open()) {
return std::nullopt;
}
return pal;
}
bool LoadTSPalette(RGBTRIPLE* ret, const std::string& szPalette, HMIXFILE hPaletteOwner)
{
if (ret == nullptr) {
return false;
}
auto&& palRet = loadTSPalette(szPalette, hPaletteOwner);
if (!palRet.has_value()) {
return false;
}
auto&& pal = palRet.value();
auto const paldata = reinterpret_cast<const RGBTRIPLE*>(pal.get_data());
memcpy(ret, paldata, 768);
convert_palet_18_to_24(reinterpret_cast<t_palet_entry*>(ret));
pal.close();
return true;
}
bool LoadTSPalette(RGBTRIPLE* ret, LPCSTR szPalette, HMIXFILE hPaletteOwner)
{
return LoadTSPalette(ret, std::string(szPalette), hPaletteOwner);
}
HTSPALETTE LoadTSPalette(const std::string& szPalette, HMIXFILE hPaletteOwner)
{
Cpal_file pal;
RGBTRIPLE* paldata;
if (dwPalCount > 255)
if (dwPalCount > 255) {
return NULL;
if (hPaletteOwner == NULL) {
if (open_read(pal, szPalette))
return NULL;
} else {
if (szPalette[0] == '_' && szPalette[1] == 'I' && szPalette[2] == 'D') {
char id[256];
strcpy_s(id, &szPalette[3]);
int iId = atoi(id);
if (pal.open(iId, mixfiles[hPaletteOwner - 1]))
return NULL;
} else {
if (pal.open(szPalette, mixfiles[hPaletteOwner - 1]) != 0)
return NULL;
}
}
if (!pal.is_open())
t_palet buffer;
if (!LoadTSPalette(reinterpret_cast<RGBTRIPLE*>(buffer), szPalette, hPaletteOwner)) {
return NULL;
dwPalCount++;
paldata = (RGBTRIPLE*)pal.get_data();
//t_palet t_p;
memcpy(ts_palettes[dwPalCount - 1], paldata, 768);
bFirstConv[dwPalCount - 1] = TRUE;
convert_palet_18_to_24(ts_palettes[dwPalCount - 1]);
pal.close();
}
memcpy(ts_palettes[dwPalCount], buffer, 768);
bFirstConv[dwPalCount] = TRUE;
dwPalCount++;// HTSPALETTE is always internal `index+1`
return dwPalCount;
}
HTSPALETTE LoadTSPalette(LPCSTR szPalette, HMIXFILE hPaletteOwner)

View file

@ -35,10 +35,10 @@ typedef DWORD HTSPALETTE;
struct SHPHEADER
{
__int16 zero;
__int16 cx;
__int16 cy;
__int16 c_images;
__int16 zero;// type
__int16 cx;// width
__int16 cy;// height
__int16 c_images;// count
};
struct SHPIMAGEHEADER
@ -199,10 +199,11 @@ namespace FSunPackLib
BOOL LoadSHPImage(int startIndex, int wantedNum, BYTE** lpPics);
BOOL LoadSHPImage(int iImageIndex, std::vector<BYTE>& pic);
bool LoadTSPalette(RGBTRIPLE* ret, const std::string& szPalette, HMIXFILE hPaletteOwner = NULL);
bool LoadTSPalette(RGBTRIPLE* ret, LPCSTR szPalette, HMIXFILE hPaletteOwner = NULL);
HTSPALETTE LoadTSPalette(LPCSTR szPalette, HMIXFILE hPaletteOwner);
HTSPALETTE LoadTSPalette(const std::string& szPalette, HMIXFILE hPaletteOwner);
BOOL SetTSPaletteEntry(HTSPALETTE hPalette, BYTE bIndex, RGBTRIPLE* rgb, RGBTRIPLE* orig);