began doExtract method

This commit is contained in:
Jack Andersen 2015-07-15 15:57:34 -10:00
parent a4d1fdbcfa
commit 07ae1e7379
31 changed files with 274 additions and 64 deletions

View File

@ -3,6 +3,7 @@ project(RetroCommon)
if (NOT TARGET NOD) if (NOT TARGET NOD)
add_subdirectory(NODLib) add_subdirectory(NODLib)
endif() endif()
include_directories(${ATHENA_INCLUDE_DIR} ${LOG_VISOR_INCLUDE_DIR}) include_directories(${ATHENA_INCLUDE_DIR} ${LOG_VISOR_INCLUDE_DIR} ${ANGELSCRIPT_INCLUDE_DIR})
set(NOD_LIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/NODLib/include)
add_subdirectory(DataSpec) add_subdirectory(DataSpec)
add_subdirectory(Runtime) add_subdirectory(Runtime)

View File

@ -3,6 +3,8 @@
namespace Retro namespace Retro
{ {
LogVisor::LogModule LogDNACommon("Retro::DNACommon");
const HECL::FourCC ENGL("ENGL"); const HECL::FourCC ENGL("ENGL");
const HECL::FourCC FREN("FREN"); const HECL::FourCC FREN("FREN");
const HECL::FourCC GERM("GERM"); const HECL::FourCC GERM("GERM");

View File

@ -3,11 +3,12 @@
#include <Athena/DNA.hpp> #include <Athena/DNA.hpp>
#include "HECL/HECL.hpp" #include "HECL/HECL.hpp"
#include "../Logging.hpp"
namespace Retro namespace Retro
{ {
extern LogVisor::LogModule LogDNACommon;
/* This comes up a great deal */ /* This comes up a great deal */
typedef Athena::io::DNA<Athena::BigEndian> BigDNA; typedef Athena::io::DNA<Athena::BigEndian> BigDNA;
@ -151,7 +152,7 @@ public:
: m_buf(std::move(buf)), m_sz(sz), m_pos(pos) : m_buf(std::move(buf)), m_sz(sz), m_pos(pos)
{ {
if (m_pos >= m_sz) if (m_pos >= m_sz)
LogModule.report(LogVisor::FatalError, "PAK stream cursor overrun"); LogDNACommon.report(LogVisor::FatalError, "PAK stream cursor overrun");
} }
inline void seek(atInt64 pos, Athena::SeekOrigin origin) inline void seek(atInt64 pos, Athena::SeekOrigin origin)
{ {
@ -162,7 +163,7 @@ public:
else if (origin == Athena::End) else if (origin == Athena::End)
m_pos = m_sz + pos; m_pos = m_sz + pos;
if (m_pos >= m_sz) if (m_pos >= m_sz)
LogModule.report(LogVisor::FatalError, "PAK stream cursor overrun"); LogDNACommon.report(LogVisor::FatalError, "PAK stream cursor overrun");
} }
inline atUint64 position() const {return m_pos;} inline atUint64 position() const {return m_pos;}
inline atUint64 length() const {return m_sz;} inline atUint64 length() const {return m_sz;}

View File

@ -5,13 +5,16 @@
namespace Retro namespace Retro
{ {
HECL::Database::ASListType<std::string> ASTYPE_STRGLanguage("STRG", "Language", "string");
std::unique_ptr<ISTRG> LoadSTRG(Athena::io::IStreamReader& reader) std::unique_ptr<ISTRG> LoadSTRG(Athena::io::IStreamReader& reader)
{ {
reader.setEndian(Athena::BigEndian); reader.setEndian(Athena::BigEndian);
uint32_t magic = reader.readUint32(); uint32_t magic = reader.readUint32();
if (magic != 0x87654321) if (magic != 0x87654321)
{ {
LogModule.report(LogVisor::Error, "invalid STRG magic"); LogDNACommon.report(LogVisor::Error, "invalid STRG magic");
return std::unique_ptr<ISTRG>(); return std::unique_ptr<ISTRG>();
} }
@ -20,19 +23,19 @@ std::unique_ptr<ISTRG> LoadSTRG(Athena::io::IStreamReader& reader)
{ {
case 0: case 0:
{ {
DNAMP1::STRG* newStrg = new struct DNAMP1::STRG; DNAMP1::STRG* newStrg = new DNAMP1::STRG;
newStrg->_read(reader); newStrg->_read(reader);
return std::unique_ptr<ISTRG>(newStrg); return std::unique_ptr<ISTRG>(newStrg);
} }
case 1: case 1:
{ {
DNAMP2::STRG* newStrg = new struct DNAMP2::STRG; DNAMP2::STRG* newStrg = new DNAMP2::STRG;
newStrg->_read(reader); newStrg->_read(reader);
return std::unique_ptr<ISTRG>(newStrg); return std::unique_ptr<ISTRG>(newStrg);
} }
case 3: case 3:
{ {
DNAMP3::STRG* newStrg = new struct DNAMP3::STRG; DNAMP3::STRG* newStrg = new DNAMP3::STRG;
newStrg->_read(reader); newStrg->_read(reader);
return std::unique_ptr<ISTRG>(newStrg); return std::unique_ptr<ISTRG>(newStrg);
} }

View File

@ -2,21 +2,31 @@
#define __COMMON_STRG_HPP__ #define __COMMON_STRG_HPP__
#include <string> #include <string>
#include <fstream>
#include <angelscript.h>
#include <HECL/HECL.hpp> #include <HECL/HECL.hpp>
#include <HECL/Database.hpp>
#include "DNACommon.hpp" #include "DNACommon.hpp"
#include "../Logging.hpp"
namespace Retro namespace Retro
{ {
struct ISTRG struct ISTRG
{ {
virtual ~ISTRG() {}
virtual size_t count() const=0; virtual size_t count() const=0;
virtual std::string getUTF8(const FourCC& lang, size_t idx) const=0; virtual std::string getUTF8(const FourCC& lang, size_t idx) const=0;
virtual std::wstring getUTF16(const FourCC& lang, size_t idx) const=0; virtual std::wstring getUTF16(const FourCC& lang, size_t idx) const=0;
virtual HECL::SystemString getSystemString(const FourCC& lang, size_t idx) const=0; virtual HECL::SystemString getSystemString(const FourCC& lang, size_t idx) const=0;
virtual int32_t lookupIdx(const std::string& name) const=0; virtual int32_t lookupIdx(const std::string& name) const=0;
virtual bool readAngelScript(const AngelScript::asIScriptModule& in)=0;
virtual void writeAngelScript(std::ofstream& out) const=0;
}; };
std::unique_ptr<ISTRG> LoadSTRG(Athena::io::IStreamReader& reader); std::unique_ptr<ISTRG> LoadSTRG(Athena::io::IStreamReader& reader);
extern HECL::Database::ASListType<std::string> ASTYPE_STRGLanguage;
} }
#endif // __COMMON_STRG_HPP__ #endif // __COMMON_STRG_HPP__

View File

@ -2,6 +2,9 @@ make_dnalist(liblist
PAK PAK
MLVL MLVL
STRG) STRG)
add_library(DNAMP1 ${liblist} add_library(DNAMP1
DNAMP1.hpp
DNAMP1.cpp
${liblist}
PAK.cpp PAK.cpp
STRG.cpp) STRG.cpp)

View File

@ -0,0 +1,9 @@
#include "DNAMP1.hpp"
namespace Retro
{
namespace DNAMP1
{
LogVisor::LogModule Log("Retro::DNAMP1");
}
}

View File

@ -0,0 +1,16 @@
#ifndef __DNAMP1_HPP__
#define __DNAMP1_HPP__
#include "../DNACommon/DNACommon.hpp"
namespace Retro
{
namespace DNAMP1
{
extern LogVisor::LogModule Log;
}
}
#endif // __DNAMP1_HPP__

View File

@ -1,5 +1,6 @@
#include <zlib.h> #include <zlib.h>
#include <lzo/lzo1x.h> #include <lzo/lzo1x.h>
#include "DNAMP1.hpp"
#include "PAK.hpp" #include "PAK.hpp"
namespace Retro namespace Retro
@ -12,7 +13,7 @@ void PAK::read(Athena::io::IStreamReader& reader)
reader.setEndian(Athena::BigEndian); reader.setEndian(Athena::BigEndian);
atUint32 version = reader.readUint32(); atUint32 version = reader.readUint32();
if (version != 0x00030005) if (version != 0x00030005)
LogModule.report(LogVisor::FatalError, "unexpected PAK magic"); Log.report(LogVisor::FatalError, "unexpected PAK magic");
reader.readUint32(); reader.readUint32();
atUint32 nameCount = reader.readUint32(); atUint32 nameCount = reader.readUint32();

View File

@ -4,7 +4,6 @@
#include <unordered_map> #include <unordered_map>
#include <NOD/DiscBase.hpp> #include <NOD/DiscBase.hpp>
#include "../Logging.hpp"
#include "../DNACommon/DNACommon.hpp" #include "../DNACommon/DNACommon.hpp"
namespace Retro namespace Retro

View File

@ -1,5 +1,5 @@
#include "STRG.hpp" #include "STRG.hpp"
#include "../Logging.hpp" #include "DNAMP1.hpp"
namespace Retro namespace Retro
{ {
@ -38,11 +38,11 @@ void STRG::read(Athena::io::IStreamReader& reader)
reader.setEndian(Athena::BigEndian); reader.setEndian(Athena::BigEndian);
atUint32 magic = reader.readUint32(); atUint32 magic = reader.readUint32();
if (magic != 0x87654321) if (magic != 0x87654321)
LogModule.report(LogVisor::Error, "invalid STRG magic"); Log.report(LogVisor::Error, "invalid STRG magic");
atUint32 version = reader.readUint32(); atUint32 version = reader.readUint32();
if (version != 0) if (version != 0)
LogModule.report(LogVisor::Error, "invalid STRG version"); Log.report(LogVisor::Error, "invalid STRG version");
_read(reader); _read(reader);
} }
@ -106,5 +106,65 @@ void STRG::write(Athena::io::IStreamWriter& writer) const
} }
} }
bool STRG::readAngelScript(const AngelScript::asIScriptModule& in)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> wconv;
/* Validate pass */
for (AngelScript::asUINT i=0 ; i<in.GetGlobalVarCount() ; ++i)
{
const char* name;
int typeId;
if (in.GetGlobalVar(i, &name, 0, &typeId) < 0)
continue;
if (typeId == ASTYPE_STRGLanguage.getTypeID())
{
if (strlen(name) != 4)
{
Log.report(LogVisor::Error, "STRG language string '%s' from %s must be exactly 4 characters", name, in.GetName());
return false;
}
}
}
/* Read pass */
for (AngelScript::asUINT i=0 ; i<in.GetGlobalVarCount() ; ++i)
{
const char* name;
int typeId;
if (in.GetGlobalVar(i, &name, 0, &typeId) < 0)
continue;
if (typeId == ASTYPE_STRGLanguage.getTypeID())
{
const std::vector<std::string*>& strsin = ASTYPE_STRGLanguage.vectorCast(in.GetAddressOfGlobalVar(i));
std::vector<std::wstring> strs;
for (const std::string* str : strsin)
strs.emplace_back(wconv.from_bytes(*str));
langs.emplace(std::make_pair(FourCC(name), strs));
}
}
return true;
}
void STRG::writeAngelScript(std::ofstream& out) const
{
std::wbuffer_convert<std::codecvt_utf8<wchar_t>> wconv(out.rdbuf());
std::wostream wout(&wconv);
for (const std::pair<FourCC, std::vector<std::wstring>>& lang : langs)
{
out << "STRG::Language " << lang.first.toString() << "({";
bool comma = false;
for (const std::wstring& str : lang.second)
{
out << (comma?", \"":"\"");
wout << str;
out << "\"";
comma = true;
}
out << "});\n";
}
}
} }
} }

