Merge pull request #8 from revengenowstudio/feature/shp-turret

Refactored SHP/Vxl handling by doing the same thing as FA2sp, and resolved shp turret display issues .
This commit is contained in:
Zero Fanker 2024-05-25 20:58:27 -04:00 committed by GitHub
commit 9e3c3e2700
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 1983 additions and 1987 deletions

3
.gitmodules vendored
View file

@ -1,3 +1,6 @@
[submodule "gtest-lib"]
path = googletest
url = ../gtest-lib.git
[submodule "3rdParty/CncVxlRender"]
path = 3rdParty/CncVxlRender
url = ../CncVxlRenderText.git

1
3rdParty/CncVxlRender vendored Submodule

@ -0,0 +1 @@
Subproject commit ebea5a3718f27be0a57e717fafa8cc2afbede0e1

View file

@ -257,7 +257,7 @@ int Ccc_file::read()
return 0;
}
int Ccc_file::read(void* data, int size)
int Ccc_file::read(void* data, int64_t size)
{
if (get_p() < 0 || get_p() + size > get_size())
return 1;

View file

@ -114,7 +114,7 @@ public:
void load(const Ccc_file& f);
t_file_type get_file_type(bool fast = true);
int read();
int read(void* data, int size);
int read(void* data, int64_t size);
int extract(const string& name);
virtual void close();
Ccc_file(bool read_on_open);
@ -154,7 +154,7 @@ public:
return m_data;
}
int get_p() const
int64_t get_p() const
{
return m_p;
}
@ -174,7 +174,7 @@ public:
m_p = p;
}
void skip(int p)
void skip(int64_t p)
{
m_p += p;
}
@ -189,7 +189,7 @@ private:
Cvirtual_binary m_data;
Cfile32 m_f;
bool m_is_open = false;
int m_p;
int64_t m_p;
const bool m_read_on_open;
size_t m_size;
int64_t m_size;
};

View file

@ -194,7 +194,7 @@ struct t_mix_index_entry
{
t_mix_index_entry() = default;
t_mix_index_entry(unsigned int id_, int offset_, int size_)
t_mix_index_entry(unsigned int id_, int offset_, unsigned __int32 size_)
{
id = id_;
offset = offset_;
@ -203,7 +203,7 @@ struct t_mix_index_entry
unsigned __int32 id;
__int32 offset;
__int32 size;
unsigned __int32 size;
};
struct t_mix_rg_header

View file

@ -318,7 +318,7 @@ string Cmix_file::get_name(int id)
#endif
}
int Cmix_file::get_id(t_game game, string name)
unsigned int Cmix_file::get_id(t_game game, string name)
{
boost::to_upper(name);
std::replace(name.begin(), name.end(), '/', '\\');

View file

@ -26,7 +26,7 @@ class Cmix_file : public Ccc_file
public:
int post_open();
string get_name(int id);
static int get_id(t_game game, string name);
static unsigned int get_id(t_game game, string name);
int get_index(unsigned int id) const;
using Ccc_file::get_size;
using Ccc_file::vdata;
@ -80,10 +80,14 @@ public:
return m_index[get_index(id)].offset;
}
int get_size(unsigned int id) const
size_t get_size(unsigned int id) const
{
assert(get_index(id) != -1);
return m_index[get_index(id)].size;
auto const idx = get_index(id);
//assert(idx != -1);
if (idx >= 0) {
return m_index[idx].size;
}
return 0;
}
bool has_checksum() const
@ -101,7 +105,7 @@ public:
return &m_index[0];
}
private:
using t_id_index = map<int, int>;
using t_id_index = map<unsigned int, int>;
static bool m_ft_support;

View file

