mirror of https://github.com/AxioDL/metaforce.git
Runtime/CGameOptions: Use std::array where applicable
Makes the data a little more strongly typed; preventing implicit array->pointer decay. It also allows simplifying assignments within the CGameState code. While we're at it, we can also eliminate several instances of magic numbers related to the array sizes throughout the code.
This commit is contained in:
parent
cf294db9eb
commit
acb9ac92e7
|
@ -15,42 +15,51 @@
|
||||||
|
|
||||||
namespace urde {
|
namespace urde {
|
||||||
|
|
||||||
static const SGameOption VisorOpts[] = {
|
constexpr std::array<SGameOption, 5> VisorOpts{{
|
||||||
{EGameOption::VisorOpacity, 21, 0.f, 255.f, 1.f, EOptionType::Float},
|
{EGameOption::VisorOpacity, 21, 0.f, 255.f, 1.f, EOptionType::Float},
|
||||||
{EGameOption::HelmetOpacity, 22, 0.f, 255.f, 1.f, EOptionType::Float},
|
{EGameOption::HelmetOpacity, 22, 0.f, 255.f, 1.f, EOptionType::Float},
|
||||||
{EGameOption::HUDLag, 23, 0.f, 1.f, 1.f, EOptionType::DoubleEnum},
|
{EGameOption::HUDLag, 23, 0.f, 1.f, 1.f, EOptionType::DoubleEnum},
|
||||||
{EGameOption::HintSystem, 24, 0.f, 1.f, 1.f, EOptionType::DoubleEnum},
|
{EGameOption::HintSystem, 24, 0.f, 1.f, 1.f, EOptionType::DoubleEnum},
|
||||||
{EGameOption::RestoreDefaults, 35, 0.f, 1.f, 1.f, EOptionType::RestoreDefaults}};
|
{EGameOption::RestoreDefaults, 35, 0.f, 1.f, 1.f, EOptionType::RestoreDefaults},
|
||||||
|
}};
|
||||||
|
|
||||||
static const SGameOption DisplayOpts[] = {
|
constexpr std::array<SGameOption, 5> DisplayOpts{{
|
||||||
//{EGameOption::ScreenBrightness, 25, 0.f, 8.f, 1.f, EOptionType::Float},
|
//{EGameOption::ScreenBrightness, 25, 0.f, 8.f, 1.f, EOptionType::Float},
|
||||||
{EGameOption::ScreenBrightness, 25, -100.f, 100.f, 1.f, EOptionType::Float},
|
{EGameOption::ScreenBrightness, 25, -100.f, 100.f, 1.f, EOptionType::Float},
|
||||||
{EGameOption::ScreenOffsetX, 26, -30.f, 30.f, 1.f, EOptionType::Float},
|
{EGameOption::ScreenOffsetX, 26, -30.f, 30.f, 1.f, EOptionType::Float},
|
||||||
{EGameOption::ScreenOffsetY, 27, -30.f, 30.f, 1.f, EOptionType::Float},
|
{EGameOption::ScreenOffsetY, 27, -30.f, 30.f, 1.f, EOptionType::Float},
|
||||||
{EGameOption::ScreenStretch, 28, -10.f, 10.f, 1.f, EOptionType::Float},
|
{EGameOption::ScreenStretch, 28, -10.f, 10.f, 1.f, EOptionType::Float},
|
||||||
{EGameOption::RestoreDefaults, 35, 0.f, 1.f, 1.f, EOptionType::RestoreDefaults}};
|
{EGameOption::RestoreDefaults, 35, 0.f, 1.f, 1.f, EOptionType::RestoreDefaults},
|
||||||
|
}};
|
||||||
|
|
||||||
static const SGameOption SoundOpts[] = {
|
constexpr std::array<SGameOption, 4> SoundOpts{{
|
||||||
{EGameOption::SFXVolume, 29, 0.f, 127.f, 1.f, EOptionType::Float},
|
{EGameOption::SFXVolume, 29, 0.f, 127.f, 1.f, EOptionType::Float},
|
||||||
{EGameOption::MusicVolume, 30, 0.f, 127.f, 1.f, EOptionType::Float},
|
{EGameOption::MusicVolume, 30, 0.f, 127.f, 1.f, EOptionType::Float},
|
||||||
{EGameOption::SoundMode, 31, 0.f, 1.f, 1.f, EOptionType::TripleEnum},
|
{EGameOption::SoundMode, 31, 0.f, 1.f, 1.f, EOptionType::TripleEnum},
|
||||||
{EGameOption::RestoreDefaults, 35, 0.f, 1.f, 1.f, EOptionType::RestoreDefaults}};
|
{EGameOption::RestoreDefaults, 35, 0.f, 1.f, 1.f, EOptionType::RestoreDefaults},
|
||||||
|
}};
|
||||||
|
|
||||||
static const SGameOption ControllerOpts[] = {
|
constexpr std::array<SGameOption, 4> ControllerOpts{{
|
||||||
{EGameOption::ReverseYAxis, 32, 0.f, 1.f, 1.f, EOptionType::DoubleEnum},
|
{EGameOption::ReverseYAxis, 32, 0.f, 1.f, 1.f, EOptionType::DoubleEnum},
|
||||||
{EGameOption::Rumble, 33, 0.f, 1.f, 1.f, EOptionType::DoubleEnum},
|
{EGameOption::Rumble, 33, 0.f, 1.f, 1.f, EOptionType::DoubleEnum},
|
||||||
{EGameOption::SwapBeamControls, 34, 0.f, 1.f, 1.f, EOptionType::DoubleEnum},
|
{EGameOption::SwapBeamControls, 34, 0.f, 1.f, 1.f, EOptionType::DoubleEnum},
|
||||||
{EGameOption::RestoreDefaults, 35, 0.f, 1.f, 1.f, EOptionType::RestoreDefaults}};
|
{EGameOption::RestoreDefaults, 35, 0.f, 1.f, 1.f, EOptionType::RestoreDefaults},
|
||||||
|
}};
|
||||||
|
|
||||||
const std::pair<int, const SGameOption*> GameOptionsRegistry[] = {
|
const std::array<std::pair<size_t, const SGameOption*>, 5> GameOptionsRegistry{{
|
||||||
{5, VisorOpts}, {5, DisplayOpts}, {4, SoundOpts}, {4, ControllerOpts}, {0, nullptr}};
|
{VisorOpts.size(), VisorOpts.data()},
|
||||||
|
{DisplayOpts.size(), DisplayOpts.data()},
|
||||||
|
{SoundOpts.size(), SoundOpts.data()},
|
||||||
|
{ControllerOpts.size(), ControllerOpts.data()},
|
||||||
|
{0, nullptr},
|
||||||
|
}};
|
||||||
|
|
||||||
CPersistentOptions::CPersistentOptions(CBitStreamReader& stream) {
|
CPersistentOptions::CPersistentOptions(CBitStreamReader& stream) {
|
||||||
for (int b = 0; b < 98; ++b)
|
for (u8& entry : x0_nesState)
|
||||||
x0_nesState[b] = stream.ReadEncoded(8);
|
entry = stream.ReadEncoded(8);
|
||||||
|
|
||||||
for (int b = 0; b < 64; ++b)
|
for (bool& entry : x68_)
|
||||||
x68_[b] = stream.ReadEncoded(8);
|
entry = stream.ReadEncoded(8);
|
||||||
|
|
||||||
xc0_frozenFpsCount = stream.ReadEncoded(2);
|
xc0_frozenFpsCount = stream.ReadEncoded(2);
|
||||||
xc4_frozenBallCount = stream.ReadEncoded(2);
|
xc4_frozenBallCount = stream.ReadEncoded(2);
|
||||||
|
@ -89,11 +98,11 @@ CPersistentOptions::CPersistentOptions(CBitStreamReader& stream) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPersistentOptions::PutTo(CBitStreamWriter& w) const {
|
void CPersistentOptions::PutTo(CBitStreamWriter& w) const {
|
||||||
for (int b = 0; b < 98; ++b)
|
for (const u8 entry : x0_nesState)
|
||||||
w.WriteEncoded(x0_nesState[b], 8);
|
w.WriteEncoded(entry, 8);
|
||||||
|
|
||||||
for (int b = 0; b < 64; ++b)
|
for (const bool entry : x68_)
|
||||||
w.WriteEncoded(x68_[b], 8);
|
w.WriteEncoded(entry, 8);
|
||||||
|
|
||||||
w.WriteEncoded(xc0_frozenFpsCount, 2);
|
w.WriteEncoded(xc0_frozenFpsCount, 2);
|
||||||
w.WriteEncoded(xc4_frozenBallCount, 2);
|
w.WriteEncoded(xc4_frozenBallCount, 2);
|
||||||
|
@ -138,8 +147,8 @@ void CPersistentOptions::SetCinematicState(CAssetId mlvlId, TEditorId cineId, bo
|
||||||
}
|
}
|
||||||
|
|
||||||
CGameOptions::CGameOptions(CBitStreamReader& stream) {
|
CGameOptions::CGameOptions(CBitStreamReader& stream) {
|
||||||
for (int b = 0; b < 64; ++b)
|
for (u8& entry : x0_)
|
||||||
x0_[b] = stream.ReadEncoded(8);
|
entry = stream.ReadEncoded(8);
|
||||||
|
|
||||||
x44_soundMode = CAudioSys::ESurroundModes(stream.ReadEncoded(2));
|
x44_soundMode = CAudioSys::ESurroundModes(stream.ReadEncoded(2));
|
||||||
x48_screenBrightness = stream.ReadEncoded(4);
|
x48_screenBrightness = stream.ReadEncoded(4);
|
||||||
|
@ -179,8 +188,8 @@ void CGameOptions::ResetToDefaults() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameOptions::PutTo(CBitStreamWriter& writer) const {
|
void CGameOptions::PutTo(CBitStreamWriter& writer) const {
|
||||||
for (int b = 0; b < 64; ++b)
|
for (const u8 entry : x0_)
|
||||||
writer.WriteEncoded(x0_[b], 8);
|
writer.WriteEncoded(entry, 8);
|
||||||
|
|
||||||
writer.WriteEncoded(u32(x44_soundMode), 2);
|
writer.WriteEncoded(u32(x44_soundMode), 2);
|
||||||
writer.WriteEncoded(x48_screenBrightness, 4);
|
writer.WriteEncoded(x48_screenBrightness, 4);
|
||||||
|
@ -311,15 +320,21 @@ void CGameOptions::SetControls(int controls) {
|
||||||
ResetControllerAssets(controls);
|
ResetControllerAssets(controls);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::pair<CAssetId, CAssetId> CStickToDPadRemap[] = {
|
const std::array<std::pair<CAssetId, CAssetId>, 5> CStickToDPadRemap{{
|
||||||
{0x2A13C23E, 0xF13452F8}, {0xA91A7703, 0xC042EC91}, {0x12A12131, 0x5F556002},
|
{0x2A13C23E, 0xF13452F8},
|
||||||
{0xA9798329, 0xB306E26F}, {0xCD7B1ACA, 0x8ADA8184},
|
{0xA91A7703, 0xC042EC91},
|
||||||
};
|
{0x12A12131, 0x5F556002},
|
||||||
|
{0xA9798329, 0xB306E26F},
|
||||||
|
{0xCD7B1ACA, 0x8ADA8184},
|
||||||
|
}};
|
||||||
|
|
||||||
static const std::pair<CAssetId, CAssetId> CStickOutlineToDPadRemap[] = {
|
const std::array<std::pair<CAssetId, CAssetId>, 5> CStickOutlineToDPadRemap{{
|
||||||
{0x1A29C0E6, 0xF13452F8}, {0x5D9F9796, 0xC042EC91}, {0x951546A8, 0x5F556002},
|
{0x1A29C0E6, 0xF13452F8},
|
||||||
{0x7946C4C5, 0xB306E26F}, {0x409AA72E, 0x8ADA8184},
|
{0x5D9F9796, 0xC042EC91},
|
||||||
};
|
{0x951546A8, 0x5F556002},
|
||||||
|
{0x7946C4C5, 0xB306E26F},
|
||||||
|
{0x409AA72E, 0x8ADA8184},
|
||||||
|
}};
|
||||||
|
|
||||||
static std::pair<CAssetId, CAssetId> TranslatePairToNew(const std::pair<CAssetId, CAssetId>& p) {
|
static std::pair<CAssetId, CAssetId> TranslatePairToNew(const std::pair<CAssetId, CAssetId>& p) {
|
||||||
return {g_ResFactory->TranslateOriginalToNew(p.first), g_ResFactory->TranslateOriginalToNew(p.second)};
|
return {g_ResFactory->TranslateOriginalToNew(p.first), g_ResFactory->TranslateOriginalToNew(p.second)};
|
||||||
|
@ -331,13 +346,13 @@ void CGameOptions::ResetControllerAssets(int controls) {
|
||||||
} else if (x6c_controlTxtrMap.empty()) {
|
} else if (x6c_controlTxtrMap.empty()) {
|
||||||
x6c_controlTxtrMap.reserve(15);
|
x6c_controlTxtrMap.reserve(15);
|
||||||
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
for (const auto& entry : CStickToDPadRemap) {
|
||||||
x6c_controlTxtrMap.push_back(TranslatePairToNew(CStickToDPadRemap[i]));
|
const auto& emplaced = x6c_controlTxtrMap.emplace_back(TranslatePairToNew(entry));
|
||||||
x6c_controlTxtrMap.push_back({x6c_controlTxtrMap.back().second, x6c_controlTxtrMap.back().first});
|
x6c_controlTxtrMap.emplace_back(emplaced.second, emplaced.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 5; ++i)
|
for (const auto& entry : CStickOutlineToDPadRemap)
|
||||||
x6c_controlTxtrMap.push_back(TranslatePairToNew(CStickOutlineToDPadRemap[i]));
|
x6c_controlTxtrMap.emplace_back(TranslatePairToNew(entry));
|
||||||
|
|
||||||
std::sort(x6c_controlTxtrMap.begin(), x6c_controlTxtrMap.end(),
|
std::sort(x6c_controlTxtrMap.begin(), x6c_controlTxtrMap.end(),
|
||||||
[](const std::pair<CAssetId, CAssetId>& a, const std::pair<CAssetId, CAssetId>& b) {
|
[](const std::pair<CAssetId, CAssetId>& a, const std::pair<CAssetId, CAssetId>& b) {
|
||||||
|
@ -365,8 +380,8 @@ void CGameOptions::EnsureSettings() {
|
||||||
|
|
||||||
void CGameOptions::TryRestoreDefaults(const CFinalInput& input, int category, int option, bool frontend,
|
void CGameOptions::TryRestoreDefaults(const CFinalInput& input, int category, int option, bool frontend,
|
||||||
bool forceRestore) {
|
bool forceRestore) {
|
||||||
const std::pair<int, const SGameOption*>& options = GameOptionsRegistry[category];
|
const auto& options = GameOptionsRegistry[category];
|
||||||
if (!options.first)
|
if (options.first == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (options.second[option].option != EGameOption::RestoreDefaults)
|
if (options.second[option].option != EGameOption::RestoreDefaults)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include "RetroTypes.hpp"
|
#include "RetroTypes.hpp"
|
||||||
#include "Audio/CAudioSys.hpp"
|
#include "Audio/CAudioSys.hpp"
|
||||||
#include "CSaveWorld.hpp"
|
#include "CSaveWorld.hpp"
|
||||||
|
@ -39,13 +40,13 @@ struct SGameOption {
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Static registry of Option UI presentation information */
|
/** Static registry of Option UI presentation information */
|
||||||
extern const std::pair<int, const SGameOption*> GameOptionsRegistry[];
|
extern const std::array<std::pair<size_t, const SGameOption*>, 5> GameOptionsRegistry;
|
||||||
|
|
||||||
/** Options tracked persistently between game sessions */
|
/** Options tracked persistently between game sessions */
|
||||||
class CPersistentOptions {
|
class CPersistentOptions {
|
||||||
friend class CGameState;
|
friend class CGameState;
|
||||||
u8 x0_nesState[98] = {};
|
std::array<u8, 98> x0_nesState{};
|
||||||
bool x68_[64] = {};
|
std::array<bool, 64> x68_{};
|
||||||
std::vector<std::pair<CAssetId, TEditorId>> xac_cinematicStates; /* (MLVL, Cinematic) */
|
std::vector<std::pair<CAssetId, TEditorId>> xac_cinematicStates; /* (MLVL, Cinematic) */
|
||||||
u32 xbc_autoMapperKeyState = 0;
|
u32 xbc_autoMapperKeyState = 0;
|
||||||
u32 xc0_frozenFpsCount = 0;
|
u32 xc0_frozenFpsCount = 0;
|
||||||
|
@ -96,12 +97,13 @@ public:
|
||||||
|
|
||||||
void PutTo(CBitStreamWriter& w) const;
|
void PutTo(CBitStreamWriter& w) const;
|
||||||
|
|
||||||
u8* GetNESState() { return x0_nesState; }
|
u8* GetNESState() { return x0_nesState.data(); }
|
||||||
|
const u8* GetNESState() const { return x0_nesState.data(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Options tracked per game session */
|
/** Options tracked per game session */
|
||||||
class CGameOptions {
|
class CGameOptions {
|
||||||
u8 x0_[64] = {};
|
std::array<u8, 64> x0_{};
|
||||||
CAudioSys::ESurroundModes x44_soundMode = CAudioSys::ESurroundModes::Stereo;
|
CAudioSys::ESurroundModes x44_soundMode = CAudioSys::ESurroundModes::Stereo;
|
||||||
u32 x48_screenBrightness = 4;
|
u32 x48_screenBrightness = 4;
|
||||||
s32 x4c_screenXOffset = 0;
|
s32 x4c_screenXOffset = 0;
|
||||||
|
|
|
@ -179,7 +179,7 @@ void CGameState::ImportPersistentOptions(const CPersistentOptions& opts) {
|
||||||
if (opts.xd0_27_fusionBeat)
|
if (opts.xd0_27_fusionBeat)
|
||||||
xa8_systemOptions.xd0_27_fusionBeat = true;
|
xa8_systemOptions.xd0_27_fusionBeat = true;
|
||||||
if (&opts != &xa8_systemOptions)
|
if (&opts != &xa8_systemOptions)
|
||||||
memcpy(xa8_systemOptions.x0_nesState, opts.x0_nesState, 98);
|
xa8_systemOptions.x0_nesState = opts.x0_nesState;
|
||||||
xa8_systemOptions.SetLogScanPercent(opts.GetLogScanPercent());
|
xa8_systemOptions.SetLogScanPercent(opts.GetLogScanPercent());
|
||||||
xa8_systemOptions.SetAllItemsCollected(opts.GetAllItemsCollected());
|
xa8_systemOptions.SetAllItemsCollected(opts.GetAllItemsCollected());
|
||||||
xa8_systemOptions.SetPlayerBeatNormalMode(opts.GetPlayerBeatNormalMode());
|
xa8_systemOptions.SetPlayerBeatNormalMode(opts.GetPlayerBeatNormalMode());
|
||||||
|
@ -192,7 +192,7 @@ void CGameState::ExportPersistentOptions(CPersistentOptions& opts) const {
|
||||||
if (xa8_systemOptions.xd0_27_fusionBeat)
|
if (xa8_systemOptions.xd0_27_fusionBeat)
|
||||||
opts.xd0_27_fusionBeat = true;
|
opts.xd0_27_fusionBeat = true;
|
||||||
if (&opts != &xa8_systemOptions)
|
if (&opts != &xa8_systemOptions)
|
||||||
memcpy(opts.x0_nesState, xa8_systemOptions.x0_nesState, 98);
|
opts.x0_nesState = xa8_systemOptions.x0_nesState;
|
||||||
opts.SetPlayerFusionSuitActive(xa8_systemOptions.GetPlayerFusionSuitActive());
|
opts.SetPlayerFusionSuitActive(xa8_systemOptions.GetPlayerFusionSuitActive());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1502,12 +1502,12 @@ void CFrontEndUI::SOptionsFrontEndFrame::HandleRightSelectionChange() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrontEndUI::SOptionsFrontEndFrame::SetRightUIText() {
|
void CFrontEndUI::SOptionsFrontEndFrame::SetRightUIText() {
|
||||||
int userSel = x24_tablegroup_leftmenu->GetUserSelection();
|
const int userSel = x24_tablegroup_leftmenu->GetUserSelection();
|
||||||
const std::pair<int, const SGameOption*>& options = GameOptionsRegistry[userSel];
|
const auto& options = GameOptionsRegistry[userSel];
|
||||||
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
std::string name = fmt::format(fmt("textpane_right{}"), i);
|
std::string name = fmt::format(fmt("textpane_right{}"), i);
|
||||||
if (i < options.first) {
|
if (i < static_cast<int>(options.first)) {
|
||||||
FindTextPanePair(x1c_loadedFrame, name.c_str()).SetPairText(
|
FindTextPanePair(x1c_loadedFrame, name.c_str()).SetPairText(
|
||||||
x20_loadedPauseStrg->GetString(options.second[i].stringId));
|
x20_loadedPauseStrg->GetString(options.second[i].stringId));
|
||||||
x28_tablegroup_rightmenu->GetWorkerWidget(i)->SetIsSelectable(true);
|
x28_tablegroup_rightmenu->GetWorkerWidget(i)->SetIsSelectable(true);
|
||||||
|
|
Loading…
Reference in New Issue