View File

@ -21,7 +21,7 @@ struct STRG : ISTRG, BigDNA
inline size_t count() const inline size_t count() const
{ {
size_t retval = 0; size_t retval = 0;
for (auto item : langs) for (const auto& item : langs)
{ {
size_t sz = item.second.size(); size_t sz = item.second.size();
if (sz > retval) if (sz > retval)
@ -54,6 +54,9 @@ struct STRG : ISTRG, BigDNA
#endif #endif
return std::string(); return std::string();
} }
bool readAngelScript(const AngelScript::asIScriptModule& in);
void writeAngelScript(std::ofstream& out) const;
}; };
} }

View File

@ -1,5 +1,8 @@
make_dnalist(liblist make_dnalist(liblist
MLVL MLVL
STRG) STRG)
add_library(DNAMP2 ${liblist} add_library(DNAMP2
DNAMP2.hpp
DNAMP2.cpp
${liblist}
STRG.cpp) STRG.cpp)

View File

@ -0,0 +1,9 @@
#include "DNAMP2.hpp"
namespace Retro
{
namespace DNAMP2
{
LogVisor::LogModule Log("Retro::DNAMP2");
}
}

View File

@ -0,0 +1,16 @@
#ifndef __DNAMP2_HPP__
#define __DNAMP2_HPP__
#include "../DNACommon/DNACommon.hpp"
namespace Retro
{
namespace DNAMP2
{
extern LogVisor::LogModule Log;
}
}
#endif // __DNAMP2_HPP__

