mirror of https://github.com/AxioDL/metaforce.git
began doExtract method
This commit is contained in:
parent
a4d1fdbcfa
commit
07ae1e7379
|
@ -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)
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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;}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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__
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include "DNAMP1.hpp"
|
||||||
|
|
||||||
|
namespace Retro
|
||||||
|
{
|
||||||
|
namespace DNAMP1
|
||||||
|
{
|
||||||
|
LogVisor::LogModule Log("Retro::DNAMP1");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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__
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include "DNAMP2.hpp"
|
||||||
|
|
||||||
|
namespace Retro
|
||||||
|
{
|
||||||
|
namespace DNAMP2
|
||||||
|
{
|
||||||
|
LogVisor::LogModule Log("Retro::DNAMP2");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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__
|
|
@ -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
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include "DNAMP3.hpp"
|
||||||
|
|
||||||
|
namespace Retro
|
||||||
|
{
|
||||||
|
namespace DNAMP3
|
||||||
|
{
|
||||||
|
LogVisor::LogModule Log("Retro::DNAMP3");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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__
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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__
|
|
|
@ -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))
|
||||||
{
|
|
||||||
if (!memcmp(gameID, "R3M", 3))
|
|
||||||
standalone = false;
|
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)
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
2
NODLib
|
@ -1 +1 @@
|
||||||
Subproject commit 993b30e4a5657f8bfb7bd1adedb82244219b66eb
|
Subproject commit 7114f079a45788f5f9ddd6bfca8fa8901d939f9a
|
Loading…
Reference in New Issue