MemoryCard PutTo implementations

This commit is contained in:
Jack Andersen 2016-10-09 11:41:23 -10:00
parent 545fccc4cc
commit a85ea968c3
10 changed files with 194 additions and 17 deletions

View File

@ -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)
{
x14_[eid] = visited;

View File

@ -15,7 +15,7 @@ class CMapWorldInfo
public:
CMapWorldInfo()=default;
CMapWorldInfo(CBitStreamReader&, const CSaveWorld& saveWorld, ResId mlvlId);
void PutTo(COutputStream&);
void PutTo(CBitStreamWriter& writer, const CSaveWorld& savw) const;
bool IsMapped() const;
void SetIsMapped(bool) const;
void SetDoorVisited(TEditorId eid, bool val);

View File

@ -3,17 +3,26 @@
#include <stdint.h>
#include <stdlib.h>
#include <chrono>
#include "RetroTypes.hpp"
namespace urde
{
using OSTime = s64;
class CBasics
{
public:
static void Init();
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);
};
}

View File

@ -1,5 +1,6 @@
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include "CBasics.hpp"
@ -20,4 +21,42 @@ const char* CBasics::Stringize(const char* fmt, ...)
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);
}
}

View File

@ -91,6 +91,29 @@ CGameOptions::CGameOptions(CBitStreamReader& stream)
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()
{
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);
}
}
}

View File

@ -86,6 +86,7 @@ public:
CGameOptions();
CGameOptions(CBitStreamReader& stream);
void InitSoundMode();
void PutTo(CBitStreamWriter& writer) const;
};
class CHintOptions
@ -113,6 +114,7 @@ private:
public:
CHintOptions() = default;
CHintOptions(CBitStreamReader& stream);
void PutTo(CBitStreamWriter& writer) const;
};
}

View File

@ -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)
{
if (x0_areaLayers.size())
@ -63,6 +79,15 @@ CWorldState::CWorldState(CBitStreamReader& reader, ResId mlvlId, const CSaveWorl
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()
{
x98_playerState.reset(new CPlayerState());
@ -75,17 +100,26 @@ CGameState::CGameState(CBitStreamReader& stream)
x228_25_deferPowerupInit = true;
for (u32 i = 0; i < 128; i++)
stream.ReadEncoded(8);
u32 tmp = stream.ReadEncoded(32);
float val1 = reinterpret_cast<float&>(tmp);
bool val2 = stream.ReadEncoded(1);
stream.ReadEncoded(1);
tmp = stream.ReadEncoded(32);
float val3 = reinterpret_cast<float&>(tmp);
tmp = stream.ReadEncoded(32);
float val4 = reinterpret_cast<float&>(tmp);
tmp = stream.ReadEncoded(32);
float val5 = reinterpret_cast<float&>(tmp);
x0_[i] = stream.ReadEncoded(8);
u32 tsSeconds = stream.ReadEncoded(32);
x228_24_ = stream.ReadEncoded(1);
x228_25_deferPowerupInit = stream.ReadEncoded(1);
x84_mlvlId = stream.ReadEncoded(32);
EnsureWorldPakReady(x84_mlvlId);
union BitsToDouble
{
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);
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)

View File

@ -38,6 +38,13 @@ public:
}
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
@ -57,6 +64,7 @@ public:
const std::shared_ptr<CRelayTracker>& RelayTracker() const { return x8_relayTracker; }
const std::shared_ptr<CMapWorldInfo>& MapWorldInfo() const { return xc_mapWorldInfo; }
const std::shared_ptr<CWorldLayerState>& GetLayerState() const { return x14_layerState; }
void PutTo(CBitStreamWriter& writer, const CSaveWorld& savw) const;
};
class CGameState
@ -83,10 +91,12 @@ class CGameState
u8 _dummy = 0;
};
static void EnsureWorldPakReady(ResId mlvl);
public:
CGameState();
CGameState(CBitStreamReader& stream);
void SetCurrentWorldId(unsigned int id);
void SetCurrentWorldId(ResId id);
std::shared_ptr<CPlayerState> GetPlayerState() {return x98_playerState;}
std::shared_ptr<CWorldTransManager> GetWorldTransitionManager() {return x9c_transManager;}
void SetTotalPlayTime(float time);
@ -95,6 +105,7 @@ public:
CWorldState& StateForWorld(ResId mlvlId);
CWorldState& CurrentWorldState() { return StateForWorld(x84_mlvlId); }
ResId CurrentWorldAssetId() const { return x84_mlvlId; }
void PutTo(CBitStreamWriter& writer) const;
};
}

View File

@ -291,8 +291,6 @@ public:
const std::shared_ptr<CMapWorldInfo>& MapWorldInfo() const { return x8c0_mapWorldInfo; }
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* Player() const { return x84c_player.get(); }

View File

@ -4,6 +4,7 @@
#include "CSimplePool.hpp"
#include "CStateManager.hpp"
#include "World/CScriptAreaAttributes.hpp"
#include "CGameState.hpp"
namespace urde
{
@ -841,7 +842,7 @@ void CGameArea::VerifyTokenList(CStateManager& stateMgr)
int lidx = 0;
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 end = xac_deps2.begin() + off;