View File

@ -1,5 +1,5 @@
#include "STRG.hpp" #include "STRG.hpp"
#include "../Logging.hpp" #include "DNAMP2.hpp"
namespace Retro namespace Retro
{ {
@ -53,11 +53,11 @@ void STRG::read(Athena::io::IStreamReader& reader)
reader.setEndian(Athena::BigEndian); reader.setEndian(Athena::BigEndian);
atUint32 magic = reader.readUint32(); atUint32 magic = reader.readUint32();
if (magic != 0x87654321) if (magic != 0x87654321)
LogModule.report(LogVisor::Error, "invalid STRG magic"); Log.report(LogVisor::Error, "invalid STRG magic");
atUint32 version = reader.readUint32(); atUint32 version = reader.readUint32();
if (version != 1) if (version != 1)
LogModule.report(LogVisor::Error, "invalid STRG version"); Log.report(LogVisor::Error, "invalid STRG version");
_read(reader); _read(reader);
} }
@ -134,5 +134,13 @@ void STRG::write(Athena::io::IStreamWriter& writer) const
} }
} }
bool STRG::readAngelScript(const AngelScript::asIScriptModule& in)
{
}
void STRG::writeAngelScript(std::ofstream& out) const
{
}
} }
} }

View File

@ -28,7 +28,7 @@ struct STRG : ISTRG, BigDNA
inline size_t count() const inline size_t count() const
{ {
size_t retval = 0; size_t retval = 0;
for (auto item : langs) for (const auto& item : langs)
{ {
size_t sz = item.second.size(); size_t sz = item.second.size();
if (sz > retval) if (sz > retval)
@ -61,6 +61,9 @@ struct STRG : ISTRG, BigDNA
#endif #endif
return std::string(); return std::string();
} }
bool readAngelScript(const AngelScript::asIScriptModule& in);
void writeAngelScript(std::ofstream& out) const;
}; };
} }

