Skip to content

Commit

Permalink
Adding dll ini data stuff.
Browse files Browse the repository at this point in the history
  • Loading branch information
MainMemory committed Mar 8, 2015
1 parent e5ee7c1 commit 4a35c7d
Show file tree
Hide file tree
Showing 7 changed files with 224 additions and 10 deletions.
56 changes: 48 additions & 8 deletions src/SADXModLoader/IniFile.cpp
Expand Up @@ -137,6 +137,46 @@ float IniGroup::getFloat(const string &key, float def) const
return (float)strtod(value.c_str(), nullptr);
}

std::unordered_map<string, string>::iterator IniGroup::begin()
{
return m_data.begin();
}

std::unordered_map<string, string>::const_iterator IniGroup::cbegin() const
{
return m_data.cbegin();
}

std::unordered_map<string, string>::reverse_iterator IniGroup::rbegin()
{
return m_data.rbegin();
}

std::unordered_map<string, string>::const_reverse_iterator IniGroup::crbegin() const
{
return m_data.crbegin();
}

std::unordered_map<string, string>::iterator IniGroup::end()
{
return m_data.end();
}

std::unordered_map<string, string>::const_iterator IniGroup::cend() const
{
return m_data.cend();
}

std::unordered_map<string, string>::reverse_iterator IniGroup::rend()
{
return m_data.rend();
}

std::unordered_map<string, string>::const_reverse_iterator IniGroup::crend() const
{
return m_data.crend();
}

/** IniFile **/

IniFile::IniFile(const string &filename)
Expand Down Expand Up @@ -312,42 +352,42 @@ float IniFile::getFloat(const string &section, const string &key, float def) con
return group->getFloat(key, def);
}

std::unordered_map<std::string, IniGroup*>::iterator IniFile::begin()
std::unordered_map<string, IniGroup*>::iterator IniFile::begin()
{
return m_groups.begin();
}

std::unordered_map<std::string, IniGroup*>::const_iterator IniFile::cbegin() const
std::unordered_map<string, IniGroup*>::const_iterator IniFile::cbegin() const
{
return m_groups.cbegin();
}

std::unordered_map<std::string, IniGroup*>::reverse_iterator IniFile::rbegin()
std::unordered_map<string, IniGroup*>::reverse_iterator IniFile::rbegin()
{
return m_groups.rbegin();
}

std::unordered_map<std::string, IniGroup*>::const_reverse_iterator IniFile::crbegin() const
std::unordered_map<string, IniGroup*>::const_reverse_iterator IniFile::crbegin() const
{
return m_groups.crbegin();
}

std::unordered_map<std::string, IniGroup*>::iterator IniFile::end()
std::unordered_map<string, IniGroup*>::iterator IniFile::end()
{
return m_groups.end();
}

std::unordered_map<std::string, IniGroup*>::const_iterator IniFile::cend() const
std::unordered_map<string, IniGroup*>::const_iterator IniFile::cend() const
{
return m_groups.cend();
}

std::unordered_map<std::string, IniGroup*>::reverse_iterator IniFile::rend()
std::unordered_map<string, IniGroup*>::reverse_iterator IniFile::rend()
{
return m_groups.rend();
}

std::unordered_map<std::string, IniGroup*>::const_reverse_iterator IniFile::crend() const
std::unordered_map<string, IniGroup*>::const_reverse_iterator IniFile::crend() const
{
return m_groups.crend();
}
Expand Down
9 changes: 9 additions & 0 deletions src/SADXModLoader/IniFile.hpp
Expand Up @@ -30,6 +30,15 @@ class IniGroup
int getInt(const std::string &key, int def = 0) const;
float getFloat(const std::string &key, float def = 0) const;

std::unordered_map<std::string, std::string>::iterator begin();
std::unordered_map<std::string, std::string>::const_iterator cbegin() const;
std::unordered_map<std::string, std::string>::reverse_iterator rbegin();
std::unordered_map<std::string, std::string>::const_reverse_iterator crbegin() const;
std::unordered_map<std::string, std::string>::iterator end();
std::unordered_map<std::string, std::string>::const_iterator cend() const;
std::unordered_map<std::string, std::string>::reverse_iterator rend();
std::unordered_map<std::string, std::string>::const_reverse_iterator crend() const;

protected:
friend class IniFile;

Expand Down
160 changes: 158 additions & 2 deletions src/SADXModLoader/dllmain.cpp
Expand Up @@ -1572,7 +1572,7 @@ static void ProcessStageLightDataListINI(const IniGroup *group, const wstring &m
ProcessPointerList(group->getString("pointer"), list);
}

