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 "CMDLMaterials.hpp"
|
||||
#include "BlenderConnection.hpp"
|
||||
|
||||
namespace Retro
|
||||
{
|
||||
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
|
||||
${liblist}
|
||||
PAK.cpp
|
||||
STRG.hpp STRG.cpp)
|
||||
STRG.hpp STRG.cpp
|
||||
CMDL.cpp)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "STRG.hpp"
|
||||
#include "MLVL.hpp"
|
||||
#include "../DNACommon/TXTR.hpp"
|
||||
#include "CMDL.hpp"
|
||||
|
||||
namespace Retro
|
||||
{
|
||||
|
@ -52,6 +53,8 @@ ResExtractor PAKBridge::LookupExtractor(const PAK::Entry& entry)
|
|||
return {STRG::Extract, ".as"};
|
||||
case SBIG('TXTR'):
|
||||
return {TXTR::Extract, ".png"};
|
||||
case SBIG('CMDL'):
|
||||
return {CMDL::Extract, ".blend"};
|
||||
}
|
||||
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