View File

@ -2,6 +2,9 @@ make_dnalist(liblist
PAK PAK
MLVL MLVL
STRG) STRG)
add_library(DNAMP3 ${liblist} add_library(DNAMP3
DNAMP3.hpp
DNAMP3.cpp
${liblist}
PAK.cpp PAK.cpp
STRG.cpp) STRG.cpp)

View File

@ -0,0 +1,9 @@
#include "DNAMP3.hpp"
namespace Retro
{
namespace DNAMP3
{
LogVisor::LogModule Log("Retro::DNAMP3");
}
}

View File

@ -0,0 +1,16 @@
#ifndef __DNAMP3_HPP__
#define __DNAMP3_HPP__
#include "../DNACommon/DNACommon.hpp"
namespace Retro
{
namespace DNAMP3
{
extern LogVisor::LogModule Log;
}
}
#endif // __DNAMP3_HPP__

View File

@ -1,4 +1,5 @@
#include "PAK.hpp" #include "PAK.hpp"
#include "DNAMP3.hpp"
namespace Retro namespace Retro
{ {
@ -12,7 +13,7 @@ void PAK::read(Athena::io::IStreamReader& reader)
reader.setEndian(Athena::BigEndian); reader.setEndian(Athena::BigEndian);
m_header.read(reader); m_header.read(reader);
if (m_header.version != 2) if (m_header.version != 2)
LogModule.report(LogVisor::FatalError, "unexpected PAK magic"); Log.report(LogVisor::FatalError, "unexpected PAK magic");
reader.seek(8, Athena::Current); reader.seek(8, Athena::Current);
atUint32 strgSz = reader.readUint32(); atUint32 strgSz = reader.readUint32();
@ -115,7 +116,7 @@ std::unique_ptr<atUint8[]> PAK::Entry::getBuffer(const NOD::DiscBase::IPartition
strm->read(&head, 8); strm->read(&head, 8);
if (head.magic != CMPD) if (head.magic != CMPD)
{ {
LogModule.report(LogVisor::Error, "invalid CMPD block"); Log.report(LogVisor::Error, "invalid CMPD block");
return std::unique_ptr<atUint8[]>(); return std::unique_ptr<atUint8[]>();
} }
head.blockCount = HECL::SBig(head.blockCount); head.blockCount = HECL::SBig(head.blockCount);

View File

@ -6,7 +6,6 @@
#include <lzo/lzo1x.h> #include <lzo/lzo1x.h>
#include <NOD/DiscBase.hpp> #include <NOD/DiscBase.hpp>
#include "../DNACommon/DNACommon.hpp" #include "../DNACommon/DNACommon.hpp"
#include "../Logging.hpp"
namespace Retro namespace Retro
{ {

View File

@ -1,5 +1,5 @@
#include "STRG.hpp" #include "STRG.hpp"
#include "../Logging.hpp" #include "DNAMP3.hpp"
namespace Retro namespace Retro
{ {
@ -67,14 +67,14 @@ void STRG::read(Athena::io::IStreamReader& reader)
atUint32 magic = reader.readUint32(); atUint32 magic = reader.readUint32();
if (magic != 0x87654321) if (magic != 0x87654321)
{ {
LogModule.report(LogVisor::Error, "invalid STRG magic"); Log.report(LogVisor::Error, "invalid STRG magic");
return; return;
} }
atUint32 version = reader.readUint32(); atUint32 version = reader.readUint32();
if (version != 3) if (version != 3)
{ {
LogModule.report(LogVisor::Error, "invalid STRG version"); Log.report(LogVisor::Error, "invalid STRG version");
return; return;
} }
@ -142,5 +142,13 @@ void STRG::write(Athena::io::IStreamWriter& writer) const
} }
} }
bool STRG::readAngelScript(const AngelScript::asIScriptModule& in)
{
}
void STRG::writeAngelScript(std::ofstream& out) const
{
}
} }
} }