static const struct { const char *name; void (__cdecl *func)(const IniGroup *group, const wstring &mod_dir); } exedatafuncarray[] = {
static const struct { const char *name; void (__cdecl *func)(const IniGroup *, const wstring &); } exedatafuncarray[] = {
{ "landtable", ProcessLandTableINI },
{ "model", ProcessModelINI },
{ "basicdxmodel", ProcessModelINI },
Expand Down Expand Up @@ -1601,7 +1601,104 @@ static const struct { const char *name; void (__cdecl *func)(const IniGroup *gro
{ "stagelightdatalist", ProcessStageLightDataListINI }
};

static unordered_map<string, void (__cdecl *)(const IniGroup *group, const wstring &mod_dir)> exedatafuncmap;
static unordered_map<string, void (__cdecl *)(const IniGroup *, const wstring &)> exedatafuncmap;

static unordered_map<string, void *> dlllabels;

static void LoadDLLLandTable(const wstring &path)
{
LandTableInfo *info = new LandTableInfo(path);
auto labels = info->getlabels();
for (auto iter = labels->cbegin(); iter != labels->cend(); iter++)
dlllabels[iter->first] = iter->second;
}

static void LoadDLLModel(const wstring &path)
{
ModelInfo *info = new ModelInfo(path);
auto labels = info->getlabels();
for (auto iter = labels->cbegin(); iter != labels->cend(); iter++)
dlllabels[iter->first] = iter->second;
}

static void LoadDLLAnimation(const wstring &path)
{
AnimationFile *info = new AnimationFile(path);
dlllabels[info->getlabel()] = info->getmotion();
}

static const struct { const char *name; void (__cdecl *func)(const wstring &); } dllfilefuncarray[] = {
{ "landtable", LoadDLLLandTable },
{ "model", LoadDLLModel },
{ "basicdxmodel", LoadDLLModel },
{ "chunkmodel", LoadDLLModel },
{ "animation", LoadDLLAnimation }
};

static unordered_map<string, void (__cdecl *)(const wstring &)> dllfilefuncmap;

static void ProcessLandTableDLL(const IniGroup *group, void *exp)
{
memcpy(exp, dlllabels[group->getString("Label")], sizeof(LandTable));
}

static void ProcessLandTableArrayDLL(const IniGroup *group, void *exp)
{
((LandTable **)exp)[group->getInt("Index")] = (LandTable *)dlllabels[group->getString("Label")];
}

static void ProcessModelDLL(const IniGroup *group, void *exp)
{
memcpy(exp, dlllabels[group->getString("Label")], sizeof(NJS_OBJECT));
}

static void ProcessModelArrayDLL(const IniGroup *group, void *exp)
{
((NJS_OBJECT **)exp)[group->getInt("Index")] = (NJS_OBJECT *)dlllabels[group->getString("Label")];
}

static void ProcessActionArrayDLL(const IniGroup *group, void *exp)
{
string field = group->getString("Field");
NJS_ACTION *act = ((NJS_ACTION **)exp)[group->getInt("Index")];
if (field == "object")
act->object = (NJS_OBJECT *)dlllabels[group->getString("Label")];
else if (field == "motion")
act->motion = (NJS_MOTION *)dlllabels[group->getString("Label")];
}

static const struct { const char *name; void (__cdecl *func)(const IniGroup *, void *); } dlldatafuncarray[] = {
{ "landtable", ProcessLandTableDLL },
{ "landtablearray", ProcessLandTableArrayDLL },
{ "model", ProcessModelDLL },
{ "modelarray", ProcessModelArrayDLL },
{ "basicdxmodel", ProcessModelDLL },
{ "basicdxmodelarray", ProcessModelArrayDLL },
{ "chunkmodel", ProcessModelDLL },
{ "chunkmodelarray", ProcessModelArrayDLL },
{ "actionarray", ProcessActionArrayDLL },
};

static unordered_map<string, void (__cdecl *)(const IniGroup *, void *)> dlldatafuncmap;

static const string dlldatakeys[] = {
"CHRMODELSData",
"ADV00MODELSData",
"ADV01MODELSData",
"ADV01CMODELSData",
"ADV02MODELSData",
"ADV03MODELSData",
"BOSSCHAOS0MODELSData",
"CHAOSTGGARDEN02MR_DAYTIMEData",
"CHAOSTGGARDEN02MR_EVENINGData",
"CHAOSTGGARDEN02MR_NIGHTData"
};

static unordered_map<wstring, HMODULE> dllhandles;

struct dllexportinfo { void *address; string type; };
struct dllexportcontainer { unordered_map<string, dllexportinfo> exports; };
static unordered_map<wstring, dllexportcontainer> dllexports;

static void __cdecl InitMods(void)
{
Expand Down Expand Up @@ -1892,6 +1989,64 @@ static void __cdecl InitMods(void)
}
delete exedata;
}

// Check if the mod has DLL data replacements.
for (unsigned int i = 0; i < LengthOfArray(dlldatakeys); i++)
if (modinfo->hasKeyNonEmpty(dlldatakeys[i]))
{
IniFile *dlldata = new IniFile(mod_dir + L'\\' + modinfo->getWString(dlldatakeys[i]));
if (dllfilefuncmap.size() == 0)
for (unsigned int i = 0; i < LengthOfArray(dllfilefuncarray); i++)
dllfilefuncmap[dllfilefuncarray[i].name] = dllfilefuncarray[i].func;
dlllabels.clear();
const IniGroup *group = dlldata->getGroup("Files");
for (auto iter = group->cbegin(); iter != group->cend(); iter++)
{
auto type = dllfilefuncmap.find(split(iter->second, '|')[0]);
if (type != dllfilefuncmap.end())
type->second(mod_dir + L'\\' + MBStoUTF16(iter->first, CP_UTF8));
}
wstring dllname = dlldata->getWString("", "name");
HMODULE dllhandle;
if (dllhandles.find(dllname) != dllhandles.cend())
dllhandle = dllhandles[dllname];
else
{
dllhandle = GetModuleHandle(dllname.c_str());
dllhandles[dllname] = dllhandle;
}
if (dllexports.find(dllname) == dllexports.end())
{
group = dlldata->getGroup("Exports");
dllexportcontainer exp;
for (auto iter = group->cbegin(); iter != group->cend(); iter++)
{
dllexportinfo inf;
inf.address = GetProcAddress(dllhandle, iter->first.c_str());
inf.type = iter->second;
exp.exports[iter->first] = inf;
}
dllexports[dllname] = exp;
}
const auto exports = &dllexports[dllname].exports;
if (dlldatafuncmap.size() == 0)
for (unsigned int i = 0; i < LengthOfArray(dlldatafuncarray); i++)
dlldatafuncmap[dlldatafuncarray[i].name] = dlldatafuncarray[i].func;
char buf[9];
for (int i = 0; i < 9999; i++)
{
_snprintf(buf, 5, "Item%d", i);
if (dlldata->hasGroup(buf))
{
group = dlldata->getGroup(buf);
const dllexportinfo &exp = (*exports)[group->getString("Export")];
auto type = dlldatafuncmap.find(exp.type);
if (type != dlldatafuncmap.end())
type->second(group, exp.address);
}
}
delete dlldata;
}
}

// Replace filenames. ("ReplaceFiles", "SwapFiles")
Expand Down Expand Up @@ -2047,6 +2202,7 @@ static void __cdecl LoadChrmodels(void)
L"SADX Mod Loader", MB_ICONERROR);
ExitProcess(1);
}
dllhandles[L"CHRMODELS_orig"] = chrmodelshandle;
WriteCall((void *)0x402513, (void *)InitMods);
}