@ -27,7 +27,7 @@ public:
bool is_valid() const
{
const t_tmp_header& h = header();
int size = get_size();
auto const size = get_size();
return !(sizeof(t_tmp_header) > size ||
h.cx != 24 ||
h.cy != 24 ||

View file

@ -34,7 +34,10 @@ public:
bool is_valid() const
{
const t_tmp_ts_header& h = header();
auto const size = get_size();
if (get_size() < 0) {
return false;
}
auto const size = static_cast<size_t>(get_size());
if (sizeof(t_tmp_ts_header) > size ||
!h.cblocks_x || !h.cblocks_y ||
h.cx != 48 && h.cx != 60 ||

View file

@ -6,6 +6,7 @@ MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MissionEditor", "MissionEditor\MissionEditor.vcxproj", "{9326D29A-6547-42B9-A668-519F3C0720A9}"
ProjectSection(ProjectDependencies) = postProject
{5E445578-CB45-4D82-9A1C-FC7D3E8D866A} = {5E445578-CB45-4D82-9A1C-FC7D3E8D866A}
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63} = {BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MissionEditorPackLib", "MissionEditorPackLib\MissionEditorPackLib.vcxproj", "{DEB40EF0-E215-4C2F-A0AD-3742E2E01A8C}"
@ -17,6 +18,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XCC Library", "3rdParty\xcc
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTest", "UnitTest\UnitTest.vcxproj", "{75E18879-7564-4A2C-8C00-393A5A17171F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CncVxlRenderText", "3rdParty\CncVxlRender\CncVxlRenderText.vcxproj", "{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -39,6 +42,8 @@ Global
Template|x64 = Template|x64
Tests FinalAlertDebug YR|Win32 = Tests FinalAlertDebug YR|Win32
Tests FinalAlertDebug YR|x64 = Tests FinalAlertDebug YR|x64
Tool|Win32 = Tool|Win32
Tool|x64 = Tool|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9326D29A-6547-42B9-A668-519F3C0720A9}.Debug|Win32.ActiveCfg = Tests FinalAlertDebug YR|Win32
@ -81,6 +86,10 @@ Global
{9326D29A-6547-42B9-A668-519F3C0720A9}.Tests FinalAlertDebug YR|Win32.Build.0 = Tests FinalAlertDebug YR|Win32
{9326D29A-6547-42B9-A668-519F3C0720A9}.Tests FinalAlertDebug YR|x64.ActiveCfg = Tests FinalAlertDebug YR|x64
{9326D29A-6547-42B9-A668-519F3C0720A9}.Tests FinalAlertDebug YR|x64.Build.0 = Tests FinalAlertDebug YR|x64
{9326D29A-6547-42B9-A668-519F3C0720A9}.Tool|Win32.ActiveCfg = Template|Win32
{9326D29A-6547-42B9-A668-519F3C0720A9}.Tool|Win32.Build.0 = Template|Win32
{9326D29A-6547-42B9-A668-519F3C0720A9}.Tool|x64.ActiveCfg = Template|x64
{9326D29A-6547-42B9-A668-519F3C0720A9}.Tool|x64.Build.0 = Template|x64
{DEB40EF0-E215-4C2F-A0AD-3742E2E01A8C}.Debug|Win32.ActiveCfg = Debug|Win32
{DEB40EF0-E215-4C2F-A0AD-3742E2E01A8C}.Debug|Win32.Build.0 = Debug|Win32
{DEB40EF0-E215-4C2F-A0AD-3742E2E01A8C}.Debug|x64.ActiveCfg = Debug|x64
@ -121,6 +130,10 @@ Global
{DEB40EF0-E215-4C2F-A0AD-3742E2E01A8C}.Tests FinalAlertDebug YR|Win32.Build.0 = Debug|Win32
{DEB40EF0-E215-4C2F-A0AD-3742E2E01A8C}.Tests FinalAlertDebug YR|x64.ActiveCfg = Debug|x64
{DEB40EF0-E215-4C2F-A0AD-3742E2E01A8C}.Tests FinalAlertDebug YR|x64.Build.0 = Debug|x64
{DEB40EF0-E215-4C2F-A0AD-3742E2E01A8C}.Tool|Win32.ActiveCfg = Release|Win32
{DEB40EF0-E215-4C2F-A0AD-3742E2E01A8C}.Tool|Win32.Build.0 = Release|Win32
{DEB40EF0-E215-4C2F-A0AD-3742E2E01A8C}.Tool|x64.ActiveCfg = Release|x64
{DEB40EF0-E215-4C2F-A0AD-3742E2E01A8C}.Tool|x64.Build.0 = Release|x64
{5E445578-CB45-4D82-9A1C-FC7D3E8D866A}.Debug|Win32.ActiveCfg = Debug|Win32
{5E445578-CB45-4D82-9A1C-FC7D3E8D866A}.Debug|Win32.Build.0 = Debug|Win32
{5E445578-CB45-4D82-9A1C-FC7D3E8D866A}.Debug|x64.ActiveCfg = Debug|x64
@ -161,6 +174,10 @@ Global
{5E445578-CB45-4D82-9A1C-FC7D3E8D866A}.Tests FinalAlertDebug YR|Win32.Build.0 = DebugMinimal|Win32
{5E445578-CB45-4D82-9A1C-FC7D3E8D866A}.Tests FinalAlertDebug YR|x64.ActiveCfg = Debug|x64
{5E445578-CB45-4D82-9A1C-FC7D3E8D866A}.Tests FinalAlertDebug YR|x64.Build.0 = Debug|x64
{5E445578-CB45-4D82-9A1C-FC7D3E8D866A}.Tool|Win32.ActiveCfg = Release|Win32
{5E445578-CB45-4D82-9A1C-FC7D3E8D866A}.Tool|Win32.Build.0 = Release|Win32
{5E445578-CB45-4D82-9A1C-FC7D3E8D866A}.Tool|x64.ActiveCfg = ReleaseMinimal|x64
{5E445578-CB45-4D82-9A1C-FC7D3E8D866A}.Tool|x64.Build.0 = ReleaseMinimal|x64
{75E18879-7564-4A2C-8C00-393A5A17171F}.Debug|Win32.ActiveCfg = Debug|Win32
{75E18879-7564-4A2C-8C00-393A5A17171F}.Debug|Win32.Build.0 = Debug|Win32
{75E18879-7564-4A2C-8C00-393A5A17171F}.Debug|x64.ActiveCfg = Debug|x64
@ -201,6 +218,54 @@ Global
{75E18879-7564-4A2C-8C00-393A5A17171F}.Tests FinalAlertDebug YR|Win32.Build.0 = Debug|Win32
{75E18879-7564-4A2C-8C00-393A5A17171F}.Tests FinalAlertDebug YR|x64.ActiveCfg = Debug|x64
{75E18879-7564-4A2C-8C00-393A5A17171F}.Tests FinalAlertDebug YR|x64.Build.0 = Debug|x64
{75E18879-7564-4A2C-8C00-393A5A17171F}.Tool|Win32.ActiveCfg = Release|Win32
{75E18879-7564-4A2C-8C00-393A5A17171F}.Tool|Win32.Build.0 = Release|Win32
{75E18879-7564-4A2C-8C00-393A5A17171F}.Tool|x64.ActiveCfg = Release|x64
{75E18879-7564-4A2C-8C00-393A5A17171F}.Tool|x64.Build.0 = Release|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Debug|Win32.ActiveCfg = Debug|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Debug|Win32.Build.0 = Debug|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Debug|x64.ActiveCfg = Debug|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Debug|x64.Build.0 = Debug|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalAlertDebug YR|Win32.ActiveCfg = Debug|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalAlertDebug YR|Win32.Build.0 = Debug|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalAlertDebug YR|x64.ActiveCfg = Debug|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalAlertDebug YR|x64.Build.0 = Debug|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalAlertDebug|Win32.ActiveCfg = Debug|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalAlertDebug|Win32.Build.0 = Debug|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalAlertDebug|x64.ActiveCfg = Debug|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalAlertDebug|x64.Build.0 = Debug|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalAlertRelease YR|Win32.ActiveCfg = Release|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalAlertRelease YR|Win32.Build.0 = Release|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalAlertRelease YR|x64.ActiveCfg = Release|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalAlertRelease YR|x64.Build.0 = Release|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalAlertRelease|Win32.ActiveCfg = Release|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalAlertRelease|Win32.Build.0 = Release|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalAlertRelease|x64.ActiveCfg = Release|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalAlertRelease|x64.Build.0 = Release|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalSunDebug|Win32.ActiveCfg = Debug|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalSunDebug|Win32.Build.0 = Debug|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalSunDebug|x64.ActiveCfg = Debug|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalSunDebug|x64.Build.0 = Debug|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalSunRelease|Win32.ActiveCfg = Release|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalSunRelease|Win32.Build.0 = Release|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalSunRelease|x64.ActiveCfg = Release|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.FinalSunRelease|x64.Build.0 = Release|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Release|Win32.ActiveCfg = Release|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Release|Win32.Build.0 = Release|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Release|x64.ActiveCfg = Release|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Release|x64.Build.0 = Release|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Template|Win32.ActiveCfg = Tool|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Template|Win32.Build.0 = Tool|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Template|x64.ActiveCfg = Tool|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Template|x64.Build.0 = Tool|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Tests FinalAlertDebug YR|Win32.ActiveCfg = Debug|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Tests FinalAlertDebug YR|Win32.Build.0 = Debug|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Tests FinalAlertDebug YR|x64.ActiveCfg = Debug|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Tests FinalAlertDebug YR|x64.Build.0 = Debug|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Tool|Win32.ActiveCfg = Tool|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Tool|Win32.Build.0 = Tool|Win32
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Tool|x64.ActiveCfg = Tool|x64
{BAE32EF7-4F88-40D8-8984-A2EAF14C0A63}.Tool|x64.Build.0 = Tool|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View file

@ -13,7 +13,7 @@ const CIniFile* IniFileGroup::Nth(int idx) const
return m_group.at(idx);
}
const CString& IniFileGroup::GetString(const CString & section, const CString & key) const
const CString& IniFileGroup::GetString(const CString& section, const CString & key) const
{
for (auto it = m_group.rbegin(); it != m_group.rend(); ++it) {
auto const& got = (*it)->GetString(section, key);

View file

@ -27,6 +27,15 @@ public:
CString GetStringOr(const CString& section, const CString& key, const CString& def) const;
IniSectionGroup GetSection(const CString& section) const;
bool GetBool(const CString& pSection, const CString& pKey, bool def = false) const
{
return INIHelper::StringToBool(GetString(pSection, pKey), def);
}
int GetInteger(const CString& pSection, const CString& pKey, int def = 0) const
{
return INIHelper::StringToInteger(GetString(pSection, pKey), def);
}
auto Size() const { return m_group.size(); }
void Append(const CIniFile& INI);
@ -94,12 +103,17 @@ public:
const CString& m_section;
};
IniSectionGroup(const IniFileGroup& source, const CString& secName) :
m_source(source),
IniSectionGroup(IniFileGroup&& source, const CString& secName) :
m_source(std::move(source)),
m_section(secName)
{
}
IniSectionGroup(const IniFileGroup& source, const CString& secName) :
IniSectionGroup(IniFileGroup(source), secName)
{
}
Iterator begin() const {
auto groupBeg = m_source.begin();
auto [secItBeg, secItEnd] = acquireNextKvGroup(groupBeg);
@ -137,6 +151,6 @@ private:
return acquireNextKvGroup(m_section, beg, m_source.end());
}
const IniFileGroup& m_source;
const IniFileGroup m_source;
CString m_section;
};

33
MissionEditor/IniMega.h Normal file
View file

@ -0,0 +1,33 @@
#pragma once
#include <afxcview.h>
#include "INIMeta.h"
#include "variables.h"
extern CIniFile rules;
class IniMegaFile
{
friend class IniFileGroup;
public:
static IniFileGroup GetRules();
static bool IsNullOrEmpty(const CString& value) { return isNullOrEmpty(value); }
private:
static bool isNullOrEmpty(const CString& value);
};
inline IniFileGroup IniMegaFile::GetRules()
{
IniFileGroup m_group;
m_group.Append(rules);
m_group.Append(Map->GetIniFile());
return m_group;
}
inline bool IniMegaFile::isNullOrEmpty(const CString& value)
{
return !value.GetLength() || value == "none" || value == "<none>";
}

View file

@ -547,24 +547,33 @@ inline void CalculateHouseColorPalette(int house_pal[houseColorRelMax + 1], cons
/*
There is no need for newpal
*/
__forceinline void BlitPic(void* dst, int x, int y, int dleft, int dtop, int dpitch, int dright, int dbottom, PICDATA& pd, int* color = NULL, int* newPal = NULL)//BYTE* src, int swidth, int sheight)
__forceinline void BlitPic(void* dst, int x, int y, int dleft, int dtop, int dpitch, int dright, int dbottom,
PICDATA& pd, int* color = NULL, const int* newPal = NULL)//BYTE* src, int swidth, int sheight)
{
ASSERT(pd.bType != PICDATA_TYPE_BMP);
if (newPal == NULL) newPal = pd.pal;
if (newPal == NULL) {
newPal = pd.pal;
}
BYTE* src = (BYTE*)pd.pic;
int swidth = pd.wMaxWidth;
int sheight = pd.wMaxHeight;
if (src == NULL || dst == NULL) return;
if (src == NULL || dst == NULL) {
return;
}
//x += 1;
//y += 1;
//y -= f_y;
if (x + swidth < dleft || y + sheight < dtop) return;
if (x >= dright || y >= dbottom) return;
if (x + swidth < dleft || y + sheight < dtop) {
return;
}
if (x >= dright || y >= dbottom) {
return;
}
RECT blrect;
@ -650,7 +659,7 @@ __forceinline void BlitPic(void* dst, int x, int y, int dleft, int dtop, int dpi
}
}
__forceinline void BlitPicHalfTransp(void* dst, int x, int y, int dleft, int dtop, int dpitch, int dright, int dbottom, PICDATA& pd, int* color = NULL, int* newPal = NULL)//BYTE* src, int swidth, int sheight)
__forceinline void BlitPicHalfTransp(void* dst, int x, int y, int dleft, int dtop, int dpitch, int dright, int dbottom, PICDATA& pd, int* color = NULL, const int* newPal = NULL)//BYTE* src, int swidth, int sheight)
{
ASSERT(pd.bType != PICDATA_TYPE_BMP);
@ -5372,7 +5381,7 @@ void CIsoView::DrawMap()
int w = 1, h = 1;
PICDATA pic;
if (id > -1 && id < 0x0F00) {
if (id > -1 && id < buildingInfoCapacity) {
w = buildinginfo[id].w;
h = buildinginfo[id].h;
int dir = objp.direction / 32;
@ -5402,7 +5411,9 @@ void CIsoView::DrawMap()
::Map->UpdateBuildingInfo(&objp.type);
int dir = (7 - objp.direction / 32) % 8;
pic = buildinginfo[id].pic[dir];
if (pic.pic == NULL) pic = buildinginfo[id].pic[0];
if (pic.pic == NULL) {
pic = buildinginfo[id].pic[0];
}
}
if (pic.pic == NULL) {
#ifndef NOSURFACES
@ -5480,7 +5491,7 @@ void CIsoView::DrawMap()
int id = m.node.type;
int w = 1, h = 1;
PICDATA pic;
if (id > -1 && id < 0x0F00) {
if (id > -1 && id < buildingInfoCapacity) {
w = buildinginfo[id].w;
h = buildinginfo[id].h;
pic = buildinginfo[id].pic[0];
@ -5506,6 +5517,7 @@ void CIsoView::DrawMap()
SetError("Loading graphics");
theApp.m_loading->LoadUnitGraphic(buildingId);
::Map->UpdateBuildingInfo(&buildingId);
pic = buildinginfo[id].pic[0];
}
if (pic.pic == NULL) {
@ -5693,7 +5705,7 @@ void CIsoView::DrawMap()
int id = m.terraintype;
int w = 1, h = 1;
PICDATA pic;
if (id > -1 && id < 0x0F00) {
if (id > -1 && id < buildingInfoCapacity) {
w = treeinfo[id].w;
h = treeinfo[id].h;
pic = treeinfo[id].pic;
@ -5744,7 +5756,7 @@ void CIsoView::DrawMap()
int id = m.smudgetype;
PICDATA pic;
if (id > -1 && id < 0x0F00) {
if (id > -1 && id < buildingInfoCapacity) {
pic = smudgeinfo[id].pic;
}

File diff suppressed because it is too large Load diff

View file

@ -23,6 +23,7 @@
#include "FinalSunDlg.h"
#include "MissionEditorPackLib.h"
#include "Palettes.h"
#include <memory>
#include <optional>
@ -90,9 +91,7 @@ class CLoading : public CDialog
{
// Construction
public:
void CreateConvTable(RGBTRIPLE* pal, int* iPal);
void FetchPalettes();
void PrepareUnitGraphic(LPCSTR lpUnittype);
void PrepareUnitGraphic(const CString& lpUnittype);
void LoadStrings();
void FreeAll();
void FreeTileSet();
@ -110,15 +109,52 @@ public:
CLoading(CWnd* pParent = NULL); // Standardconstructor
void InitPics(CProgressCtrl* prog = NULL);
void Load();
bool LoadSingleFrameShape(const CString& name, int nFrame = 0, int deltaX = 0, int deltaY = 0);
void LoadBuilding(const CString& ID);
void LoadInfantry(const CString& ID);
void LoadTerrainOrSmudge(const CString& ID);
void LoadVehicleOrAircraft(const CString& ID);
void SetImageData(unsigned char* pBuffer, const CString& NameInDict, int FullWidth, int FullHeight, Palette* pPal);
void SetImageData(unsigned char* pBuffer, PICDATA& pData, const int FullWidth, const int FullHeight, Palette* pPal);
void UnionSHP_Add(unsigned char* pBuffer, int Width, int Height, int DeltaX = 0, int DeltaY = 0, bool UseTemp = false);
void UnionSHP_GetAndClear(unsigned char*& pOutBuffer, int* OutWidth, int* OutHeight, bool clearBuffer = true, bool UseTemp = false);
void VXL_Add(const unsigned char* pCache, int X, int Y, int Width, int Height);
void VXL_GetAndClear(unsigned char*& pBuffer, int* OutWidth, int* OutHeight);
void VXL_Reset();
BOOL LoadUnitGraphic(const CString& lpUnittype);
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;
}
enum class ObjectType
{
Unknown = -1,
Infantry = 0,
Vehicle = 1,
Aircraft = 2,
Building = 3,
Terrain = 4,
Smudge = 5
};
ObjectType GetItemType(const CString& ID);
CString GetArtID(const CString& ID);
CString GetVehicleOrAircraftFileID(const CString& ID);
CString GetTerrainOrSmudgeFileID(const CString& ID);
CString GetBuildingFileID(const CString& ID);
CString GetInfantryFileID(const CString& ID);
// Dialog data
//{{AFX_DATA(CLoading)
@ -156,29 +192,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;
@ -212,7 +228,19 @@ private:
std::unique_ptr<VoxelNormalTables> m_voxelNormalTables;
struct SHPUnionData
{
unsigned char* Buffer;// This buffer allocated from outside
int Width;
int Height;
int DeltaX;
int DeltaY;
};
std::map<CString, ObjectType> ObjectTypes;
std::vector<SHPUnionData> UnionSHP_Data[2];
static auto constexpr VoxelBlendCacheLength = 0x10000;
unsigned char VXL_Data[VoxelBlendCacheLength];
};
//{{AFX_INSERT_LOCATION}}

View file

@ -3453,7 +3453,7 @@ void CMapData::UpdateBuildingInfo(const CString* lpUnitType)
CIniFile& ini = GetIniFile();
if (!lpUnitType) {
memset(buildinginfo, 0, 0x0F00 * sizeof(BUILDING_INFO));
memset(buildinginfo, 0, buildingInfoCapacity * sizeof(BUILDING_INFO));
for (auto const& [seq, id] : rules.GetSection("BuildingTypes")) {
auto const& type = id;
@ -3464,7 +3464,7 @@ void CMapData::UpdateBuildingInfo(const CString* lpUnitType)
int n = Map->GetUnitTypeID(type);
if (n >= 0 && n < 0x0F00) {
if (n >= 0 && n < buildingInfoCapacity) {
buildinginfo[n].w = foundation.Width;
buildinginfo[n].h = foundation.Height;
@ -3493,6 +3493,10 @@ void CMapData::UpdateBuildingInfo(const CString* lpUnitType)
buildinginfo[n].bUrban = TRUE;
}
if (type == "NALASR") {
printf("");
}
buildinginfo[n].pic_count = 8;
for (auto k = 0; k < 8; k++) {
lpPicFile = GetUnitPictureFilename(type, k);
@ -3521,7 +3525,7 @@ void CMapData::UpdateBuildingInfo(const CString* lpUnitType)
int n = Map->GetUnitTypeID(type);
if (n >= 0 && n < 0x0F00) {
if (n >= 0 && n < buildingInfoCapacity) {
buildinginfo[n].w = foundation.Width;
buildinginfo[n].h = foundation.Height;
buildinginfo[n].bSnow = TRUE;
@ -3556,7 +3560,7 @@ void CMapData::UpdateBuildingInfo(const CString* lpUnitType)
int n = Map->GetUnitTypeID(type);
if (n >= 0 && n < 0x0F00) {
if (n >= 0 && n < buildingInfoCapacity) {
buildinginfo[n].w = foundation.Width;
buildinginfo[n].h = foundation.Height;
CString lpPicFile = GetUnitPictureFilename(type, 0);

View file

@ -348,7 +348,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='FinalAlertDebug YR|x64'">
<ClCompile>
<PreprocessorDefinitions>NOMINMAX;RA2_MODE;YR_MODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\MissionEditorPackLib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\MissionEditorPackLib;..\3rdParty\CncVxlRender\inc</AdditionalIncludeDirectories>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>RA2_MODE;YR_MODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@ -522,6 +522,7 @@
<ClCompile Include="NewMapSpDlg.cpp" />
<ClCompile Include="NewMapTypeDlg.cpp" />
<ClCompile Include="NewRA2HouseDlg.cpp" />
<ClCompile Include="Palettes.cpp" />
<ClCompile Include="ProgressDlg.cpp" />
<ClCompile Include="RightFrame.cpp" />
<ClCompile Include="RTPDlg.cpp" />
@ -588,6 +589,7 @@
<ClCompile Include="UserScriptsDlg.cpp" />
<ClCompile Include="variables.cpp" />
<ClCompile Include="ViewObjects.cpp" />
<ClCompile Include="VoxelDrawer.cpp" />
<ClCompile Include="WaypointID.cpp" />
<ClCompile Include="MapCode.cpp" />
</ItemGroup>
@ -610,6 +612,7 @@
<ClInclude Include="ComboUInputDlg.h" />
<ClInclude Include="defines.h" />
<ClInclude Include="IniHelper.h" />
<ClInclude Include="IniMega.h" />
<ClInclude Include="INIMeta.h" />
<ClInclude Include="LineDrawer.h" />
<ClInclude Include="DynamicGraphDlg.h" />
@ -650,6 +653,7 @@
<ClInclude Include="NewMapTypeDlg.h" />
<ClInclude Include="NewRA2HouseDlg.h" />
<ClInclude Include="ovrlinline.h" />
<ClInclude Include="Palettes.h" />
<ClInclude Include="ProgressDlg.h" />
<ClInclude Include="Resource.h" />
<ClInclude Include="RightFrame.h" />
@ -688,6 +692,7 @@
<ClInclude Include="variables.h" />
<ClInclude Include="Vec2.h" />
<ClInclude Include="ViewObjects.h" />
<ClInclude Include="VoxelDrawer.h" />
<ClInclude Include="WaypointID.h" />
<ClInclude Include="MapCode.h" />
</ItemGroup>

View file

@ -285,6 +285,12 @@
<ClCompile Include="INIMeta.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Palettes.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="VoxelDrawer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="MissionEditor.rc">
@ -577,6 +583,15 @@
<ClInclude Include="INIMeta.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="IniMega.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Palettes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="VoxelDrawer.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="res\clifftoo.bmp">

350
MissionEditor/Palettes.cpp Normal file
View file

@ -0,0 +1,350 @@
#include "stdafx.h"
#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;
}
}

93
MissionEditor/Palettes.h Normal file
View file

@ -0,0 +1,93 @@
#pragma once
#include <afxcview.h>
#include <map>
#include "MissionEditorPackLib.h"
class CLoading;
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;
}
const BGRStruct* GetData() const { return Data; }
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

@ -30,7 +30,7 @@
<Link>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(XccVcpkgDir)\lib</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(VxlLibDir);$(XccVcpkgDir)\lib</AdditionalLibraryDirectories>
<SubSystem>Windows</SubSystem>
<StackReserveSize>11194304</StackReserveSize>
<StackCommitSize>11194304</StackCommitSize>

View file

@ -6,6 +6,7 @@
<PropertyGroup>
<XccVcpkgDirTriplet>$(XccDir)\vcpkg_installed\$(Platform)-windows\$(Platform)-windows</XccVcpkgDirTriplet>
<XccVcpkgDir>$(XccVcpkgDirTriplet)\debug</XccVcpkgDir>
<VxlLibDir>$(SolutionDir)$(Platform)\Debug</VxlLibDir>
</PropertyGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
@ -25,7 +26,7 @@
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<AdditionalDependencies>ddraw.lib;dxguid.lib;winmm.lib;gdiplus.lib;lzo2.lib;bz2d.lib;zlibd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>CncVxlRenderText.lib;ddraw.lib;dxguid.lib;winmm.lib;gdiplus.lib;lzo2.lib;bz2d.lib;zlibd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreSpecificDefaultLibraries>libcmt.lib</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>

View file

@ -15,6 +15,7 @@
<XccVcpkgBin Include="$(XccVcpkgDir)\bin\bz2*.dll" />
<XccVcpkgBin Include="$(XccVcpkgDir)\bin\lzo2.dll" />
<XccVcpkgBin Include="$(XccVcpkgDir)\bin\zlib*1.dll" />
<VxlLibBin Include="$(VxlLibDir)\*.dll" />
<InstallData Include="$(MSBuildThisFileDirectory)\..\data\shared\**\*" />
<InstallData Include="$(MSBuildThisFileDirectory)\..\..\LICENSE.md" />
<LicDir Include="$(XccDir)\COPYING" DestDir="xcc" />
@ -29,6 +30,9 @@
<Target Name="CopyDllFiles" AfterTargets="Build" BeforeTargets="BuildAndZipDistribution">
<Copy SourceFiles="@(XccVcpkgBin)" DestinationFolder="$(OutDir)" />
</Target>
<Target Name="CopyDllFiles" AfterTargets="Build" BeforeTargets="BuildAndZipDistribution">
<Copy SourceFiles="@(VxlLibBin)" DestinationFolder="$(OutDir)" />
</Target>
<Target Name="CopyDataFiles" AfterTargets="Build" BeforeTargets="BuildAndZipDistribution">
<Copy SourceFiles="@(InstallData)" DestinationFolder="$(OutDir)\%(RecursiveDir)" />
</Target>

View file

@ -6,6 +6,7 @@
<PropertyGroup>
<XccVcpkgDirTriplet>$(XccDir)\vcpkg_installed\$(Platform)-windows\$(Platform)-windows</XccVcpkgDirTriplet>
<XccVcpkgDir>$(XccVcpkgDirTriplet)</XccVcpkgDir>
<VxlLibDir>$(SolutionDir)$(Platform)\Release</VxlLibDir>
</PropertyGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
@ -25,7 +26,7 @@
<PreprocessorDefinitions>NDEBUG;_AFXDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<AdditionalDependencies>ddraw.lib;dxguid.lib;winmm.lib;gdiplus.lib;lzo2.lib;bz2.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>CncVxlRenderText.lib;ddraw.lib;dxguid.lib;winmm.lib;gdiplus.lib;lzo2.lib;bz2.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreSpecificDefaultLibraries>libcmt.lib; libcmtd.lib; msvcrtd.lib</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>

View file

@ -118,7 +118,7 @@ struct PICDATA {
#else
void* pic = nullptr; // BYTE* to image, exception: if bType==PICDATA_TYPE_BMP then this is a LPDIRECTDRAWSURFACE!
VBORDER* vborder = nullptr;
int* pal = nullptr;
const int* pal = nullptr;
std::shared_ptr<std::vector<BYTE>> lighting;
std::shared_ptr<std::vector<BYTE>> rawPic;
std::shared_ptr<std::vector<VBORDER>> _vBorder;

View file

@ -33,7 +33,7 @@
#include "rtpdlg.h"
#include "TubeTool.h"
#include "StringHelper.h"
#include "INIMeta.h"
#include "IniMega.h"
#ifdef _DEBUG
#define new DEBUG_NEW
@ -514,19 +514,6 @@ __inline HTREEITEM TV_InsertItemW(HWND hWnd, WCHAR* lpString, int len, HTREEITEM
return res;
}
IniFileGroup IniMegaFile::GetRules()
{
IniFileGroup m_group;
m_group.Append(rules);
m_group.Append(Map->GetIniFile());
return m_group;
}
bool IniMegaFile::isNullOrEmpty(const CString& value)
{
return !value.GetLength() || value == "none" || value == "<none>";
}
const IgnoreSet CollectIgnoreSet()
{
IgnoreSet ret;

View file

@ -32,8 +32,6 @@
#define MAKE_MASK(refVal) 1 << static_cast<int>(refVal)
class TreeViewBuilder;
class CViewObjects;
class IniFileGroup;
using IgnoreSet = std::unordered_set<std::string>;
@ -225,20 +223,6 @@ private:
void HandleBrushSize(int iTile);
};
class IniMegaFile
{
friend class IniFileGroup;
public:
static IniFileGroup GetRules();
static bool IsNullOrEmpty(const CString& value) { return isNullOrEmpty(value); }
private:
static bool isNullOrEmpty(const CString& value);
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}

View file

@ -0,0 +1,83 @@
#include "stdafx.h"
#include "VoxelDrawer.h"
#include <vxlapi.h>
#include "variables.h"
#include "MissionEditorPackLib.h"
CString makeFullPath(const CString& name)
{
return TSPath + name;
}
std::pair<MemoryBuffer, bool> readFile(const CString& name, HMIXFILE hMix)
{
if (hMix == NULL) {
return FSunPackLib::LoadCCFile(makeFullPath(name), NULL);
}
return FSunPackLib::LoadCCFile(name, hMix);
}
void VoxelDrawer::Initalize()
{
CncImgCreate();
CncImgSetMaxFacing(32);
}
void VoxelDrawer::Finalize()
{
CncImgRelease();
}
bool VoxelDrawer::LoadVPLFile(const CString& name, const FindFileInMixHandler& mixFindler)
{
bool result = false;
auto const&& ret = readFile(name, mixFindler(name, nullptr));
if (ret.second) {
result = CncImgLoadVPLFile(reinterpret_cast<const BYTE*>(ret.first.data()));
}
return result;
}
bool VoxelDrawer::LoadVXLFile(const CString& name, const FindFileInMixHandler& mixFindler)
{
bool result = false;
auto const&& ret = readFile(name, mixFindler(name, nullptr));
if (ret.second) {
if (CncImgIsVXLLoaded()) {
CncImgClearCurrentVXL();
}
result = CncImgLoadVXLFile(reinterpret_cast<const BYTE*>(ret.first.data()));
}
return result;
}
bool VoxelDrawer::LoadHVAFile(const CString& name, const FindFileInMixHandler& mixFindler)
{
bool result = false;
auto const&& ret = readFile(name, mixFindler(name, nullptr));
if (ret.second) {
result = CncImgLoadHVAFile(reinterpret_cast<const BYTE*>(ret.first.data()));
}
return result;
}
bool VoxelDrawer::GetImageData(unsigned int nFacing, unsigned char*& pBuffer, int& width,
int& height, int& x, int& y, const int F, const int L, const int H)
{
const unsigned int nIndex = nFacing * 4;
CncImgPrepareVXLCache(nIndex, F, L, H);
CncImgGetImageFrame(nIndex, &width, &height, &x, &y);
if (width < 0 || height < 0)
return false;
return CncImgGetImageData(nIndex, &pBuffer);
}
bool VoxelDrawer::GetImageData(unsigned int nFacing, unsigned char*& pBuffer, VoxelRectangle& rect, const int F, const int L, const int H)
{
return GetImageData(nFacing, pBuffer, rect.W, rect.H, rect.X, rect.Y, F, L, H);
}
bool VoxelDrawer::IsVPLLoaded()
{
return CncImgIsVPLLoaded();
}

View file

@ -0,0 +1,27 @@
#pragma once
#include <afxcview.h>
#include <functional>
using HMIXFILE = DWORD;
using FindFileInMixHandler = std::function<HMIXFILE(LPCTSTR lpFilename, char* pTheaterChar)>;
struct VoxelRectangle
{
int X, Y, W, H;
};
class VoxelDrawer
{
public:
static void Initalize();
static void Finalize();
static bool LoadVPLFile(const CString& name, const FindFileInMixHandler& mixFindler);
static bool LoadVXLFile(const CString& name, const FindFileInMixHandler& mixFindler);
static bool LoadHVAFile(const CString& name, const FindFileInMixHandler& mixFindler);
static bool GetImageData(unsigned int nFacing, unsigned char*& pBuffer,
int& width, int& height, int& x, int& y, const int F = 0, const int L = 0, const int H = 0);
static bool GetImageData(unsigned int nFacing, unsigned char*& pBuffer,
VoxelRectangle& rect, const int F = 0, const int L = 0, const int H = 0);
static bool IsVPLLoaded();
};

View file

@ -47,49 +47,42 @@ inline BOOL isFalse(CString expr)
return FALSE;
}
// retrieve the picture filename of a unit (as it is saved in the pics map). The returned file may not exist in the pics map (you need to do a check!).
inline CString GetUnitPictureFilename(LPCTSTR lpUnitName, DWORD dwPicIndex)
inline CString GetUnitPictureFilename(const CString& lpUnitName, DWORD dwPicIndex)
{
CIniFile& ini = Map->GetIniFile();
CString UnitName = lpUnitName;
auto artname = rules.GetStringOr(lpUnitName, "Image", lpUnitName);
artname = ini.GetStringOr(lpUnitName, "Image", artname);
UnitName = ini.GetString(lpUnitName, "Image");
if (UnitName.IsEmpty()) {
UnitName = rules.GetString(lpUnitName, "Image");
}
CString artname = UnitName;
if (UnitName.IsEmpty()) {
artname = lpUnitName;
}
auto const shapeName = art.GetString(UnitName, "Image");
auto const& shapeName = art.GetString(artname, "Image");
if (!shapeName.IsEmpty()) {
if (!g_data.GetBool("IgnoreArtImage", UnitName)) {
if (!g_data.GetBool("IgnoreArtImage", artname)) {
artname = shapeName;
}
}
CString filename = UnitName;
CString filename = artname;
if (art.GetBool(UnitName, "NewTheater") && !art.GetBool(UnitName, "DemandLoad")) {
if (art.GetBool(artname, "NewTheater") && !art.GetBool(artname, "DemandLoad")) {
filename.SetAt(1, 'T');
}
char n[50];
_itoa_s(dwPicIndex, n, 10);
if (pics.find(artname + n) != pics.end()) {
filename = artname; // yes, found
// store differently for each type even they shares same image,
// because they can have different components, e.g. turret image
if (pics.find((lpUnitName + n)) != pics.end()) {
filename = lpUnitName; // yes, found
filename += n;
} else if (pics.find(artname + ".bmp") != pics.end()) // since June, 15th (Matze): Only use BMP if no SHP/VXL exists
{
} else if (pics.find(artname + ".bmp") != pics.end()) { // since June, 15th (Matze): Only use BMP if no SHP/VXL exists
filename = (CString)artname + ".bmp";
} else
} else {
filename = "";
}
return filename;
}

View file

@ -176,7 +176,8 @@ bool bAllowAccessBehindCliffs = false;
// infos for buildings and trees (should be extended to infantry, units, and aircraft)
// they are initialized in CIsoView, should be changed to CMapData
BUILDING_INFO buildinginfo[0x0F00];
BUILDING_INFO buildinginfo[buildingInfoCapacity];
TREE_INFO treeinfo[0x0F00];
#ifdef SMUDGE_SUPP
SMUDGE_INFO smudgeinfo[0x0F00];

View file

@ -104,7 +104,10 @@ extern vector<CString> rndterrainsrc;
// infos for buildings and trees (should be extended to infantry, units, and aircraft)
// they are initialized in CIsoView, should be changed to CMapData
extern BUILDING_INFO buildinginfo[0x0F00];
size_t constexpr buildingInfoCapacity = 0x0F000;
extern BUILDING_INFO buildinginfo[buildingInfoCapacity];
extern TREE_INFO treeinfo[0x0F00];
#ifdef SMUDGE_SUPP
extern SMUDGE_INFO smudgeinfo[0x0F00];

View file

@ -25,6 +25,7 @@ struct IUnknown;
#include <map>
#include <vector>
#include <optional>
#include "mix_file.h"
#include "cc_file.h"
@ -348,6 +349,35 @@ namespace FSunPackLib
return pDDS->SetColorKey(DDCKEY_SRCBLT, &color_key);
}
std::pair<MemoryBuffer, bool> LoadCCFile(LPCTSTR filepath, HMIXFILE hMix)
{
MemoryBuffer buffer;
Ccc_file file(true);
if (hMix != NULL) {
if (file.open(filepath, mixfiles[hMix - 1])) {
return {};
}
} else {
if (file.open(filepath)) {
return {};
}
}
auto const size = file.get_size();
if (size < 0) {
return {};
}
buffer.resize(size);
if (file.read(buffer.data(), size)) {
return {};
}
return { std::move(buffer), true };
}
BOOL XCC_Initialize(BOOL bLoadFromRegistry)
{
if (bLoadFromRegistry)
@ -412,7 +442,7 @@ namespace FSunPackLib
BOOL XCC_DoesFileExist(LPCSTR szFile, HMIXFILE hOwner)
{
if (hOwner == 0)
if (hOwner == NULL)
return FALSE;
if (hOwner > dwMixFileCount)
return FALSE;
@ -558,26 +588,30 @@ namespace FSunPackLib
return TRUE;
};
BOOL SetCurrentSHP(LPCSTR szSHP, HMIXFILE hOwner)
bool SetCurrentSHP(LPCSTR szSHP, HMIXFILE hOwner)
{
if (cur_shp.is_open()) cur_shp.close();
if (cur_shp.is_open()) {
cur_shp.close();
}
if (hOwner == NULL) {
if (open_read(cur_shp, szSHP) != 0) {
return FALSE;
return false;
}
} else {
int id = mixfiles[hOwner - 1].get_id(mixfiles[hOwner - 1].get_game(), szSHP);
int size = mixfiles[hOwner - 1].get_size(id);
if (size == 0)
auto const id = mixfiles[hOwner - 1].get_id(mixfiles[hOwner - 1].get_game(), szSHP);
auto const size = mixfiles[hOwner - 1].get_size(id);
if (size == 0) {
OutputDebugString("NULL size");
return false;
}
BYTE* b = new(BYTE[size]);
mixfiles[hOwner - 1].seek(mixfiles[hOwner - 1].get_offset(id));
mixfiles[hOwner - 1].read(b, size);
cur_shp.load(Cvirtual_binary(b, size));
}
return TRUE;
return true;
};
BOOL XCC_GetTMPTileInfo(int iTile, POINT* lpPos, int* lpWidth, int* lpHeight, BYTE* lpDirection, BYTE* lpTileHeight, BYTE* lpTileType, RGBTRIPLE* lpRgbLeft, RGBTRIPLE* lpRgbRight)
@ -876,7 +910,7 @@ namespace FSunPackLib
}
BOOL LoadSHPImage(int iImageIndex, int iCount, BYTE** lpPics)
BOOL LoadSHPImage(int startIndex, int wantedNum, BYTE** lpPics)
{
t_shp_ts_image_header imghead;
BYTE* image = NULL;
@ -889,26 +923,22 @@ namespace FSunPackLib
return FALSE;
}
int pic;
std::vector<byte> decode_image_buffer;
for (pic = 0; pic < iCount; pic++) {
if (cur_shp.get_image_header(iImageIndex + pic)) {
imghead = *(cur_shp.get_image_header(iImageIndex + pic));
for (auto frameIdx = 0; frameIdx < wantedNum; frameIdx++) {
if (cur_shp.get_image_header(startIndex + frameIdx)) {
imghead = *(cur_shp.get_image_header(startIndex + frameIdx));
// if(imghead.offset!=0)
{
if (cur_shp.is_compressed(iImageIndex + pic)) {
if (cur_shp.is_compressed(startIndex + frameIdx)) {
decode_image_buffer.resize(imghead.cx * imghead.cy);
image = decode_image_buffer.data();
decode3(cur_shp.get_image(iImageIndex + pic), image, imghead.cx, imghead.cy);
decode3(cur_shp.get_image(startIndex + frameIdx), image, imghead.cx, imghead.cy);
} else
image = (unsigned char*)cur_shp.get_image(iImageIndex + pic);
image = (unsigned char*)cur_shp.get_image(startIndex + frameIdx);
lpPics[pic] = new(BYTE[head.cx * head.cy]);
lpPics[frameIdx] = new(BYTE[head.cx * head.cy]);
int i, e;
for (i = 0; i < head.cx; i++) {
@ -920,9 +950,9 @@ namespace FSunPackLib
dwRead = (i - imghead.x) + (e - imghead.y) * imghead.cx;
if (dwRead != 0xFFFFFFFF) {
lpPics[pic][dwWrite] = image[dwRead];
lpPics[frameIdx][dwWrite] = image[dwRead];
} else
lpPics[pic][dwWrite] = 0;
lpPics[frameIdx][dwWrite] = 0;
}
@ -1818,8 +1848,22 @@ namespace FSunPackLib
return TRUE;
}
BOOL LoadVXLImage(const VoxelNormalTables& normalTables, Vec3f lightDirection, const Vec3f rotation, const Vec3f modelOffset, std::vector<BYTE>& image, std::vector<BYTE>& lighting, int* lpXCenter, int* lpYCenter, int ZAdjust, int* lpXCenterZMax, int* lpYCenterZMax, int i3dCenterX, int i3dCenterY, RECT* vxlrect)
{
BOOL LoadVXLImage(
const VoxelNormalTables& normalTables,
Vec3f lightDirection,
const Vec3f rotation,
const Vec3f modelOffset,
OUT std::vector<BYTE>& image,
OUT std::vector<BYTE>& lighting,
OUT OPTIONAL int* lpXCenter,
OUT OPTIONAL int* lpYCenter,
int ZAdjust,
OUT OPTIONAL int* lpXCenterZMax,
OUT OPTIONAL int* lpYCenterZMax,
int i3dCenterX,
int i3dCenterY,
OUT OPTIONAL RECT* vxlrect
) {
last_succeeded_operation = 1;
int i;
@ -1934,46 +1978,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

@ -28,17 +28,31 @@
#include <string>
#include "Vec3.h"
#ifndef IN
#define IN
#endif
#ifndef OUT
#define OUT
#endif
#ifndef OPTIONAL
#define OPTIONAL
#endif
class VoxelNormalTables;
typedef DWORD HMIXFILE;
typedef DWORD HTSPALETTE;
using MemoryBuffer = std::vector<char>;
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
@ -181,7 +195,7 @@ namespace FSunPackLib
BOOL SetCurrentTMP(LPCSTR szTMP, HMIXFILE hOwner);
BOOL SetCurrentSHP(LPCSTR szSHP, HMIXFILE hOwner);
bool SetCurrentSHP(LPCSTR szSHP, HMIXFILE hOwner);
BOOL XCC_GetTMPTileInfo(int iTile, POINT* lpPos, int* lpWidth, int* lpHeight, BYTE* lpDirection, BYTE* lpTileHeight, BYTE* lpTileType, RGBTRIPLE* lpRgbLeft, RGBTRIPLE* lpRgbRight);
@ -195,13 +209,15 @@ namespace FSunPackLib
BOOL LoadTMPImage(int iStart, int iCount, BYTE** lpTileArray);
BOOL LoadSHPImageInSurface(IDirectDraw4* pdd, HTSPALETTE hPalette, int iImageIndex, int iCount, LPDIRECTDRAWSURFACE4* pdds);
BOOL LoadSHPImage(int iImageIndex, int iCount, BYTE** lpPics);
// load 'wantedNum' frames at 'startIndex'
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);
@ -215,13 +231,27 @@ namespace FSunPackLib
BOOL LoadVXLImageInSurface(const VoxelNormalTables& normalTables, Vec3f lightDirection, IDirectDraw4* pdd, int iStart, int iCount, Vec3f rotation, Vec3f modelOffset, LPDIRECTDRAWSURFACE4* pdds, HTSPALETTE hPalette, int* lpXCenter = NULL, int* lpYCenter = NULL, int ZAdjust = 0, int* lpXCenterZMax = NULL, int* lpYCenterZMax = NULL, int i3dCenterX = -1, int i3dCenterY = -1);
// modelOffset is applied before VXL/HVA translates and scales and before model-to-world rotation
BOOL LoadVXLImage(const VoxelNormalTables& normalTables, Vec3f lightDirection, Vec3f rotation, Vec3f modelOffset, std::vector<BYTE>& image, std::vector<BYTE>& lighting, int* lpXCenter = NULL, int* lpYCenter = NULL, int ZAdjust = 0, int* lpXCenterZMax = NULL, int* lpYCenterZMax = NULL, int i3dCenterX = -1, int i3dCenterY = -1, RECT* vxlrect = NULL);
BOOL LoadVXLImage(const VoxelNormalTables& normalTables,
Vec3f lightDirection,
Vec3f rotation,
Vec3f modelOffset,
OUT std::vector<BYTE>& image,
OUT std::vector<BYTE>& lighting,
OUT OPTIONAL int* lpXCenter = NULL,
OUT OPTIONAL int* lpYCenter = NULL,
int ZAdjust = 0,
OUT OPTIONAL int* lpXCenterZMax = NULL,
OUT OPTIONAL int* lpYCenterZMax = NULL,
int i3dCenterX = -1,
int i3dCenterY = -1,
OUT OPTIONAL RECT* vxlrect = NULL);
BOOL WriteMixFile(LPCTSTR lpMixFile, LPCSTR* lpFiles, DWORD dwFileCount, Game game);
HRESULT SetColorKey(IDirectDrawSurface4* pDDS, COLORREF rgb);
std::pair<MemoryBuffer, bool> LoadCCFile(LPCTSTR name, HMIXFILE hMix);
};
#endif

View file

@ -29,12 +29,18 @@ TEST(IniFileGroup, ValidIniWithValidContentTest) {
auto const bldTypes = group.GetSection("BuildingTypes");
auto idx = 0;
//for (auto const& [key, val] : bldTypes) {
for (auto it = bldTypes.begin(); it != bldTypes.end(); ++it) {
auto const& [key, val] = *it;
EXPECT_EQ(val, referenceList[idx++]);
}
// This is to test RHS issue
idx = 0;
for (auto const& [key, val] : group.GetSection("BuildingTypes")) {
EXPECT_EQ(val, referenceList[idx++]);
}
EXPECT_EQ(group.GetString("GACNST", "Strength"), "2000");
}
#endif