View File

@ -28,7 +28,7 @@ struct STRG : ISTRG, BigDNA
inline size_t count() const inline size_t count() const
{ {
size_t retval = 0; size_t retval = 0;
for (auto item : langs) for (const auto& item : langs)
{ {
size_t sz = item.second.size(); size_t sz = item.second.size();
if (sz > retval) if (sz > retval)
@ -61,6 +61,9 @@ struct STRG : ISTRG, BigDNA
#endif #endif
return std::string(); return std::string();
} }
bool readAngelScript(const AngelScript::asIScriptModule& in);
void writeAngelScript(std::ofstream& out) const;
}; };
} }

View File

@ -1,11 +0,0 @@
#ifndef __RETRO_DATASPEC_LOGGING__
#define __RETRO_DATASPEC_LOGGING__
#include <LogVisor/LogVisor.hpp>
namespace Retro
{
extern LogVisor::LogModule LogModule;
}
#endif // __RETRO_DATASPEC_LOGGING__

View File

@ -3,27 +3,22 @@
namespace Retro namespace Retro
{ {
LogVisor::LogModule LogModule("RetroDataSpec");
bool SpecBase::canExtract(const ExtractPassInfo& info, std::vector<ExtractReport>& reps) bool SpecBase::canExtract(const ExtractPassInfo& info, std::vector<ExtractReport>& reps)
{ {
bool isWii; bool isWii;
std::unique_ptr<NOD::DiscBase> disc = NOD::OpenDiscFromImage(info.srcpath.c_str(), isWii); m_disc = NOD::OpenDiscFromImage(info.srcpath.c_str(), isWii);
if (!disc) if (!m_disc)
return false; return false;
const char* gameID = disc->getHeader().gameID; const char* gameID = m_disc->getHeader().gameID;
bool standalone = true; bool standalone = true;
if (isWii) if (isWii && !memcmp(gameID, "R3M", 3))
{ standalone = false;
if (!memcmp(gameID, "R3M", 3))
standalone = false;
}
if (standalone && !checkStandaloneID(gameID)) if (standalone && !checkStandaloneID(gameID))
return false; return false;
char region = disc->getHeader().gameID[3]; char region = m_disc->getHeader().gameID[3];
static const HECL::SystemString regNONE = _S(""); static const HECL::SystemString regNONE = _S("");
static const HECL::SystemString regE = _S("NTSC"); static const HECL::SystemString regE = _S("NTSC");
static const HECL::SystemString regJ = _S("NTSC-J"); static const HECL::SystemString regJ = _S("NTSC-J");
@ -43,13 +38,14 @@ bool SpecBase::canExtract(const ExtractPassInfo& info, std::vector<ExtractReport
} }
if (standalone) if (standalone)
return checkFromStandaloneDisc(*disc.get(), *regstr, info.extractArgs, reps); return checkFromStandaloneDisc(*m_disc.get(), *regstr, info.extractArgs, reps);
else else
return checkFromTrilogyDisc(*disc.get(), *regstr, info.extractArgs, reps); return checkFromTrilogyDisc(*m_disc.get(), *regstr, info.extractArgs, reps);
} }
void SpecBase::doExtract(const HECL::Database::Project& project, const ExtractPassInfo& info) void SpecBase::doExtract(const HECL::Database::Project& project, const ExtractPassInfo&)
{ {
extractFromDisc(*m_disc.get(), project);
} }
bool SpecBase::canCook(const HECL::Database::Project& project, const CookTaskInfo& info) bool SpecBase::canCook(const HECL::Database::Project& project, const CookTaskInfo& info)

View File

@ -9,8 +9,6 @@
namespace Retro namespace Retro
{ {
extern LogVisor::LogModule LogModule;
struct SpecBase : HECL::Database::IDataSpec struct SpecBase : HECL::Database::IDataSpec
{ {
bool canExtract(const ExtractPassInfo& info, std::vector<ExtractReport>& reps); bool canExtract(const ExtractPassInfo& info, std::vector<ExtractReport>& reps);
@ -33,7 +31,7 @@ struct SpecBase : HECL::Database::IDataSpec
const HECL::SystemString& regstr, const HECL::SystemString& regstr,
const std::vector<HECL::SystemString>& args, const std::vector<HECL::SystemString>& args,
std::vector<ExtractReport>& reps)=0; std::vector<ExtractReport>& reps)=0;
virtual bool extractFromDisc()=0; virtual bool extractFromDisc(NOD::DiscBase& disc, const HECL::Database::Project& project)=0;
virtual bool checkFromProject(HECL::Database::Project& proj)=0; virtual bool checkFromProject(HECL::Database::Project& proj)=0;
virtual bool readFromProject(HECL::Database::Project& proj)=0; virtual bool readFromProject(HECL::Database::Project& proj)=0;
@ -49,6 +47,9 @@ struct SpecBase : HECL::Database::IDataSpec
virtual bool visitAreas(std::function<bool(const IAreaSpec&)>)=0; virtual bool visitAreas(std::function<bool(const IAreaSpec&)>)=0;
}; };
virtual bool visitLevels(std::function<bool(const ILevelSpec&)>)=0; virtual bool visitLevels(std::function<bool(const ILevelSpec&)>)=0;
private:
std::unique_ptr<NOD::DiscBase> m_disc;
}; };
} }

