mirror of https://github.com/AxioDL/metaforce.git
Added CRandom16 implementation
This commit is contained in:
parent
a517adcb01
commit
fca9e101a2
|
@ -0,0 +1,142 @@
|
||||||
|
#include <cstddef>
|
||||||
|
#include "CMDL.hpp"
|
||||||
|
#include "DNAMP1.hpp"
|
||||||
|
|
||||||
|
namespace Retro
|
||||||
|
{
|
||||||
|
namespace DNAMP1
|
||||||
|
{
|
||||||
|
|
||||||
|
bool CMDL::ReadToBlender(HECL::BlenderConnection& conn, Athena::io::IStreamReader& reader)
|
||||||
|
{
|
||||||
|
reader.setEndian(Athena::BigEndian);
|
||||||
|
|
||||||
|
CMDL::Header head;
|
||||||
|
head.read(reader);
|
||||||
|
|
||||||
|
if (head.magic != 0xDEADBABE)
|
||||||
|
{
|
||||||
|
Log.report(LogVisor::Error, "invalid CMDL magic");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (head.version != 2)
|
||||||
|
{
|
||||||
|
Log.report(LogVisor::Error, "invalid CMDL version for MP1");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open Py Stream */
|
||||||
|
HECL::BlenderConnection::PyOutStream os = conn.beginPythonOut();
|
||||||
|
os << "bm = bmesh.new();\n";
|
||||||
|
|
||||||
|
for (size_t s=0 ; s<head.secCount ; ++s)
|
||||||
|
{
|
||||||
|
atUint64 secStart = reader.position();
|
||||||
|
|
||||||
|
std::unique_ptr<atVec3f[]> vertPos;
|
||||||
|
std::unique_ptr<atVec3f[]> vertNorm;
|
||||||
|
typedef atInt16 ShortVec3[3];
|
||||||
|
std::unique_ptr<ShortVec3[]> vertNormShort;
|
||||||
|
std::unique_ptr<atVec2f[]> vertUVs;
|
||||||
|
typedef atInt16 ShortVec2[2];
|
||||||
|
std::unique_ptr<ShortVec2[]> vertUVsShort;
|
||||||
|
bool visitedDLOffsets = false;
|
||||||
|
if (s < head.matSetCount)
|
||||||
|
{
|
||||||
|
MaterialSet matSet;
|
||||||
|
matSet.read(reader);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (s-head.matSetCount)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
/* Positions */
|
||||||
|
size_t vertCount = head.secSizes[s] / 12;
|
||||||
|
vertPos.reset(new atVec3f[vertCount]);
|
||||||
|
for (size_t i=0 ; i<vertCount ; ++i)
|
||||||
|
vertPos[i] = reader.readVec3f();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
/* Normals */
|
||||||
|
if (head.flags.shortNormals())
|
||||||
|
{
|
||||||
|
size_t normCount = head.secSizes[s] / 6;
|
||||||
|
vertNormShort.reset(new ShortVec3[normCount]);
|
||||||
|
for (size_t i=0 ; i<normCount ; ++i)
|
||||||
|
{
|
||||||
|
vertNormShort[i][0] = reader.readInt16();
|
||||||
|
vertNormShort[i][1] = reader.readInt16();
|
||||||
|
vertNormShort[i][2] = reader.readInt16();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t normCount = head.secSizes[s] / 12;
|
||||||
|
vertNorm.reset(new atVec3f[normCount]);
|
||||||
|
for (size_t i=0 ; i<normCount ; ++i)
|
||||||
|
vertNorm[i] = reader.readVec3f();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
/* Colors */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
/* Float UVs */
|
||||||
|
size_t uvCount = head.secSizes[s] / 8;
|
||||||
|
vertUVs.reset(new atVec2f[uvCount]);
|
||||||
|
for (size_t i=0 ; i<uvCount ; ++i)
|
||||||
|
vertUVs[i] = reader.readVec2f();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
/* Short UVs */
|
||||||
|
if (head.flags.shortUVs())
|
||||||
|
{
|
||||||
|
size_t uvCount = head.secSizes[s] / 4;
|
||||||
|
vertUVsShort.reset(new ShortVec2[uvCount]);
|
||||||
|
for (size_t i=0 ; i<uvCount ; ++i)
|
||||||
|
{
|
||||||
|
vertUVsShort[i][0] = reader.readInt16();
|
||||||
|
vertUVsShort[i][1] = reader.readInt16();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DL Offsets (here or next section) */
|
||||||
|
visitedDLOffsets = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
if (!visitedDLOffsets)
|
||||||
|
{
|
||||||
|
visitedDLOffsets = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* GX Display List (surface) */
|
||||||
|
SurfaceHeader sHead;
|
||||||
|
sHead.read(reader);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.seek(secStart + head.secSizes[s], Athena::Begin);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,15 +3,59 @@
|
||||||
|
|
||||||
#include "../DNACommon/DNACommon.hpp"
|
#include "../DNACommon/DNACommon.hpp"
|
||||||
#include "CMDLMaterials.hpp"
|
#include "CMDLMaterials.hpp"
|
||||||
|
#include "BlenderConnection.hpp"
|
||||||
|
|
||||||
namespace Retro
|
namespace Retro
|
||||||
{
|
{
|
||||||
namespace DNAMP1
|
namespace DNAMP1
|
||||||
{
|
{
|
||||||
|
|
||||||
struct CMDL : BigDNA
|
struct CMDL
|
||||||
{
|
{
|
||||||
DECL_DNA
|
struct Header : BigDNA
|
||||||
|
{
|
||||||
|
DECL_DNA
|
||||||
|
Value<atUint32> magic;
|
||||||
|
Value<atUint32> version;
|
||||||
|
struct Flags
|
||||||
|
{
|
||||||
|
DECL_DNA
|
||||||
|
Value<atUint32> flags;
|
||||||
|
inline bool shortNormals() const {return (flags & 0x2) != 0;}
|
||||||
|
inline void setShortNormals(bool val) {flags &= ~0x2; flags |= val << 1;}
|
||||||
|
inline bool shortUVs() const {return (flags & 0x4) != 0;}
|
||||||
|
inline void setShortUVs(bool val) {flags &= ~0x4; flags |= val << 2;}
|
||||||
|
} flags;
|
||||||
|
Value<atVec3f> aabbMin;
|
||||||
|
Value<atVec3f> aabbMax;
|
||||||
|
Value<atUint32> secCount;
|
||||||
|
Value<atUint32> matSetCount;
|
||||||
|
Vector<atUint32, DNA_COUNT(secCount)> secSizes;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SurfaceHeader : BigDNA
|
||||||
|
{
|
||||||
|
DECL_DNA
|
||||||
|
Value<atVec3f> centroid;
|
||||||
|
Value<atUint32> matIdx;
|
||||||
|
Value<atInt16> qDiv;
|
||||||
|
Value<atUint16> dlSize;
|
||||||
|
Seek<8, Athena::Current> seek;
|
||||||
|
Value<atUint32> aabbSz;
|
||||||
|
Value<atVec3f> reflectionNormal;
|
||||||
|
Seek<DNA_COUNT(aabbSz), Athena::Current> seek2;
|
||||||
|
Align<32> align;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool ReadToBlender(HECL::BlenderConnection& conn, Athena::io::IStreamReader& reader);
|
||||||
|
|
||||||
|
static bool Extract(PAKEntryReadStream& rs, const HECL::ProjectPath& outPath)
|
||||||
|
{
|
||||||
|
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
|
||||||
|
if (!conn.createBlend(outPath.getAbsolutePath()))
|
||||||
|
return false;
|
||||||
|
return ReadToBlender(conn, rs);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,4 +7,5 @@ add_library(DNAMP1
|
||||||
DNAMP1.hpp DNAMP1.cpp
|
DNAMP1.hpp DNAMP1.cpp
|
||||||
${liblist}
|
${liblist}
|
||||||
PAK.cpp
|
PAK.cpp
|
||||||
STRG.hpp STRG.cpp)
|
STRG.hpp STRG.cpp
|
||||||
|
CMDL.cpp)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "STRG.hpp"
|
#include "STRG.hpp"
|
||||||
#include "MLVL.hpp"
|
#include "MLVL.hpp"
|
||||||
#include "../DNACommon/TXTR.hpp"
|
#include "../DNACommon/TXTR.hpp"
|
||||||
|
#include "CMDL.hpp"
|
||||||
|
|
||||||
namespace Retro
|
namespace Retro
|
||||||
{
|
{
|
||||||
|
@ -52,6 +53,8 @@ ResExtractor PAKBridge::LookupExtractor(const PAK::Entry& entry)
|
||||||
return {STRG::Extract, ".as"};
|
return {STRG::Extract, ".as"};
|
||||||
case SBIG('TXTR'):
|
case SBIG('TXTR'):
|
||||||
return {TXTR::Extract, ".png"};
|
return {TXTR::Extract, ".png"};
|
||||||
|
case SBIG('CMDL'):
|
||||||
|
return {CMDL::Extract, ".blend"};
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
2
NODLib
2
NODLib
|
@ -1 +1 @@
|
||||||
Subproject commit 7fafe3ce0c14f9e244bb47572f5448e82b597a68
|
Subproject commit ebb5c0743da7fafbe4c3945d0117700c43845425
|
|
@ -0,0 +1,2 @@
|
||||||
|
add_library(RetroCore
|
||||||
|
CRandom16.hpp CRandom16.cpp)
|
|
@ -0,0 +1 @@
|
||||||
|
#include "CRandom16.hpp"
|
|
@ -0,0 +1,81 @@
|
||||||
|
#ifndef RETRO_CRANDOM16_HPP
|
||||||
|
#define RETRO_CRANDOM16_HPP
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "CRandom16.hpp"
|
||||||
|
|
||||||
|
namespace Retro
|
||||||
|
{
|
||||||
|
|
||||||
|
extern class CRandom16* GLOBAL_RANDOM;
|
||||||
|
extern class CGlobalRandom* GLOBAL_RANDOM_TOKEN;
|
||||||
|
|
||||||
|
class CRandom16
|
||||||
|
{
|
||||||
|
uint32_t m_seed;
|
||||||
|
public:
|
||||||
|
CRandom16(uint32_t p) : m_seed(p) {}
|
||||||
|
|
||||||
|
inline uint32_t Next()
|
||||||
|
{
|
||||||
|
m_seed = m_seed * 0x41c64e6d + 0x00003039;
|
||||||
|
return m_seed >> 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t GetSeed() const
|
||||||
|
{
|
||||||
|
return m_seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SetSeed(time_t p)
|
||||||
|
{
|
||||||
|
m_seed = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Float()
|
||||||
|
{
|
||||||
|
return Next() * 0.000015259022;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Range(float min, float max)
|
||||||
|
{
|
||||||
|
return min + Float() * (max - min);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int32_t Range(int32_t min, int32_t max)
|
||||||
|
{
|
||||||
|
uint32_t diff = max - min;
|
||||||
|
uint32_t rand = 0xffffffff;
|
||||||
|
while (rand == 0xffffffff)
|
||||||
|
rand = (Next() << 16) | Next();
|
||||||
|
return rand % diff + min;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CRandom16* GetRandomNumber() {return GLOBAL_RANDOM;}
|
||||||
|
static void SetRandomNumber(CRandom16* rnd) {GLOBAL_RANDOM = rnd;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CGlobalRandom
|
||||||
|
{
|
||||||
|
CRandom16& m_random;
|
||||||
|
CGlobalRandom* m_prev;
|
||||||
|
public:
|
||||||
|
CGlobalRandom(CRandom16& rand)
|
||||||
|
: m_random(rand), m_prev(GLOBAL_RANDOM_TOKEN)
|
||||||
|
{
|
||||||
|
GLOBAL_RANDOM_TOKEN = this;
|
||||||
|
CRandom16::SetRandomNumber(&m_random);
|
||||||
|
}
|
||||||
|
~CGlobalRandom()
|
||||||
|
{
|
||||||
|
GLOBAL_RANDOM_TOKEN = m_prev;
|
||||||
|
if (m_prev)
|
||||||
|
CRandom16::SetRandomNumber(&m_prev->m_random);
|
||||||
|
else
|
||||||
|
CRandom16::SetRandomNumber(nullptr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // RETRO_CRANDOM16_HPP
|
Loading…
Reference in New Issue