Expand Down
5 changes: 5 additions & 0 deletions src/libmodutils/LandTableInfo.cpp
Expand Up @@ -90,6 +90,11 @@ void *LandTableInfo::getdata(const string &label)
return elem->second;
}

const std::unordered_map<string, void *> *LandTableInfo::getlabels()
{
return &labels2;
}

static string getstring(istream &stream)
{
auto start = stream.tellg();
Expand Down
1 change: 1 addition & 0 deletions src/libmodutils/LandTableInfo.h
Expand Up @@ -30,6 +30,7 @@ class LandTableInfo
const uint8_t *getmetadata(uint32_t identifier, uint32_t &size);
const std::string &getlabel(void *data);
void *getdata(const std::string &label);
const std::unordered_map<std::string, void *> *getlabels();

private:
static const uint64_t SA1LVL = 0x4C564C314153ULL;
Expand Down
2 changes: 2 additions & 0 deletions src/libmodutils/ModelInfo.cpp
Expand Up @@ -92,6 +92,8 @@ void *ModelInfo::getdata(const string &label)
return elem->second;
}

const std::unordered_map<string, void *> *ModelInfo::getlabels() { return &labels2; }

const list<string> &ModelInfo::getanimations() { return animations; }

const list<string> &ModelInfo::getmorphs() { return morphs; }
Expand Down
1 change: 1 addition & 0 deletions src/libmodutils/ModelInfo.h
Expand Up @@ -39,6 +39,7 @@ class ModelInfo
const uint8_t *getmetadata(uint32_t identifier, uint32_t &size);
const std::string &getlabel(void *data);
void *getdata(const std::string &label);
const std::unordered_map<std::string, void *> *getlabels();
const std::list<std::string> &getanimations();
const std::list<std::string> &getmorphs();

Expand Down

0 comments on commit 4a35c7d

Please sign in to comment.