View File

@ -1,4 +1,5 @@
#include <utility> #include <utility>
#include <stdio.h>
#define NOD_ATHENA 1 #define NOD_ATHENA 1
#include "SpecBase.hpp" #include "SpecBase.hpp"
@ -9,6 +10,8 @@
namespace Retro namespace Retro
{ {
static LogVisor::LogModule Log("Retro::SpecMP1");
struct SpecMP1 : SpecBase struct SpecMP1 : SpecBase
{ {
bool checkStandaloneID(const char* id) const bool checkStandaloneID(const char* id) const
@ -95,7 +98,7 @@ struct SpecMP1 : SpecBase
m_orderedPaks[dpak.node.getName()] = &dpak; m_orderedPaks[dpak.node.getName()] = &dpak;
/* Assemble extract report */ /* Assemble extract report */
for (std::pair<std::string, DiscPAK*> item : m_orderedPaks) for (const std::pair<std::string, DiscPAK*>& item : m_orderedPaks)
{ {
rep.childOpts.emplace_back(); rep.childOpts.emplace_back();
ExtractReport& childRep = rep.childOpts.back(); ExtractReport& childRep = rep.childOpts.back();
@ -205,8 +208,36 @@ struct SpecMP1 : SpecBase
return true; return true;
} }
bool extractFromDisc()
bool extractFromDisc(NOD::DiscBase& disc, const HECL::Database::Project& project)
{ {
HECL::ProjectPath mp1Path(project.getProjectRootPath(), "MP1");
for (const DiscPAK& pak : m_paks)
{
const std::string& name = pak.node.getName();
std::string::const_iterator extit = name.end() - 4;
std::string baseName(name.begin(), extit);
HECL::ProjectPath pakPath(mp1Path, baseName);
for (const std::pair<UniqueID32, DNAMP1::PAK::Entry*>& item : pak.pak.m_idMap)
{
if (item.second->type == STRG)
{
DNAMP1::STRG strg;
PAKEntryReadStream strgIn = item.second->beginReadStream(pak.node);
strg.read(strgIn);
HECL::SystemChar strgPath[1024];
HECL::SNPrintf(strgPath, 1024, _S("%s/%08X.strg"), pakPath.getAbsolutePath().c_str(), item.second->id.toUint32());
std::ofstream strgOut(strgPath);
strg.writeAngelScript(strgOut);
}
}
}
return true;
} }
bool checkFromProject(HECL::Database::Project& proj) bool checkFromProject(HECL::Database::Project& proj)

View File

@ -9,6 +9,8 @@
namespace Retro namespace Retro
{ {
static LogVisor::LogModule Log("Retro::SpecMP2");
struct SpecMP2 : SpecBase struct SpecMP2 : SpecBase
{ {
bool checkStandaloneID(const char* id) const bool checkStandaloneID(const char* id) const
@ -95,7 +97,7 @@ struct SpecMP2 : SpecBase
m_orderedPaks[dpak.node.getName()] = &dpak; m_orderedPaks[dpak.node.getName()] = &dpak;
/* Assemble extract report */ /* Assemble extract report */
for (std::pair<std::string, DiscPAK*> item : m_orderedPaks) for (const std::pair<std::string, DiscPAK*>& item : m_orderedPaks)
{ {
rep.childOpts.emplace_back(); rep.childOpts.emplace_back();
ExtractReport& childRep = rep.childOpts.back(); ExtractReport& childRep = rep.childOpts.back();
@ -205,7 +207,8 @@ struct SpecMP2 : SpecBase
return true; return true;
} }
bool extractFromDisc()
bool extractFromDisc(NOD::DiscBase& disc, const HECL::Database::Project& project)
{ {
} }

View File

@ -10,6 +10,8 @@
namespace Retro namespace Retro
{ {
static LogVisor::LogModule Log("Retro::SpecMP3");
struct SpecMP3 : SpecBase struct SpecMP3 : SpecBase
{ {
bool checkStandaloneID(const char* id) const bool checkStandaloneID(const char* id) const
@ -96,7 +98,7 @@ struct SpecMP3 : SpecBase
m_orderedPaks[dpak.node.getName()] = &dpak; m_orderedPaks[dpak.node.getName()] = &dpak;
/* Assemble extract report */ /* Assemble extract report */
for (std::pair<std::string, DiscPAK*> item : m_orderedPaks) for (const std::pair<std::string, DiscPAK*>& item : m_orderedPaks)
{ {
rep.childOpts.emplace_back(); rep.childOpts.emplace_back();
ExtractReport& childRep = rep.childOpts.back(); ExtractReport& childRep = rep.childOpts.back();
@ -105,6 +107,7 @@ struct SpecMP3 : SpecBase
continue; continue;
else if (!item.first.compare("Metroid6.pak")) else if (!item.first.compare("Metroid6.pak"))
{ {
/* Phaaze doesn't have a world name D: */
childRep.desc = _S("Phaaze"); childRep.desc = _S("Phaaze");
continue; continue;
} }
@ -219,7 +222,8 @@ struct SpecMP3 : SpecBase
return true; return true;
} }
bool extractFromDisc()
bool extractFromDisc(NOD::DiscBase& disc, const HECL::Database::Project& project)
{ {
} }

2
NODLib

@ -1 +1 @@
Subproject commit 993b30e4a5657f8bfb7bd1adedb82244219b66eb Subproject commit 7114f079a45788f5f9ddd6bfca8fa8901d939f9a