mirror of https://github.com/AxioDL/metaforce.git
CScriptMidi and work on CGameArea loading
This commit is contained in:
parent
628e5b41df
commit
e923d83617
|
@ -70,6 +70,10 @@ void AROTBuilder::Node::nodeCount(size_t& sz, size_t& idxRefs, BitmapPool& bmpPo
|
|||
if (poolIdx > 65535)
|
||||
Log.report(logvisor::Fatal, "AROT bitmap exceeds 16-bit node addressing; area too complex");
|
||||
|
||||
uint32_t childCount = AROTChildCounts[flags];
|
||||
nodeOff = curOff;
|
||||
nodeSz = childCount * 2 + 4;
|
||||
curOff += nodeSz;
|
||||
if (childNodes.size())
|
||||
{
|
||||
for (int i=0 ; i < 1 + ((flags & 0x1) != 0) ; ++i)
|
||||
|
@ -82,10 +86,6 @@ void AROTBuilder::Node::nodeCount(size_t& sz, size_t& idxRefs, BitmapPool& bmpPo
|
|||
}
|
||||
}
|
||||
}
|
||||
uint32_t childCount = AROTChildCounts[flags];
|
||||
nodeOff = curOff;
|
||||
nodeSz = childCount * 2 + 4;
|
||||
curOff += nodeSz;
|
||||
idxRefs += childCount;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,6 +270,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
|
|||
{
|
||||
addedPaths.insert(path.hash());
|
||||
urde::SObjectTag tag = g_curSpec->BuildTagFromPath(path, btok);
|
||||
if (tag.id != -1)
|
||||
areaOut.deps.emplace_back(tag.id, tag.type);
|
||||
}
|
||||
}
|
||||
|
@ -308,11 +309,13 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
|
|||
{
|
||||
addedPaths.insert(path.hash());
|
||||
urde::SObjectTag tag = g_curSpec->BuildTagFromPath(path, btok);
|
||||
if (tag.id != -1)
|
||||
areaOut.deps.emplace_back(tag.id, tag.type);
|
||||
}
|
||||
}
|
||||
|
||||
urde::SObjectTag tag = g_curSpec->BuildTagFromPath(areaPath, btok);
|
||||
if (tag.id != -1)
|
||||
areaOut.deps.emplace_back(tag.id, tag.type);
|
||||
}
|
||||
|
||||
|
|
|
@ -518,7 +518,7 @@ bool MREA::PCCook(const hecl::ProjectPath& outPath,
|
|||
}
|
||||
}
|
||||
if (!good)
|
||||
secs.emplace_back(0, 0);
|
||||
secs.emplace_back(4, 0);
|
||||
}
|
||||
|
||||
/* PATH */
|
||||
|
|
|
@ -13,11 +13,11 @@ struct Midi : IScriptObject
|
|||
{
|
||||
DECL_YAML
|
||||
String<-1> name;
|
||||
Value<bool> unknown1;
|
||||
Value<bool> active;
|
||||
UniqueID32 song;
|
||||
Value<float> unknown2;
|
||||
Value<float> unknown3;
|
||||
Value<atUint32> unknown4;
|
||||
Value<float> fadeInTime;
|
||||
Value<float> fadeOutTime;
|
||||
Value<atUint32> volume;
|
||||
|
||||
void nameIDs(PAKRouter<PAKBridge>& pakRouter) const
|
||||
{
|
||||
|
|
|
@ -532,10 +532,19 @@ void ProjectResourceFactoryBase::AsyncTask::CookComplete()
|
|||
/* Ready for buffer transaction at this point */
|
||||
u32 availSz = std::max(0, s32(fr.length()) - s32(x14_resOffset));
|
||||
x14_resSize = std::min(x14_resSize, availSz);
|
||||
if (xc_targetDataRawPtr)
|
||||
{
|
||||
m_bufTransaction = m_parent.m_clientProc.addBufferTransaction(m_cookedPath,
|
||||
xc_targetDataRawPtr,
|
||||
x14_resSize, x14_resOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
x10_loadBuffer.reset(new u8[x14_resSize]);
|
||||
m_bufTransaction = m_parent.m_clientProc.addBufferTransaction(m_cookedPath,
|
||||
x10_loadBuffer.get(),
|
||||
x14_resSize, x14_resOffset);
|
||||
}
|
||||
}
|
||||
|
||||
bool ProjectResourceFactoryBase::AsyncTask::AsyncPump()
|
||||
|
@ -778,6 +787,17 @@ ProjectResourceFactoryBase::LoadResourcePartAsync(const urde::SObjectTag& tag,
|
|||
std::make_shared<AsyncTask>(*this, tag, target, size, off))).first->second;
|
||||
}
|
||||
|
||||
std::shared_ptr<ProjectResourceFactoryBase::AsyncTask>
|
||||
ProjectResourceFactoryBase::LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, u8* target)
|
||||
{
|
||||
if ((tag.id & 0xffffffff) == 0xffffffff || !tag.id)
|
||||
Log.report(logvisor::Fatal, "attempted to access null id");
|
||||
if (m_asyncLoadList.find(tag) != m_asyncLoadList.end())
|
||||
return {};
|
||||
return m_asyncLoadList.emplace(std::make_pair(tag,
|
||||
std::make_shared<AsyncTask>(*this, tag, target, size, off))).first->second;
|
||||
}
|
||||
|
||||
std::unique_ptr<u8[]> ProjectResourceFactoryBase::LoadResourceSync(const urde::SObjectTag& tag)
|
||||
{
|
||||
if ((tag.id & 0xffffffff) == 0xffffffff || !tag.id)
|
||||
|
@ -986,6 +1006,13 @@ bool ProjectResourceFactoryBase::AsyncPumpTask(
|
|||
task.x0_tag.type.toString().c_str(),
|
||||
u32(task.x0_tag.id));
|
||||
}
|
||||
else if (task.xc_targetDataRawPtr)
|
||||
{
|
||||
/* Buffer only raw */
|
||||
Log.report(logvisor::Info, "async-loaded %.4s %08X",
|
||||
task.x0_tag.type.toString().c_str(),
|
||||
u32(task.x0_tag.id));
|
||||
}
|
||||
}
|
||||
|
||||
it = m_asyncLoadList.erase(it);
|
||||
|
|
|
@ -27,6 +27,7 @@ public:
|
|||
SObjectTag x0_tag;
|
||||
//IDvdRequest* x8_dvdReq = nullptr;
|
||||
std::unique_ptr<u8[]>* xc_targetDataPtr = nullptr;
|
||||
u8* xc_targetDataRawPtr = nullptr;
|
||||
IObj** xc_targetObjPtr = nullptr;
|
||||
std::unique_ptr<u8[]> x10_loadBuffer;
|
||||
u32 x14_resSize = UINT32_MAX;
|
||||
|
@ -50,6 +51,11 @@ public:
|
|||
: m_parent(parent), x0_tag(tag), xc_targetDataPtr(&ptr), x14_resSize(size),
|
||||
x14_resOffset(off) {}
|
||||
|
||||
AsyncTask(ProjectResourceFactoryBase& parent, const SObjectTag& tag,
|
||||
u8* ptr, u32 size, u32 off)
|
||||
: m_parent(parent), x0_tag(tag), xc_targetDataRawPtr(ptr), x14_resSize(size),
|
||||
x14_resOffset(off) {}
|
||||
|
||||
AsyncTask(ProjectResourceFactoryBase& parent, const SObjectTag& tag,
|
||||
IObj** ptr, const CVParamTransfer& xfer, CObjectReference* selfRef)
|
||||
: m_parent(parent), x0_tag(tag), xc_targetObjPtr(ptr), x18_cvXfer(xfer), m_selfRef(selfRef) {}
|
||||
|
@ -131,6 +137,7 @@ public:
|
|||
u32 ResourceSize(const SObjectTag& tag);
|
||||
std::shared_ptr<AsyncTask> LoadResourceAsync(const urde::SObjectTag& tag, std::unique_ptr<u8[]>& target);
|
||||
std::shared_ptr<AsyncTask> LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, std::unique_ptr<u8[]>& target);
|
||||
std::shared_ptr<AsyncTask> LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, u8* target);
|
||||
std::unique_ptr<u8[]> LoadResourceSync(const urde::SObjectTag& tag);
|
||||
std::unique_ptr<u8[]> LoadResourcePartSync(const urde::SObjectTag& tag, u32 size, u32 off);
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "Runtime/CScannableObjectInfo.hpp"
|
||||
#include "Audio/CAudioGroupSet.hpp"
|
||||
#include "Audio/CSfxManager.hpp"
|
||||
#include "Audio/CMidiManager.hpp"
|
||||
#include "Runtime/CDependencyGroup.hpp"
|
||||
#include "DataSpec/DNACommon/TXTR.hpp"
|
||||
#include "CSimplePool.hpp"
|
||||
|
@ -109,6 +110,7 @@ ProjectResourceFactoryMP1::ProjectResourceFactoryMP1(hecl::ClientProcess& client
|
|||
m_factoryMgr.AddFactory(FOURCC('DCLN'), FFactoryFunc(FCollidableOBBTreeGroupFactory));
|
||||
m_factoryMgr.AddFactory(FOURCC('DGRP'), FFactoryFunc(FDependencyGroupFactory));
|
||||
m_factoryMgr.AddFactory(FOURCC('AGSC'), FMemFactoryFunc(FAudioGroupSetDataFactory));
|
||||
m_factoryMgr.AddFactory(FOURCC('CSNG'), FFactoryFunc(FMidiDataFactory));
|
||||
m_factoryMgr.AddFactory(FOURCC('ATBL'), FFactoryFunc(FAudioTranslationTableFactory));
|
||||
m_factoryMgr.AddFactory(FOURCC('STRG'), FFactoryFunc(FStringTableFactory));
|
||||
m_factoryMgr.AddFactory(FOURCC('HINT'), FFactoryFunc(FHintFactory));
|
||||
|
|
|
@ -3,9 +3,58 @@
|
|||
namespace urde
|
||||
{
|
||||
|
||||
std::unordered_set<CMidiHandle> CMidiManager::m_MidiWrappers = {};
|
||||
|
||||
void CMidiManager::StopAll()
|
||||
{
|
||||
for (auto it = m_MidiWrappers.begin() ; it != m_MidiWrappers.end() ;)
|
||||
it = Stop(it, 0);
|
||||
}
|
||||
|
||||
void CMidiManager::Stop(const CMidiHandle& handle, float fadeTime)
|
||||
{
|
||||
handle->GetAudioSysHandle()->stopSong(fadeTime);
|
||||
m_MidiWrappers.erase(handle);
|
||||
}
|
||||
|
||||
std::unordered_set<CMidiHandle>::iterator
|
||||
CMidiManager::Stop(std::unordered_set<CMidiHandle>::iterator handle, float fadeTime)
|
||||
{
|
||||
const CMidiHandle& h = *handle;
|
||||
h->GetAudioSysHandle()->stopSong(fadeTime);
|
||||
return m_MidiWrappers.erase(handle);
|
||||
}
|
||||
|
||||
CMidiHandle CMidiManager::Play(const CMidiData& data, float fadeTime, bool stopExisting, float volume)
|
||||
{
|
||||
if (stopExisting)
|
||||
for (auto it = m_MidiWrappers.begin() ; it != m_MidiWrappers.end() ;)
|
||||
it = Stop(it, fadeTime);
|
||||
|
||||
CMidiHandle handle = *m_MidiWrappers.insert(std::make_shared<CMidiWrapper>()).first;
|
||||
handle->SetAudioSysHandle(CAudioSys::GetAmuseEngine().seqPlay(
|
||||
data.GetGroupId(), data.GetSetupId(), data.GetArrData()));
|
||||
handle->GetAudioSysHandle()->setVolume(volume, fadeTime);
|
||||
handle->SetSongId(data.GetSetupId());
|
||||
return handle;
|
||||
}
|
||||
|
||||
CMidiManager::CMidiData::CMidiData(CInputStream& in)
|
||||
{
|
||||
in.readUint32Big();
|
||||
x0_setupId = in.readUint32Big();
|
||||
x2_groupId = in.readUint32Big();
|
||||
x4_agscId = in.readUint32Big();
|
||||
u32 length = in.readUint32Big();
|
||||
x8_arrData.reset(new u8[length]);
|
||||
in.readUBytesToBuf(x8_arrData.get(), length);
|
||||
}
|
||||
|
||||
CFactoryFnReturn FMidiDataFactory(const SObjectTag& tag, CInputStream& in,
|
||||
const CVParamTransfer& parms,
|
||||
CObjectReference* selfRef)
|
||||
{
|
||||
return TToken<CMidiManager::CMidiData>::GetIObjObjectFor(std::make_unique<CMidiManager::CMidiData>(in));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,15 +1,62 @@
|
|||
#ifndef __URDE_CMIDIMANAGER_HPP__
|
||||
#define __URDE_CMIDIMANAGER_HPP__
|
||||
|
||||
#include "CSfxManager.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
class CMidiManager
|
||||
{
|
||||
public:
|
||||
class CMidiData
|
||||
{
|
||||
u16 x0_setupId;
|
||||
u16 x2_groupId;
|
||||
ResId x4_agscId;
|
||||
std::unique_ptr<u8[]> x8_arrData;
|
||||
public:
|
||||
u16 GetSetupId() const { return x0_setupId; }
|
||||
u16 GetGroupId() const { return x2_groupId; }
|
||||
ResId GetAGSCAssetId() const { return x4_agscId; }
|
||||
const u8* GetArrData() const { return x8_arrData.get(); }
|
||||
CMidiData(CInputStream& in);
|
||||
};
|
||||
|
||||
class CMidiWrapper
|
||||
{
|
||||
std::shared_ptr<amuse::Sequencer> x0_sequencer;
|
||||
//CSfxHandle x4_handle;
|
||||
u16 x8_songId;
|
||||
bool xa_available = true;
|
||||
public:
|
||||
const std::shared_ptr<amuse::Sequencer>& GetAudioSysHandle() const { return x0_sequencer; }
|
||||
void SetAudioSysHandle(const std::shared_ptr<amuse::Sequencer>& sequencer) { x0_sequencer = sequencer; }
|
||||
//const CSfxHandle& GetManagerHandle() const { return x4_handle; }
|
||||
//void SetMidiHandle(const CSfxHandle& handle) { x4_handle = handle; }
|
||||
bool IsAvailable() const { return xa_available; }
|
||||
void SetAvailable(bool available) { xa_available = available; }
|
||||
u16 GetSongId() const { return x8_songId; }
|
||||
void SetSongId(u16 songId) { x8_songId = songId; }
|
||||
};
|
||||
using CMidiHandle = std::shared_ptr<CMidiWrapper>;
|
||||
|
||||
static void StopAll();
|
||||
static void Stop(const CMidiHandle& handle, float fadeTime);
|
||||
static std::unordered_set<CMidiHandle>::iterator
|
||||
Stop(std::unordered_set<CMidiHandle>::iterator handle, float fadeTime);
|
||||
static CMidiHandle Play(const CMidiData& data, float fadeTime, bool stopExisting, float volume);
|
||||
|
||||
private:
|
||||
static std::unordered_set<CMidiHandle> m_MidiWrappers;
|
||||
};
|
||||
|
||||
CFactoryFnReturn FMidiDataFactory(const SObjectTag& tag, CInputStream& in,
|
||||
const CVParamTransfer& parms,
|
||||
CObjectReference* selfRef);
|
||||
|
||||
using CMidiHandle = CMidiManager::CMidiHandle;
|
||||
|
||||
}
|
||||
|
||||
#endif // __URDE_CMIDIMANAGER_HPP__
|
||||
|
|
|
@ -16,14 +16,14 @@ public:
|
|||
{
|
||||
float x0_fadeIn, x4_fadeOut, x8_volume;
|
||||
std::string xc_fileName;
|
||||
u32 x1c_handle;
|
||||
ResId x1c_res;
|
||||
Audio(float fadeIn, float fadeOut, float vol, const std::string& fileName, u32 handle)
|
||||
: x0_fadeIn(fadeIn), x4_fadeOut(fadeOut), x8_volume(vol), xc_fileName(fileName), x1c_handle(handle) {}
|
||||
: x0_fadeIn(fadeIn), x4_fadeOut(fadeOut), x8_volume(vol), xc_fileName(fileName), x1c_res(handle) {}
|
||||
float GetFadeIn() const { return x0_fadeIn; }
|
||||
float GetFadeOut() const { return x4_fadeOut; }
|
||||
float GetVolume() const { return x8_volume; }
|
||||
const std::string& GetFileName() const { return xc_fileName; }
|
||||
u32 GetHandle() const { return x1c_handle; }
|
||||
ResId GetResId() const { return x1c_res; }
|
||||
static Audio None() { return Audio{0.f, 0.f, 0.f, "", 0}; }
|
||||
};
|
||||
enum class EType
|
||||
|
|
|
@ -703,14 +703,14 @@ void CStateManager::InitializeState(ResId mlvlId, TAreaId aid, ResId mreaId)
|
|||
bool hadRandom = x900_activeRandom != nullptr;
|
||||
SetActiveRandomToDefault();
|
||||
|
||||
if (xb3c_initPhase == InitPhase::LoadWorld)
|
||||
if (xb3c_initPhase == EInitPhase::LoadWorld)
|
||||
{
|
||||
CreateStandardGameObjects();
|
||||
x850_world.reset(new CWorld(*g_SimplePool, *g_ResFactory, mlvlId));
|
||||
xb3c_initPhase = InitPhase::LoadFirstArea;
|
||||
xb3c_initPhase = EInitPhase::LoadFirstArea;
|
||||
}
|
||||
|
||||
if (xb3c_initPhase == InitPhase::LoadFirstArea)
|
||||
if (xb3c_initPhase == EInitPhase::LoadFirstArea)
|
||||
{
|
||||
if (!x8f0_shadowTex.IsLoaded())
|
||||
return;
|
||||
|
@ -725,7 +725,7 @@ void CStateManager::InitializeState(ResId mlvlId, TAreaId aid, ResId mreaId)
|
|||
area->StartStreamIn(*this);
|
||||
return;
|
||||
}
|
||||
xb3c_initPhase = InitPhase::Done;
|
||||
xb3c_initPhase = EInitPhase::Done;
|
||||
}
|
||||
|
||||
SetCurrentAreaId(x8cc_nextAreaId);
|
||||
|
|
|
@ -147,12 +147,12 @@ class CStateManager
|
|||
|
||||
std::set<std::string> xab4_uniqueInstanceNames;
|
||||
|
||||
enum class InitPhase
|
||||
enum class EInitPhase
|
||||
{
|
||||
LoadWorld,
|
||||
LoadFirstArea,
|
||||
Done
|
||||
} xb3c_initPhase = InitPhase::LoadWorld;
|
||||
} xb3c_initPhase = EInitPhase::LoadWorld;
|
||||
|
||||
CFinalInput xb54_finalInput;
|
||||
CCameraFilterPass xb84_camFilterPasses[9];
|
||||
|
|
|
@ -99,10 +99,10 @@ void CAreaOctTree::SwapTreeNode(u8* ptr, Node::ETreeType type)
|
|||
}
|
||||
}
|
||||
|
||||
CAreaOctTree::CAreaOctTree(const zeus::CAABox& aabb, Node::ETreeType treeType, u8* buf, std::unique_ptr<u8[]>&& treeBuf,
|
||||
u32 matCount, u32* materials, u8* vertMats, u8* edgeMats, u8* polyMats,
|
||||
u32 edgeCount, CCollisionEdge* edges, u32 polyCount, u16* polyEdges,
|
||||
u32 vertCount, zeus::CVector3f* verts)
|
||||
CAreaOctTree::CAreaOctTree(const zeus::CAABox& aabb, Node::ETreeType treeType, const u8* buf, std::unique_ptr<u8[]>&& treeBuf,
|
||||
u32 matCount, const u32* materials, const u8* vertMats, const u8* edgeMats, const u8* polyMats,
|
||||
u32 edgeCount, const CCollisionEdge* edges, u32 polyCount, const u16* polyEdges,
|
||||
u32 vertCount, const zeus::CVector3f* verts)
|
||||
: x0_aabb(aabb), x18_treeType(treeType), x1c_buf(buf), x20_treeBuf(std::move(treeBuf)),
|
||||
x24_matCount(matCount), x2c_vertMats(vertMats),
|
||||
x30_edgeMats(edgeMats), x34_polyMats(polyMats), x38_edgeCount(edgeCount),
|
||||
|
@ -140,7 +140,7 @@ CAreaOctTree::CAreaOctTree(const zeus::CAABox& aabb, Node::ETreeType treeType, u
|
|||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<CAreaOctTree> CAreaOctTree::MakeFromMemory(void* buf, unsigned int size)
|
||||
std::unique_ptr<CAreaOctTree> CAreaOctTree::MakeFromMemory(const void* buf, unsigned int size)
|
||||
{
|
||||
athena::io::MemoryReader r(buf, size);
|
||||
r.readUint32Big();
|
||||
|
@ -149,48 +149,48 @@ std::unique_ptr<CAreaOctTree> CAreaOctTree::MakeFromMemory(void* buf, unsigned i
|
|||
aabb.readBoundingBoxBig(r);
|
||||
Node::ETreeType nodeType = Node::ETreeType(r.readUint32Big());
|
||||
u32 treeSize = r.readUint32Big();
|
||||
u8* cur = reinterpret_cast<u8*>(buf) + r.position();
|
||||
const u8* cur = reinterpret_cast<const u8*>(buf) + r.position();
|
||||
|
||||
std::unique_ptr<u8[]> treeBuf(new u8[treeSize]);
|
||||
memmove(treeBuf.get(), cur, treeSize);
|
||||
cur += treeSize;
|
||||
|
||||
u32 matCount = hecl::SBig(*reinterpret_cast<u32*>(cur));
|
||||
u32 matCount = hecl::SBig(*reinterpret_cast<const u32*>(cur));
|
||||
cur += 4;
|
||||
u32* matBuf = reinterpret_cast<u32*>(cur);
|
||||
const u32* matBuf = reinterpret_cast<const u32*>(cur);
|
||||
cur += 4 * matCount;
|
||||
|
||||
u32 vertMatsCount = hecl::SBig(*reinterpret_cast<u32*>(cur));
|
||||
u32 vertMatsCount = hecl::SBig(*reinterpret_cast<const u32*>(cur));
|
||||
cur += 4;
|
||||
u8* vertMatsBuf = cur;
|
||||
const u8* vertMatsBuf = cur;
|
||||
cur += vertMatsCount;
|
||||
|
||||
u32 edgeMatsCount = hecl::SBig(*reinterpret_cast<u32*>(cur));
|
||||
u32 edgeMatsCount = hecl::SBig(*reinterpret_cast<const u32*>(cur));
|
||||
cur += 4;
|
||||
u8* edgeMatsBuf = cur;
|
||||
const u8* edgeMatsBuf = cur;
|
||||
cur += edgeMatsCount;
|
||||
|
||||
u32 polyMatsCount = hecl::SBig(*reinterpret_cast<u32*>(cur));
|
||||
u32 polyMatsCount = hecl::SBig(*reinterpret_cast<const u32*>(cur));
|
||||
cur += 4;
|
||||
u8* polyMatsBuf = cur;
|
||||
const u8* polyMatsBuf = cur;
|
||||
cur += polyMatsCount;
|
||||
|
||||
u32 edgeCount = hecl::SBig(*reinterpret_cast<u32*>(cur));
|
||||
u32 edgeCount = hecl::SBig(*reinterpret_cast<const u32*>(cur));
|
||||
cur += 4;
|
||||
CCollisionEdge* edgeBuf = reinterpret_cast<CCollisionEdge*>(cur);
|
||||
const CCollisionEdge* edgeBuf = reinterpret_cast<const CCollisionEdge*>(cur);
|
||||
cur += edgeCount * sizeof(edgeCount);
|
||||
|
||||
u32 polyCount = hecl::SBig(*reinterpret_cast<u32*>(cur));
|
||||
u32 polyCount = hecl::SBig(*reinterpret_cast<const u32*>(cur));
|
||||
cur += 4;
|
||||
u16* polyBuf = reinterpret_cast<u16*>(cur);
|
||||
const u16* polyBuf = reinterpret_cast<const u16*>(cur);
|
||||
cur += polyCount * 2;
|
||||
|
||||
u32 vertCount = hecl::SBig(*reinterpret_cast<u32*>(cur));
|
||||
u32 vertCount = hecl::SBig(*reinterpret_cast<const u32*>(cur));
|
||||
cur += 4;
|
||||
zeus::CVector3f* vertBuf = reinterpret_cast<zeus::CVector3f*>(cur);
|
||||
const zeus::CVector3f* vertBuf = reinterpret_cast<const zeus::CVector3f*>(cur);
|
||||
cur += polyCount * 2;
|
||||
|
||||
return std::make_unique<CAreaOctTree>(aabb, nodeType, reinterpret_cast<u8*>(buf), std::move(treeBuf),
|
||||
return std::make_unique<CAreaOctTree>(aabb, nodeType, reinterpret_cast<const u8*>(buf), std::move(treeBuf),
|
||||
matCount, matBuf, vertMatsBuf, edgeMatsBuf, polyMatsBuf,
|
||||
edgeCount, edgeBuf, polyCount, polyBuf, vertCount, vertBuf);
|
||||
}
|
||||
|
|
|
@ -94,13 +94,13 @@ public:
|
|||
|
||||
zeus::CAABox x0_aabb;
|
||||
Node::ETreeType x18_treeType;
|
||||
u8* x1c_buf;
|
||||
const u8* x1c_buf;
|
||||
std::unique_ptr<u8[]> x20_treeBuf;
|
||||
u32 x24_matCount;
|
||||
std::vector<u32> x28_materials;
|
||||
u8* x2c_vertMats;
|
||||
u8* x30_edgeMats;
|
||||
u8* x34_polyMats;
|
||||
const u8* x2c_vertMats;
|
||||
const u8* x30_edgeMats;
|
||||
const u8* x34_polyMats;
|
||||
u32 x38_edgeCount;
|
||||
std::vector<CCollisionEdge> x3c_edges;
|
||||
u32 x40_polyCount;
|
||||
|
@ -111,10 +111,10 @@ public:
|
|||
void SwapTreeNode(u8* ptr, Node::ETreeType type);
|
||||
|
||||
public:
|
||||
CAreaOctTree(const zeus::CAABox& aabb, Node::ETreeType treeType, u8* buf, std::unique_ptr<u8[]>&& treeBuf,
|
||||
u32 matCount, u32* materials, u8* vertMats, u8* edgeMats, u8* polyMats,
|
||||
u32 edgeCount, CCollisionEdge* edges, u32 polyCount, u16* polyEdges,
|
||||
u32 vertCount, zeus::CVector3f* verts);
|
||||
CAreaOctTree(const zeus::CAABox& aabb, Node::ETreeType treeType, const u8* buf, std::unique_ptr<u8[]>&& treeBuf,
|
||||
u32 matCount, const u32* materials, const u8* vertMats, const u8* edgeMats, const u8* polyMats,
|
||||
u32 edgeCount, const CCollisionEdge* edges, u32 polyCount, const u16* polyEdges,
|
||||
u32 vertCount, const zeus::CVector3f* verts);
|
||||
|
||||
Node GetRootNode() const { return Node(x20_treeBuf.get(), x0_aabb, *this, x18_treeType); }
|
||||
const u8* GetTreeMemory() const { return x20_treeBuf.get(); }
|
||||
|
@ -129,7 +129,7 @@ public:
|
|||
const u16* GetTriangleVertexIndices(u16 idx) const;
|
||||
const u16* GetTriangleEdgeIndices(u16 idx) const;
|
||||
|
||||
static std::unique_ptr<CAreaOctTree> MakeFromMemory(void* buf, unsigned int size);
|
||||
static std::unique_ptr<CAreaOctTree> MakeFromMemory(const void* buf, unsigned int size);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -353,5 +353,12 @@ bool CInGameGuiManager::GetIsGameDraw() const
|
|||
return x3c_pauseScreen->GetX50_25();
|
||||
}
|
||||
|
||||
std::string CInGameGuiManager::GetIdentifierForMidiEvent(ResId world, ResId area,
|
||||
const std::string& midiObj)
|
||||
{
|
||||
return hecl::Format("World %8.8x Area %8.8x MidiObject: %s",
|
||||
u32(world), u32(area), midiObj.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,6 +135,7 @@ public:
|
|||
bool IsInGame() const { return x1c0_nextState >= EInGameGuiState::Zero && x1c0_nextState <= EInGameGuiState::InGame; }
|
||||
bool IsInSaveUI() const { return x1f8_27_inSaveUI; }
|
||||
bool GetIsGameDraw() const;
|
||||
static std::string GetIdentifierForMidiEvent(ResId world, ResId area, const std::string& midiObj);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -379,7 +379,7 @@ CIOWin::EMessageReturn CMFGameLoader::OnMessage(const CArchitectureMessage& msg,
|
|||
wldState.GetLayerState());
|
||||
}
|
||||
|
||||
if (x14_stateMgr->xb3c_initPhase != CStateManager::InitPhase::Done)
|
||||
if (x14_stateMgr->xb3c_initPhase != CStateManager::EInitPhase::Done)
|
||||
{
|
||||
CWorldState& wldState = g_GameState->CurrentWorldState();
|
||||
x14_stateMgr->InitializeState(wldState.GetWorldAssetId(),
|
||||
|
|
|
@ -53,6 +53,7 @@ CENTITY_TYPES = (
|
|||
('CScriptPointOfInterest', 'World/CScriptPointOfInterest.hpp'),
|
||||
('CScriptRoomAcoustics', 'World/CScriptRoomAcoustics.hpp'),
|
||||
('CScriptSound', 'World/CScriptSound.hpp'),
|
||||
('CScriptMidi', 'World/CScriptMidi.hpp'),
|
||||
('CScriptSpawnPoint', 'World/CScriptSpawnPoint.hpp'),
|
||||
('CScriptSpecialFunction', 'World/CScriptSpecialFunction.hpp'),
|
||||
('CScriptSpiderBallAttractionSurface', 'World/CScriptSpiderBallAttractionSurface.hpp'),
|
||||
|
|
|
@ -9,27 +9,29 @@
|
|||
namespace urde
|
||||
{
|
||||
|
||||
CAreaRenderOctTree::CAreaRenderOctTree(std::unique_ptr<u8[]>&& buf)
|
||||
: x0_buf(std::move(buf))
|
||||
static logvisor::Module Log("CGameArea");
|
||||
|
||||
CAreaRenderOctTree::CAreaRenderOctTree(const u8* buf)
|
||||
: x0_buf(buf)
|
||||
{
|
||||
athena::io::MemoryReader r(x0_buf.get() + 8, INT32_MAX);
|
||||
athena::io::MemoryReader r(x0_buf + 8, INT32_MAX);
|
||||
x8_bitmapCount = r.readUint32Big();
|
||||
xc_meshCount = r.readUint32Big();
|
||||
x10_nodeCount = r.readUint32Big();
|
||||
x14_bitmapWordCount = (xc_meshCount + 31) / 32;
|
||||
x18_aabb.readBoundingBoxBig(r);
|
||||
|
||||
x30_bitmaps = reinterpret_cast<u32*>(x0_buf.get() + 64);
|
||||
x30_bitmaps = reinterpret_cast<const u32*>(x0_buf + 64);
|
||||
u32 wc = x14_bitmapWordCount * x8_bitmapCount;
|
||||
for (u32 i=0 ; i<wc ; ++i)
|
||||
x30_bitmaps[i] = hecl::SBig(x30_bitmaps[i]);
|
||||
const_cast<u32*>(x30_bitmaps)[i] = hecl::SBig(x30_bitmaps[i]);
|
||||
|
||||
x34_indirectionTable = x30_bitmaps + wc;
|
||||
x38_entries = reinterpret_cast<u8*>(x34_indirectionTable) + x10_nodeCount;
|
||||
x38_entries = reinterpret_cast<const u8*>(x34_indirectionTable + x10_nodeCount);
|
||||
for (u32 i=0 ; i<x10_nodeCount ; ++i)
|
||||
{
|
||||
x34_indirectionTable[i] = hecl::SBig(x34_indirectionTable[i]);
|
||||
Node* n = reinterpret_cast<Node*>(x38_entries + x34_indirectionTable[i]);
|
||||
const_cast<u32*>(x34_indirectionTable)[i] = hecl::SBig(x34_indirectionTable[i]);
|
||||
Node* n = reinterpret_cast<Node*>(const_cast<u8*>(x38_entries) + x34_indirectionTable[i]);
|
||||
n->x0_bitmapIdx = hecl::SBig(n->x0_bitmapIdx);
|
||||
n->x2_flags = hecl::SBig(n->x2_flags);
|
||||
if (n->x2_flags)
|
||||
|
@ -596,42 +598,42 @@ bool CGameArea::StartStreamingMainArea()
|
|||
|
||||
switch (xf4_phase)
|
||||
{
|
||||
case Phase::LoadHeader:
|
||||
case EPhase::LoadHeader:
|
||||
{
|
||||
x110_mreaSecBufs.reserve(3);
|
||||
AllocNewAreaData(0, 96);
|
||||
x12c_postConstructed.reset(new CPostConstructed());
|
||||
xf4_phase = Phase::LoadSecSizes;
|
||||
xf4_phase = EPhase::LoadSecSizes;
|
||||
break;
|
||||
}
|
||||
case Phase::LoadSecSizes:
|
||||
case EPhase::LoadSecSizes:
|
||||
{
|
||||
CullDeadAreaRequests();
|
||||
if (xf8_loadTransactions.size())
|
||||
break;
|
||||
MREAHeader header = VerifyHeader();
|
||||
AllocNewAreaData(x110_mreaSecBufs[0].second, ROUND_UP_32(header.secCount * 4));
|
||||
xf4_phase = Phase::ReserveSections;
|
||||
xf4_phase = EPhase::ReserveSections;
|
||||
break;
|
||||
}
|
||||
case Phase::ReserveSections:
|
||||
case EPhase::ReserveSections:
|
||||
{
|
||||
CullDeadAreaRequests();
|
||||
if (xf8_loadTransactions.size())
|
||||
break;
|
||||
x110_mreaSecBufs.reserve(GetNumPartSizes() + 2);
|
||||
//x110_mreaSecBufs.reserve(GetNumPartSizes() + 2);
|
||||
x124_secCount = 0;
|
||||
x128_mreaDataOffset = x110_mreaSecBufs[0].second + x110_mreaSecBufs[1].second;
|
||||
xf4_phase = Phase::LoadDataSections;
|
||||
xf4_phase = EPhase::LoadDataSections;
|
||||
break;
|
||||
}
|
||||
case Phase::LoadDataSections:
|
||||
case EPhase::LoadDataSections:
|
||||
{
|
||||
CullDeadAreaRequests();
|
||||
|
||||
u32 totalSz = 0;
|
||||
u32 secCount = GetNumPartSizes();
|
||||
for (u32 i=2 ; i<secCount ; ++i)
|
||||
for (u32 i=0 ; i<secCount ; ++i)
|
||||
totalSz += hecl::SBig(reinterpret_cast<u32*>(x110_mreaSecBufs[1].first.get())[i]);
|
||||
|
||||
AllocNewAreaData(x128_mreaDataOffset, totalSz);
|
||||
|
@ -641,17 +643,17 @@ bool CGameArea::StartStreamingMainArea()
|
|||
m_resolvedBufs.emplace_back(x110_mreaSecBufs[1].first.get(), x110_mreaSecBufs[1].second);
|
||||
|
||||
u32 curOff = 0;
|
||||
for (u32 i=2 ; i<secCount ; ++i)
|
||||
for (u32 i=0 ; i<secCount ; ++i)
|
||||
{
|
||||
u32 size = hecl::SBig(reinterpret_cast<u32*>(x110_mreaSecBufs[1].first.get())[i]);
|
||||
m_resolvedBufs.emplace_back(x110_mreaSecBufs[2].first.get() + curOff, size);
|
||||
curOff += size;
|
||||
}
|
||||
|
||||
xf4_phase = Phase::WaitForFinish;
|
||||
xf4_phase = EPhase::WaitForFinish;
|
||||
break;
|
||||
}
|
||||
case Phase::WaitForFinish:
|
||||
case EPhase::WaitForFinish:
|
||||
{
|
||||
CullDeadAreaRequests();
|
||||
if (xf8_loadTransactions.size())
|
||||
|
@ -684,7 +686,7 @@ void CGameArea::AllocNewAreaData(int offset, int size)
|
|||
xf8_loadTransactions.push_back(
|
||||
static_cast<ProjectResourceFactoryBase*>(g_ResFactory)->
|
||||
LoadResourcePartAsync(SObjectTag{FOURCC('MREA'), x84_mrea}, size, offset,
|
||||
x110_mreaSecBufs.back().first));
|
||||
x110_mreaSecBufs.back().first.get()));
|
||||
}
|
||||
|
||||
bool CGameArea::Invalidate(CStateManager& mgr)
|
||||
|
@ -707,6 +709,32 @@ void CGameArea::CullDeadAreaRequests()
|
|||
|
||||
void CGameArea::StartStreamIn(CStateManager& mgr)
|
||||
{
|
||||
if (xf0_24_postConstructed || xf0_27_paused)
|
||||
return;
|
||||
|
||||
VerifyTokenList(mgr);
|
||||
|
||||
if (!xf0_26_tokensReady)
|
||||
{
|
||||
u32 notLoaded = 0;
|
||||
for (CToken& tok : xdc_tokens)
|
||||
{
|
||||
tok.Lock();
|
||||
if (!tok.IsLoaded())
|
||||
++notLoaded;
|
||||
}
|
||||
if (notLoaded)
|
||||
return;
|
||||
xf0_26_tokensReady = true;
|
||||
}
|
||||
|
||||
StartStreamingMainArea();
|
||||
if (xf4_phase != EPhase::WaitForFinish)
|
||||
return;
|
||||
CullDeadAreaRequests();
|
||||
if (xf8_loadTransactions.size())
|
||||
return;
|
||||
Validate(mgr);
|
||||
}
|
||||
|
||||
void CGameArea::Validate(CStateManager& mgr)
|
||||
|
@ -774,7 +802,7 @@ void CGameArea::LoadScriptObjects(CStateManager& mgr)
|
|||
mgr.InitScriptObjects(objIds);
|
||||
}
|
||||
|
||||
std::pair<u8*, u32> CGameArea::GetLayerScriptBuffer(int layer)
|
||||
std::pair<const u8*, u32> CGameArea::GetLayerScriptBuffer(int layer)
|
||||
{
|
||||
if (!xf0_24_postConstructed)
|
||||
return {};
|
||||
|
@ -785,32 +813,35 @@ void CGameArea::PostConstructArea()
|
|||
{
|
||||
MREAHeader header = VerifyHeader();
|
||||
|
||||
auto secIt = x110_mreaSecBufs.begin() + 2;
|
||||
auto secIt = m_resolvedBufs.begin() + 2;
|
||||
|
||||
/* Materials */
|
||||
++secIt;
|
||||
|
||||
u32 sec = 3;
|
||||
|
||||
/* Models */
|
||||
if (header.modelCount)
|
||||
{
|
||||
for (u32 i=0 ; i<header.modelCount ; ++i)
|
||||
{
|
||||
u32 surfCount = hecl::SBig(*reinterpret_cast<u32*>((secIt+6)->first.get()));
|
||||
secIt += 7 + surfCount;
|
||||
}
|
||||
u32 surfCount = hecl::SBig(*reinterpret_cast<const u32*>((secIt+4)->first));
|
||||
secIt += 5 + surfCount;
|
||||
sec += 5 + surfCount;
|
||||
}
|
||||
|
||||
/* Render octree */
|
||||
if (header.version == 15 && header.arotSecIdx != -1)
|
||||
{
|
||||
x12c_postConstructed->xc_octTree.emplace(std::move(secIt->first));
|
||||
x12c_postConstructed->xc_octTree.emplace(secIt->first);
|
||||
++secIt;
|
||||
}
|
||||
|
||||
/* Scriptable layer section */
|
||||
x12c_postConstructed->x10c8_sclyBuf = std::move(secIt->first);
|
||||
x12c_postConstructed->x10c8_sclyBuf = secIt->first;
|
||||
x12c_postConstructed->x10d0_sclySize = secIt->second;
|
||||
++secIt;
|
||||
|
||||
/* Collision section */
|
||||
std::unique_ptr<CAreaOctTree> collision = CAreaOctTree::MakeFromMemory(secIt->first.get(), secIt->second);
|
||||
std::unique_ptr<CAreaOctTree> collision = CAreaOctTree::MakeFromMemory(secIt->first, secIt->second);
|
||||
if (collision)
|
||||
{
|
||||
x12c_postConstructed->x0_collision = std::move(collision);
|
||||
|
@ -824,7 +855,7 @@ void CGameArea::PostConstructArea()
|
|||
/* Lights section */
|
||||
if (header.version > 6)
|
||||
{
|
||||
athena::io::MemoryReader r(secIt->first.get(), secIt->second);
|
||||
athena::io::MemoryReader r(secIt->first, secIt->second);
|
||||
u32 magic = r.readUint32Big();
|
||||
if (magic == 0xBABEDEAD)
|
||||
{
|
||||
|
@ -855,7 +886,7 @@ void CGameArea::PostConstructArea()
|
|||
/* PVS section */
|
||||
if (header.version > 7)
|
||||
{
|
||||
athena::io::MemoryReader r(secIt->first.get(), secIt->second);
|
||||
athena::io::MemoryReader r(secIt->first, secIt->second);
|
||||
u32 magic = r.readUint32Big();
|
||||
if (magic == 'VISI')
|
||||
{
|
||||
|
@ -864,7 +895,7 @@ void CGameArea::PostConstructArea()
|
|||
{
|
||||
x12c_postConstructed->x1108_29_ = r.readBool();
|
||||
x12c_postConstructed->x1108_30_ = r.readBool();
|
||||
x12c_postConstructed->xa0_pvs = std::make_unique<CPVSAreaSet>(secIt->first.get() + r.position(),
|
||||
x12c_postConstructed->xa0_pvs = std::make_unique<CPVSAreaSet>(secIt->first + r.position(),
|
||||
secIt->second - r.position());
|
||||
}
|
||||
}
|
||||
|
@ -875,7 +906,7 @@ void CGameArea::PostConstructArea()
|
|||
/* Pathfinding section */
|
||||
if (header.version > 9)
|
||||
{
|
||||
athena::io::MemoryReader r(secIt->first.get(), secIt->second);
|
||||
athena::io::MemoryReader r(secIt->first, secIt->second);
|
||||
ResId pathId = r.readUint32Big();
|
||||
x12c_postConstructed->x10ac_path = g_SimplePool->GetObj(SObjectTag{FOURCC('PATH'), pathId});
|
||||
++secIt;
|
||||
|
@ -889,7 +920,7 @@ void CGameArea::PostConstructArea()
|
|||
/* Resolve layer pointers */
|
||||
if (x12c_postConstructed->x10c8_sclyBuf)
|
||||
{
|
||||
athena::io::MemoryReader r(x12c_postConstructed->x10c8_sclyBuf.get(), x12c_postConstructed->x10d0_sclySize);
|
||||
athena::io::MemoryReader r(x12c_postConstructed->x10c8_sclyBuf, x12c_postConstructed->x10d0_sclySize);
|
||||
u32 magic = r.readUint32Big();
|
||||
if (magic == 'SCLY')
|
||||
{
|
||||
|
@ -898,7 +929,7 @@ void CGameArea::PostConstructArea()
|
|||
x12c_postConstructed->x110c_layerPtrs.resize(layerCount);
|
||||
for (u32 l=0 ; l<layerCount ; ++l)
|
||||
x12c_postConstructed->x110c_layerPtrs[l].second = r.readUint32Big();
|
||||
u8* ptr = x12c_postConstructed->x10c8_sclyBuf.get() + r.position();
|
||||
const u8* ptr = x12c_postConstructed->x10c8_sclyBuf + r.position();
|
||||
for (u32 l=0 ; l<layerCount ; ++l)
|
||||
{
|
||||
x12c_postConstructed->x110c_layerPtrs[l].first = ptr;
|
||||
|
@ -967,6 +998,9 @@ CGameArea::MREAHeader CGameArea::VerifyHeader() const
|
|||
MREAHeader header;
|
||||
athena::io::MemoryReader r(x110_mreaSecBufs[0].first.get() + 4, INT32_MAX);
|
||||
u32 version = r.readUint32Big();
|
||||
if (!(version & 0x10000))
|
||||
Log.report(logvisor::Fatal, "Attempted to load non-URDE MREA");
|
||||
version &= ~0x10000;
|
||||
header.version = (version >= 12 && version <= 15) ? version : 0;
|
||||
if (!header.version)
|
||||
return {};
|
||||
|
|
|
@ -61,17 +61,17 @@ struct CAreaRenderOctTree
|
|||
const zeus::CAABox& testAABB) const;
|
||||
};
|
||||
|
||||
std::unique_ptr<u8[]> x0_buf;
|
||||
const u8* x0_buf;
|
||||
u32 x8_bitmapCount;
|
||||
u32 xc_meshCount;
|
||||
u32 x10_nodeCount;
|
||||
u32 x14_bitmapWordCount;
|
||||
zeus::CAABox x18_aabb;
|
||||
u32* x30_bitmaps;
|
||||
u32* x34_indirectionTable;
|
||||
u8* x38_entries;
|
||||
const u32* x30_bitmaps;
|
||||
const u32* x34_indirectionTable;
|
||||
const u8* x38_entries;
|
||||
|
||||
CAreaRenderOctTree(std::unique_ptr<u8[]>&& buf);
|
||||
CAreaRenderOctTree(const u8* buf);
|
||||
|
||||
void FindOverlappingModels(std::vector<u32>& out, const zeus::CAABox& testAABB) const;
|
||||
};
|
||||
|
@ -110,14 +110,14 @@ class CGameArea : public IGameArea
|
|||
u8 _dummy = 0;
|
||||
};
|
||||
|
||||
enum class Phase
|
||||
enum class EPhase
|
||||
{
|
||||
LoadHeader,
|
||||
LoadSecSizes,
|
||||
ReserveSections,
|
||||
LoadDataSections,
|
||||
WaitForFinish
|
||||
} xf4_phase = Phase::LoadHeader;
|
||||
} xf4_phase = EPhase::LoadHeader;
|
||||
|
||||
std::list<std::shared_ptr<ProjectResourceFactoryBase::AsyncTask>> xf8_loadTransactions;
|
||||
|
||||
|
@ -187,7 +187,7 @@ public:
|
|||
u32 x10bc_ = 0;
|
||||
std::unique_ptr<CAreaObjectList> x10c0_areaObjs;
|
||||
std::unique_ptr<CAreaFog> x10c4_areaFog;
|
||||
std::unique_ptr<u8[]> x10c8_sclyBuf;
|
||||
const u8* x10c8_sclyBuf = nullptr;
|
||||
u32 x10d0_sclySize = 0;
|
||||
u32 x10d4_ = 0;
|
||||
const CScriptAreaAttributes* x10d8_areaAttributes = nullptr;
|
||||
|
@ -213,7 +213,7 @@ public:
|
|||
};
|
||||
u8 _dummy = 0;
|
||||
};
|
||||
std::vector<std::pair<u8*, u32>> x110c_layerPtrs;
|
||||
std::vector<std::pair<const u8*, u32>> x110c_layerPtrs;
|
||||
float x111c_thermalCurrent = 0.f;
|
||||
float x1120_thermalSpeed = 0.f;
|
||||
float x1124_thermalTarget = 0.f;
|
||||
|
@ -226,7 +226,7 @@ public:
|
|||
};
|
||||
private:
|
||||
std::vector<std::pair<std::unique_ptr<u8[]>, int>> x110_mreaSecBufs;
|
||||
std::vector<std::pair<u8*, int>> m_resolvedBufs;
|
||||
std::vector<std::pair<const u8*, int>> m_resolvedBufs;
|
||||
u32 x124_secCount = 0;
|
||||
u32 x128_mreaDataOffset = 0;
|
||||
std::unique_ptr<CPostConstructed> x12c_postConstructed;
|
||||
|
@ -303,7 +303,7 @@ public:
|
|||
void StartStreamIn(CStateManager& mgr);
|
||||
void Validate(CStateManager& mgr);
|
||||
void LoadScriptObjects(CStateManager& mgr);
|
||||
std::pair<u8*, u32> GetLayerScriptBuffer(int layer);
|
||||
std::pair<const u8*, u32> GetLayerScriptBuffer(int layer);
|
||||
void PostConstructArea();
|
||||
void FillInStaticGeometry();
|
||||
void VerifyTokenList(CStateManager& stateMgr);
|
||||
|
|
|
@ -74,6 +74,7 @@ set(WORLD_SOURCES
|
|||
CScriptRoomAcoustics.hpp CScriptRoomAcoustics.cpp
|
||||
CScriptColorModulate.hpp CScriptColorModulate.cpp
|
||||
CScriptStreamedMusic.hpp CScriptStreamedMusic.cpp
|
||||
CScriptMidi.hpp CScriptMidi.cpp
|
||||
CRepulsor.hpp CRepulsor.cpp
|
||||
CScriptGunTurret.hpp CScriptGunTurret.cpp
|
||||
CScriptCameraPitchVolume.hpp CScriptCameraPitchVolume.cpp
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
#include "CScriptMidi.hpp"
|
||||
#include "TCastTo.hpp"
|
||||
#include "CSimplePool.hpp"
|
||||
#include "GameGlobalObjects.hpp"
|
||||
#include "CStateManager.hpp"
|
||||
#include "MP1/CInGameGuiManager.hpp"
|
||||
#include "CInGameTweakManagerBase.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
CScriptMidi::CScriptMidi(TUniqueId id, const CEntityInfo& info, const std::string& name,
|
||||
bool active, ResId csng, float fadeIn, float fadeOut, s32 volume)
|
||||
: CEntity(id, info, active, name), x40_fadeInTime(fadeIn), x44_fadeOutTime(fadeOut),
|
||||
x48_volume(volume)
|
||||
{
|
||||
x34_song = g_SimplePool->GetObj(SObjectTag{FOURCC('CSNG'), csng});
|
||||
}
|
||||
|
||||
void CScriptMidi::StopInternal(float fadeTime)
|
||||
{
|
||||
if (x3c_handle)
|
||||
{
|
||||
CMidiManager::Stop(x3c_handle, fadeTime);
|
||||
x3c_handle.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptMidi::Stop(CStateManager& mgr, float fadeTime)
|
||||
{
|
||||
const CWorld* wld = mgr.GetWorld();
|
||||
const CGameArea* area = wld->GetAreaAlways(x4_areaId);
|
||||
std::string twkName = MP1::CInGameGuiManager::GetIdentifierForMidiEvent(wld->IGetWorldAssetId(),
|
||||
area->GetAreaAssetId(),
|
||||
x10_name);
|
||||
if (g_TweakManager->HasTweakValue(twkName))
|
||||
{
|
||||
const CTweakValue::Audio& audio = g_TweakManager->GetTweakValue(twkName)->GetAudio();
|
||||
fadeTime = audio.GetFadeOut();
|
||||
}
|
||||
|
||||
StopInternal(fadeTime);
|
||||
}
|
||||
|
||||
void CScriptMidi::Play(CStateManager& mgr, float fadeTime)
|
||||
{
|
||||
u32 volume = x48_volume;
|
||||
const CWorld* wld = mgr.GetWorld();
|
||||
const CGameArea* area = wld->GetAreaAlways(x4_areaId);
|
||||
std::string twkName = MP1::CInGameGuiManager::GetIdentifierForMidiEvent(wld->IGetWorldAssetId(),
|
||||
area->GetAreaAssetId(),
|
||||
x10_name);
|
||||
if (g_TweakManager->HasTweakValue(twkName))
|
||||
{
|
||||
const CTweakValue::Audio& audio = g_TweakManager->GetTweakValue(twkName)->GetAudio();
|
||||
x34_song = g_SimplePool->GetObj(SObjectTag{FOURCC('CSNG'), audio.GetResId()});
|
||||
fadeTime = audio.GetFadeIn();
|
||||
volume = audio.GetVolume() * 127.f;
|
||||
}
|
||||
|
||||
x3c_handle = CMidiManager::Play(*x34_song, fadeTime, false, volume / 127.f);
|
||||
}
|
||||
|
||||
void CScriptMidi::Accept(IVisitor& visitor)
|
||||
{
|
||||
visitor.Visit(this);
|
||||
}
|
||||
|
||||
void CScriptMidi::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr)
|
||||
{
|
||||
CEntity::AcceptScriptMsg(msg, objId, stateMgr);
|
||||
switch (msg)
|
||||
{
|
||||
case EScriptObjectMessage::Play:
|
||||
if (GetActive())
|
||||
Play(stateMgr, x40_fadeInTime);
|
||||
break;
|
||||
case EScriptObjectMessage::Stop:
|
||||
if (GetActive())
|
||||
Stop(stateMgr, x44_fadeOutTime);
|
||||
break;
|
||||
case EScriptObjectMessage::Deactivate:
|
||||
StopInternal(0.f);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef __URDE_CSCRIPTMIDI_HPP__
|
||||
#define __URDE_CSCRIPTMIDI_HPP__
|
||||
|
||||
#include "CEntity.hpp"
|
||||
#include "CToken.hpp"
|
||||
#include "Audio/CMidiManager.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
class CScriptMidi : public CEntity
|
||||
{
|
||||
TToken<CMidiManager::CMidiData> x34_song;
|
||||
CMidiHandle x3c_handle;
|
||||
float x40_fadeInTime;
|
||||
float x44_fadeOutTime;
|
||||
u16 x48_volume;
|
||||
|
||||
void StopInternal(float fadeTime);
|
||||
|
||||
public:
|
||||
CScriptMidi(TUniqueId id, const CEntityInfo& info, const std::string& name,
|
||||
bool active, ResId csng, float, float, s32);
|
||||
|
||||
void Stop(CStateManager& mgr, float fadeTime);
|
||||
void Play(CStateManager& mgr, float fadeTime);
|
||||
void Accept(IVisitor& visitor);
|
||||
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __URDE_CSCRIPTSTREAMEDMUSIC_HPP__
|
|
@ -64,6 +64,7 @@
|
|||
#include "MP1/World/CActorContraption.hpp"
|
||||
#include "CScriptShadowProjector.hpp"
|
||||
#include "CScriptStreamedMusic.hpp"
|
||||
#include "CScriptMidi.hpp"
|
||||
#include "CScriptRoomAcoustics.hpp"
|
||||
#include "CPatternedInfo.hpp"
|
||||
#include "CSimplePool.hpp"
|
||||
|
@ -1916,7 +1917,16 @@ CEntity* ScriptLoader::LoadThardusRockProjectile(CStateManager& mgr, CInputStrea
|
|||
|
||||
CEntity* ScriptLoader::LoadMidi(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
|
||||
{
|
||||
if (!EnsurePropertyCount(propCount, 6, "Midi"))
|
||||
return nullptr;
|
||||
|
||||
std::string name = mgr.HashInstanceName(in);
|
||||
bool active = in.readBool();
|
||||
u32 csng = in.readUint32Big();
|
||||
float fadeIn = in.readFloatBig();
|
||||
float fadeOut = in.readFloatBig();
|
||||
u32 vol = in.readUint32Big();
|
||||
return new CScriptMidi(mgr.AllocateUniqueId(), info, name, active, csng, fadeIn, fadeOut, vol);
|
||||
}
|
||||
|
||||
CEntity* ScriptLoader::LoadStreamedAudio(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
|
||||
|
|
2
amuse
2
amuse
|
@ -1 +1 @@
|
|||
Subproject commit 5c8fa2e8ab76cb95dad7a6add9efd8ecb9bfbbfe
|
||||
Subproject commit a23af16349383be647494e9ae245568cc5194eae
|
|
@ -4,7 +4,6 @@
|
|||
#define VISI_MIN_LENGTH 8.0
|
||||
|
||||
static logvisor::Module Log("VISIBuilder");
|
||||
const VISIBuilder::Leaf VISIBuilder::NullLeaf = {};
|
||||
|
||||
VISIBuilder::PVSRenderCache::PVSRenderCache(VISIRenderer& renderer)
|
||||
: m_renderer(renderer)
|
||||
|
@ -245,6 +244,9 @@ void VISIBuilder::Node::calculateSizesAndOffs(size_t& cur, size_t leafSz)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!leaf)
|
||||
flags &= ~0x8;
|
||||
else
|
||||
cur += leafSz;
|
||||
}
|
||||
}
|
||||
|
@ -294,7 +296,7 @@ void VISIBuilder::Node::writeNodes(athena::io::MemoryWriter& w, size_t leafBytes
|
|||
childNodes[nodeSel].writeNodes(w, leafBytes);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (leaf)
|
||||
{
|
||||
leaf.write(w, leafBytes);
|
||||
}
|
||||
|
|
|
@ -77,7 +77,6 @@ struct VISIBuilder
|
|||
}
|
||||
}
|
||||
};
|
||||
static const Leaf NullLeaf;
|
||||
|
||||
class PVSRenderCache
|
||||
{
|
||||
|
@ -113,7 +112,7 @@ struct VISIBuilder
|
|||
|
||||
bool operator==(const Node& other) const
|
||||
{
|
||||
if (!leaf || !other.leaf)
|
||||
if ((flags & 0x7) || (other.flags & 0x7))
|
||||
return false;
|
||||
return leaf == other.leaf;
|
||||
}
|
||||
|
|
|
@ -296,6 +296,10 @@ void VISIRenderer::RenderPVSOpaque(RGBA8* bufOut, const zeus::CVector3f& pos, bo
|
|||
zeus::CFrustum frustum;
|
||||
frustum.updatePlanes(mv, g_Proj);
|
||||
|
||||
// Fill depth buffer with backfaces initially
|
||||
glCullFace(GL_FRONT);
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
|
||||
for (const Model& model : m_models)
|
||||
{
|
||||
if (!frustum.aabbFrustumTest(model.aabb))
|
||||
|
@ -311,6 +315,24 @@ void VISIRenderer::RenderPVSOpaque(RGBA8* bufOut, const zeus::CVector3f& pos, bo
|
|||
needTransparent = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw frontfaces
|
||||
glCullFace(GL_BACK);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
||||
for (const Model& model : m_models)
|
||||
{
|
||||
if (!frustum.aabbFrustumTest(model.aabb))
|
||||
continue;
|
||||
glBindVertexArray(model.vao);
|
||||
for (const Model::Surface& surf : model.surfaces)
|
||||
{
|
||||
// Non-transparents first
|
||||
if (!surf.transparent)
|
||||
glDrawElements(model.topology, surf.count, GL_UNSIGNED_INT,
|
||||
reinterpret_cast<void*>(uintptr_t(surf.first * 4)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//m_swapFunc();
|
||||
|
|
Loading…
Reference in New Issue