mirror of https://github.com/AxioDL/metaforce.git
Fix save loading, rewrite Loadout classes to use CInputStream
This commit is contained in:
parent
aa1d6006ed
commit
80362a9483
|
@ -137,6 +137,7 @@ set(RUNTIME_SOURCES_B
|
||||||
GCNTypes.hpp
|
GCNTypes.hpp
|
||||||
CTextureCache.hpp CTextureCache.cpp
|
CTextureCache.hpp CTextureCache.cpp
|
||||||
CMayaSpline.hpp CMayaSpline.cpp
|
CMayaSpline.hpp CMayaSpline.cpp
|
||||||
|
ImGuiPlayerLoadouts.hpp ImGuiPlayerLoadouts.cpp
|
||||||
${PLAT_SRCS})
|
${PLAT_SRCS})
|
||||||
|
|
||||||
function(add_runtime_common_library name)
|
function(add_runtime_common_library name)
|
||||||
|
|
|
@ -263,7 +263,7 @@ static void RenderEntityColumns(const ImGuiEntityEntry& entry) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiConsole::ShowInspectWindow(bool* isOpen) {
|
void ImGuiConsole::ShowInspectWindow(bool* isOpen) {
|
||||||
float initialWindowSize = 400.f * ImGui::GetIO().DisplayFramebufferScale.x;
|
float initialWindowSize = 400.f * aurora::get_window_size().scale;
|
||||||
ImGui::SetNextWindowSize(ImVec2{initialWindowSize, initialWindowSize * 1.5f}, ImGuiCond_FirstUseEver);
|
ImGui::SetNextWindowSize(ImVec2{initialWindowSize, initialWindowSize * 1.5f}, ImGuiCond_FirstUseEver);
|
||||||
|
|
||||||
if (ImGui::Begin("Inspect", isOpen)) {
|
if (ImGui::Begin("Inspect", isOpen)) {
|
||||||
|
@ -383,7 +383,7 @@ bool ImGuiConsole::ShowEntityInfoWindow(TUniqueId uid) {
|
||||||
|
|
||||||
void ImGuiConsole::ShowConsoleVariablesWindow() {
|
void ImGuiConsole::ShowConsoleVariablesWindow() {
|
||||||
// For some reason the window shows up tiny without this
|
// For some reason the window shows up tiny without this
|
||||||
float initialWindowSize = 350.f * ImGui::GetIO().DisplayFramebufferScale.x;
|
float initialWindowSize = 350.f * aurora::get_window_size().scale;
|
||||||
ImGui::SetNextWindowSize(ImVec2{initialWindowSize, initialWindowSize}, ImGuiCond_FirstUseEver);
|
ImGui::SetNextWindowSize(ImVec2{initialWindowSize, initialWindowSize}, ImGuiCond_FirstUseEver);
|
||||||
if (ImGui::Begin("Console Variables", &m_showConsoleVariablesWindow)) {
|
if (ImGui::Begin("Console Variables", &m_showConsoleVariablesWindow)) {
|
||||||
if (ImGui::Button("Clear")) {
|
if (ImGui::Button("Clear")) {
|
||||||
|
@ -633,7 +633,7 @@ std::optional<std::string> ImGuiConsole::ShowAboutWindow(bool canClose, std::str
|
||||||
flags |= ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove;
|
flags |= ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove;
|
||||||
}
|
}
|
||||||
if (ImGui::Begin("About", open, flags)) {
|
if (ImGui::Begin("About", open, flags)) {
|
||||||
float iconSize = 128.f * ImGui::GetIO().DisplayFramebufferScale.x;
|
float iconSize = 128.f * aurora::get_window_size().scale;
|
||||||
ImGui::SameLine(ImGui::GetWindowSize().x / 2 - iconSize + (iconSize / 2));
|
ImGui::SameLine(ImGui::GetWindowSize().x / 2 - iconSize + (iconSize / 2));
|
||||||
ImGui::Image(ImGuiEngine::metaforceIcon, ImVec2{iconSize, iconSize});
|
ImGui::Image(ImGuiEngine::metaforceIcon, ImVec2{iconSize, iconSize});
|
||||||
ImGui::PushFont(ImGuiEngine::fontLarge);
|
ImGui::PushFont(ImGuiEngine::fontLarge);
|
||||||
|
@ -942,7 +942,7 @@ void ImGuiConsole::ShowInputViewer() {
|
||||||
}
|
}
|
||||||
ImGui::SetNextWindowBgAlpha(0.65f);
|
ImGui::SetNextWindowBgAlpha(0.65f);
|
||||||
if (ImGui::Begin("Input Overlay", nullptr, windowFlags)) {
|
if (ImGui::Begin("Input Overlay", nullptr, windowFlags)) {
|
||||||
float scale = ImGui::GetIO().DisplayFramebufferScale.x;
|
float scale = aurora::get_window_size().scale;
|
||||||
if (!m_controllerName.empty()) {
|
if (!m_controllerName.empty()) {
|
||||||
TextCenter(m_controllerName);
|
TextCenter(m_controllerName);
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
@ -1508,7 +1508,7 @@ void ImGuiConsole::ShowItemsWindow() {
|
||||||
|
|
||||||
void ImGuiConsole::ShowLayersWindow() {
|
void ImGuiConsole::ShowLayersWindow() {
|
||||||
// For some reason the window shows up tiny without this
|
// For some reason the window shows up tiny without this
|
||||||
float initialWindowSize = 350.f * ImGui::GetIO().DisplayFramebufferScale.x;
|
float initialWindowSize = 350.f * aurora::get_window_size().scale;
|
||||||
ImGui::SetNextWindowSize(ImVec2{initialWindowSize, initialWindowSize}, ImGuiCond_FirstUseEver);
|
ImGui::SetNextWindowSize(ImVec2{initialWindowSize, initialWindowSize}, ImGuiCond_FirstUseEver);
|
||||||
|
|
||||||
if (ImGui::Begin("Layers", &m_showLayersWindow)) {
|
if (ImGui::Begin("Layers", &m_showLayersWindow)) {
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
#include "Runtime/ImGuiPlayerLoadouts.hpp"
|
||||||
|
#include "Runtime/Streams/ContainerReaders.hpp"
|
||||||
|
#include "Runtime/Streams/ContainerWriters.hpp"
|
||||||
|
|
||||||
|
#include <logvisor/logvisor.hpp>
|
||||||
|
|
||||||
|
#include "magic_enum.hpp"
|
||||||
|
namespace metaforce {
|
||||||
|
namespace {
|
||||||
|
logvisor::Module Log("metaforce::ImGuiPlayerLoadouts");
|
||||||
|
constexpr u32 CurrentVersion = 1;
|
||||||
|
} // namespace
|
||||||
|
ImGuiPlayerLoadouts::Item::Item(CInputStream& in)
|
||||||
|
: type(magic_enum::enum_cast<CPlayerState::EItemType>(in.Get<std::string>()).value()), amount(in.ReadLong()) {}
|
||||||
|
|
||||||
|
void ImGuiPlayerLoadouts::Item::PutTo(COutputStream& out) const {
|
||||||
|
out.Put(magic_enum::enum_name<CPlayerState::EItemType>(type));
|
||||||
|
out.Put(amount);
|
||||||
|
}
|
||||||
|
ImGuiPlayerLoadouts::LoadOut::LoadOut(CInputStream& in) : name(in.Get<std::string>()) { read_vector(items, in); }
|
||||||
|
|
||||||
|
void ImGuiPlayerLoadouts::LoadOut::PutTo(COutputStream& out) const {
|
||||||
|
out.Put(name);
|
||||||
|
write_vector(items, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiPlayerLoadouts::ImGuiPlayerLoadouts(CInputStream& in) {
|
||||||
|
FourCC magic;
|
||||||
|
in.Get(reinterpret_cast<u8*>(&magic), 4);
|
||||||
|
auto version = in.ReadLong();
|
||||||
|
if (magic != FOURCC('LOAD') && version != CurrentVersion) {
|
||||||
|
Log.report(logvisor::Error, FMT_STRING("Incorrect loadout version, expected {} got {}"), CurrentVersion, version);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
read_vector(loadouts, in);
|
||||||
|
}
|
||||||
|
void ImGuiPlayerLoadouts::PutTo(COutputStream& out) const {
|
||||||
|
auto magic = FOURCC('LOAD');
|
||||||
|
out.Put(reinterpret_cast<const u8*>(&magic), 4);
|
||||||
|
out.Put(CurrentVersion);
|
||||||
|
write_vector(loadouts, out);
|
||||||
|
}
|
||||||
|
} // namespace metaforce
|
|
@ -1,23 +1,27 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <athena/DNA.hpp>
|
#include "Runtime/CPlayerState.hpp"
|
||||||
#include <athena/DNAYaml.hpp>
|
|
||||||
|
|
||||||
namespace metaforce {
|
namespace metaforce {
|
||||||
struct ImGuiPlayerLoadouts : athena::io::DNA<athena::Endian::Big> {
|
struct ImGuiPlayerLoadouts {
|
||||||
AT_DECL_DNA_YAML
|
struct Item {
|
||||||
struct Item : athena::io::DNA<athena::Endian::Big> {
|
CPlayerState::EItemType type = CPlayerState::EItemType::Invalid;
|
||||||
AT_DECL_DNA_YAML
|
u32 amount = 0;
|
||||||
String<-1> type;
|
Item() = default;
|
||||||
Value<u32> amount;
|
explicit Item(CInputStream& in);
|
||||||
|
void PutTo(COutputStream& out) const;
|
||||||
};
|
};
|
||||||
struct LoadOut : athena::io::DNA<athena::Endian::Big> {
|
struct LoadOut{
|
||||||
AT_DECL_DNA_YAML
|
std::string name;
|
||||||
String<-1> name;
|
std::vector<Item> items;
|
||||||
Value<u32> itemCount;
|
LoadOut() = default;
|
||||||
Vector<Item, AT_DNA_COUNT(itemCount)> items;
|
explicit LoadOut(CInputStream& in);
|
||||||
|
void PutTo(COutputStream& out) const;
|
||||||
};
|
};
|
||||||
Value<u32> loadoutCount;
|
std::vector<LoadOut> loadouts;
|
||||||
Vector<LoadOut, AT_DNA_COUNT(loadoutCount)> loadouts;
|
|
||||||
|
ImGuiPlayerLoadouts() = default;
|
||||||
|
explicit ImGuiPlayerLoadouts(CInputStream& in);
|
||||||
|
void PutTo(COutputStream& out) const;
|
||||||
};
|
};
|
||||||
} // namespace metaforce
|
} // namespace metaforce
|
||||||
|
|
|
@ -89,32 +89,36 @@ u32 CInputStream::ReadBytes(void* dest, u32 len) {
|
||||||
return curReadLen;
|
return curReadLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CInputStream::ReadBits(u32 bitCount) {
|
|
||||||
u32 ret = x20_bitOffset;
|
|
||||||
if (ret < bitCount) {
|
|
||||||
const u32 shiftAmt = bitCount - x20_bitOffset;
|
|
||||||
const u32 mask = ret == 32 ? -1 : (1 << x20_bitOffset) - 1;
|
|
||||||
|
|
||||||
u32 uVar2 = x1c_bitWord;
|
u32 CInputStream::ReadBits(u32 bitCount) {
|
||||||
x20_bitOffset = 0;
|
u32 ret = 0;
|
||||||
u32 len = min_containing_bytes(shiftAmt);
|
const s32 shiftAmt = x20_bitOffset - s32(bitCount);
|
||||||
Get(reinterpret_cast<u8*>(&x1c_bitWord), len);
|
if (shiftAmt < 0) {
|
||||||
|
/* OR in remaining bits of cached value */
|
||||||
|
u32 mask = bitCount == 32 ? UINT32_MAX : ((1U << bitCount) - 1);
|
||||||
|
ret |= (x1c_bitWord << u32(-shiftAmt)) & mask;
|
||||||
|
/* Load in exact number of bytes remaining */
|
||||||
|
auto loadDiv = std::div(-shiftAmt, 8);
|
||||||
|
if (loadDiv.rem != 0) {
|
||||||
|
++loadDiv.quot;
|
||||||
|
}
|
||||||
|
Get(reinterpret_cast<u8*>(&x1c_bitWord) + 4 - loadDiv.quot, loadDiv.quot);
|
||||||
#if METAFORCE_TARGET_BYTE_ORDER == __ORDER_LITTLE_ENDIAN__
|
#if METAFORCE_TARGET_BYTE_ORDER == __ORDER_LITTLE_ENDIAN__
|
||||||
x1c_bitWord = CBasics::SwapBytes(x1c_bitWord);
|
x1c_bitWord = CBasics::SwapBytes(x1c_bitWord);
|
||||||
#endif
|
#endif
|
||||||
|
/* New bit offset */
|
||||||
const u32 retMask = shiftAmt == 32 ? -1 : (1 << shiftAmt) - 1;
|
x20_bitOffset = loadDiv.quot * 8 + shiftAmt;
|
||||||
const u32 tmpOffset = x20_bitOffset;
|
/* OR in next bits */
|
||||||
x20_bitOffset = len * 8;
|
mask = (1U << u32(-shiftAmt)) - 1;
|
||||||
ret = ((mask & uVar2) >> (32 - ret) << shiftAmt) | (retMask & (x1c_bitWord >> (32 - shiftAmt))) << tmpOffset;
|
ret |= (x1c_bitWord >> x20_bitOffset) & mask;
|
||||||
x20_bitOffset -= shiftAmt;
|
|
||||||
x1c_bitWord <<= shiftAmt;
|
|
||||||
} else {
|
} else {
|
||||||
|
/* OR in bits of cached value */
|
||||||
|
const u32 mask = bitCount == 32 ? UINT32_MAX : ((1U << bitCount) - 1);
|
||||||
|
ret |= (x1c_bitWord >> u32(shiftAmt)) & mask;
|
||||||
|
/* New bit offset */
|
||||||
x20_bitOffset -= bitCount;
|
x20_bitOffset -= bitCount;
|
||||||
ret = bitCount == 32 ? -1 : (1 << bitCount) - 1;
|
|
||||||
ret &= x1c_bitWord >> (32 - bitCount);
|
|
||||||
x1c_bitWord <<= bitCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,27 +78,27 @@ void COutputStream::Put(const u8* ptr, u32 len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void COutputStream::WriteBits(u32 val, u32 bitCount) {
|
void COutputStream::WriteBits(u32 val, u32 bitCount) {
|
||||||
const u32 bitOffset = x18_shiftRegisterOffset;
|
const s32 shiftAmt = x18_shiftRegisterOffset - s32(bitCount);
|
||||||
if (x18_shiftRegisterOffset < bitCount) {
|
if (shiftAmt < 0) {
|
||||||
/* OR remaining bits to cached value */
|
/* OR remaining bits to cached value */
|
||||||
const u32 shiftAmt = (bitCount - x18_shiftRegisterOffset);
|
const u32 mask = (1U << x18_shiftRegisterOffset) - 1;
|
||||||
const u32 mask = bitOffset == 32 ? -1 : (1 << bitOffset) - 1;
|
x14_shiftRegister |= (val >> u32(-shiftAmt)) & mask;
|
||||||
|
|
||||||
/* Write out 32-bits */
|
/* Write out 32-bits */
|
||||||
x14_shiftRegister |= (val >> shiftAmt) & mask;
|
|
||||||
x18_shiftRegisterOffset = 0;
|
|
||||||
FlushShiftRegister();
|
FlushShiftRegister();
|
||||||
|
|
||||||
/* Cache remaining bits */
|
/* Cache remaining bits */
|
||||||
x14_shiftRegister = (val & (shiftAmt == 32 ? -1 : (1 << shiftAmt) - 1)) << (32 - shiftAmt);
|
x18_shiftRegisterOffset = 0x20 + shiftAmt;
|
||||||
x18_shiftRegisterOffset -= shiftAmt;
|
x14_shiftRegister = val << x18_shiftRegisterOffset;
|
||||||
} else {
|
} else {
|
||||||
/* OR bits to cached value */
|
/* OR bits to cached value */
|
||||||
const u32 mask = bitOffset == 0x20 ? -1 : (1 << bitOffset) - 1;
|
const u32 mask = bitCount == 32 ? UINT32_MAX : ((1U << bitCount) - 1);
|
||||||
x14_shiftRegister |= (val & mask) << (bitOffset - bitCount);
|
x14_shiftRegister |= (val & mask) << u32(shiftAmt);
|
||||||
|
|
||||||
/* New bit offset */
|
/* New bit offset */
|
||||||
x18_shiftRegisterOffset -= bitCount;
|
x18_shiftRegisterOffset -= bitCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void COutputStream::WriteChar(u8 c) {
|
void COutputStream::WriteChar(u8 c) {
|
||||||
|
@ -199,6 +199,14 @@ void coutput_stream_helper(const std::string& t, COutputStream& out) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void coutput_stream_helper(const std::string_view& t, COutputStream& out) {
|
||||||
|
for (size_t i = 0; i < t.size() + 1; ++i) {
|
||||||
|
out.FlushShiftRegister();
|
||||||
|
out.Put(t[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u32 COutputStream::GetBitCount(u32 val) {
|
u32 COutputStream::GetBitCount(u32 val) {
|
||||||
int bits = 0;
|
int bits = 0;
|
||||||
for (; val != 0; val >>= 1) {
|
for (; val != 0; val >>= 1) {
|
||||||
|
|
|
@ -86,4 +86,6 @@ template <>
|
||||||
void coutput_stream_helper(const double& t, COutputStream& out);
|
void coutput_stream_helper(const double& t, COutputStream& out);
|
||||||
template <>
|
template <>
|
||||||
void coutput_stream_helper(const std::string& t, COutputStream& out);
|
void coutput_stream_helper(const std::string& t, COutputStream& out);
|
||||||
|
template <>
|
||||||
|
void coutput_stream_helper(const std::string_view& t, COutputStream& out);
|
||||||
} // namespace metaforce
|
} // namespace metaforce
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Runtime/rstl.hpp"
|
|
||||||
#include "Runtime/Streams/CInputStream.hpp"
|
#include "Runtime/Streams/CInputStream.hpp"
|
||||||
|
#include "Runtime/rstl.hpp"
|
||||||
|
#include <vector>
|
||||||
namespace metaforce {
|
namespace metaforce {
|
||||||
template <class T, size_t N>
|
template <class T, size_t N>
|
||||||
void read_reserved_vector(rstl::reserved_vector<T, N>& v, CInputStream& in) {
|
void read_reserved_vector(rstl::reserved_vector<T, N>& v, CInputStream& in) {
|
||||||
|
@ -11,4 +12,13 @@ void read_reserved_vector(rstl::reserved_vector<T, N>& v, CInputStream& in) {
|
||||||
v[i] = in.Get<T>();
|
v[i] = in.Get<T>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void read_vector(std::vector<T>& v, CInputStream& in) {
|
||||||
|
u32 count = in.ReadLong();
|
||||||
|
v.reserve(count);
|
||||||
|
for (u32 i = 0; i < count; ++i) {
|
||||||
|
v.emplace_back(in.Get<T>());
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace metaforce
|
} // namespace metaforce
|
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Runtime/Streams/COutputStream.hpp"
|
||||||
|
#include "Runtime/rstl.hpp"
|
||||||
|
#include <vector>
|
||||||
|
namespace metaforce {
|
||||||
|
template <class T, size_t N>
|
||||||
|
void write_reserved_vector(const rstl::reserved_vector<T, N>& v, COutputStream& out) {
|
||||||
|
out.Put(v.size());
|
||||||
|
for (const auto& t : v) {
|
||||||
|
out.Put(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void write_vector(const std::vector<T>& v, COutputStream& out) {
|
||||||
|
out.Put(v.size());
|
||||||
|
for (const auto& t : v) {
|
||||||
|
out.Put(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace metaforce
|
Loading…
Reference in New Issue