mirror of https://github.com/AxioDL/metaforce.git
MemoryCard PutTo implementations
This commit is contained in:
parent
545fccc4cc
commit
a85ea968c3
|
@ -19,6 +19,11 @@ CMapWorldInfo::CMapWorldInfo(CBitStreamReader& reader, const CSaveWorld& saveWor
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMapWorldInfo::PutTo(CBitStreamWriter& writer, const CSaveWorld& savw) const
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void CMapWorldInfo::SetDoorVisited(TEditorId eid, bool visited)
|
void CMapWorldInfo::SetDoorVisited(TEditorId eid, bool visited)
|
||||||
{
|
{
|
||||||
x14_[eid] = visited;
|
x14_[eid] = visited;
|
||||||
|
|
|
@ -15,7 +15,7 @@ class CMapWorldInfo
|
||||||
public:
|
public:
|
||||||
CMapWorldInfo()=default;
|
CMapWorldInfo()=default;
|
||||||
CMapWorldInfo(CBitStreamReader&, const CSaveWorld& saveWorld, ResId mlvlId);
|
CMapWorldInfo(CBitStreamReader&, const CSaveWorld& saveWorld, ResId mlvlId);
|
||||||
void PutTo(COutputStream&);
|
void PutTo(CBitStreamWriter& writer, const CSaveWorld& savw) const;
|
||||||
bool IsMapped() const;
|
bool IsMapped() const;
|
||||||
void SetIsMapped(bool) const;
|
void SetIsMapped(bool) const;
|
||||||
void SetDoorVisited(TEditorId eid, bool val);
|
void SetDoorVisited(TEditorId eid, bool val);
|
||||||
|
|
|
@ -3,17 +3,26 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
#include "RetroTypes.hpp"
|
#include "RetroTypes.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
|
using OSTime = s64;
|
||||||
|
|
||||||
class CBasics
|
class CBasics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void Init();
|
static void Init();
|
||||||
static const char* Stringize(const char* fmt, ...);
|
static const char* Stringize(const char* fmt, ...);
|
||||||
|
|
||||||
|
static const u64 SECONDS_TO_2000;
|
||||||
|
static const u64 TICKS_PER_SECOND;
|
||||||
|
|
||||||
|
static OSTime ToWiiTime(std::chrono::system_clock::time_point time);
|
||||||
|
static std::chrono::system_clock::time_point FromWiiTime(OSTime wiiTime);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include "CBasics.hpp"
|
#include "CBasics.hpp"
|
||||||
|
|
||||||
|
@ -20,4 +21,42 @@ const char* CBasics::Stringize(const char* fmt, ...)
|
||||||
return STRINGIZE_STR;
|
return STRINGIZE_STR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const u64 CBasics::SECONDS_TO_2000 = 946684800LL;
|
||||||
|
const u64 CBasics::TICKS_PER_SECOND = 60750000LL;
|
||||||
|
|
||||||
|
OSTime CBasics::ToWiiTime(std::chrono::system_clock::time_point time)
|
||||||
|
{
|
||||||
|
time_t sysTime, tzDiff;
|
||||||
|
struct tm* gmTime;
|
||||||
|
|
||||||
|
sysTime = std::chrono::system_clock::to_time_t(time);
|
||||||
|
// Account for DST where needed
|
||||||
|
gmTime = localtime(&sysTime);
|
||||||
|
if (!gmTime)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Lazy way to get local time in sec
|
||||||
|
gmTime = gmtime(&sysTime);
|
||||||
|
tzDiff = sysTime - mktime(gmTime);
|
||||||
|
|
||||||
|
return OSTime(TICKS_PER_SECOND * ((sysTime + tzDiff) - SECONDS_TO_2000));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::chrono::system_clock::time_point CBasics::FromWiiTime(OSTime wiiTime)
|
||||||
|
{
|
||||||
|
time_t time = SECONDS_TO_2000 + wiiTime / TICKS_PER_SECOND;
|
||||||
|
|
||||||
|
time_t sysTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||||
|
// Account for DST where needed
|
||||||
|
struct tm* gmTime = localtime(&sysTime);
|
||||||
|
if (!gmTime)
|
||||||
|
return std::chrono::system_clock::from_time_t(0);
|
||||||
|
|
||||||
|
// Lazy way to get local time in sec
|
||||||
|
gmTime = gmtime(&sysTime);
|
||||||
|
time_t tzDiff = sysTime - mktime(gmTime);
|
||||||
|
|
||||||
|
return std::chrono::system_clock::from_time_t(time - tzDiff);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,29 @@ CGameOptions::CGameOptions(CBitStreamReader& stream)
|
||||||
x68_27_ = stream.ReadEncoded(1);
|
x68_27_ = stream.ReadEncoded(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGameOptions::PutTo(CBitStreamWriter& writer) const
|
||||||
|
{
|
||||||
|
for (int b=0 ; b<64 ; ++b)
|
||||||
|
writer.WriteEncoded(x0_[b], 1);
|
||||||
|
|
||||||
|
writer.WriteEncoded(u32(x44_soundMode), 2);
|
||||||
|
writer.WriteEncoded(x48_, 4);
|
||||||
|
|
||||||
|
writer.WriteEncoded(x4c_, 6);
|
||||||
|
writer.WriteEncoded(x50_, 6);
|
||||||
|
writer.WriteEncoded(x54_, 5);
|
||||||
|
writer.WriteEncoded(x58_, 7);
|
||||||
|
writer.WriteEncoded(x5c_, 7);
|
||||||
|
writer.WriteEncoded(x60_, 8);
|
||||||
|
writer.WriteEncoded(x64_, 8);
|
||||||
|
|
||||||
|
writer.WriteEncoded(x68_24_, 1);
|
||||||
|
writer.WriteEncoded(x68_28_, 1);
|
||||||
|
writer.WriteEncoded(x68_25_, 1);
|
||||||
|
writer.WriteEncoded(x68_26_, 1);
|
||||||
|
writer.WriteEncoded(x68_27_, 1);
|
||||||
|
}
|
||||||
|
|
||||||
CGameOptions::CGameOptions()
|
CGameOptions::CGameOptions()
|
||||||
{
|
{
|
||||||
x68_24_ = true;
|
x68_24_ = true;
|
||||||
|
@ -126,4 +149,13 @@ CHintOptions::CHintOptions(CBitStreamReader& stream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CHintOptions::PutTo(CBitStreamWriter& writer) const
|
||||||
|
{
|
||||||
|
for (const SHintState& hint : x0_hintStates)
|
||||||
|
{
|
||||||
|
writer.WriteEncoded(u32(hint.x0_state), 2);
|
||||||
|
writer.WriteEncoded(reinterpret_cast<const u32&>(hint.x4_time), 32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,7 @@ public:
|
||||||
CGameOptions();
|
CGameOptions();
|
||||||
CGameOptions(CBitStreamReader& stream);
|
CGameOptions(CBitStreamReader& stream);
|
||||||
void InitSoundMode();
|
void InitSoundMode();
|
||||||
|
void PutTo(CBitStreamWriter& writer) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CHintOptions
|
class CHintOptions
|
||||||
|
@ -113,6 +114,7 @@ private:
|
||||||
public:
|
public:
|
||||||
CHintOptions() = default;
|
CHintOptions() = default;
|
||||||
CHintOptions(CBitStreamReader& stream);
|
CHintOptions(CBitStreamReader& stream);
|
||||||
|
void PutTo(CBitStreamWriter& writer) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,22 @@ CWorldLayerState::CWorldLayerState(CBitStreamReader& reader, const CSaveWorld& s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CWorldLayerState::PutTo(CBitStreamWriter& writer) const
|
||||||
|
{
|
||||||
|
u32 totalLayerCount = 0;
|
||||||
|
for (int i=0 ; i<x0_areaLayers.size() ; ++i)
|
||||||
|
totalLayerCount += GetAreaLayerCount(i) - 1;
|
||||||
|
|
||||||
|
writer.WriteEncoded(totalLayerCount, 10);
|
||||||
|
|
||||||
|
for (int i=0 ; i<x0_areaLayers.size() ; ++i)
|
||||||
|
{
|
||||||
|
u32 count = GetAreaLayerCount(i);
|
||||||
|
for (u32 l=1 ; l<count ; ++l)
|
||||||
|
writer.WriteEncoded(IsLayerActive(i, l), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CWorldLayerState::InitializeWorldLayers(const std::vector<CWorldLayers::Area>& layers)
|
void CWorldLayerState::InitializeWorldLayers(const std::vector<CWorldLayers::Area>& layers)
|
||||||
{
|
{
|
||||||
if (x0_areaLayers.size())
|
if (x0_areaLayers.size())
|
||||||
|
@ -63,6 +79,15 @@ CWorldState::CWorldState(CBitStreamReader& reader, ResId mlvlId, const CSaveWorl
|
||||||
x14_layerState = std::make_shared<CWorldLayerState>(reader, saveWorld);
|
x14_layerState = std::make_shared<CWorldLayerState>(reader, saveWorld);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CWorldState::PutTo(CBitStreamWriter& writer, const CSaveWorld& savw) const
|
||||||
|
{
|
||||||
|
writer.WriteEncoded(x4_areaId, 32);
|
||||||
|
writer.WriteEncoded(x10_, 32);
|
||||||
|
x8_relayTracker->PutTo(writer, savw);
|
||||||
|
xc_mapWorldInfo->PutTo(writer, savw);
|
||||||
|
x14_layerState->PutTo(writer);
|
||||||
|
}
|
||||||
|
|
||||||
CGameState::CGameState()
|
CGameState::CGameState()
|
||||||
{
|
{
|
||||||
x98_playerState.reset(new CPlayerState());
|
x98_playerState.reset(new CPlayerState());
|
||||||
|
@ -75,17 +100,26 @@ CGameState::CGameState(CBitStreamReader& stream)
|
||||||
x228_25_deferPowerupInit = true;
|
x228_25_deferPowerupInit = true;
|
||||||
|
|
||||||
for (u32 i = 0; i < 128; i++)
|
for (u32 i = 0; i < 128; i++)
|
||||||
stream.ReadEncoded(8);
|
x0_[i] = stream.ReadEncoded(8);
|
||||||
u32 tmp = stream.ReadEncoded(32);
|
u32 tsSeconds = stream.ReadEncoded(32);
|
||||||
float val1 = reinterpret_cast<float&>(tmp);
|
|
||||||
bool val2 = stream.ReadEncoded(1);
|
x228_24_ = stream.ReadEncoded(1);
|
||||||
stream.ReadEncoded(1);
|
x228_25_deferPowerupInit = stream.ReadEncoded(1);
|
||||||
tmp = stream.ReadEncoded(32);
|
x84_mlvlId = stream.ReadEncoded(32);
|
||||||
float val3 = reinterpret_cast<float&>(tmp);
|
EnsureWorldPakReady(x84_mlvlId);
|
||||||
tmp = stream.ReadEncoded(32);
|
|
||||||
float val4 = reinterpret_cast<float&>(tmp);
|
union BitsToDouble
|
||||||
tmp = stream.ReadEncoded(32);
|
{
|
||||||
float val5 = reinterpret_cast<float&>(tmp);
|
struct
|
||||||
|
{
|
||||||
|
u32 low;
|
||||||
|
u32 high;
|
||||||
|
};
|
||||||
|
double doub;
|
||||||
|
} conv;
|
||||||
|
conv.low = stream.ReadEncoded(32);
|
||||||
|
conv.high = stream.ReadEncoded(32);
|
||||||
|
xa0_playTime = conv.doub;
|
||||||
|
|
||||||
x98_playerState = std::make_shared<CPlayerState>(stream);
|
x98_playerState = std::make_shared<CPlayerState>(stream);
|
||||||
float currentHealth = x98_playerState->GetHealthInfo().GetHP();
|
float currentHealth = x98_playerState->GetHealthInfo().GetHP();
|
||||||
|
@ -103,8 +137,54 @@ CGameState::CGameState(CBitStreamReader& stream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameState::SetCurrentWorldId(unsigned int id)
|
|
||||||
|
void CGameState::PutTo(CBitStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
|
for (u32 i = 0; i < 128; i++)
|
||||||
|
writer.WriteEncoded(x0_[i], 8);
|
||||||
|
|
||||||
|
writer.WriteEncoded(CBasics::ToWiiTime(std::chrono::system_clock::now()) / CBasics::TICKS_PER_SECOND, 32);
|
||||||
|
writer.WriteEncoded(x228_24_, 1);
|
||||||
|
writer.WriteEncoded(x228_25_deferPowerupInit, 1);
|
||||||
|
writer.WriteEncoded(x84_mlvlId, 32);
|
||||||
|
|
||||||
|
union BitsToDouble
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u32 low;
|
||||||
|
u32 high;
|
||||||
|
};
|
||||||
|
double doub;
|
||||||
|
} conv;
|
||||||
|
conv.doub = xa0_playTime;
|
||||||
|
writer.WriteEncoded(conv.low, 32);
|
||||||
|
writer.WriteEncoded(conv.high, 32);
|
||||||
|
|
||||||
|
x98_playerState->PutTo(writer);
|
||||||
|
x17c_gameOptions.PutTo(writer);
|
||||||
|
x1f8_hintOptions.PutTo(writer);
|
||||||
|
|
||||||
|
const auto& memWorlds = g_MemoryCardSys->GetMemoryWorlds();
|
||||||
|
for (const auto& memWorld : memWorlds)
|
||||||
|
{
|
||||||
|
TLockedToken<CSaveWorld> saveWorld =
|
||||||
|
g_SimplePool->GetObj(SObjectTag{FOURCC('SAVW'), memWorld.second.GetSaveWorldAssetId()});
|
||||||
|
const CWorldState& wld = const_cast<CGameState&>(*this).StateForWorld(memWorld.first);
|
||||||
|
wld.PutTo(writer, *saveWorld);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGameState::EnsureWorldPakReady(ResId mlvl)
|
||||||
|
{
|
||||||
|
/* TODO: Schedule resource list load for World Pak containing mlvl */
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGameState::SetCurrentWorldId(ResId id)
|
||||||
|
{
|
||||||
|
StateForWorld(id);
|
||||||
|
x84_mlvlId = id;
|
||||||
|
EnsureWorldPakReady(x84_mlvlId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameState::SetTotalPlayTime(float time)
|
void CGameState::SetTotalPlayTime(float time)
|
||||||
|
|
|
@ -38,6 +38,13 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeWorldLayers(const std::vector<CWorldLayers::Area>& layers);
|
void InitializeWorldLayers(const std::vector<CWorldLayers::Area>& layers);
|
||||||
|
|
||||||
|
u32 GetAreaLayerCount(int areaIdx) const
|
||||||
|
{
|
||||||
|
return x0_areaLayers[areaIdx].m_layerCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PutTo(CBitStreamWriter& writer) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CWorldState
|
class CWorldState
|
||||||
|
@ -57,6 +64,7 @@ public:
|
||||||
const std::shared_ptr<CRelayTracker>& RelayTracker() const { return x8_relayTracker; }
|
const std::shared_ptr<CRelayTracker>& RelayTracker() const { return x8_relayTracker; }
|
||||||
const std::shared_ptr<CMapWorldInfo>& MapWorldInfo() const { return xc_mapWorldInfo; }
|
const std::shared_ptr<CMapWorldInfo>& MapWorldInfo() const { return xc_mapWorldInfo; }
|
||||||
const std::shared_ptr<CWorldLayerState>& GetLayerState() const { return x14_layerState; }
|
const std::shared_ptr<CWorldLayerState>& GetLayerState() const { return x14_layerState; }
|
||||||
|
void PutTo(CBitStreamWriter& writer, const CSaveWorld& savw) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CGameState
|
class CGameState
|
||||||
|
@ -83,10 +91,12 @@ class CGameState
|
||||||
u8 _dummy = 0;
|
u8 _dummy = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void EnsureWorldPakReady(ResId mlvl);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CGameState();
|
CGameState();
|
||||||
CGameState(CBitStreamReader& stream);
|
CGameState(CBitStreamReader& stream);
|
||||||
void SetCurrentWorldId(unsigned int id);
|
void SetCurrentWorldId(ResId id);
|
||||||
std::shared_ptr<CPlayerState> GetPlayerState() {return x98_playerState;}
|
std::shared_ptr<CPlayerState> GetPlayerState() {return x98_playerState;}
|
||||||
std::shared_ptr<CWorldTransManager> GetWorldTransitionManager() {return x9c_transManager;}
|
std::shared_ptr<CWorldTransManager> GetWorldTransitionManager() {return x9c_transManager;}
|
||||||
void SetTotalPlayTime(float time);
|
void SetTotalPlayTime(float time);
|
||||||
|
@ -95,6 +105,7 @@ public:
|
||||||
CWorldState& StateForWorld(ResId mlvlId);
|
CWorldState& StateForWorld(ResId mlvlId);
|
||||||
CWorldState& CurrentWorldState() { return StateForWorld(x84_mlvlId); }
|
CWorldState& CurrentWorldState() { return StateForWorld(x84_mlvlId); }
|
||||||
ResId CurrentWorldAssetId() const { return x84_mlvlId; }
|
ResId CurrentWorldAssetId() const { return x84_mlvlId; }
|
||||||
|
void PutTo(CBitStreamWriter& writer) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -291,8 +291,6 @@ public:
|
||||||
const std::shared_ptr<CMapWorldInfo>& MapWorldInfo() const { return x8c0_mapWorldInfo; }
|
const std::shared_ptr<CMapWorldInfo>& MapWorldInfo() const { return x8c0_mapWorldInfo; }
|
||||||
const std::shared_ptr<CWorldLayerState>& LayerState() const { return x8c8_worldLayerState; }
|
const std::shared_ptr<CWorldLayerState>& LayerState() const { return x8c8_worldLayerState; }
|
||||||
|
|
||||||
bool IsLayerActive(TAreaId area, int layerIdx) { return false; }
|
|
||||||
|
|
||||||
CPlayer& GetPlayer() const { return *x84c_player; }
|
CPlayer& GetPlayer() const { return *x84c_player; }
|
||||||
CPlayer* Player() const { return x84c_player.get(); }
|
CPlayer* Player() const { return x84c_player.get(); }
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "CSimplePool.hpp"
|
#include "CSimplePool.hpp"
|
||||||
#include "CStateManager.hpp"
|
#include "CStateManager.hpp"
|
||||||
#include "World/CScriptAreaAttributes.hpp"
|
#include "World/CScriptAreaAttributes.hpp"
|
||||||
|
#include "CGameState.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -841,7 +842,7 @@ void CGameArea::VerifyTokenList(CStateManager& stateMgr)
|
||||||
int lidx = 0;
|
int lidx = 0;
|
||||||
for (u32 off : xbc_layerDepOffsets)
|
for (u32 off : xbc_layerDepOffsets)
|
||||||
{
|
{
|
||||||
if (stateMgr.IsLayerActive(x4_selfIdx, lidx))
|
if (stateMgr.LayerState()->IsLayerActive(x4_selfIdx, lidx))
|
||||||
{
|
{
|
||||||
auto it = xac_deps2.begin() + lastOff;
|
auto it = xac_deps2.begin() + lastOff;
|
||||||
auto end = xac_deps2.begin() + off;
|
auto end = xac_deps2.begin() + off;
|
||||||
|
|
Loading…
Reference in New Issue