diff --git a/Runtime/CGameOptionsTouchBar.cpp b/Runtime/CGameOptionsTouchBar.cpp deleted file mode 100644 index 5faeb43a1..000000000 --- a/Runtime/CGameOptionsTouchBar.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "Runtime/CGameOptionsTouchBar.hpp" - -namespace metaforce { - -CGameOptionsTouchBar::EAction CGameOptionsTouchBar::PopAction() { return EAction::None; } - -void CGameOptionsTouchBar::GetSelection(int& left, int& right, int& value) { - left = -1; - right = -1; - value = -1; -} - -void CGameOptionsTouchBar::SetSelection([[maybe_unused]] int left, [[maybe_unused]] int right, - [[maybe_unused]] int value) {} - -//#ifndef __APPLE__ -std::unique_ptr NewGameOptionsTouchBar() { return std::make_unique(); } -//#endif - -} // namespace metaforce diff --git a/Runtime/CGameOptionsTouchBar.hpp b/Runtime/CGameOptionsTouchBar.hpp deleted file mode 100644 index 832e0d4c3..000000000 --- a/Runtime/CGameOptionsTouchBar.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include -#include - -namespace metaforce { - -class CGameOptionsTouchBar { -public: - enum class EAction { None, Back, Advance, ValueChange }; - - virtual ~CGameOptionsTouchBar() = default; - virtual EAction PopAction(); - virtual void GetSelection(int& left, int& right, int& value); - virtual void SetSelection(int left, int right, int value); -}; - -std::unique_ptr NewGameOptionsTouchBar(); - -} // namespace metaforce diff --git a/Runtime/CGameOptionsTouchBarMac.mm b/Runtime/CGameOptionsTouchBarMac.mm deleted file mode 100644 index 5c7a98722..000000000 --- a/Runtime/CGameOptionsTouchBarMac.mm +++ /dev/null @@ -1,260 +0,0 @@ -#include "CGameOptions.hpp" -#include "CGameOptionsTouchBar.hpp" -#include "GameGlobalObjects.hpp" -#include "GuiSys/CStringTable.hpp" -#include "MP1/MP1.hpp" -#include - -#if !__has_feature(objc_arc) -#error ARC Required -#endif - -static NSColor *BlueConfirm() { - return [NSColor colorWithSRGBRed:0 / 255.f green:130 / 255.f blue:215 / 255.f alpha:1.f]; -} - -@interface GameOptionsTouchBar : NSObject { -@public - metaforce::CStringTable *_pauseScreenStrg; - metaforce::CGameOptionsTouchBar::EAction _action; - std::pair _selection; - int _value, _pendingValue; -} -- (IBAction)onBack:(id)sender; -- (IBAction)onSlide:(id)sender; -- (IBAction)onSet0:(id)sender; -- (IBAction)onSet1:(id)sender; -- (IBAction)onSet2:(id)sender; -- (IBAction)onLeft:(id)sender; -- (IBAction)onRight:(id)sender; -@end - -@implementation GameOptionsTouchBar -- (NSTouchBar *)makeTouchBar { - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items = @[ @"optionsGroup" ]; - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - touchBar.principalItemIdentifier = @"optionsGroup"; - return touchBar; -} -- (NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier { - if ([identifier isEqualToString:@"optionsGroup"]) { - NSGroupTouchBarItem *item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items; - if (_selection.first == -1) { - items = [NSMutableArray arrayWithCapacity:5]; - [items addObject:@"back"]; - for (int i = 0; i < 4; ++i) - [items addObject:[NSString stringWithFormat:@"left/%d", i]]; - } else if (_selection.second == -1) { - const std::pair &opt = metaforce::GameOptionsRegistry[_selection.first]; - items = [NSMutableArray arrayWithCapacity:opt.first + 1]; - [items addObject:@"back"]; - for (int i = 0; i < opt.first; ++i) - [items addObject:[NSString stringWithFormat:@"right/%d", i]]; - } else { - const std::pair &opt = metaforce::GameOptionsRegistry[_selection.first]; - const metaforce::SGameOption &subopt = opt.second[_selection.second]; - if (subopt.type == metaforce::EOptionType::Float) - items = @[ @"back", @"value" ]; - else if (subopt.type == metaforce::EOptionType::DoubleEnum) - items = @[ @"back", @"label", @"double0", @"double1" ]; - else if (subopt.type == metaforce::EOptionType::TripleEnum) - items = @[ @"back", @"label", @"triple0", @"triple1", @"triple2" ]; - } - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - item.groupTouchBar = touchBar; - return item; - } else if ([identifier isEqualToString:@"back"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithImage:[NSImage imageNamed:NSImageNameTouchBarGoBackTemplate] - target:self - action:@selector(onBack:)]; - item.view = button; - return item; - } else if ([identifier isEqualToString:@"label"]) { - const std::pair &opt = metaforce::GameOptionsRegistry[_selection.first]; - const metaforce::SGameOption &subopt = opt.second[_selection.second]; - - const char16_t *cStr = _pauseScreenStrg->GetString(subopt.stringId); - NSString *str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; - - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSTextField *label = [NSTextField labelWithString:[str stringByAppendingString:@":"]]; - item.view = label; - return item; - } else if ([identifier isEqualToString:@"value"]) { - const std::pair &opt = metaforce::GameOptionsRegistry[_selection.first]; - const metaforce::SGameOption &subopt = opt.second[_selection.second]; - - const char16_t *cStr = _pauseScreenStrg->GetString(subopt.stringId); - NSString *str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; - - NSSliderTouchBarItem *item = [[NSSliderTouchBarItem alloc] initWithIdentifier:identifier]; - NSSlider *slider = [NSSlider sliderWithValue:_value - minValue:subopt.minVal - maxValue:subopt.maxVal - target:nil - action:nil]; - item.target = self; - item.action = @selector(onSlide:); - item.slider = slider; - item.label = str; - return item; - } else if ([identifier isEqualToString:@"double0"]) { - const char16_t *cStr = _pauseScreenStrg->GetString(95); // Off - NSString *str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; - - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:str target:self action:@selector(onSet0:)]; - if (_value == 0) - button.bezelColor = BlueConfirm(); - item.view = button; - return item; - } else if ([identifier isEqualToString:@"double1"]) { - const char16_t *cStr = _pauseScreenStrg->GetString(94); // On - NSString *str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; - - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:str target:self action:@selector(onSet1:)]; - if (_value == 1) - button.bezelColor = BlueConfirm(); - item.view = button; - return item; - } else if ([identifier isEqualToString:@"triple0"]) { - const char16_t *cStr = _pauseScreenStrg->GetString(96); // Mono - NSString *str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; - - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:str target:self action:@selector(onSet0:)]; - if (_value == 0) - button.bezelColor = BlueConfirm(); - item.view = button; - return item; - } else if ([identifier isEqualToString:@"triple1"]) { - const char16_t *cStr = _pauseScreenStrg->GetString(97); // Stereo - NSString *str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; - - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:str target:self action:@selector(onSet1:)]; - if (_value == 1) - button.bezelColor = BlueConfirm(); - item.view = button; - return item; - } else if ([identifier isEqualToString:@"triple2"]) { - const char16_t *cStr = _pauseScreenStrg->GetString(98); // Dolby - NSString *str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; - - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:str target:self action:@selector(onSet2:)]; - if (_value == 2) - button.bezelColor = BlueConfirm(); - item.view = button; - return item; - } else { - NSArray *pc = [identifier pathComponents]; - if ([pc count] == 2) { - NSString *first = [pc objectAtIndex:0]; - if ([first isEqualToString:@"left"]) { - auto idx = strtoul([[pc objectAtIndex:1] UTF8String], nullptr, 10); - const char16_t *cStr = _pauseScreenStrg->GetString(16 + idx); - NSString *str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; - - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:str target:self action:@selector(onLeft:)]; - button.tag = idx; - item.view = button; - return item; - } else if ([first isEqualToString:@"right"]) { - const std::pair &opt = metaforce::GameOptionsRegistry[_selection.first]; - auto idx = strtoul([[pc objectAtIndex:1] UTF8String], nullptr, 10); - const metaforce::SGameOption &subopt = opt.second[idx]; - const char16_t *cStr = _pauseScreenStrg->GetString(subopt.stringId); - NSString *str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; - - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:str target:self action:@selector(onRight:)]; - button.tag = idx; - item.view = button; - return item; - } - } - } - return nil; -} -- (IBAction)onBack:(id)sender { - _action = metaforce::CGameOptionsTouchBar::EAction::Back; -} -- (IBAction)onSlide:(id)sender { - _pendingValue = [((NSSliderTouchBarItem *)sender).slider intValue]; - _action = metaforce::CGameOptionsTouchBar::EAction::ValueChange; -} -- (IBAction)onSet0:(id)sender { - _pendingValue = 0; - _action = metaforce::CGameOptionsTouchBar::EAction::ValueChange; -} -- (IBAction)onSet1:(id)sender { - _pendingValue = 1; - _action = metaforce::CGameOptionsTouchBar::EAction::ValueChange; -} -- (IBAction)onSet2:(id)sender { - _pendingValue = 2; - _action = metaforce::CGameOptionsTouchBar::EAction::ValueChange; -} -- (IBAction)onLeft:(id)sender { - _selection.first = ((NSButton *)sender).tag; - _action = metaforce::CGameOptionsTouchBar::EAction::Advance; -} -- (IBAction)onRight:(id)sender { - _selection.second = ((NSButton *)sender).tag; - _action = metaforce::CGameOptionsTouchBar::EAction::Advance; -} -@end - -namespace metaforce { - -class CGameOptionsTouchBarMac : public CGameOptionsTouchBar { - TLockedToken m_pauseScreen; - GameOptionsTouchBar *m_touchBar; - bool m_initialized = false; - -public: - CGameOptionsTouchBarMac() { - m_pauseScreen = g_SimplePool->GetObj("STRG_PauseScreen"); - m_touchBar = [GameOptionsTouchBar new]; - m_touchBar->_pauseScreenStrg = m_pauseScreen.GetObj(); - m_touchBar->_selection = std::make_pair(-1, -1); - m_touchBar->_value = -1; - } - EAction PopAction() { - if (m_touchBar->_action != EAction::None) { - EAction action = m_touchBar->_action; - m_touchBar->_action = EAction::None; - return action; - } - return EAction::None; - } - void GetSelection(int &left, int &right, int &value) { - left = m_touchBar->_selection.first; - right = m_touchBar->_selection.second; - value = m_touchBar->_pendingValue; - } - void SetSelection(int left, int right, int value) { - if (m_initialized && left == m_touchBar->_selection.first && right == m_touchBar->_selection.second && - value == m_touchBar->_value) - return; - m_initialized = true; - m_touchBar->_selection = std::make_pair(left, right); - m_touchBar->_value = value; - g_Main->GetMainWindow()->setTouchBarProvider((__bridge_retained void *)m_touchBar); - } -}; - -std::unique_ptr NewGameOptionsTouchBar() { return std::make_unique(); } - -} diff --git a/Runtime/CMakeLists.txt b/Runtime/CMakeLists.txt index 7275fcb85..6a67e9e7d 100644 --- a/Runtime/CMakeLists.txt +++ b/Runtime/CMakeLists.txt @@ -110,7 +110,6 @@ set(RUNTIME_SOURCES_B IObjectStore.hpp CSimplePool.hpp CSimplePool.cpp CGameOptions.hpp CGameOptions.cpp - CGameOptionsTouchBar.hpp CGameOptionsTouchBar.cpp CStaticInterference.hpp CStaticInterference.cpp CCRC32.hpp CCRC32.cpp IFactory.hpp diff --git a/Runtime/CMemoryCardSys.cpp b/Runtime/CMemoryCardSys.cpp index 6b29b12cf..e70e75f27 100644 --- a/Runtime/CMemoryCardSys.cpp +++ b/Runtime/CMemoryCardSys.cpp @@ -171,38 +171,39 @@ std::pair CMemoryCardSys::GetAreaAndWorldIdForSaveId(s32 save void CMemoryCardSys::CCardFileInfo::LockBannerToken(CAssetId bannerTxtr, CSimplePool& sp) { x3c_bannerTex = bannerTxtr; - x40_bannerTok.emplace(sp.GetObj({FOURCC('TXTR'), bannerTxtr}, m_texParam)); + x40_bannerTok.emplace(sp.GetObj({FOURCC('TXTR'), bannerTxtr})); } -CMemoryCardSys::CCardFileInfo::Icon::Icon(CAssetId id, kabufuda::EAnimationSpeed speed, CSimplePool& sp, - const CVParamTransfer& cv) -: x0_id(id), x4_speed(speed), x8_tex(sp.GetObj({FOURCC('TXTR'), id}, cv)) {} +CMemoryCardSys::CCardFileInfo::Icon::Icon(CAssetId id, kabufuda::EAnimationSpeed speed, CSimplePool& sp) +: x0_id(id), x4_speed(speed), x8_tex(sp.GetObj({FOURCC('TXTR'), id})) {} void CMemoryCardSys::CCardFileInfo::LockIconToken(CAssetId iconTxtr, kabufuda::EAnimationSpeed speed, CSimplePool& sp) { - x50_iconToks.emplace_back(iconTxtr, speed, sp, m_texParam); + x50_iconToks.emplace_back(iconTxtr, speed, sp); } u32 CMemoryCardSys::CCardFileInfo::CalculateBannerDataSize() const { u32 ret = 68; if (x3c_bannerTex.IsValid()) { - if ((*x40_bannerTok)->GetMemoryCardTexelFormat() == ETexelFormat::RGB5A3) + if ((*x40_bannerTok)->GetTextureFormat() == ETexelFormat::RGB5A3) { ret = 6212; - else + } else { ret = 3652; + } } bool paletteTex = false; for (const Icon& icon : x50_iconToks) { - if (icon.x8_tex->GetMemoryCardTexelFormat() == ETexelFormat::RGB5A3) + if (icon.x8_tex->GetTextureFormat() == ETexelFormat::RGB5A3) { ret += 2048; - else { + } else { ret += 1024; paletteTex = true; } } - if (paletteTex) + if (paletteTex) { ret += 512; + } return ret; } @@ -233,35 +234,36 @@ void CMemoryCardSys::CCardFileInfo::BuildCardBuffer() { void CMemoryCardSys::CCardFileInfo::WriteBannerData(COutputStream& out) const { if (x3c_bannerTex.IsValid()) { const TLockedToken& tex = *x40_bannerTok; - u32 bufSz; - ETexelFormat fmt; - std::unique_ptr palette; - std::unique_ptr texels = tex->BuildMemoryCardTex(bufSz, fmt, palette); - - if (fmt == ETexelFormat::RGB5A3) - out.Write(texels.get(), 6144); - else - out.Write(texels.get(), 3072); - - if (fmt == ETexelFormat::C8) - out.Write(palette.get(), 512); + const auto format = tex->GetTextureFormat(); + const auto* texels = tex->GetConstBitMapData(0); + if (format == ETexelFormat::RGB5A3) { + out.Write(texels, 6144); + } else { + out.Write(texels, 3072); + } + if (format == ETexelFormat::C8) { + out.Write(tex->GetPalette()->GetEntries(), 512); + } } } void CMemoryCardSys::CCardFileInfo::WriteIconData(COutputStream& out) const { - std::unique_ptr palette; + const u8* palette = nullptr; for (const Icon& icon : x50_iconToks) { - u32 bufSz; - ETexelFormat fmt; - std::unique_ptr texels = icon.x8_tex->BuildMemoryCardTex(bufSz, fmt, palette); - - if (fmt == ETexelFormat::RGB5A3) - out.Write(texels.get(), 2048); - else - out.Write(texels.get(), 1024); + const auto format = icon.x8_tex->GetTextureFormat(); + const auto* texels = icon.x8_tex->GetConstBitMapData(0); + if (format == ETexelFormat::RGB5A3) { + out.Write(texels, 2048); + } else { + out.Write(texels, 1024); + } + if (format == ETexelFormat::C8) { + palette = icon.x8_tex->GetPalette()->GetEntries(); + } + } + if (palette != nullptr) { + out.Write(palette, 512); } - if (palette) - out.Write(palette.get(), 512); } ECardResult CMemoryCardSys::CCardFileInfo::PumpCardTransfer() { @@ -292,26 +294,29 @@ ECardResult CMemoryCardSys::CCardFileInfo::PumpCardTransfer() { ECardResult CMemoryCardSys::CCardFileInfo::GetStatus(kabufuda::CardStat& stat) const { ECardResult result = CMemoryCardSys::GetStatus(m_handle.slot, m_handle.getFileNo(), stat); - if (result != ECardResult::READY) + if (result != ECardResult::READY) { return result; + } stat.SetCommentAddr(4); stat.SetIconAddr(68); kabufuda::EImageFormat bannerFmt; if (x3c_bannerTex.IsValid()) { - if ((*x40_bannerTok)->GetMemoryCardTexelFormat() == ETexelFormat::RGB5A3) + if ((*x40_bannerTok)->GetTextureFormat() == ETexelFormat::RGB5A3) { bannerFmt = kabufuda::EImageFormat::RGB5A3; - else + } else { bannerFmt = kabufuda::EImageFormat::C8; - } else + } + } else { bannerFmt = kabufuda::EImageFormat::None; + } stat.SetBannerFormat(bannerFmt); int idx = 0; for (const Icon& icon : x50_iconToks) { - stat.SetIconFormat(icon.x8_tex->GetMemoryCardTexelFormat() == ETexelFormat::RGB5A3 ? kabufuda::EImageFormat::RGB5A3 - : kabufuda::EImageFormat::C8, + stat.SetIconFormat(icon.x8_tex->GetTextureFormat() == ETexelFormat::RGB5A3 ? kabufuda::EImageFormat::RGB5A3 + : kabufuda::EImageFormat::C8, idx); stat.SetIconSpeed(icon.x4_speed, idx); ++idx; @@ -555,9 +560,8 @@ void CMemoryCardSys::CommitToDisk(kabufuda::ECardSlot port) { } bool CMemoryCardSys::CreateDolphinCard(kabufuda::ECardSlot slot) { - std::string path = - _CreateDolphinCard(slot, slot == kabufuda::ECardSlot::SlotA ? mc_dolphinAPath->hasDefaultValue() - : mc_dolphinBPath->hasDefaultValue()); + std::string path = _CreateDolphinCard(slot, slot == kabufuda::ECardSlot::SlotA ? mc_dolphinAPath->hasDefaultValue() + : mc_dolphinBPath->hasDefaultValue()); if (CardProbe(slot).x0_error != ECardResult::READY) { return false; } diff --git a/Runtime/CMemoryCardSys.hpp b/Runtime/CMemoryCardSys.hpp index 8be8ddba1..b676425a9 100644 --- a/Runtime/CMemoryCardSys.hpp +++ b/Runtime/CMemoryCardSys.hpp @@ -115,7 +115,7 @@ public: CAssetId x0_id; kabufuda::EAnimationSpeed x4_speed; TLockedToken x8_tex; - Icon(CAssetId id, kabufuda::EAnimationSpeed speed, CSimplePool& sp, const CVParamTransfer& cv); + Icon(CAssetId id, kabufuda::EAnimationSpeed speed, CSimplePool& sp); }; enum class EStatus { Standby, Transferring, Done }; @@ -131,8 +131,6 @@ public: std::vector xf4_saveBuffer; std::vector x104_cardBuffer; - CVParamTransfer m_texParam = {new TObjOwnerParam(SBIG('OTEX'))}; - CCardFileInfo(kabufuda::ECardSlot port, std::string_view name) : m_handle(port), x18_fileName(name) {} void LockBannerToken(CAssetId bannerTxtr, CSimplePool& sp); diff --git a/Runtime/Graphics/CCubeMaterial.cpp b/Runtime/Graphics/CCubeMaterial.cpp index c4e32a30d..f417ddefa 100644 --- a/Runtime/Graphics/CCubeMaterial.cpp +++ b/Runtime/Graphics/CCubeMaterial.cpp @@ -54,7 +54,7 @@ void CCubeMaterial::SetCurrent(const CModelFlags& flags, const CCubeSurface& sur materialDataCur += 8; for (u32 i = 0; i < texCount; ++i) { u32 texIdx = SBig(*reinterpret_cast(materialDataCur)); - sRenderingModel->GetTexture(texIdx)->Load(i, CTexture::EClampMode::Repeat); + sRenderingModel->GetTexture(texIdx)->Load(static_cast(i), EClampMode::Repeat); materialDataCur += 4; } } @@ -423,7 +423,7 @@ void CCubeMaterial::DoPassthru(u32 finalTevCount) { } void CCubeMaterial::DoModelShadow(u32 texCount, u32 tcgCount) { - // CCubeModel::sShadowTexture->Load(texCount, CTexture::EClampMode::One); + // CCubeModel::sShadowTexture->Load(texCount, EClampMode::One); // TODO } } // namespace metaforce diff --git a/Runtime/Graphics/CCubeMaterial.hpp b/Runtime/Graphics/CCubeMaterial.hpp index ca572c750..066aadbb1 100644 --- a/Runtime/Graphics/CCubeMaterial.hpp +++ b/Runtime/Graphics/CCubeMaterial.hpp @@ -14,71 +14,6 @@ class CCubeModel; class CCubeSurface; struct CModelFlags; -template -class Flags { -public: - using MaskType = typename std::underlying_type::type; - - // constructors - constexpr Flags() noexcept : m_mask(0) {} - - constexpr Flags(BitType bit) noexcept : m_mask(static_cast(bit)) {} - - constexpr Flags(Flags const& rhs) noexcept : m_mask(rhs.m_mask) {} - - constexpr explicit Flags(MaskType flags) noexcept : m_mask(flags) {} - - [[nodiscard]] constexpr bool IsSet(Flags const bit) const noexcept { return bool(*this & bit); } - - // relational operators - auto operator<=>(Flags const&) const noexcept = default; - - // logical operator - constexpr bool operator!() const noexcept { return !m_mask; } - - // bitwise operators - constexpr Flags operator&(Flags const& rhs) const noexcept { - return Flags(m_mask & rhs.m_mask); - } - - constexpr Flags operator|(Flags const& rhs) const noexcept { - return Flags(m_mask | rhs.m_mask); - } - - constexpr Flags operator^(Flags const& rhs) const noexcept { - return Flags(m_mask ^ rhs.m_mask); - } - - // assignment operators - constexpr Flags& operator=(Flags const& rhs) noexcept { - m_mask = rhs.m_mask; - return *this; - } - - constexpr Flags& operator|=(Flags const& rhs) noexcept { - m_mask |= rhs.m_mask; - return *this; - } - - constexpr Flags& operator&=(Flags const& rhs) noexcept { - m_mask &= rhs.m_mask; - return *this; - } - - constexpr Flags& operator^=(Flags const& rhs) noexcept { - m_mask ^= rhs.m_mask; - return *this; - } - - // cast operators - explicit constexpr operator bool() const noexcept { return m_mask != 0; } - - explicit constexpr operator MaskType() const noexcept { return m_mask; } - -private: - MaskType m_mask; -}; - enum class CCubeMaterialFlagBits : u32 { fKonstValues = 0x8, fDepthSorting = 0x10, diff --git a/Runtime/Graphics/CCubeRenderer.hpp b/Runtime/Graphics/CCubeRenderer.hpp index ca21dd901..4d7ebe801 100644 --- a/Runtime/Graphics/CCubeRenderer.hpp +++ b/Runtime/Graphics/CCubeRenderer.hpp @@ -64,11 +64,11 @@ private: std::optional xc8_pvs; bool xdc_{}; u32 xe0_pvsAreaIdx = UINT32_MAX; - CTexture xe4_blackTex{ETexelFormat::RGB565, 4, 4, 1}; + CTexture xe4_blackTex{ETexelFormat::RGB565, 4, 4, 1, "Black Texture"}; std::unique_ptr x14c_reflectionTex; - CTexture x150_reflectionTex{ETexelFormat::IA8, 32, 32, 1}; - CTexture x1b8_fogVolumeRamp{ETexelFormat::I8, 256, 256, 1}; - CTexture x220_sphereRamp{ETexelFormat::I8, 32, 32, 1}; + CTexture x150_reflectionTex{ETexelFormat::IA8, 32, 32, 1, "Reflection Texture"}; + CTexture x1b8_fogVolumeRamp{ETexelFormat::I8, 256, 256, 1, "Fog Volume Ramp Texture"}; + CTexture x220_sphereRamp{ETexelFormat::I8, 32, 32, 1, "Sphere Ramp Texture"}; // CGraphicsPalette x288_thermoPalette{1, 16}; CRandom16 x2a8_thermalRand{20}; std::list x2ac_fogVolumes; diff --git a/Runtime/Graphics/CFont.cpp b/Runtime/Graphics/CFont.cpp index 38d8bc0fd..3fe8f0a85 100644 --- a/Runtime/Graphics/CFont.cpp +++ b/Runtime/Graphics/CFont.cpp @@ -12,8 +12,8 @@ std::unique_ptr CFont::mpTexture; CFont::CFont(float scale) : x0_fontSize(16.f * scale), x4_scale(scale) { if (sNumInstances == 0) { - mpTexture = std::make_unique(ETexelFormat::I8, 256, 256, 1); - u8* fontData = new u8[(mpTexture->GetBitsPerPixel() * mpTexture->GetWidth() * mpTexture->GetHeight()) / 8]; + mpTexture = std::make_unique(ETexelFormat::I8, 256, 256, 1, "Font Texture"); + u8* fontData = new u8[(mpTexture->GetBitDepth() * mpTexture->GetWidth() * mpTexture->GetHeight()) / 8]; memcpy(fontData, sSystemFont.data(), sSystemFont.size()); // u8* textureData = mpTexture->GetBitMapData(); // LinearToTile8(textureData, fontData); diff --git a/Runtime/Graphics/CGraphics.cpp b/Runtime/Graphics/CGraphics.cpp index 0880c9f2b..84e4162ca 100644 --- a/Runtime/Graphics/CGraphics.cpp +++ b/Runtime/Graphics/CGraphics.cpp @@ -511,58 +511,61 @@ void CGraphics::SetCopyClear(const zeus::CColor& color, float depth) { void CGraphics::SetIsBeginSceneClearFb(bool clear) { g_IsBeginSceneClearFb = clear; } -const CTevCombiners::CTevPass CGraphics::sTevPass805a564c{ - {GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_RASC}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_RASA}, -}; +// Stream API +static EStreamFlags sStreamFlags; +static zeus::CColor sQueuedColor; +static zeus::CVector2f sQueuedTexCoord; +static zeus::CVector3f sQueuedNormal; -const CTevCombiners::CTevPass CGraphics::sTevPass805a5698{ - {GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_RASC, GX::TevColorArg::CC_C0, GX::TevColorArg::CC_ZERO}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_RASA, GX::TevAlphaArg::CA_A0, GX::TevAlphaArg::CA_ZERO}, -}; +void CGraphics::SetTevOp(ERglTevStage stage, const CTevCombiners::CTevPass& pass) { + CTevCombiners::SetupPass(stage, pass); +} -const CTevCombiners::CTevPass CGraphics::sTevPass805a5e70{ - {GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_C0}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_A0}, -}; +void CGraphics::StreamBegin(GX::Primitive primitive) { + sStreamFlags = {}; + aurora::gfx::stream_begin(primitive); +} -const CTevCombiners::CTevPass CGraphics::sTevPass805a5ebc{ - {GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_RASC, GX::TevColorArg::CC_TEXC, GX::TevColorArg::CC_ZERO}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_RASA, GX::TevAlphaArg::CA_TEXA, GX::TevAlphaArg::CA_ZERO}, -}; +void CGraphics::StreamNormal(const zeus::CVector3f& nrm) { + sQueuedNormal = nrm; + sStreamFlags |= EStreamFlagBits::fHasNormal; +} -const CTevCombiners::CTevPass CGraphics::sTevPass805a5f08{ - {GX::TevColorArg::CC_RASC, GX::TevColorArg::CC_TEXC, GX::TevColorArg::CC_TEXA, GX::TevColorArg::CC_ZERO}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_RASA}, -}; +void CGraphics::StreamColor(float r, float g, float b, float a) { + sQueuedColor = zeus::CColor{r, g, b, a}; + sStreamFlags |= EStreamFlagBits::fHasColor; +} -const CTevCombiners::CTevPass CGraphics::sTevPass805a5f54{ - {GX::TevColorArg::CC_RASC, GX::TevColorArg::CC_ONE, GX::TevColorArg::CC_TEXC, GX::TevColorArg::CC_ZERO}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_TEXA, GX::TevAlphaArg::CA_RASA, GX::TevAlphaArg::CA_ZERO}, -}; +void CGraphics::StreamColor(const zeus::CColor& color) { + sQueuedColor = color; + sStreamFlags |= EStreamFlagBits::fHasColor; +} -const CTevCombiners::CTevPass CGraphics::sTevPass805a5fa0{ - {GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_TEXC}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_TEXA}, -}; +void CGraphics::StreamTexcoord(float x, float y) { + sQueuedTexCoord = {x, y}; + sStreamFlags |= EStreamFlagBits::fHasTexture; +} -const CTevCombiners::CTevPass CGraphics::sTevPass804bfcc0{ - {GX::TevColorArg::CC_C0, GX::TevColorArg::CC_TEXC, GX::TevColorArg::CC_RASC, GX::TevColorArg::CC_ZERO}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_RASA}, -}; +void CGraphics::StreamTexcoord(const zeus::CVector2f& uv) { + sQueuedTexCoord = uv; + sStreamFlags |= EStreamFlagBits::fHasTexture; +} -const CTevCombiners::CTevPass CGraphics::sTevPass805a5fec{ - {GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_RASC}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_TEXA, GX::TevAlphaArg::CA_RASA, GX::TevAlphaArg::CA_ZERO}, -}; +void CGraphics::StreamVertex(float xyz) { + const zeus::CVector3f pos{xyz, xyz, xyz}; + aurora::gfx::stream_vertex(sStreamFlags, pos, sQueuedNormal, sQueuedColor, sQueuedTexCoord); +} -const CTevCombiners::CTevPass CGraphics::sTevPass805a6038{ - {GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_TEXC, GX::TevColorArg::CC_RASC, GX::TevColorArg::CC_ZERO}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_KONST, GX::TevAlphaArg::CA_RASA, GX::TevAlphaArg::CA_ZERO}, -}; +void CGraphics::StreamVertex(float x, float y, float z) { + const zeus::CVector3f pos{x, y, z}; + aurora::gfx::stream_vertex(sStreamFlags, pos, sQueuedNormal, sQueuedColor, sQueuedTexCoord); +} -const CTevCombiners::CTevPass CGraphics::sTevPass805a6084{ - {GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_CPREV, GX::TevColorArg::CC_APREV, GX::TevColorArg::CC_ZERO}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_APREV}, -}; +void CGraphics::StreamVertex(const zeus::CVector3f& pos) { + aurora::gfx::stream_vertex(sStreamFlags, pos, sQueuedNormal, sQueuedColor, sQueuedTexCoord); +} + +void CGraphics::StreamEnd() { + aurora::gfx::stream_end(); +} } // namespace metaforce diff --git a/Runtime/Graphics/CGraphics.hpp b/Runtime/Graphics/CGraphics.hpp index 6788d7d41..8914ecc1b 100644 --- a/Runtime/Graphics/CGraphics.hpp +++ b/Runtime/Graphics/CGraphics.hpp @@ -1,23 +1,21 @@ #pragma once +#include "Runtime/RetroTypes.hpp" +#include "Runtime/Graphics/GX.hpp" +#include "Runtime/Graphics/CTevCombiners.hpp" +#include "Runtime/ConsoleVariables/CVar.hpp" + #include #include #include -#include "optick.h" - -#include "Runtime/RetroTypes.hpp" - -#include "Runtime/Graphics/GX.hpp" - -#include "Runtime/ConsoleVariables/CVar.hpp" - #include #include #include #include #include +#include using frame_clock = std::chrono::high_resolution_clock; @@ -94,25 +92,6 @@ struct SClipScreenRect { } }; -enum class ETexelFormat { - Invalid = -1, - I4 = 0, - I8 = 1, - IA4 = 2, - IA8 = 3, - C4 = 4, - C8 = 5, - C14X2 = 6, - RGB565 = 7, - RGB5A3 = 8, - RGBA8 = 9, - CMPR = 10, - RGBA8PC = 16, - C8PC = 17, - CMPRPC = 18, - CMPRPCA = 19, -}; - #define DEPTH_FAR 1.f #define DEPTH_SKY 0.999f #define DEPTH_TARGET_MANAGER 0.12500012f @@ -124,47 +103,6 @@ enum class ETexelFormat { #define CUBEMAP_RES 256 #define CUBEMAP_MIPS 6 -static s32 sNextUniquePass = 0; -namespace CTevCombiners { -struct CTevOp { - bool x0_clamp = true; - GX::TevOp x4_op = GX::TevOp::TEV_ADD; - GX::TevBias x8_bias = GX::TevBias::TB_ZERO; - GX::TevScale xc_scale = GX::TevScale::CS_SCALE_1; - GX::TevRegID xc_regId = GX::TevRegID::TEVPREV; -}; - -struct ColorPass { - GX::TevColorArg x0_a; - GX::TevColorArg x4_b; - GX::TevColorArg x8_c; - GX::TevColorArg xc_d; -}; -struct AlphaPass { - GX::TevAlphaArg x0_a; - GX::TevAlphaArg x4_b; - GX::TevAlphaArg x8_c; - GX::TevAlphaArg xc_d; -}; - -class CTevPass { - u32 x0_id; - ColorPass x4_colorPass; - AlphaPass x14_alphaPass; - CTevOp x24_colorOp; - CTevOp x38_alphaOp; - -public: - CTevPass(const ColorPass& colPass, const AlphaPass& alphaPass, const CTevOp& colorOp = CTevOp(), - const CTevOp alphaOp = CTevOp()) - : x0_id(++sNextUniquePass) - , x4_colorPass(colPass) - , x14_alphaPass(alphaPass) - , x24_colorOp(colorOp) - , x38_alphaOp(alphaOp) {} -}; -}; // namespace CTevCombiners - class CGraphics { public: struct CProjectionState { @@ -352,26 +290,17 @@ public: // static void DrawArray(size_t start, size_t count) { g_BooMainCommandQueue->draw(start, count); } // static void DrawArrayIndexed(size_t start, size_t count) { g_BooMainCommandQueue->drawIndexed(start, count); } - static const CTevCombiners::CTevPass sTevPass805a564c; - static const CTevCombiners::CTevPass sTevPass805a5698; - - static const CTevCombiners::CTevPass sTevPass805a5e70; - - static const CTevCombiners::CTevPass sTevPass805a5ebc; - - static const CTevCombiners::CTevPass sTevPass805a5f08; - - static const CTevCombiners::CTevPass sTevPass805a5f54; - - static const CTevCombiners::CTevPass sTevPass805a5fa0; - - static const CTevCombiners::CTevPass sTevPass804bfcc0; - - static const CTevCombiners::CTevPass sTevPass805a5fec; - - static const CTevCombiners::CTevPass sTevPass805a6038; - - static const CTevCombiners::CTevPass sTevPass805a6084; + static void SetTevOp(ERglTevStage stage, const CTevCombiners::CTevPass& pass); + static void StreamBegin(GX::Primitive primitive); + static void StreamNormal(const zeus::CVector3f& nrm); + static void StreamColor(float r, float g, float b, float a); + static void StreamColor(const zeus::CColor& color); + static void StreamTexcoord(float x, float y); + static void StreamTexcoord(const zeus::CVector2f& uv); + static void StreamVertex(float xyz); + static void StreamVertex(float x, float y, float z); + static void StreamVertex(const zeus::CVector3f& pos); + static void StreamEnd(); }; template diff --git a/Runtime/Graphics/CGraphicsPalette.hpp b/Runtime/Graphics/CGraphicsPalette.hpp index af9a78450..04280cee7 100644 --- a/Runtime/Graphics/CGraphicsPalette.hpp +++ b/Runtime/Graphics/CGraphicsPalette.hpp @@ -1,7 +1,8 @@ #pragma once +#include "RetroTypes.hpp" + #include -#include "Runtime/RetroTypes.hpp" namespace metaforce { class CInputStream; @@ -24,10 +25,12 @@ class CGraphicsPalette { public: explicit CGraphicsPalette(EPaletteFormat fmt, int count); - explicit CGraphicsPalette(CInputStream& in); void Load(); + + [[nodiscard]] const u8* GetEntries() const { return xc_entries.get(); } + static void SetCurrentFrameCount(u32 frameCount) { sCurrentFrameCount = frameCount; } }; diff --git a/Runtime/Graphics/CMakeLists.txt b/Runtime/Graphics/CMakeLists.txt index 17062c1e4..d764e5b19 100644 --- a/Runtime/Graphics/CMakeLists.txt +++ b/Runtime/Graphics/CMakeLists.txt @@ -10,8 +10,8 @@ set(GRAPHICS_SOURCES CLineRenderer.hpp CLineRenderer.cpp CMetroidModelInstance.cpp CMetroidModelInstance.hpp CLight.hpp CLight.cpp - DolphinCTexture.hpp DolphinCTexture.cpp - CTexture.hpp CTextureBoo.cpp + CTevCombiners.cpp CTevCombiners.hpp + CTexture.hpp CTexture.cpp CModel.cpp CModel.hpp CSkinnedModel.hpp CSkinnedModel.cpp CVertexMorphEffect.hpp CVertexMorphEffect.cpp diff --git a/Runtime/Graphics/CMoviePlayer.cpp b/Runtime/Graphics/CMoviePlayer.cpp index 6431c56f9..18df6210b 100644 --- a/Runtime/Graphics/CMoviePlayer.cpp +++ b/Runtime/Graphics/CMoviePlayer.cpp @@ -1,8 +1,10 @@ -#include "Runtime/Graphics/CMoviePlayer.hpp" +#include "Graphics/CMoviePlayer.hpp" -#include "Runtime/Audio/g721.h" -#include "Runtime/CDvdRequest.hpp" -#include "Runtime/Graphics/CGraphics.hpp" +#include "Audio/g721.h" +#include "CDvdRequest.hpp" +#include "Graphics/CGraphics.hpp" +#include "Graphics/CCubeRenderer.hpp" +#include "GameGlobalObjects.hpp" #include #include @@ -190,29 +192,28 @@ CMoviePlayer::CMoviePlayer(const char* path, float preLoadSeconds, bool loop, bo CTHPTextureSet& set = x80_textures.emplace_back(); if (deinterlace) { /* metaforce addition: this way interlaced THPs don't look horrible */ - set.Y[0] = aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width, x6c_videoInfo.height / 2, 1, - aurora::gfx::TextureFormat::R8, - fmt::format(FMT_STRING("Movie {} Texture Set {} Y[0]"), path, i)); - set.Y[1] = aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width, x6c_videoInfo.height / 2, 1, - aurora::gfx::TextureFormat::R8, - fmt::format(FMT_STRING("Movie {} Texture Set {} Y[1]"), path, i)); - set.U = aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, 1, - aurora::gfx::TextureFormat::R8, - fmt::format(FMT_STRING("Movie {} Texture Set {} U"), path, i)); - set.V = aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, 1, - aurora::gfx::TextureFormat::R8, - fmt::format(FMT_STRING("Movie {} Texture Set {} V"), path, i)); + set.Y[0] = + aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width, x6c_videoInfo.height / 2, 1, ETexelFormat::R8PC, + fmt::format(FMT_STRING("Movie {} Texture Set {} Y[0]"), path, i)); + set.Y[1] = + aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width, x6c_videoInfo.height / 2, 1, ETexelFormat::R8PC, + fmt::format(FMT_STRING("Movie {} Texture Set {} Y[1]"), path, i)); + set.U = + aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, 1, ETexelFormat::R8PC, + fmt::format(FMT_STRING("Movie {} Texture Set {} U"), path, i)); + set.V = + aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, 1, ETexelFormat::R8PC, + fmt::format(FMT_STRING("Movie {} Texture Set {} V"), path, i)); } else { /* normal progressive presentation */ - set.Y[0] = aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width, x6c_videoInfo.height, 1, - aurora::gfx::TextureFormat::R8, + set.Y[0] = aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width, x6c_videoInfo.height, 1, ETexelFormat::R8PC, fmt::format(FMT_STRING("Movie {} Texture Set {} Y"), path, i)); - set.U = aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, 1, - aurora::gfx::TextureFormat::R8, - fmt::format(FMT_STRING("Movie {} Texture Set {} U"), path, i)); - set.V = aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, 1, - aurora::gfx::TextureFormat::R8, - fmt::format(FMT_STRING("Movie {} Texture Set {} V"), path, i)); + set.U = + aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, 1, ETexelFormat::R8PC, + fmt::format(FMT_STRING("Movie {} Texture Set {} U"), path, i)); + set.V = + aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, 1, ETexelFormat::R8PC, + fmt::format(FMT_STRING("Movie {} Texture Set {} V"), path, i)); } if (xf4_25_hasAudio) set.audioBuf.reset(new s16[x28_thpHead.maxAudioSamples * 2]); @@ -364,20 +365,37 @@ void CMoviePlayer::Rewind() { xe8_curSeconds = 0.f; } -void CMoviePlayer::SetFrame(float hpad, float vpad) { - m_hpad = hpad; - m_vpad = vpad; +void CMoviePlayer::Draw() { + if (GetIsFullyCached()) { + g_Renderer->SetDepthReadWrite(false, false); + g_Renderer->SetViewportOrtho(false, -4096.f, 4096.f); + const auto vpHeight = CGraphics::GetViewportHeight(); + const auto vpWidth = CGraphics::GetViewportWidth(); + const auto vpTop = CGraphics::GetViewportTop(); + const auto vpLeft = CGraphics::GetViewportLeft(); + const auto [width, height] = GetVideoDimensions(); + const auto centerX = (width - vpWidth) / 2; + const auto centerY = (height - vpHeight) / 2; + DrawFrame(vpLeft - centerX, vpLeft + vpWidth + centerX, vpTop - centerY, vpTop + vpHeight + centerY); + } } -void CMoviePlayer::DrawFrame() { +void CMoviePlayer::DrawFrame(u32 left, u32 right, u32 top, u32 bottom) { + DrawFrame({static_cast(left), 0.f, static_cast(bottom)}, + {static_cast(right), 0.f, static_cast(bottom)}, + {static_cast(left), 0.f, static_cast(top)}, + {static_cast(right), 0.f, static_cast(top)}); +} + +void CMoviePlayer::DrawFrame(const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3, + const zeus::CVector3f& v4) { if (xd0_drawTexSlot == UINT32_MAX) return; SCOPED_GRAPHICS_DEBUG_GROUP("CMoviePlayer::DrawFrame", zeus::skYellow); /* draw appropriate field */ CTHPTextureSet& tex = x80_textures[xd0_drawTexSlot]; - aurora::gfx::queue_movie_player(tex.Y[m_deinterlace ? (xfc_fieldIndex != 0) : 0], tex.U, tex.V, zeus::skWhite, m_hpad, - m_vpad); + aurora::gfx::queue_movie_player(tex.Y[m_deinterlace ? (xfc_fieldIndex != 0) : 0], tex.U, tex.V, v1, v2, v3, v4); /* ensure second field is being displayed by VI to signal advance * (faked in metaforce with continuous xor) */ diff --git a/Runtime/Graphics/CMoviePlayer.hpp b/Runtime/Graphics/CMoviePlayer.hpp index 61e4e2042..7020ca011 100644 --- a/Runtime/Graphics/CMoviePlayer.hpp +++ b/Runtime/Graphics/CMoviePlayer.hpp @@ -109,10 +109,14 @@ private: float m_hpad; float m_vpad; - static u32 THPAudioDecode(s16* buffer, const u8* audioFrame, bool stereo); void DecodeFromRead(const void* data); - void ReadCompleted(); + void DrawFrame(u32 left, u32 right, u32 top, u32 bottom); + void DrawFrame(const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3, + const zeus::CVector3f& v4); void PostDVDReadRequestIfNeeded(); + void ReadCompleted(); + + static u32 THPAudioDecode(s16* buffer, const u8* audioFrame, bool stereo); public: CMoviePlayer(const char* path, float preLoadSeconds, bool loop, bool deinterlace); @@ -135,8 +139,7 @@ public: float GetPlayedSeconds() const { return xdc_frameRem + xe8_curSeconds; } float GetTotalSeconds() const { return xe4_totalSeconds; } void SetPlayMode(EPlayMode mode) { xe0_playMode = mode; } - void SetFrame(float hpad, float vpad); - void DrawFrame(); + void Draw(); void Update(float dt); std::pair GetVideoDimensions() const { return {x6c_videoInfo.width, x6c_videoInfo.height}; } diff --git a/Runtime/Graphics/CTevCombiners.cpp b/Runtime/Graphics/CTevCombiners.cpp new file mode 100644 index 000000000..3c2fe5aa3 --- /dev/null +++ b/Runtime/Graphics/CTevCombiners.cpp @@ -0,0 +1,102 @@ +#include "Graphics/CTevCombiners.hpp" + +namespace metaforce::CTevCombiners { +u32 CTevPass::sNextUniquePass = 0; + +void CTevPass::Execute(ERglTevStage stage) const { + aurora::gfx::update_tev_stage(stage, x4_colorPass, x14_alphaPass, x24_colorOp, x38_alphaOp); +} + +constexpr u32 maxTevPasses = 2; +static u32 sNumEnabledPasses; +static std::array sValidPasses; + +const CTevPass skPassThru{ + {GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_RASC}, + {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_RASA}, +}; +const CTevPass sTevPass805a5698{ + {GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_RASC, GX::TevColorArg::CC_C0, GX::TevColorArg::CC_ZERO}, + {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_RASA, GX::TevAlphaArg::CA_A0, GX::TevAlphaArg::CA_ZERO}, +}; +const CTevPass sTevPass805a5e70{ + {GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_C0}, + {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_A0}, +}; +const CTevPass sTevPass805a5ebc{ + {GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_RASC, GX::TevColorArg::CC_TEXC, GX::TevColorArg::CC_ZERO}, + {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_RASA, GX::TevAlphaArg::CA_TEXA, GX::TevAlphaArg::CA_ZERO}, +}; +const CTevPass sTevPass805a5f08{ + {GX::TevColorArg::CC_RASC, GX::TevColorArg::CC_TEXC, GX::TevColorArg::CC_TEXA, GX::TevColorArg::CC_ZERO}, + {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_RASA}, +}; +const CTevPass sTevPass805a5f54{ + {GX::TevColorArg::CC_RASC, GX::TevColorArg::CC_ONE, GX::TevColorArg::CC_TEXC, GX::TevColorArg::CC_ZERO}, + {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_TEXA, GX::TevAlphaArg::CA_RASA, GX::TevAlphaArg::CA_ZERO}, +}; +const CTevPass sTevPass805a5fa0{ + {GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_TEXC}, + {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_TEXA}, +}; +const CTevPass sTevPass804bfcc0{ + {GX::TevColorArg::CC_C0, GX::TevColorArg::CC_TEXC, GX::TevColorArg::CC_RASC, GX::TevColorArg::CC_ZERO}, + {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_RASA}, +}; +const CTevPass sTevPass805a5fec{ + {GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_RASC}, + {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_TEXA, GX::TevAlphaArg::CA_RASA, GX::TevAlphaArg::CA_ZERO}, +}; +const CTevPass sTevPass805a6038{ + {GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_TEXC, GX::TevColorArg::CC_RASC, GX::TevColorArg::CC_ZERO}, + {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_KONST, GX::TevAlphaArg::CA_RASA, GX::TevAlphaArg::CA_ZERO}, +}; +const CTevPass sTevPass805a6084{ + {GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_CPREV, GX::TevColorArg::CC_APREV, GX::TevColorArg::CC_ZERO}, + {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_APREV}, +}; + +void Init() { + sNumEnabledPasses = maxTevPasses; + sValidPasses.fill(true); + for (int i = 0; i < maxTevPasses; ++i) { + DeletePass(static_cast(i)); + } + sValidPasses.fill(false); + RecomputePasses(); +} + +void SetupPass(ERglTevStage stage, const CTevPass& pass) { + if (pass == skPassThru) { + DeletePass(stage); + return; + } + if (SetPassCombiners(stage, pass)) { + sValidPasses[static_cast(stage)] = true; + RecomputePasses(); + } +} + +void DeletePass(ERglTevStage stage) { + SetPassCombiners(stage, skPassThru); + sValidPasses[static_cast(stage)] = false; + RecomputePasses(); +} + +bool SetPassCombiners(ERglTevStage stage, const CTevPass& pass) { + pass.Execute(stage); + return true; +} + +void RecomputePasses() { + sNumEnabledPasses = std::count(sValidPasses.begin(), sValidPasses.end(), true); + // CGX::SetNumTevStages(sNumEnabledPasses); +} + +void ResetStates() { + sValidPasses.fill(false); + skPassThru.Execute(ERglTevStage::Stage0); + sNumEnabledPasses = 1; + // CGX::SetNumTevStages(1); +} +} // namespace metaforce::CTevCombiners diff --git a/Runtime/Graphics/CTevCombiners.hpp b/Runtime/Graphics/CTevCombiners.hpp new file mode 100644 index 000000000..7c7e6aa24 --- /dev/null +++ b/Runtime/Graphics/CTevCombiners.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include "Graphics/GX.hpp" +#include "RetroTypes.hpp" + +#include + +namespace metaforce::CTevCombiners { +class CTevPass { + u32 x0_id; + ColorPass x4_colorPass; + AlphaPass x14_alphaPass; + CTevOp x24_colorOp; + CTevOp x38_alphaOp; + + static u32 sNextUniquePass; + +public: + CTevPass(const ColorPass& colPass, const AlphaPass& alphaPass, const CTevOp& colorOp = {}, const CTevOp& alphaOp = {}) + : x0_id(++sNextUniquePass) + , x4_colorPass(colPass) + , x14_alphaPass(alphaPass) + , x24_colorOp(colorOp) + , x38_alphaOp(alphaOp) {} + + void Execute(ERglTevStage stage) const; + + bool operator<=>(const CTevPass&) const = default; +}; + +extern const CTevPass skPassThru; +extern const CTevPass sTevPass805a5698; +extern const CTevPass sTevPass805a5e70; +extern const CTevPass sTevPass805a5ebc; +extern const CTevPass sTevPass805a5f08; +extern const CTevPass sTevPass805a5f54; +extern const CTevPass sTevPass805a5fa0; +extern const CTevPass sTevPass804bfcc0; +extern const CTevPass sTevPass805a5fec; +extern const CTevPass sTevPass805a6038; +extern const CTevPass sTevPass805a6084; + +void Init(); +void SetupPass(ERglTevStage stage, const CTevPass& pass); +void DeletePass(ERglTevStage stage); +bool SetPassCombiners(ERglTevStage stage, const CTevPass& pass); +void RecomputePasses(); +void ResetStates(); +} // namespace metaforce::CTevCombiners diff --git a/Runtime/Graphics/DolphinCTexture.cpp b/Runtime/Graphics/CTexture.cpp similarity index 82% rename from Runtime/Graphics/DolphinCTexture.cpp rename to Runtime/Graphics/CTexture.cpp index 9a487254c..9f67fee73 100644 --- a/Runtime/Graphics/DolphinCTexture.cpp +++ b/Runtime/Graphics/CTexture.cpp @@ -1,7 +1,9 @@ -#include "Runtime/Graphics/DolphinCTexture.hpp" +#include "Graphics/CTexture.hpp" -#include "Runtime/CToken.hpp" -#include "zeus/Math.hpp" +#include "CToken.hpp" + +#include +#include u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, bool mipmap, u8 max_lod) { s32 shiftX = 0; @@ -70,30 +72,29 @@ u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, bool mipmap, u8 max_lo return bufLen; } -namespace metaforce::WIP { -namespace { +namespace metaforce { static std::array sLoadedTextures{}; -} -CTexture::CTexture(ETexelFormat fmt, s16 w, s16 h, s32 mips) +CTexture::CTexture(ETexelFormat fmt, u16 w, u16 h, s32 mips, std::string_view label) : x0_fmt(fmt) , x4_w(w) , x6_h(h) , x8_mips(mips) , x9_bitsPerPixel(TexelFormatBitsPerPixel(fmt)) -, x64_frameAllocated(sCurrentFrameCount) { +, x64_frameAllocated(sCurrentFrameCount) +, m_label(fmt::format(FMT_STRING("{} ({})"), label, magic_enum::enum_name(fmt))) { InitBitmapBuffers(fmt, w, h, mips); - InitTextureObjs(); + InitTextureObjs(false); } -CTexture::CTexture(CInputStream& in, EAutoMipmap automip, EBlackKey blackKey) { - x64_frameAllocated = sCurrentFrameCount; - x0_fmt = ETexelFormat(in.ReadLong()); - x4_w = in.ReadShort(); - x6_h = in.ReadShort(); - x8_mips = in.ReadLong(); - +CTexture::CTexture(CInputStream& in, std::string_view label, EAutoMipmap automip, EBlackKey blackKey) +: x0_fmt(ETexelFormat(in.ReadLong())) +, x4_w(in.ReadShort()) +, x6_h(in.ReadShort()) +, x8_mips(in.ReadLong()) +, x64_frameAllocated(sCurrentFrameCount) +, m_label(fmt::format(FMT_STRING("{} ({})"), label, magic_enum::enum_name(x0_fmt))) { bool hasPalette = (x0_fmt == ETexelFormat::C4 || x0_fmt == ETexelFormat::C8 || x0_fmt == ETexelFormat::C14X2); if (hasPalette) { x10_graphicsPalette = std::make_unique(in); @@ -128,10 +129,10 @@ CTexture::CTexture(CInputStream& in, EAutoMipmap automip, EBlackKey blackKey) { } } - InitTextureObjs(); + InitTextureObjs(true); } -void* CTexture::Lock() { +u8* CTexture::Lock() { xa_24_locked = true; return GetBitMapData(0); } @@ -141,7 +142,8 @@ void CTexture::UnLock() { CountMemory(); // DCFlushRange(x44_aramToken.GetMRAMSafe(), ROUND_UP_32(xc_memoryAllocated)); } -void CTexture::Load(GX::TexMapID id, CTexture::EClampMode clamp) { + +void CTexture::Load(GX::TexMapID id, EClampMode clamp) { if (sLoadedTextures[id] != this || xa_29_canLoadObj) { auto* image_ptr = /*x44_aramToken.GetMRAMSafe() */ x44_aramToken_x4_buff.get(); CountMemory(); @@ -161,8 +163,8 @@ void CTexture::Load(GX::TexMapID id, CTexture::EClampMode clamp) { x64_frameAllocated = sCurrentFrameCount; } } -void CTexture::LoadMipLevel(s32 mip, GX::TexMapID id, CTexture::EClampMode clamp) { +void CTexture::LoadMipLevel(s32 mip, GX::TexMapID id, EClampMode clamp) { auto image_ptr = /*x44_aramToken.GetMRAMSafe() */ x44_aramToken_x4_buff.get(); u32 width = x4_w; u32 height = x6_h; @@ -196,7 +198,7 @@ void CTexture::MakeSwappable() { xa_27_noSwap = false; } -const void* CTexture::GetConstBitMapData(s32 mip) const { +const u8* CTexture::GetConstBitMapData(s32 mip) const { u32 buffOffset = 0; if (x8_mips > 0) { for (u32 i = 0; i < x8_mips; ++i) { @@ -206,9 +208,9 @@ const void* CTexture::GetConstBitMapData(s32 mip) const { return x44_aramToken_x4_buff.get() + buffOffset; /* x44_aramToken.GetMRAMSafe() + buffOffset*/ } -void* CTexture::GetBitMapData(s32 mip) const { return const_cast(GetConstBitMapData(mip)); } +u8* CTexture::GetBitMapData(s32 mip) const { return const_cast(GetConstBitMapData(mip)); } -void CTexture::InitBitmapBuffers(ETexelFormat fmt, s16 width, s16 height, s32 mips) { +void CTexture::InitBitmapBuffers(ETexelFormat fmt, u16 width, u16 height, s32 mips) { switch (fmt) { case ETexelFormat::I4: x18_gxFormat = GX::TF_I4; @@ -252,11 +254,12 @@ void CTexture::InitBitmapBuffers(ETexelFormat fmt, s16 width, s16 height, s32 mi : x18_gxFormat; xc_memoryAllocated = GXGetTexBufferSize(width, height, format, mips > 1, mips > 1 ? 11 : 0); - x44_aramToken_x4_buff.reset(new u8[xc_memoryAllocated]); + x44_aramToken_x4_buff = std::make_unique(xc_memoryAllocated); /*x44_aramToken.PostConstruct(buf, xc_memoryAllocated, 1);*/ CountMemory(); } -void CTexture::InitTextureObjs() { + +void CTexture::InitTextureObjs(bool write) { xa_26_isPowerOfTwo = zeus::floorPowerOfTwo(x4_w) == x4_w && zeus::floorPowerOfTwo(x6_h) == x6_h; if (!xa_26_isPowerOfTwo) { @@ -267,12 +270,17 @@ void CTexture::InitTextureObjs() { if (IsCITexture()) { // GXInitTexObjCI(x20_texObj, x44_aramToken_x4_buff.get(), x4_w, x6_h, x1c_gxCIFormat, u32(x40_clampMode), // u32(x40_clampMode), x8_mips > 1, 0); + // TODO } else { // GXInitTexObj(x20_texObj, x44_aramToken_x4_buff.get(), x4_w, x6_h, x1c_gxCIFormat, u32(x40_clampMode), // u32(x40_clampMode), x8_mips > 1); // GXInitTexObjLOD(x20_texObj, x8_mips > 1 ? GX_LIN_MIP_LIN : GX_LINEAR, 0.f, static_cast(x8_mips) - 1.f, // 0.f, // false, false, x8_mips > 1 ? GX_ANISO_4 : GX_ANISO_1); + x20_texObj = aurora::gfx::new_dynamic_texture_2d(x4_w, x6_h, x8_mips, x0_fmt, m_label); + if (write) { + aurora::gfx::write_texture(x20_texObj, {x44_aramToken_x4_buff.get(), xc_memoryAllocated}); + } } xa_29_canLoadObj = true; } @@ -325,12 +333,11 @@ bool CTexture::sMangleMips = false; u32 CTexture::sCurrentFrameCount = 0; u32 CTexture::sTotalAllocatedMemory = 0; -void CTexture::InvalidateTexMap(GX::TexMapID id) { - sLoadedTextures[id] = nullptr; -} +void CTexture::InvalidateTexMap(GX::TexMapID id) { sLoadedTextures[id] = nullptr; } CFactoryFnReturn FTextureFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms, CObjectReference* selfRef) { - return TToken::GetIObjObjectFor(std::make_unique(in)); + const auto label = fmt::format("{} {}", tag.type, tag.id); + return TToken::GetIObjObjectFor(std::make_unique(in, label)); } -} // namespace metaforce::WIP \ No newline at end of file +} // namespace metaforce diff --git a/Runtime/Graphics/CTexture.hpp b/Runtime/Graphics/CTexture.hpp index 1cf50baf7..fcf0905e4 100644 --- a/Runtime/Graphics/CTexture.hpp +++ b/Runtime/Graphics/CTexture.hpp @@ -1,19 +1,13 @@ #pragma once -#include -#include - #include "Runtime/CFactoryMgr.hpp" -#include "Runtime/GCNTypes.hpp" #include "Runtime/Graphics/CGraphics.hpp" -#include "Runtime/IObj.hpp" -#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Graphics/CGraphicsPalette.hpp" +#include "Runtime/Graphics/GX.hpp" +#include "Runtime/IObj.hpp" +#include "Runtime/Streams/CInputStream.hpp" namespace metaforce { -class CVParamTransfer; -class CTextureInfo; - class CTexture { class CDumpedBitmapDataReloader { int x0_; @@ -26,12 +20,13 @@ class CTexture { }; public: - enum class EClampMode { - Clamp, - Repeat, - Mirror, + enum class EAutoMipmap { + Zero, + One, }; + enum class EBlackKey { Zero, One }; + enum class EFontType { None = -1, OneLayer = 0, /* Fill bit0 */ @@ -43,74 +38,77 @@ public: }; private: + static bool sMangleMips; static u32 sCurrentFrameCount; - ETexelFormat x0_fmt; - u16 x4_w; - u16 x6_h; - u8 x8_mips; - u8 x9_bitsPerPixel; - u32 xc_memoryAllocated{}; + static u32 sTotalAllocatedMemory; + + ETexelFormat x0_fmt = ETexelFormat::Invalid; + u16 x4_w = 0; + u16 x6_h = 0; + u8 x8_mips = 0; + u8 x9_bitsPerPixel = 0; + bool xa_24_locked : 1 = false; + bool xa_25_canLoadPalette : 1 = false; + bool xa_26_isPowerOfTwo : 1 = false; + bool xa_27_noSwap : 1 = true; + bool xa_28_counted : 1 = false; + bool xa_29_canLoadObj : 1 = false; + u32 xc_memoryAllocated = 0; std::unique_ptr x10_graphicsPalette; std::unique_ptr x14_bitmapReloader; - u32 x18_gxFormat{}; - u32 x1c_gxCIFormat{}; - /* GXTexObj x20_texObj */ + u32 x18_gxFormat = GX::TF_RGB565; + u32 x1c_gxCIFormat = GX::TF_C8; + aurora::gfx::TextureHandle x20_texObj; // was GXTexObj EClampMode x40_clampMode = EClampMode::Repeat; - /* CARAMToken x44_aramToken */ + std::unique_ptr x44_aramToken_x4_buff; // was CARAMToken u32 x64_frameAllocated{}; - aurora::gfx::TextureHandle m_tex; - aurora::gfx::TextureHandle m_paletteTex; - std::unique_ptr m_otex; - EFontType m_ftype = EFontType::None; - const CTextureInfo* m_textureInfo{}; + // Metaforce additions + std::string m_label; - size_t ComputeMippedTexelCount() const; - size_t ComputeMippedBlockCountDXT1() const; - void BuildI4FromGCN(CInputStream& in, aurora::zstring_view label); - void BuildI8FromGCN(CInputStream& in, aurora::zstring_view label); - void BuildIA4FromGCN(CInputStream& in, aurora::zstring_view label); - void BuildIA8FromGCN(CInputStream& in, aurora::zstring_view label); - void BuildC4FromGCN(CInputStream& in, aurora::zstring_view label); - void BuildC8FromGCN(CInputStream& in, aurora::zstring_view label); - void BuildC14X2FromGCN(CInputStream& in, aurora::zstring_view label); - void BuildRGB565FromGCN(CInputStream& in, aurora::zstring_view label); - void BuildRGB5A3FromGCN(CInputStream& in, aurora::zstring_view label); - void BuildRGBA8FromGCN(CInputStream& in, aurora::zstring_view label); - void BuildDXT1FromGCN(CInputStream& in, aurora::zstring_view label); - void BuildRGBA8(const void* data, size_t length, aurora::zstring_view label); - void BuildC8(const void* data, size_t length, aurora::zstring_view label); - void BuildC8Font(const void* data, EFontType ftype, aurora::zstring_view label); - void BuildDXT1(const void* data, size_t length, aurora::zstring_view label); - void BuildDXT3(const void* data, size_t length, aurora::zstring_view label); - - void InitBitmapBuffers(ETexelFormat fmt, s16 width, s16 height, s32 mips); - void InitTextureObjs(); + void InitBitmapBuffers(ETexelFormat fmt, u16 width, u16 height, s32 mips); + void InitTextureObjs(bool write); // write param is added + void CountMemory(); + void UncountMemory(); + void MangleMipmap(u32 mip); + static u32 TexelFormatBitsPerPixel(ETexelFormat fmt); public: - CTexture(ETexelFormat, s16, s16, s32); - CTexture(std::unique_ptr&& in, u32 length, bool otex, const CTextureInfo* inf, CAssetId id); - [[nodiscard]] ETexelFormat GetTexelFormat() const { return x0_fmt; } - [[nodiscard]] ETexelFormat GetMemoryCardTexelFormat() const { - return x0_fmt == ETexelFormat::C8PC ? ETexelFormat::C8 : ETexelFormat::RGB5A3; - } + // Label parameters are new for Metaforce + CTexture(ETexelFormat fmt, u16 w, u16 h, s32 mips, std::string_view label); + CTexture(CInputStream& in, std::string_view label, EAutoMipmap automip = EAutoMipmap::Zero, + EBlackKey blackKey = EBlackKey::Zero); + + [[nodiscard]] ETexelFormat GetTextureFormat() const { return x0_fmt; } [[nodiscard]] u16 GetWidth() const { return x4_w; } [[nodiscard]] u16 GetHeight() const { return x6_h; } - [[nodiscard]] u8 GetNumMips() const { return x8_mips; } - [[nodiscard]] u8 GetBitsPerPixel() const { return x9_bitsPerPixel; } - void Load(int slot, EClampMode clamp) const; - [[nodiscard]] const aurora::gfx::TextureHandle& GetTexture() const { return m_tex; } - [[nodiscard]] const aurora::gfx::TextureHandle& GetPaletteTexture() const { return m_paletteTex; } - std::unique_ptr BuildMemoryCardTex(u32& sizeOut, ETexelFormat& fmtOut, std::unique_ptr& paletteOut) const; - const aurora::gfx::TextureHandle& GetFontTexture(EFontType tp); + [[nodiscard]] u8 GetNumberOfMipMaps() const { return x8_mips; } + [[nodiscard]] u32 GetBitDepth() const { return x9_bitsPerPixel; } + [[nodiscard]] u32 GetMemoryAllocated() const { return xc_memoryAllocated; } + [[nodiscard]] const std::unique_ptr& GetPalette() const { return x10_graphicsPalette; } + [[nodiscard]] bool HasPalette() const { return x10_graphicsPalette != nullptr; } + [[nodiscard]] u8* Lock(); + void UnLock(); + void Load(GX::TexMapID id, EClampMode clamp); + void LoadMipLevel(s32 mip, GX::TexMapID id, EClampMode clamp); + // void UnloadBitmapData(u32) const; + // void TryReloadBitmapData(CResFactory&) const; + // void LoadToMRAM() const; + // void LoadToARAM() const; + // bool IsARAMTransferInProgress() const { return false; } + void MakeSwappable(); - [[nodiscard]] const CTextureInfo* GetTextureInfo() const { return m_textureInfo; } + [[nodiscard]] const u8* GetConstBitMapData(s32 mip) const; + [[nodiscard]] u8* GetBitMapData(s32 mip) const; + [[nodiscard]] bool IsCITexture() const { + return x0_fmt == ETexelFormat::C4 || x0_fmt == ETexelFormat::C8 || x0_fmt == ETexelFormat::C14X2; + } - static u32 TexelFormatBitsPerPixel(ETexelFormat fmt); + static void InvalidateTexMap(GX::TexMapID id); + static void SetMangleMips(bool b) { sMangleMips = b; } static void SetCurrentFrameCount(u32 frameCount) { sCurrentFrameCount = frameCount; } }; -CFactoryFnReturn FTextureFactory(const metaforce::SObjectTag& tag, std::unique_ptr&& in, u32 len, - const metaforce::CVParamTransfer& vparms, CObjectReference* selfRef); - +CFactoryFnReturn FTextureFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms, + CObjectReference* selfRef); } // namespace metaforce diff --git a/Runtime/Graphics/CTexture.hpp.old b/Runtime/Graphics/CTexture.hpp.old new file mode 100644 index 000000000..1cf50baf7 --- /dev/null +++ b/Runtime/Graphics/CTexture.hpp.old @@ -0,0 +1,116 @@ +#pragma once + +#include +#include + +#include "Runtime/CFactoryMgr.hpp" +#include "Runtime/GCNTypes.hpp" +#include "Runtime/Graphics/CGraphics.hpp" +#include "Runtime/IObj.hpp" +#include "Runtime/Streams/IOStreams.hpp" +#include "Runtime/Graphics/CGraphicsPalette.hpp" + +namespace metaforce { +class CVParamTransfer; +class CTextureInfo; + +class CTexture { + class CDumpedBitmapDataReloader { + int x0_; + u32 x4_; + int x8_; + u32 xc_; + bool x10_; + int x14_; + void* x18_; + }; + +public: + enum class EClampMode { + Clamp, + Repeat, + Mirror, + }; + + enum class EFontType { + None = -1, + OneLayer = 0, /* Fill bit0 */ + OneLayerOutline = 1, /* Fill bit0, Outline bit1 */ + FourLayers = 2, + TwoLayersOutlines = 3, /* Fill bit0/2, Outline bit1/3 */ + TwoLayers = 4, /* Fill bit0/1 and copied to bit2/3 */ + TwoLayersOutlines2 = 8 /* Fill bit2/3, Outline bit0/1 */ + }; + +private: + static u32 sCurrentFrameCount; + ETexelFormat x0_fmt; + u16 x4_w; + u16 x6_h; + u8 x8_mips; + u8 x9_bitsPerPixel; + u32 xc_memoryAllocated{}; + std::unique_ptr x10_graphicsPalette; + std::unique_ptr x14_bitmapReloader; + u32 x18_gxFormat{}; + u32 x1c_gxCIFormat{}; + /* GXTexObj x20_texObj */ + EClampMode x40_clampMode = EClampMode::Repeat; + /* CARAMToken x44_aramToken */ + u32 x64_frameAllocated{}; + + aurora::gfx::TextureHandle m_tex; + aurora::gfx::TextureHandle m_paletteTex; + std::unique_ptr m_otex; + EFontType m_ftype = EFontType::None; + const CTextureInfo* m_textureInfo{}; + + size_t ComputeMippedTexelCount() const; + size_t ComputeMippedBlockCountDXT1() const; + void BuildI4FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildI8FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildIA4FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildIA8FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildC4FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildC8FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildC14X2FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildRGB565FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildRGB5A3FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildRGBA8FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildDXT1FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildRGBA8(const void* data, size_t length, aurora::zstring_view label); + void BuildC8(const void* data, size_t length, aurora::zstring_view label); + void BuildC8Font(const void* data, EFontType ftype, aurora::zstring_view label); + void BuildDXT1(const void* data, size_t length, aurora::zstring_view label); + void BuildDXT3(const void* data, size_t length, aurora::zstring_view label); + + void InitBitmapBuffers(ETexelFormat fmt, s16 width, s16 height, s32 mips); + void InitTextureObjs(); + +public: + CTexture(ETexelFormat, s16, s16, s32); + CTexture(std::unique_ptr&& in, u32 length, bool otex, const CTextureInfo* inf, CAssetId id); + [[nodiscard]] ETexelFormat GetTexelFormat() const { return x0_fmt; } + [[nodiscard]] ETexelFormat GetMemoryCardTexelFormat() const { + return x0_fmt == ETexelFormat::C8PC ? ETexelFormat::C8 : ETexelFormat::RGB5A3; + } + [[nodiscard]] u16 GetWidth() const { return x4_w; } + [[nodiscard]] u16 GetHeight() const { return x6_h; } + [[nodiscard]] u8 GetNumMips() const { return x8_mips; } + [[nodiscard]] u8 GetBitsPerPixel() const { return x9_bitsPerPixel; } + void Load(int slot, EClampMode clamp) const; + [[nodiscard]] const aurora::gfx::TextureHandle& GetTexture() const { return m_tex; } + [[nodiscard]] const aurora::gfx::TextureHandle& GetPaletteTexture() const { return m_paletteTex; } + std::unique_ptr BuildMemoryCardTex(u32& sizeOut, ETexelFormat& fmtOut, std::unique_ptr& paletteOut) const; + const aurora::gfx::TextureHandle& GetFontTexture(EFontType tp); + + [[nodiscard]] const CTextureInfo* GetTextureInfo() const { return m_textureInfo; } + + static u32 TexelFormatBitsPerPixel(ETexelFormat fmt); + static void SetCurrentFrameCount(u32 frameCount) { sCurrentFrameCount = frameCount; } +}; + +CFactoryFnReturn FTextureFactory(const metaforce::SObjectTag& tag, std::unique_ptr&& in, u32 len, + const metaforce::CVParamTransfer& vparms, CObjectReference* selfRef); + +} // namespace metaforce diff --git a/Runtime/Graphics/DolphinCTexture.hpp b/Runtime/Graphics/DolphinCTexture.hpp deleted file mode 100644 index 155e813fa..000000000 --- a/Runtime/Graphics/DolphinCTexture.hpp +++ /dev/null @@ -1,105 +0,0 @@ -#pragma once - -#include "Runtime/CFactoryMgr.hpp" -#include "Runtime/Graphics/CGraphics.hpp" -#include "Runtime/Graphics/CGraphicsPalette.hpp" -#include "Runtime/IObj.hpp" -#include "Runtime/Streams/CInputStream.hpp" -#include "Runtime/Graphics/GX.hpp" - -namespace metaforce::WIP { -class CTexture { - class CDumpedBitmapDataReloader { - int x0_; - u32 x4_; - int x8_; - u32 xc_; - bool x10_; - int x14_; - void* x18_; - }; - -public: - enum class EClampMode { - Clamp, - Repeat, - Mirror, - }; - - enum class EAutoMipmap { - Zero, - One, - }; - - enum class EBlackKey { Zero, One }; - -private: - static bool sMangleMips; - static u32 sCurrentFrameCount; - static u32 sTotalAllocatedMemory; - ETexelFormat x0_fmt = ETexelFormat::Invalid; - u16 x4_w = 0; - u16 x6_h = 0; - u8 x8_mips = 0; - u8 x9_bitsPerPixel = 0; - bool xa_24_locked : 1 = false; - bool xa_25_canLoadPalette : 1 = false; - bool xa_26_isPowerOfTwo : 1 = false; - bool xa_27_noSwap : 1 = true; - bool xa_28_counted : 1 = false; - bool xa_29_canLoadObj : 1 = false; - u32 xc_memoryAllocated = 0; - std::unique_ptr x10_graphicsPalette; - std::unique_ptr x14_bitmapReloader; - u32 x18_gxFormat = GX::TF_RGB565; - u32 x1c_gxCIFormat = GX::TF_C8; - /* GXTexObj x20_texObj */ - EClampMode x40_clampMode = EClampMode::Repeat; - /* CARAMToken x44_aramToken */ - std::unique_ptr x44_aramToken_x4_buff; - u32 x64_frameAllocated{}; - - void InitBitmapBuffers(ETexelFormat fmt, s16 width, s16 height, s32 mips); - void InitTextureObjs(); - void CountMemory(); - void UncountMemory(); - void MangleMipmap(u32 mip); - static u32 TexelFormatBitsPerPixel(ETexelFormat fmt); - -public: - CTexture(ETexelFormat, s16, s16, s32); - CTexture(CInputStream& in, EAutoMipmap automip = EAutoMipmap::Zero, EBlackKey blackKey = EBlackKey::Zero); - - [[nodiscard]] ETexelFormat GetTextureFormat() const { return x0_fmt; } - [[nodiscard]] s16 GetWidth(s32 mip) const { return x4_w; } - [[nodiscard]] s16 GetHeight(s32 mip) const { return x6_h; } - [[nodiscard]] u8 GetNumberOfMipMaps() const { return x8_mips; } - [[nodiscard]] u32 GetBitDepth() const { return x9_bitsPerPixel; } - [[nodiscard]] u32 GetMemoryAllocated() const { return xc_memoryAllocated; } - [[nodiscard]] const std::unique_ptr& GetPalette() const { return x10_graphicsPalette; } - [[nodiscard]] bool HasPalette() const { return x10_graphicsPalette != nullptr; } - [[nodiscard]] void* Lock(); - void UnLock(); - void Load(GX::TexMapID id, EClampMode clamp); - void LoadMipLevel(s32 mip, GX::TexMapID id, EClampMode clamp); - // void UnloadBitmapData(u32) const; - // void TryReloadBitmapData(CResFactory&) const; - // void LoadToMRAM() const; - // void LoadToARAM() const; - // bool IsARAMTransferInProgress() const { return false; } - void MakeSwappable(); - [[nodiscard]] const void* GetConstBitMapData(s32 mip) const; - [[nodiscard]] void* GetBitMapData(s32 mip) const; - - [[nodiscard]] bool IsCITexture() const { - return x0_fmt == ETexelFormat::C4 || x0_fmt == ETexelFormat::C8 || x0_fmt == ETexelFormat::C14X2; - } - - static void InvalidateTexMap(GX::TexMapID id); - static void SetMangleMips(bool b) { sMangleMips = b; } - static void SetCurrentFrameCount(u32 frameCount) { sCurrentFrameCount = frameCount; } -}; - -CFactoryFnReturn FTextureFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms, - CObjectReference* selfRef); -} // namespace metaforce::WIP diff --git a/Runtime/Graphics/GX.hpp b/Runtime/Graphics/GX.hpp index f8434df1f..a3b16e457 100644 --- a/Runtime/Graphics/GX.hpp +++ b/Runtime/Graphics/GX.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace GX { enum AttrType { NONE, DIRECT, INDEX8, INDEX16 }; diff --git a/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp b/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp index 1f83d50c8..e79beed36 100644 --- a/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp +++ b/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp @@ -36,7 +36,7 @@ void CSpaceWarpFilter::GenerateWarpRampTex() { } } m_warpTex = aurora::gfx::new_static_texture_2d( - WARP_RAMP_RES + 1, WARP_RAMP_RES + 1, 1, aurora::gfx::TextureFormat::R8, + WARP_RAMP_RES + 1, WARP_RAMP_RES + 1, 1, ETexelFormat::RGBA8PC, {reinterpret_cast(data.data()), (WARP_RAMP_RES + 1) * (WARP_RAMP_RES + 1) * 4}, "Warp Ramp"); } diff --git a/Runtime/Graphics/Shaders/CTexturedQuadFilter.cpp b/Runtime/Graphics/Shaders/CTexturedQuadFilter.cpp index fa1c0ecfa..f32682ffb 100644 --- a/Runtime/Graphics/Shaders/CTexturedQuadFilter.cpp +++ b/Runtime/Graphics/Shaders/CTexturedQuadFilter.cpp @@ -201,7 +201,7 @@ CTexturedQuadFilter::CTexturedQuadFilter(EFilterType type, const aurora::gfx::Te } CTexturedQuadFilter::CTexturedQuadFilter(EFilterType type, TLockedToken tex, ERglEnum ztest) -: CTexturedQuadFilter(type, (tex ? tex->GetTexture() : aurora::gfx::TextureHandle{}), ztest) { +: CTexturedQuadFilter(type, aurora::gfx::TextureHandle{}, ztest) { m_flipRect = true; // TODO? m_tex = tex; } @@ -339,7 +339,7 @@ CTexturedQuadFilterAlpha::CTexturedQuadFilterAlpha(EFilterType type, const auror } CTexturedQuadFilterAlpha::CTexturedQuadFilterAlpha(EFilterType type, TLockedToken tex) -: CTexturedQuadFilterAlpha(type, (tex ? tex->GetTexture() : aurora::gfx::TextureHandle{})) { +: CTexturedQuadFilterAlpha(type, aurora::gfx::TextureHandle{}) { m_tex = tex; } diff --git a/Runtime/Graphics/Shaders/CXRayBlurFilter.cpp b/Runtime/Graphics/Shaders/CXRayBlurFilter.cpp index 614bd2d76..14a67b8ce 100644 --- a/Runtime/Graphics/Shaders/CXRayBlurFilter.cpp +++ b/Runtime/Graphics/Shaders/CXRayBlurFilter.cpp @@ -19,7 +19,7 @@ void CXRayBlurFilter::Shutdown() { // s_Pipeline.reset(); } -CXRayBlurFilter::CXRayBlurFilter(TLockedToken& tex) : m_paletteTex(tex), m_booTex(tex->GetPaletteTexture()) { +CXRayBlurFilter::CXRayBlurFilter(TLockedToken& tex) : m_paletteTex(tex) { // , m_booTex(tex->GetPaletteTexture()) // CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { // struct Vert { // zeus::CVector2f m_pos; diff --git a/Runtime/GuiSys/CAuiImagePane.cpp b/Runtime/GuiSys/CAuiImagePane.cpp index f823d1846..c56594a16 100644 --- a/Runtime/GuiSys/CAuiImagePane.cpp +++ b/Runtime/GuiSys/CAuiImagePane.cpp @@ -83,18 +83,18 @@ void CAuiImagePane::DoDrawImagePane(const zeus::CColor& color, const CTexture& t bool zTest = xac_drawFlags == EGuiModelDrawFlags::Shadeless || xac_drawFlags == EGuiModelDrawFlags::Opaque; if (noBlur) { - aurora::gfx::queue_textured_quad_verts(aurora::gfx::CameraFilterType(filter), tex.GetTexture(), - aurora::gfx::ZComp::LEqual, zTest, useColor, xe0_coords, realUseUvs, 0); +// aurora::gfx::queue_textured_quad_verts(aurora::gfx::CameraFilterType(filter), tex.GetTexture(), +// aurora::gfx::ZComp::LEqual, zTest, useColor, xe0_coords, realUseUvs, 0); // quad.drawVerts(useColor, verts); - } else if ((x14c_deResFactor == 0.f && alpha == 1.f) || tex.GetNumMips() == 1) { - aurora::gfx::queue_textured_quad_verts(aurora::gfx::CameraFilterType(filter), tex.GetTexture(), - aurora::gfx::ZComp::LEqual, zTest, useColor, xe0_coords, realUseUvs, 0); + } else if ((x14c_deResFactor == 0.f && alpha == 1.f) || tex.GetNumberOfMipMaps() == 1) { +// aurora::gfx::queue_textured_quad_verts(aurora::gfx::CameraFilterType(filter), tex.GetTexture(), +// aurora::gfx::ZComp::LEqual, zTest, useColor, xe0_coords, realUseUvs, 0); } else { const float tmp = (1.f - x14c_deResFactor) * alpha; const float tmp3 = 1.f - tmp * tmp * tmp; - const float mip = tmp3 * static_cast(tex.GetNumMips() - 1); - aurora::gfx::queue_textured_quad_verts(aurora::gfx::CameraFilterType(filter), tex.GetTexture(), - aurora::gfx::ZComp::LEqual, zTest, useColor, xe0_coords, realUseUvs, mip); + const float mip = tmp3 * static_cast(tex.GetNumberOfMipMaps() - 1); +// aurora::gfx::queue_textured_quad_verts(aurora::gfx::CameraFilterType(filter), tex.GetTexture(), +// aurora::gfx::ZComp::LEqual, zTest, useColor, xe0_coords, realUseUvs, mip); } } diff --git a/Runtime/GuiSys/CRasterFont.hpp b/Runtime/GuiSys/CRasterFont.hpp index cd848d533..248360963 100644 --- a/Runtime/GuiSys/CRasterFont.hpp +++ b/Runtime/GuiSys/CRasterFont.hpp @@ -148,7 +148,7 @@ public: const char16_t* str, int len) const; const CGlyph* GetGlyph(char16_t chr) const { return InternalGetGlyph(chr); } void GetSize(const CDrawStringOptions& opts, int& width, int& height, const char16_t* str, int len) const; - const aurora::gfx::TextureHandle& GetTexture() { return x80_texture->GetFontTexture(x2c_mode); } + CTexture& GetTexture() { return *x80_texture; } bool IsFinishedLoading() const; }; diff --git a/Runtime/GuiSys/CSplashScreen.cpp b/Runtime/GuiSys/CSplashScreen.cpp index 66e23c970..6289d9259 100644 --- a/Runtime/GuiSys/CSplashScreen.cpp +++ b/Runtime/GuiSys/CSplashScreen.cpp @@ -66,29 +66,42 @@ void CSplashScreen::Draw() { CGraphics::SetAlphaCompare(ERglAlphaFunc::Always, 0, ERglAlphaOp::And, ERglAlphaFunc::Always, 0); g_Renderer->SetModelMatrix({}); CGraphics::SetViewPointMatrix({}); - // CGraphics::SetTevOp(Stage0, ?); - // CGraphics::SetTevOp(Stage1, skPassThru); + CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::sTevPass805a5ebc); + CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::skPassThru); g_Renderer->SetBlendMode_AlphaBlended(); - const auto& tex = *x28_texture.GetObj(); + auto& tex = *x28_texture.GetObj(); const auto width = tex.GetWidth(); const auto height = tex.GetHeight(); + tex.Load(GX::TEXMAP0, EClampMode::Clamp); if (x14_which == ESplashScreen::Nintendo || x14_which == ESplashScreen::Retro) { + const auto x = static_cast(133 - (width - 376) / 2); + const auto y = static_cast(170 - (height - 104) / 2); CGraphics::SetOrtho(-10.f, 650.f, -5.5f, 484.5f, -1.f, 1.f); CGraphics::SetCullMode(ERglCullMode::None); - // TODO + CGraphics::StreamBegin(GX::TRIANGLESTRIP); + CGraphics::StreamColor(color); + CGraphics::StreamTexcoord(0.f, 0.f); + CGraphics::StreamVertex({x, 0.f, y + static_cast(height)}); + CGraphics::StreamTexcoord(0.f, 1.f); + CGraphics::StreamVertex({x, 0.f, y}); + CGraphics::StreamTexcoord(1.f, 0.f); + CGraphics::StreamVertex({x + static_cast(width), 0.f, y + static_cast(height)}); + CGraphics::StreamTexcoord(1.f, 1.f); + CGraphics::StreamVertex({x + static_cast(width), 0.f, y}); + CGraphics::StreamEnd(); CGraphics::SetCullMode(ERglCullMode::Front); } else { // TODO // CGraphics::Render2D(); } - zeus::CRectangle rect; - rect.size.x() = width / (480.f * CGraphics::GetViewportAspect()); - rect.size.y() = height / 480.f; - rect.position.x() = 0.5f - rect.size.x() / 2.f; - rect.position.y() = 0.5f - rect.size.y() / 2.f; - aurora::gfx::queue_textured_quad(aurora::gfx::CameraFilterType::Blend, tex.GetTexture(), - aurora::gfx::ZComp::Always, false, color, 1.f, rect, 0.f); +// zeus::CRectangle rect; +// rect.size.x() = width / (480.f * CGraphics::GetViewportAspect()); +// rect.size.y() = height / 480.f; +// rect.position.x() = 0.5f - rect.size.x() / 2.f; +// rect.position.y() = 0.5f - rect.size.y() / 2.f; +// aurora::gfx::queue_textured_quad(aurora::gfx::CameraFilterType::Blend, tex.GetTexture(), +// aurora::gfx::ZComp::Always, false, color, 1.f, rect, 0.f); // Progressive scan options omitted } diff --git a/Runtime/MP1/CCredits.cpp b/Runtime/MP1/CCredits.cpp index 393fe33b2..3ae71bd95 100644 --- a/Runtime/MP1/CCredits.cpp +++ b/Runtime/MP1/CCredits.cpp @@ -200,20 +200,9 @@ CIOWin::EMessageReturn CCredits::ProcessUserInput(const CFinalInput& input) { } void CCredits::DrawVideo() { - /* Correct movie aspect ratio */ - float hPad, vPad; - if (CGraphics::GetViewportAspect() >= 1.78f) { - hPad = 1.78f / CGraphics::GetViewportAspect(); - vPad = 1.78f / 1.33f; - } else { - hPad = 1.f; - vPad = CGraphics::GetViewportAspect() / 1.33f; - } - - if (x28_ && x28_->GetIsFullyCached()) { + if (x28_) { /* Render movie */ - x28_->SetFrame(hPad, vPad); - x28_->DrawFrame(); + x28_->Draw(); if (x5c_27_ || x5c_28_) { float alpha = x58_ / g_tweakGui->x310_; if (x5c_27_) { diff --git a/Runtime/MP1/CFrontEndUI.cpp b/Runtime/MP1/CFrontEndUI.cpp index d53f7e074..740e949f3 100644 --- a/Runtime/MP1/CFrontEndUI.cpp +++ b/Runtime/MP1/CFrontEndUI.cpp @@ -113,8 +113,8 @@ void CFrontEndUI::PlayAdvanceSfx() { CSfxManager::SfxStart(SFXfnt_advance_R, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); } -CFrontEndUI::SNewFileSelectFrame::SNewFileSelectFrame(CSaveGameScreen* sui, u32 rnd, CFrontEndUITouchBar& touchBar) -: x0_rnd(rnd), x4_saveUI(sui), m_touchBar(touchBar) { +CFrontEndUI::SNewFileSelectFrame::SNewFileSelectFrame(CSaveGameScreen* sui, u32 rnd) +: x0_rnd(rnd), x4_saveUI(sui) { x10_frme = g_SimplePool->GetObj("FRME_NewFileSelect"); } @@ -219,7 +219,7 @@ void CFrontEndUI::SNewFileSelectFrame::Update(float dt) { } CFrontEndUI::SNewFileSelectFrame::EAction -CFrontEndUI::SNewFileSelectFrame::ProcessUserInput(const CFinalInput& input, CFrontEndUITouchBar::EAction tbAction) { +CFrontEndUI::SNewFileSelectFrame::ProcessUserInput(const CFinalInput& input) { xc_action = EAction::None; if (x8_subMenu != ESubMenu::EraseGamePopup) @@ -233,46 +233,6 @@ CFrontEndUI::SNewFileSelectFrame::ProcessUserInput(const CFinalInput& input, CFr if (x10c_saveReady) { x1c_loadedFrame->ProcessUserInput(input); - if (x8_subMenu == ESubMenu::Root || x8_subMenu == ESubMenu::EraseGame) { - if (m_touchBar.GetPhase() != CFrontEndUITouchBar::EPhase::FileSelect) - HandleActiveChange(x20_tablegroup_fileselect); - - if (tbAction >= CFrontEndUITouchBar::EAction::FileA && tbAction <= CFrontEndUITouchBar::EAction::ImageGallery) { - x20_tablegroup_fileselect->SetUserSelection(int(tbAction) - int(CFrontEndUITouchBar::EAction::FileA)); - HandleActiveChange(x20_tablegroup_fileselect); - DoFileMenuAdvance(x20_tablegroup_fileselect); - } else if (tbAction == CFrontEndUITouchBar::EAction::Back) { - DoFileMenuCancel(x20_tablegroup_fileselect); - } - } else if (x8_subMenu == ESubMenu::EraseGamePopup) { - if (m_touchBar.GetPhase() != CFrontEndUITouchBar::EPhase::EraseBack) - HandleActiveChange(x40_tablegroup_popup); - - if (tbAction != CFrontEndUITouchBar::EAction::None) { - if (tbAction == CFrontEndUITouchBar::EAction::Confirm) - x40_tablegroup_popup->SetUserSelection(1); - else - x40_tablegroup_popup->SetUserSelection(0); - HandleActiveChange(x40_tablegroup_popup); - DoPopupAdvance(x40_tablegroup_popup); - } - } else if (x8_subMenu == ESubMenu::NewGamePopup) { - if (m_touchBar.GetPhase() != CFrontEndUITouchBar::EPhase::StartOptions) - HandleActiveChange(x40_tablegroup_popup); - - if (tbAction == CFrontEndUITouchBar::EAction::Back) { - DoPopupCancel(x40_tablegroup_popup); - } else if (tbAction != CFrontEndUITouchBar::EAction::None) { - if (tbAction == CFrontEndUITouchBar::EAction::Options) - x40_tablegroup_popup->SetUserSelection(1); - else if (tbAction == CFrontEndUITouchBar::EAction::Start || tbAction == CFrontEndUITouchBar::EAction::Hard) - x40_tablegroup_popup->SetUserSelection(0); - else if (tbAction == CFrontEndUITouchBar::EAction::Normal) - x40_tablegroup_popup->SetUserSelection(2); - HandleActiveChange(x40_tablegroup_popup); - DoPopupAdvance(x40_tablegroup_popup); - } - } } if (x10d_needsEraseToggle) { @@ -308,25 +268,6 @@ void CFrontEndUI::SNewFileSelectFrame::HandleActiveChange(CGuiTableGroup* active if (active == x20_tablegroup_fileselect) { x24_model_erase->SetLocalTransform(zeus::CTransform::Translate( zeus::CVector3f{0.f, 0.f, active->GetUserSelection() * x104_rowPitch} + xf8_model_erase_position)); - - /* Set Touch Bar contents here */ - std::array tbDetails{}; - for (size_t i = 0; i < tbDetails.size(); ++i) { - if (const CGameState::GameFileStateInfo* data = x4_saveUI->GetGameData(int(i))) { - tbDetails[i].state = - data->x20_hardMode ? CFrontEndUITouchBar::EFileState::Hard : CFrontEndUITouchBar::EFileState::Normal; - tbDetails[i].percent = data->x18_itemPercent; - } - } - m_touchBar.SetFileSelectPhase(tbDetails.data(), x8_subMenu == ESubMenu::EraseGame, - CSlideShow::SlideShowGalleryFlags()); - } else if (active == x40_tablegroup_popup) { - if (x8_subMenu == ESubMenu::EraseGamePopup) - m_touchBar.SetPhase(CFrontEndUITouchBar::EPhase::EraseBack); - else if (x8_subMenu == ESubMenu::NewGamePopup) - m_touchBar.SetStartOptionsPhase(g_GameState->SystemOptions().GetPlayerBeatNormalMode()); - else - m_touchBar.SetPhase(CFrontEndUITouchBar::EPhase::None); } if (x8_subMenu == ESubMenu::Root || x8_subMenu == ESubMenu::NewGamePopup) @@ -682,7 +623,6 @@ void CFrontEndUI::SNewFileSelectFrame::DoFileMenuAdvance(CGuiTableGroup* caller) } } else { if (x4_saveUI->GetGameData(userSel)) { - m_touchBar.SetPhase(CFrontEndUITouchBar::EPhase::None); x4_saveUI->StartGame(userSel); } else x10e_needsNewToggle = true; @@ -712,7 +652,7 @@ void CFrontEndUI::SNewFileSelectFrame::StartTextAnimating(CGuiTextPane* text, st text->TextSupport().SetTypeWriteEffectOptions(true, 0.1f, chRate); } -CFrontEndUI::SFusionBonusFrame::SFusionBonusFrame(CFrontEndUITouchBar& touchBar) : m_touchBar(touchBar) { +CFrontEndUI::SFusionBonusFrame::SFusionBonusFrame() { if (!g_Main->IsTrilogy()) { x4_gbaSupport = std::make_unique(); xc_gbaScreen = g_SimplePool->GetObj("FRME_GBAScreen"); @@ -830,8 +770,7 @@ void CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::SetUIText(EUIType tp) { } CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::EAction -CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::ProcessUserInput(const CFinalInput& input, bool linkInProgress, - CFrontEndUITouchBar::EAction tbAction) { +CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::ProcessUserInput(const CFinalInput& input, bool linkInProgress) { if (linkInProgress != x40_linkInProgress) { x40_linkInProgress = linkInProgress; SetUIText(x0_uiType); @@ -845,12 +784,10 @@ CFrontEndUI::SFusionBonusFrame::SGBALinkFrame::ProcessUserInput(const CFinalInpu case EUIType::LinkFailed: case EUIType::LinkCompleteOrLinking: case EUIType::TurnOffGBA: - if (input.PA() || input.PSpecialKey(aurora::SpecialKey::Enter) || input.PMouseButton(EMouseButton::Primary) || - tbAction == CFrontEndUITouchBar::EAction::Confirm) { + if (input.PA() || input.PSpecialKey(aurora::SpecialKey::Enter) || input.PMouseButton(EMouseButton::Primary)) { PlayAdvanceSfx(); SetUIText(NextLinkUI[size_t(x0_uiType)]); - } else if (input.PB() || input.PSpecialKey(aurora::SpecialKey::Esc) || - tbAction == CFrontEndUITouchBar::EAction::Back) { + } else if (input.PB() || input.PSpecialKey(aurora::SpecialKey::Esc)) { const EUIType prevUi = PrevLinkUI[size_t(x0_uiType)]; if (prevUi == EUIType::Empty) { break; @@ -1026,8 +963,7 @@ void CFrontEndUI::SFusionBonusFrame::Update(float dt, CSaveGameScreen* saveUI) { } CFrontEndUI::SFusionBonusFrame::EAction -CFrontEndUI::SFusionBonusFrame::ProcessUserInput(const CFinalInput& input, CSaveGameScreen* sui, - CFrontEndUITouchBar::EAction tbAction) { +CFrontEndUI::SFusionBonusFrame::ProcessUserInput(const CFinalInput& input, CSaveGameScreen* sui) { x8_action = EAction::None; if (sui) @@ -1035,10 +971,7 @@ CFrontEndUI::SFusionBonusFrame::ProcessUserInput(const CFinalInput& input, CSave if (x38_lastDoDraw) { if (x0_gbaLinkFrame) { - if (m_touchBar.GetPhase() != CFrontEndUITouchBar::EPhase::ProceedBack) - m_touchBar.SetPhase(CFrontEndUITouchBar::EPhase::ProceedBack); - - SGBALinkFrame::EAction action = x0_gbaLinkFrame->ProcessUserInput(input, sui, tbAction); + SGBALinkFrame::EAction action = x0_gbaLinkFrame->ProcessUserInput(input, sui); if (action != SGBALinkFrame::EAction::None) { x0_gbaLinkFrame.reset(); if (action == SGBALinkFrame::EAction::Complete) { @@ -1054,45 +987,7 @@ CFrontEndUI::SFusionBonusFrame::ProcessUserInput(const CFinalInput& input, CSave useInput.x2d_b28_PA = true; m_gbaOverride = true; } - - bool showFusionSuit = (g_GameState->SystemOptions().GetPlayerLinkedFusion() && - g_GameState->SystemOptions().GetPlayerBeatNormalMode()) || - m_gbaOverride; - if (m_touchBar.GetPhase() != CFrontEndUITouchBar::EPhase::FusionBonus) { - m_touchBar.SetFusionBonusPhase(showFusionSuit && g_GameState->SystemOptions().GetPlayerFusionSuitActive()); - } - x24_loadedFrame->ProcessUserInput(useInput); - - switch (tbAction) { - case CFrontEndUITouchBar::EAction::NESMetroid: - x28_tablegroup_options->SetUserSelection(0); - ResetCompletionFlags(); - SetTableColors(x28_tablegroup_options); - DoAdvance(x28_tablegroup_options); - break; - case CFrontEndUITouchBar::EAction::FusionSuit: - x28_tablegroup_options->SetUserSelection(1); - ResetCompletionFlags(); - SetTableColors(x28_tablegroup_options); - if (showFusionSuit) { - if (x2c_tablegroup_fusionsuit->GetUserSelection() == 1) { - x2c_tablegroup_fusionsuit->SetUserSelection(0); - DoSelectionChange(x2c_tablegroup_fusionsuit, 0); - } else { - x2c_tablegroup_fusionsuit->SetUserSelection(1); - DoSelectionChange(x2c_tablegroup_fusionsuit, 1); - } - } else { - DoAdvance(x28_tablegroup_options); - } - break; - case CFrontEndUITouchBar::EAction::Back: - DoCancel(x28_tablegroup_options); - break; - default: - break; - } } } @@ -1125,7 +1020,6 @@ void CFrontEndUI::SFusionBonusFrame::DoSelectionChange(CGuiTableGroup* caller, i bool fusionActive = x2c_tablegroup_fusionsuit->GetUserSelection() == 1; g_GameState->SystemOptions().SetPlayerFusionSuitActive(fusionActive); g_GameState->GetPlayerState()->SetIsFusionEnabled(fusionActive); - m_touchBar.SetFusionBonusPhase(g_GameState->SystemOptions().GetPlayerFusionSuitActive()); } SetTableColors(caller); } @@ -1256,38 +1150,9 @@ void CFrontEndUI::SFrontEndFrame::Update(float dt) { } CFrontEndUI::SFrontEndFrame::EAction -CFrontEndUI::SFrontEndFrame::ProcessUserInput(const CFinalInput& input, CFrontEndUITouchBar::EAction tbAction) { - if (m_touchBar.GetPhase() != CFrontEndUITouchBar::EPhase::NoCardSelect) - m_touchBar.SetNoCardSelectPhase(CSlideShow::SlideShowGalleryFlags()); - +CFrontEndUI::SFrontEndFrame::ProcessUserInput(const CFinalInput& input) { x4_action = EAction::None; x14_loadedFrme->ProcessUserInput(input); - - switch (tbAction) { - case CFrontEndUITouchBar::EAction::Start: - x18_tablegroup_mainmenu->SetUserSelection(0); - HandleActiveChange(x18_tablegroup_mainmenu); - DoAdvance(x18_tablegroup_mainmenu); - break; - case CFrontEndUITouchBar::EAction::FusionBonus: - x18_tablegroup_mainmenu->SetUserSelection(1); - HandleActiveChange(x18_tablegroup_mainmenu); - DoAdvance(x18_tablegroup_mainmenu); - break; - case CFrontEndUITouchBar::EAction::Options: - x18_tablegroup_mainmenu->SetUserSelection(2); - HandleActiveChange(x18_tablegroup_mainmenu); - DoAdvance(x18_tablegroup_mainmenu); - break; - case CFrontEndUITouchBar::EAction::ImageGallery: - x18_tablegroup_mainmenu->SetUserSelection(3); - HandleActiveChange(x18_tablegroup_mainmenu); - DoAdvance(x18_tablegroup_mainmenu); - break; - default: - break; - } - return x4_action; } @@ -1328,8 +1193,8 @@ void CFrontEndUI::SFrontEndFrame::DoAdvance(CGuiTableGroup* caller) { } } -CFrontEndUI::SFrontEndFrame::SFrontEndFrame(u32 rnd, CFrontEndUITouchBar& touchBar) -: x0_rnd(rnd), m_touchBar(touchBar) { +CFrontEndUI::SFrontEndFrame::SFrontEndFrame(u32 rnd) +: x0_rnd(rnd) { x8_frme = g_SimplePool->GetObj("FRME_FrontEndPL"); } @@ -1501,7 +1366,6 @@ void CFrontEndUI::SOptionsFrontEndFrame::DoSliderChange(CGuiSliderGroup* caller, const auto& optionCategory = GameOptionsRegistry[leftSel]; const SGameOption& option = optionCategory.second[rightSel]; CGameOptions::SetOption(option.option, caller->GetGurVal()); - m_touchBarValueDirty = true; } } @@ -1531,7 +1395,6 @@ void CFrontEndUI::SOptionsFrontEndFrame::DoMenuSelectionChange(CGuiTableGroup* c const auto& optionCategory = GameOptionsRegistry[leftSel]; const SGameOption& option = optionCategory.second[rightSel]; CGameOptions::SetOption(option.option, caller->GetUserSelection()); - m_touchBarValueDirty = true; CSfxManager::SfxStart(SFXfnt_enum_change, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); if (option.option == EGameOption::Rumble && caller->GetUserSelection() > 0) { @@ -1709,7 +1572,6 @@ bool CFrontEndUI::SOptionsFrontEndFrame::PumpLoad() { return false; x1c_loadedFrame = x4_frme.GetObj(); x20_loadedPauseStrg = x10_pauseScreen.GetObj(); - m_touchBar = NewGameOptionsTouchBar(); FinishedLoading(); return true; } @@ -1727,66 +1589,6 @@ bool CFrontEndUI::SOptionsFrontEndFrame::ProcessUserInput(const CFinalInput& inp int leftSel = x24_tablegroup_leftmenu->GetUserSelection(); int rightSel = x28_tablegroup_rightmenu->GetUserSelection(); CGameOptions::TryRestoreDefaults(input, leftSel, rightSel, true, false); - - CGameOptionsTouchBar::EAction tbAction = m_touchBar->PopAction(); - if (x28_tablegroup_rightmenu->GetIsActive()) { - if (tbAction == CGameOptionsTouchBar::EAction::Advance && !m_touchBarInValue) { - int value; - m_touchBar->GetSelection(leftSel, rightSel, value); - x28_tablegroup_rightmenu->SetUserSelection(rightSel); - SetTableColors(x28_tablegroup_rightmenu); - HandleRightSelectionChange(); - const auto& optionCategory = GameOptionsRegistry[leftSel]; - const SGameOption& option = optionCategory.second[rightSel]; - if (option.type != EOptionType::RestoreDefaults) { - m_touchBarInValue = true; - m_touchBarValueDirty = true; - } else { - CGameOptions::TryRestoreDefaults(input, leftSel, rightSel, true, true); - } - } else if (tbAction == CGameOptionsTouchBar::EAction::Back) { - if (m_touchBarInValue) - m_touchBarInValue = false; - else - DoMenuCancel(x28_tablegroup_rightmenu); - } else if (tbAction == CGameOptionsTouchBar::EAction::ValueChange) { - int value; - m_touchBar->GetSelection(leftSel, rightSel, value); - const auto& optionCategory = GameOptionsRegistry[leftSel]; - const SGameOption& option = optionCategory.second[rightSel]; - CGameOptions::SetOption(option.option, value); - if (option.type != EOptionType::Float) - m_touchBarValueDirty = true; - HandleRightSelectionChange(); - } else { - if (m_touchBarInValue) { - if (m_touchBarValueDirty) { - const auto& optionCategory = GameOptionsRegistry[leftSel]; - const SGameOption& option = optionCategory.second[rightSel]; - int value = CGameOptions::GetOption(option.option); - m_touchBar->SetSelection(leftSel, rightSel, value); - m_touchBarValueDirty = false; - } - } else { - m_touchBar->SetSelection(leftSel, -1, -1); - } - } - } else { - if (tbAction == CGameOptionsTouchBar::EAction::Advance) { - int value; - m_touchBar->GetSelection(leftSel, rightSel, value); - x24_tablegroup_leftmenu->SetUserSelection(leftSel); - SetTableColors(x24_tablegroup_leftmenu); - SetRightUIText(); - DoLeftMenuAdvance(x24_tablegroup_leftmenu); - } - if (tbAction == CGameOptionsTouchBar::EAction::Back) { - x134_25_exitOptions = true; - CSfxManager::SfxStart(SFXfnt_back, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); - } else { - m_touchBar->SetSelection(-1, -1, -1); - } - } } } return !x134_25_exitOptions; @@ -1841,9 +1643,6 @@ CFrontEndUI::CFrontEndUI() : CIOWin("FrontEndUI") { for (int i = 0; CDvdFile::FileExists(GetAttractMovieFileName(i)); ++i) ++xc0_attractCount; - - m_touchBar = NewFrontEndUITouchBar(); - m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); } CFrontEndUI::~CFrontEndUI() { @@ -2008,23 +1807,9 @@ void CFrontEndUI::Draw() { if (xec_emuFrme) { xec_emuFrme->Draw(xdc_saveUI.get()); } else { - // g_Renderer->SetDepthReadWrite(false, false); - g_Renderer->SetViewportOrtho(false, -4096.f, 4096.f); - - /* Correct movie aspect ratio */ - float hPad, vPad; - if (CGraphics::GetViewportAspect() >= 1.78f) { - hPad = 1.78f / CGraphics::GetViewportAspect(); - vPad = 1.78f / 1.33f; - } else { - hPad = 1.f; - vPad = CGraphics::GetViewportAspect() / 1.33f; - } - - if ((xcc_curMoviePtr != nullptr) && xcc_curMoviePtr->GetIsFullyCached()) { + if ((xcc_curMoviePtr != nullptr)) { /* Render movie */ - xcc_curMoviePtr->SetFrame(hPad, vPad); - xcc_curMoviePtr->DrawFrame(); + xcc_curMoviePtr->Draw(); } if (x50_curScreen == EScreen::FileSelect && x54_nextScreen == EScreen::FileSelect) { @@ -2042,14 +1827,15 @@ void CFrontEndUI::Draw() { if (x64_pressStartAlpha > 0.f && x38_pressStart.IsLoaded()) { /* Render "Press Start" */ - const zeus::CRectangle rect(0.5f - x38_pressStart->GetWidth() / 2.f / 640.f * hPad, - 0.5f + (x38_pressStart->GetHeight() / 2.f - 240.f + 72.f) / 480.f * vPad, - x38_pressStart->GetWidth() / 640.f * hPad, - x38_pressStart->GetHeight() / 480.f * vPad); - zeus::CColor color = zeus::skWhite; - color.a() = x64_pressStartAlpha; - aurora::gfx::queue_textured_quad(aurora::gfx::CameraFilterType::Add, x38_pressStart->GetTexture(), - aurora::gfx::ZComp::Always, false, color, 1.f, rect, 0.f); + // TODO fixme +// const zeus::CRectangle rect(0.5f - x38_pressStart->GetWidth() / 2.f / 640.f * hPad, +// 0.5f + (x38_pressStart->GetHeight() / 2.f - 240.f + 72.f) / 480.f * vPad, +// x38_pressStart->GetWidth() / 640.f * hPad, +// x38_pressStart->GetHeight() / 480.f * vPad); +// zeus::CColor color = zeus::skWhite; +// color.a() = x64_pressStartAlpha; +// aurora::gfx::queue_textured_quad(aurora::gfx::CameraFilterType::Add, x38_pressStart->GetTexture(), +// aurora::gfx::ZComp::Always, false, color, 1.f, rect, 0.f); } if (xc0_attractCount > 0) { @@ -2189,14 +1975,10 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue& if (x14_phase != EPhase::DisplayFrontEnd || input.ControllerIdx() != 0) return; - /* Pop most recent action from Touch Bar */ - CFrontEndUITouchBar::EAction touchBarAction = m_touchBar->PopAction(); - if (x50_curScreen != x54_nextScreen) { if (x54_nextScreen == EScreen::AttractMovie && (input.PStart() || input.PA() || input.PSpecialKey(aurora::SpecialKey::Esc) || - input.PSpecialKey(aurora::SpecialKey::Enter) || input.PMouseButton(EMouseButton::Primary) || - touchBarAction == CFrontEndUITouchBar::EAction::Start)) { + input.PSpecialKey(aurora::SpecialKey::Enter) || input.PMouseButton(EMouseButton::Primary))) { /* Player wants to return to opening credits from attract movie */ SetFadeBlackTimer(std::min(1.f, x58_fadeBlackTimer)); PlayAdvanceSfx(); @@ -2204,8 +1986,7 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue& } if (input.PA() || input.PStart() || input.PSpecialKey(aurora::SpecialKey::Esc) || - input.PSpecialKey(aurora::SpecialKey::Enter) || input.PMouseButton(EMouseButton::Primary) || - touchBarAction == CFrontEndUITouchBar::EAction::Start) { + input.PSpecialKey(aurora::SpecialKey::Enter) || input.PMouseButton(EMouseButton::Primary)) { if (x50_curScreen == EScreen::OpenCredits && x54_nextScreen == EScreen::Title && x58_fadeBlackTimer > 1.f) { /* Player is too impatient to view opening credits */ xd0_playerSkipToTitle = true; @@ -2216,13 +1997,11 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue& } else { if (x50_curScreen == EScreen::Title) { if (input.PStart() || input.PA() || input.PSpecialKey(aurora::SpecialKey::Esc) || - input.PSpecialKey(aurora::SpecialKey::Enter) || input.PMouseButton(EMouseButton::Primary) || - touchBarAction == CFrontEndUITouchBar::EAction::Start) { + input.PSpecialKey(aurora::SpecialKey::Enter) || input.PMouseButton(EMouseButton::Primary)) { if (x58_fadeBlackTimer < 30.f - g_tweakGame->GetPressStartDelay()) { /* Proceed to file select UI */ CSfxManager::SfxStart(FETransitionBackSFX[x18_rndA][0], 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); CSfxManager::SfxStart(FETransitionBackSFX[x18_rndA][1], 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); - m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); StartStateTransition(EScreen::FileSelect); return; } @@ -2233,22 +2012,18 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue& if (xf0_optionsFrme->ProcessUserInput(input, xdc_saveUI.get())) return; /* Exit options UI */ - m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); xf0_optionsFrme.reset(); return; } else if (xe0_frontendCardFrme) { /* Control FrontEnd with memory card */ - switch (xe0_frontendCardFrme->ProcessUserInput(input, touchBarAction)) { + switch (xe0_frontendCardFrme->ProcessUserInput(input)) { case SNewFileSelectFrame::EAction::FusionBonus: - m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); StartStateTransition(EScreen::FusionBonus); return; case SNewFileSelectFrame::EAction::GameOptions: - m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); xf0_optionsFrme = std::make_unique(); return; case SNewFileSelectFrame::EAction::SlideShow: - m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); xd2_deferSlideShow = true; StartSlideShow(queue); return; @@ -2257,20 +2032,17 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue& } } else { /* Control FrontEnd without memory card */ - switch (xe8_frontendNoCardFrme->ProcessUserInput(input, touchBarAction)) { + switch (xe8_frontendNoCardFrme->ProcessUserInput(input)) { case SFrontEndFrame::EAction::FusionBonus: - m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); StartStateTransition(EScreen::FusionBonus); return; case SFrontEndFrame::EAction::GameOptions: - m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); xf0_optionsFrme = std::make_unique(); return; case SFrontEndFrame::EAction::StartGame: TransitionToGame(); return; case SFrontEndFrame::EAction::SlideShow: - m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); xd2_deferSlideShow = true; StartSlideShow(queue); return; @@ -2280,13 +2052,11 @@ void CFrontEndUI::ProcessUserInput(const CFinalInput& input, CArchitectureQueue& } } else if (x50_curScreen == EScreen::FusionBonus && x54_nextScreen == EScreen::FusionBonus) { /* Control Fusion bonus UI */ - switch (xe4_fusionBonusFrme->ProcessUserInput(input, xdc_saveUI.get(), touchBarAction)) { + switch (xe4_fusionBonusFrme->ProcessUserInput(input, xdc_saveUI.get())) { case SFusionBonusFrame::EAction::GoBack: - m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); StartStateTransition(EScreen::FileSelect); return; case SFusionBonusFrame::EAction::PlayNESMetroid: - m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); xf4_curAudio->StopMixing(); xec_emuFrme = std::make_unique(); if (xdc_saveUI) @@ -2309,7 +2079,6 @@ void CFrontEndUI::TransitionToGame() { CSfxManager::SfxStart(sfx[1], 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); x14_phase = EPhase::ToPlayGame; - m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None); StartStateTransition(EScreen::ToPlayGame); } @@ -2355,11 +2124,11 @@ CIOWin::EMessageReturn CFrontEndUI::Update(float dt, CArchitectureQueue& queue) case EPhase::LoadDeps: /* Poll loading DGRP resources */ if (PumpLoad()) { - xe0_frontendCardFrme = std::make_unique(xdc_saveUI.get(), x1c_rndB, *m_touchBar); + xe0_frontendCardFrme = std::make_unique(xdc_saveUI.get(), x1c_rndB); if (!g_Main->IsTrilogy()) { - xe4_fusionBonusFrme = std::make_unique(*m_touchBar); + xe4_fusionBonusFrme = std::make_unique(); } - xe8_frontendNoCardFrme = std::make_unique(x1c_rndB, *m_touchBar); + xe8_frontendNoCardFrme = std::make_unique(x1c_rndB); x38_pressStart.GetObj(); CAudioSys::AddAudioGroup(x44_frontendAudioGrp->GetAudioGroupData()); xd4_audio1 = std::make_unique("Audio/frontend_1.rsf", 416480, 1973664); @@ -2403,7 +2172,6 @@ CIOWin::EMessageReturn CFrontEndUI::Update(float dt, CArchitectureQueue& queue) if (moviesReady) { /* Ready to display FrontEnd */ x14_phase = EPhase::DisplayFrontEnd; - m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::PressStart); StartStateTransition(EScreen::Title); } else { return EMessageReturn::Exit; diff --git a/Runtime/MP1/CFrontEndUI.hpp b/Runtime/MP1/CFrontEndUI.hpp index c0c3a9402..37ca381c7 100644 --- a/Runtime/MP1/CFrontEndUI.hpp +++ b/Runtime/MP1/CFrontEndUI.hpp @@ -5,7 +5,6 @@ #include #include "Runtime/CGameDebug.hpp" -#include "Runtime/CGameOptionsTouchBar.hpp" #include "Runtime/CIOWin.hpp" #include "Runtime/CToken.hpp" #include "Runtime/RetroTypes.hpp" @@ -16,7 +15,6 @@ #include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp" #include "Runtime/GuiSys/CGuiTextSupport.hpp" #include "Runtime/Input/CRumbleGenerator.hpp" -#include "Runtime/MP1/CFrontEndUITouchBar.hpp" #include "Runtime/MP1/CGBASupport.hpp" #include @@ -110,14 +108,12 @@ public: bool x10d_needsEraseToggle = false; bool x10e_needsNewToggle = false; - CFrontEndUITouchBar& m_touchBar; - - SNewFileSelectFrame(CSaveGameScreen* sui, u32 rnd, CFrontEndUITouchBar& touchBar); + SNewFileSelectFrame(CSaveGameScreen* sui, u32 rnd); void FinishedLoading(); bool PumpLoad(); bool IsTextDoneAnimating() const; void Update(float dt); - EAction ProcessUserInput(const CFinalInput& input, CFrontEndUITouchBar::EAction tbAction); + EAction ProcessUserInput(const CFinalInput& input); void Draw() const; void HandleActiveChange(CGuiTableGroup* active); @@ -177,7 +173,7 @@ public: bool x40_linkInProgress; void SetUIText(EUIType tp); - EAction ProcessUserInput(const CFinalInput& input, bool linkInProgress, CFrontEndUITouchBar::EAction tbAction); + EAction ProcessUserInput(const CFinalInput& input, bool linkInProgress); void Update(float dt); void FinishedLoading(); void Draw(); @@ -199,16 +195,14 @@ public: bool x39_fusionNotComplete = false; bool x3a_mpNotComplete = false; - CFrontEndUITouchBar& m_touchBar; - bool m_gbaOverride = false; - explicit SFusionBonusFrame(CFrontEndUITouchBar& touchBar); + explicit SFusionBonusFrame(); void FinishedLoading(); bool PumpLoad(); void SetTableColors(CGuiTableGroup* tbgp) const; void Update(float dt, CSaveGameScreen* saveUI); - EAction ProcessUserInput(const CFinalInput& input, CSaveGameScreen* sui, CFrontEndUITouchBar::EAction tbAction); + EAction ProcessUserInput(const CFinalInput& input, CSaveGameScreen* sui); void Draw() const; void ResetCompletionFlags() { @@ -232,13 +226,11 @@ public: SGuiTextPair x1c_gbaPair; SGuiTextPair x24_cheatPair; - CFrontEndUITouchBar& m_touchBar; - - SFrontEndFrame(u32 rnd, CFrontEndUITouchBar& touchBar); + SFrontEndFrame(u32 rnd); void FinishedLoading(); bool PumpLoad(); void Update(float dt); - EAction ProcessUserInput(const CFinalInput& input, CFrontEndUITouchBar::EAction tbAction); + EAction ProcessUserInput(const CFinalInput& input); void Draw() const; void HandleActiveChange(CGuiTableGroup* active); @@ -282,10 +274,6 @@ public: bool x134_24_visible : 1 = true; bool x134_25_exitOptions : 1 = false; - std::unique_ptr m_touchBar; - bool m_touchBarInValue = false; - bool m_touchBarValueDirty = false; - SOptionsFrontEndFrame(); void DoSliderChange(CGuiSliderGroup* caller, float value); @@ -349,10 +337,6 @@ private: std::unique_ptr xf0_optionsFrme; CStaticAudioPlayer* xf4_curAudio = nullptr; - CColoredQuadFilter m_fadeToBlack{EFilterType::Blend}; - - std::unique_ptr m_touchBar; - void SetFadeBlackWithMovie() { x58_fadeBlackTimer = 1000000.f; x5c_fadeBlackWithMovie = true; @@ -370,7 +354,7 @@ private: public: CFrontEndUI(); - ~CFrontEndUI(); + ~CFrontEndUI() override; void StartSlideShow(CArchitectureQueue& queue); std::string GetAttractMovieFileName(int idx); std::string GetNextAttractMovieFileName(); diff --git a/Runtime/MP1/CFrontEndUITouchBar.cpp b/Runtime/MP1/CFrontEndUITouchBar.cpp deleted file mode 100644 index 41510d87b..000000000 --- a/Runtime/MP1/CFrontEndUITouchBar.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "Runtime/MP1/CFrontEndUITouchBar.hpp" - -namespace metaforce { - -CFrontEndUITouchBar::~CFrontEndUITouchBar() = default; -void CFrontEndUITouchBar::SetPhase(EPhase ph) { m_phase = ph; } -CFrontEndUITouchBar::EPhase CFrontEndUITouchBar::GetPhase() { return m_phase; } -void CFrontEndUITouchBar::SetFileSelectPhase(const SFileSelectDetail details[3], bool eraseGame, bool galleryActive) { - m_phase = EPhase::FileSelect; -} -void CFrontEndUITouchBar::SetNoCardSelectPhase(bool galleryActive) { m_phase = EPhase::NoCardSelect; } -void CFrontEndUITouchBar::SetFusionBonusPhase(bool fusionSuitActive) { m_phase = EPhase::FusionBonus; } -void CFrontEndUITouchBar::SetStartOptionsPhase(bool normalBeat) { m_phase = EPhase::StartOptions; } -CFrontEndUITouchBar::EAction CFrontEndUITouchBar::PopAction() { return EAction::None; } - -//#ifndef __APPLE__ -std::unique_ptr NewFrontEndUITouchBar() { return std::make_unique(); } -//#endif - -} // namespace metaforce diff --git a/Runtime/MP1/CFrontEndUITouchBar.hpp b/Runtime/MP1/CFrontEndUITouchBar.hpp deleted file mode 100644 index 58cb3df45..000000000 --- a/Runtime/MP1/CFrontEndUITouchBar.hpp +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include - -namespace metaforce { - -class CFrontEndUITouchBar { -public: - enum class EPhase { None, PressStart, ProceedBack, StartOptions, EraseBack, FileSelect, NoCardSelect, FusionBonus }; - enum class EAction { - None, - Start, - Normal, - Hard, - Back, - Confirm, - Options, - FileA, - FileB, - FileC, - Erase, - FusionBonus, - ImageGallery, - NESMetroid, - FusionSuit - }; - enum class EFileState { New, Normal, Hard }; - struct SFileSelectDetail { - EFileState state; - int percent; - }; - -protected: - EPhase m_phase = EPhase::None; - -public: - virtual ~CFrontEndUITouchBar(); - virtual void SetPhase(EPhase ph); - virtual EPhase GetPhase(); - virtual void SetFileSelectPhase(const SFileSelectDetail details[3], bool eraseGame, bool galleryActive); - virtual void SetNoCardSelectPhase(bool galleryActive); - virtual void SetFusionBonusPhase(bool fusionSuitActive); - virtual void SetStartOptionsPhase(bool normalBeat); - virtual EAction PopAction(); -}; - -std::unique_ptr NewFrontEndUITouchBar(); - -} // namespace metaforce diff --git a/Runtime/MP1/CFrontEndUITouchBarMac.mm b/Runtime/MP1/CFrontEndUITouchBarMac.mm deleted file mode 100644 index 4015dcbd9..000000000 --- a/Runtime/MP1/CFrontEndUITouchBarMac.mm +++ /dev/null @@ -1,667 +0,0 @@ -#include "CFrontEndUITouchBar.hpp" -#include "GameGlobalObjects.hpp" -#include "MP1/MP1.hpp" -#include - -#if !__has_feature(objc_arc) -#error ARC Required -#endif - -extern "C" uint8_t START_BUTTON_2X[]; -extern "C" size_t START_BUTTON_2X_SZ; - -static NSColor *BlueConfirm() { - return [NSColor colorWithSRGBRed:0 / 255.f green:130 / 255.f blue:215 / 255.f alpha:1.f]; -} - -static NSColor *NormalModeColor() { - return [NSColor colorWithSRGBRed:0 / 255.f green:130 / 255.f blue:0 / 255.f alpha:1.f]; -} - -static NSColor *HardModeColor() { return [NSColor redColor]; } - -static NSColor *FileColor(const metaforce::CFrontEndUITouchBar::SFileSelectDetail &detail) { - switch (detail.state) { - case metaforce::CFrontEndUITouchBar::EFileState::New: - return [NSColor darkGrayColor]; - case metaforce::CFrontEndUITouchBar::EFileState::Normal: - return NormalModeColor(); - case metaforce::CFrontEndUITouchBar::EFileState::Hard: - return HardModeColor(); - } -} - -@interface FrontEndUITouchBarPressStart : NSObject { -@public - BOOL _startPressed; -} -- (IBAction)onPressStart:(id)sender; -@end - -@implementation FrontEndUITouchBarPressStart -- (NSTouchBar *)makeTouchBar { - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items = @[ @"pressStartGroup" ]; - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - touchBar.principalItemIdentifier = @"pressStartGroup"; - return touchBar; -} -- (NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier { - if ([identifier isEqualToString:@"pressStartGroup"]) { - NSGroupTouchBarItem *item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items = @[ @"pressStart" ]; - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - item.groupTouchBar = touchBar; - return item; - } else if ([identifier isEqualToString:@"pressStart"]) { - NSData *imgData = [NSData dataWithBytesNoCopy:START_BUTTON_2X length:START_BUTTON_2X_SZ freeWhenDone:NO]; - NSImage *img = [[NSImage alloc] initWithData:imgData]; - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:@"Start" image:img target:self action:@selector(onPressStart:)]; - button.imageHugsTitle = YES; - item.view = button; - return item; - } - return nil; -} -- (IBAction)onPressStart:(id)sender { - _startPressed = YES; -} -@end - -@interface FrontEndUITouchBarProceedBack : NSObject { -@public - metaforce::CFrontEndUITouchBar::EAction _action; -} -- (IBAction)onBack:(id)sender; -- (IBAction)onProceed:(id)sender; -@end - -@implementation FrontEndUITouchBarProceedBack -- (NSTouchBar *)makeTouchBar { - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items = @[ @"proceedBackGroup" ]; - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - touchBar.principalItemIdentifier = @"proceedBackGroup"; - return touchBar; -} -- (NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier { - if ([identifier isEqualToString:@"proceedBackGroup"]) { - NSGroupTouchBarItem *item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items = @[ @"back", @"proceed" ]; - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - item.groupTouchBar = touchBar; - return item; - } else if ([identifier isEqualToString:@"back"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithImage:[NSImage imageNamed:NSImageNameTouchBarGoBackTemplate] - target:self - action:@selector(onBack:)]; - item.view = button; - return item; - } else if ([identifier isEqualToString:@"proceed"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithImage:[NSImage imageNamed:NSImageNameTouchBarGoForwardTemplate] - target:self - action:@selector(onProceed:)]; - item.view = button; - return item; - } - return nil; -} -- (IBAction)onBack:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::Back; -} -- (IBAction)onProceed:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::Confirm; -} -@end - -@interface FrontEndUITouchBarStartOptions : NSObject { -@public - metaforce::CFrontEndUITouchBar::EAction _action; - BOOL _normalBeat; -} -- (IBAction)onStart:(id)sender; -- (IBAction)onNormal:(id)sender; -- (IBAction)onHard:(id)sender; -- (IBAction)onOptions:(id)sender; -- (IBAction)onCancel:(id)sender; -@end - -@implementation FrontEndUITouchBarStartOptions -- (NSTouchBar *)makeTouchBar { - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items = @[ @"startOptionsGroup" ]; - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - touchBar.principalItemIdentifier = @"startOptionsGroup"; - return touchBar; -} -- (NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier { - if ([identifier isEqualToString:@"startOptionsGroup"]) { - NSGroupTouchBarItem *item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items = _normalBeat ? @[ @"cancel", @"normal", @"hard", @"options" ] : @[ @"cancel", @"start", @"options" ]; - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - item.groupTouchBar = touchBar; - return item; - } else if ([identifier isEqualToString:@"start"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:@"Start" target:self action:@selector(onStart:)]; - button.bezelColor = BlueConfirm(); - item.view = button; - return item; - } else if ([identifier isEqualToString:@"normal"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:@"Normal Mode" target:self action:@selector(onNormal:)]; - button.bezelColor = NormalModeColor(); - item.view = button; - return item; - } else if ([identifier isEqualToString:@"hard"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:@"Hard Mode" target:self action:@selector(onHard:)]; - button.bezelColor = HardModeColor(); - item.view = button; - return item; - } else if ([identifier isEqualToString:@"options"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:@"Options" target:self action:@selector(onOptions:)]; - item.view = button; - return item; - } else if ([identifier isEqualToString:@"cancel"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithImage:[NSImage imageNamed:NSImageNameTouchBarGoBackTemplate] - target:self - action:@selector(onCancel:)]; - item.view = button; - return item; - } - return nil; -} -- (IBAction)onStart:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::Start; -} -- (IBAction)onNormal:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::Normal; -} -- (IBAction)onHard:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::Hard; -} -- (IBAction)onOptions:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::Options; -} -- (IBAction)onCancel:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::Back; -} -@end - -@interface FrontEndUITouchBarEraseBack : NSObject { -@public - metaforce::CFrontEndUITouchBar::EAction _action; -} -- (IBAction)onCancel:(id)sender; -- (IBAction)onErase:(id)sender; -@end - -@implementation FrontEndUITouchBarEraseBack -- (NSTouchBar *)makeTouchBar { - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items = @[ @"eraseBackGroup" ]; - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - touchBar.principalItemIdentifier = @"eraseBackGroup"; - return touchBar; -} -- (NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier { - if ([identifier isEqualToString:@"eraseBackGroup"]) { - NSGroupTouchBarItem *item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items = @[ @"cancel", @"erase" ]; - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - item.groupTouchBar = touchBar; - return item; - } else if ([identifier isEqualToString:@"cancel"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:@"Cancel" target:self action:@selector(onCancel:)]; - item.view = button; - return item; - } else if ([identifier isEqualToString:@"erase"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:@"Erase" target:self action:@selector(onErase:)]; - button.bezelColor = [NSColor redColor]; - item.view = button; - return item; - } - return nil; -} -- (IBAction)onCancel:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::Back; -} -- (IBAction)onErase:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::Confirm; -} -@end - -static NSString *GetFileSelectTitle(const metaforce::CFrontEndUITouchBar::SFileSelectDetail &detail, char letter) { - switch (detail.state) { - case metaforce::CFrontEndUITouchBar::EFileState::New: - return [NSString stringWithFormat:@"[New Game %c]", letter]; - case metaforce::CFrontEndUITouchBar::EFileState::Normal: - return [NSString stringWithFormat:@"[Samus %c] %d%%", letter, detail.percent]; - case metaforce::CFrontEndUITouchBar::EFileState::Hard: - return [NSString stringWithFormat:@"[Hard %c] %d%%", letter, detail.percent]; - } - return @""; -} - -@interface FrontEndUITouchBarFileSelect : NSObject { -@public - metaforce::CFrontEndUITouchBar::SFileSelectDetail _details[3]; - metaforce::CFrontEndUITouchBar::EAction _action; - BOOL _eraseGame; - BOOL _galleryActive; -} -- (IBAction)onFileA:(id)sender; -- (IBAction)onFileB:(id)sender; -- (IBAction)onFileC:(id)sender; -- (IBAction)onErase:(id)sender; -- (IBAction)onFusionBonus:(id)sender; -- (IBAction)onImageGallery:(id)sender; -@end - -@implementation FrontEndUITouchBarFileSelect -- (NSTouchBar *)makeTouchBar { - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items = @[ @"fileSelectGroup" ]; - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - touchBar.principalItemIdentifier = @"fileSelectGroup"; - return touchBar; -} -- (NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier { - if ([identifier isEqualToString:@"fileSelectGroup"]) { - NSGroupTouchBarItem *item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items = @[ @"fileA", @"fileB", @"fileC", @"erase", @"fusionBonus", @"imageGallery" ]; - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - item.groupTouchBar = touchBar; - return item; - } else if ([identifier isEqualToString:@"fileA"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:GetFileSelectTitle(_details[0], 'A') - target:self - action:@selector(onFileA:)]; - button.bezelColor = FileColor(_details[0]); - button.enabled = !_eraseGame || _details[0].state != metaforce::CFrontEndUITouchBar::EFileState::New; - item.view = button; - return item; - } else if ([identifier isEqualToString:@"fileB"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:GetFileSelectTitle(_details[1], 'B') - target:self - action:@selector(onFileB:)]; - button.bezelColor = FileColor(_details[1]); - button.enabled = !_eraseGame || _details[1].state != metaforce::CFrontEndUITouchBar::EFileState::New; - item.view = button; - return item; - } else if ([identifier isEqualToString:@"fileC"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:GetFileSelectTitle(_details[2], 'C') - target:self - action:@selector(onFileC:)]; - button.bezelColor = FileColor(_details[2]); - button.enabled = !_eraseGame || _details[2].state != metaforce::CFrontEndUITouchBar::EFileState::New; - item.view = button; - return item; - } else if ([identifier isEqualToString:@"erase"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - if (!_eraseGame) { - NSButton *button = [NSButton buttonWithImage:[NSImage imageNamed:NSImageNameTouchBarDeleteTemplate] - target:self - action:@selector(onErase:)]; - bool hasSave = false; - for (int i = 0; i < 3; ++i) - if (_details[i].state != metaforce::CFrontEndUITouchBar::EFileState::New) { - hasSave = true; - break; - } - button.enabled = hasSave; - item.view = button; - } else { - NSButton *button = [NSButton buttonWithImage:[NSImage imageNamed:NSImageNameTouchBarGoBackTemplate] - target:self - action:@selector(onErase:)]; - item.view = button; - } - return item; - } else if ([identifier isEqualToString:@"fusionBonus"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:@"Bonuses" target:self action:@selector(onFusionBonus:)]; - button.enabled = !_eraseGame; - item.view = button; - return item; - } else if ([identifier isEqualToString:@"imageGallery"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:@"Gallery" target:self action:@selector(onImageGallery:)]; - button.enabled = !_eraseGame && _galleryActive; - item.view = button; - return item; - } - return nil; -} -- (IBAction)onFileA:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::FileA; -} -- (IBAction)onFileB:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::FileB; -} -- (IBAction)onFileC:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::FileC; -} -- (IBAction)onErase:(id)sender { - if (!_eraseGame) - _action = metaforce::CFrontEndUITouchBar::EAction::Erase; - else - _action = metaforce::CFrontEndUITouchBar::EAction::Back; -} -- (IBAction)onFusionBonus:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::FusionBonus; -} -- (IBAction)onImageGallery:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::ImageGallery; -} -@end - -@interface FrontEndUITouchBarNoCardSelect : NSObject { -@public - metaforce::CFrontEndUITouchBar::EAction _action; - BOOL _galleryActive; -} -- (IBAction)onStart:(id)sender; -- (IBAction)onOptions:(id)sender; -- (IBAction)onFusionBonus:(id)sender; -- (IBAction)onImageGallery:(id)sender; -@end - -@implementation FrontEndUITouchBarNoCardSelect -- (NSTouchBar *)makeTouchBar { - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items = @[ @"noCardSelectGroup" ]; - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - touchBar.principalItemIdentifier = @"noCardSelectGroup"; - return touchBar; -} -- (NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier { - if ([identifier isEqualToString:@"noCardSelectGroup"]) { - NSGroupTouchBarItem *item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items = @[ @"start", @"fusionBonus", @"options", @"imageGallery" ]; - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - item.groupTouchBar = touchBar; - return item; - } else if ([identifier isEqualToString:@"start"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:@"Start" target:self action:@selector(onStart:)]; - button.bezelColor = BlueConfirm(); - item.view = button; - return item; - } else if ([identifier isEqualToString:@"options"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:@"Options" target:self action:@selector(onOptions:)]; - item.view = button; - return item; - } else if ([identifier isEqualToString:@"fusionBonus"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:@"Fusion Bonuses" target:self action:@selector(onFusionBonus:)]; - item.view = button; - return item; - } else if ([identifier isEqualToString:@"imageGallery"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:@"Image Gallery" target:self action:@selector(onImageGallery:)]; - button.enabled = _galleryActive; - item.view = button; - return item; - } - return nil; -} -- (IBAction)onStart:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::Start; -} -- (IBAction)onOptions:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::Options; -} -- (IBAction)onFusionBonus:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::FusionBonus; -} -- (IBAction)onImageGallery:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::ImageGallery; -} -@end - -@interface FrontEndUITouchBarFusionBonus : NSObject { -@public - metaforce::CFrontEndUITouchBar::EAction _action; - BOOL _fusionSuitActive; -} -- (IBAction)onNESMetroid:(id)sender; -- (IBAction)onFusionSuit:(id)sender; -- (IBAction)onBack:(id)sender; -@end - -@implementation FrontEndUITouchBarFusionBonus -- (NSTouchBar *)makeTouchBar { - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items = @[ @"fusionBonusGroup" ]; - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - touchBar.principalItemIdentifier = @"fusionBonusGroup"; - return touchBar; -} -- (NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier { - if ([identifier isEqualToString:@"fusionBonusGroup"]) { - NSGroupTouchBarItem *item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items = @[ @"back", @"NESMetroid", @"fusionSuit" ]; - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - item.groupTouchBar = touchBar; - return item; - } else if ([identifier isEqualToString:@"NESMetroid"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:@"Play NES Metroid" target:self action:@selector(onNESMetroid:)]; - item.view = button; - return item; - } else if ([identifier isEqualToString:@"fusionSuit"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:@"Fusion Suit" target:self action:@selector(onFusionSuit:)]; - if (_fusionSuitActive) - button.bezelColor = BlueConfirm(); - item.view = button; - return item; - } else if ([identifier isEqualToString:@"back"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithImage:[NSImage imageNamed:NSImageNameTouchBarGoBackTemplate] - target:self - action:@selector(onBack:)]; - item.view = button; - return item; - } - return nil; -} -- (IBAction)onNESMetroid:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::NESMetroid; -} -- (IBAction)onFusionSuit:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::FusionSuit; -} -- (IBAction)onBack:(id)sender { - _action = metaforce::CFrontEndUITouchBar::EAction::Back; -} -@end - -namespace metaforce { - -class CFrontEndUITouchBarMac : public CFrontEndUITouchBar { - FrontEndUITouchBarPressStart *m_pressStartBar; - FrontEndUITouchBarProceedBack *m_proceedBackBar; - FrontEndUITouchBarStartOptions *m_startOptions; - FrontEndUITouchBarEraseBack *m_eraseBack; - FrontEndUITouchBarFileSelect *m_fileSelectBar; - FrontEndUITouchBarNoCardSelect *m_noCardSelectBar; - FrontEndUITouchBarFusionBonus *m_fusionBonusBar; - - void Activate() { - id provider = nil; - switch (m_phase) { - case EPhase::PressStart: - provider = m_pressStartBar; - break; - case EPhase::ProceedBack: - provider = m_proceedBackBar; - break; - case EPhase::StartOptions: - provider = m_startOptions; - break; - case EPhase::EraseBack: - provider = m_eraseBack; - break; - case EPhase::FileSelect: - provider = m_fileSelectBar; - break; - case EPhase::NoCardSelect: - provider = m_noCardSelectBar; - break; - case EPhase::FusionBonus: - provider = m_fusionBonusBar; - break; - default: - break; - } - g_Main->GetMainWindow()->setTouchBarProvider((__bridge_retained void *)provider); - } - -public: - CFrontEndUITouchBarMac() { - m_pressStartBar = [FrontEndUITouchBarPressStart new]; - m_proceedBackBar = [FrontEndUITouchBarProceedBack new]; - m_startOptions = [FrontEndUITouchBarStartOptions new]; - m_eraseBack = [FrontEndUITouchBarEraseBack new]; - m_fileSelectBar = [FrontEndUITouchBarFileSelect new]; - m_noCardSelectBar = [FrontEndUITouchBarNoCardSelect new]; - m_fusionBonusBar = [FrontEndUITouchBarFusionBonus new]; - } - void SetPhase(EPhase ph) { - m_phase = ph; - Activate(); - } - EPhase GetPhase() { return m_phase; } - void SetFileSelectPhase(const SFileSelectDetail details[3], bool eraseGame, bool galleryActive) { - m_fileSelectBar->_details[0] = details[0]; - m_fileSelectBar->_details[1] = details[1]; - m_fileSelectBar->_details[2] = details[2]; - m_fileSelectBar->_eraseGame = eraseGame; - m_fileSelectBar->_galleryActive = galleryActive; - m_phase = EPhase::FileSelect; - Activate(); - } - void SetNoCardSelectPhase(bool galleryActive) { - m_noCardSelectBar->_galleryActive = galleryActive; - m_phase = EPhase::NoCardSelect; - Activate(); - } - void SetFusionBonusPhase(bool fusionSuitActive) { - m_fusionBonusBar->_fusionSuitActive = fusionSuitActive; - m_phase = EPhase::FusionBonus; - Activate(); - } - void SetStartOptionsPhase(bool normalBeat) { - m_startOptions->_normalBeat = normalBeat; - m_phase = EPhase::StartOptions; - Activate(); - } - EAction PopAction() { - switch (m_phase) { - case EPhase::PressStart: - if (m_pressStartBar->_startPressed) { - m_pressStartBar->_startPressed = NO; - return EAction::Start; - } - break; - case EPhase::ProceedBack: - if (m_proceedBackBar->_action != EAction::None) { - EAction action = m_proceedBackBar->_action; - m_proceedBackBar->_action = EAction::None; - return action; - } - break; - case EPhase::StartOptions: - if (m_startOptions->_action != EAction::None) { - EAction action = m_startOptions->_action; - m_startOptions->_action = EAction::None; - return action; - } - break; - case EPhase::EraseBack: - if (m_eraseBack->_action != EAction::None) { - EAction action = m_eraseBack->_action; - m_eraseBack->_action = EAction::None; - return action; - } - break; - case EPhase::FileSelect: - if (m_fileSelectBar->_action != EAction::None) { - EAction action = m_fileSelectBar->_action; - m_fileSelectBar->_action = EAction::None; - return action; - } - break; - case EPhase::NoCardSelect: - if (m_noCardSelectBar->_action != EAction::None) { - EAction action = m_noCardSelectBar->_action; - m_noCardSelectBar->_action = EAction::None; - return action; - } - break; - case EPhase::FusionBonus: - if (m_fusionBonusBar->_action != EAction::None) { - EAction action = m_fusionBonusBar->_action; - m_fusionBonusBar->_action = EAction::None; - return action; - } - break; - default: - break; - } - return EAction::None; - } -}; - -std::unique_ptr NewFrontEndUITouchBar() { return std::make_unique(); } - -} diff --git a/Runtime/MP1/CMakeLists.txt b/Runtime/MP1/CMakeLists.txt index e43c01e42..a2d7cb6e2 100644 --- a/Runtime/MP1/CMakeLists.txt +++ b/Runtime/MP1/CMakeLists.txt @@ -1,11 +1,5 @@ add_subdirectory(World) -#if (APPLE) -# set(MP1_PLAT_SOURCES -# CFrontEndUITouchBarMac.mm -# CSaveGameScreenTouchBarMac.mm) -#endif () - set(MP1_SOURCES Tweaks/CTweakAutoMapper.hpp Tweaks/CTweakAutoMapper.cpp Tweaks/CTweakBall.hpp Tweaks/CTweakBall.cpp @@ -27,11 +21,9 @@ set(MP1_SOURCES CMFGame.hpp CMFGame.cpp CPlayMovie.hpp CPlayMovie.cpp CFrontEndUI.hpp CFrontEndUI.cpp - CFrontEndUITouchBar.hpp CFrontEndUITouchBar.cpp CPreFrontEnd.hpp CPreFrontEnd.cpp CSlideShow.hpp CSlideShow.cpp CSaveGameScreen.hpp CSaveGameScreen.cpp - CSaveGameScreenTouchBar.hpp CSaveGameScreenTouchBar.cpp CMemoryCardDriver.hpp CMemoryCardDriver.cpp CQuitGameScreen.hpp CQuitGameScreen.cpp CMessageScreen.hpp CMessageScreen.cpp diff --git a/Runtime/MP1/CSaveGameScreen.cpp b/Runtime/MP1/CSaveGameScreen.cpp index e18133df5..0e5ca888f 100644 --- a/Runtime/MP1/CSaveGameScreen.cpp +++ b/Runtime/MP1/CSaveGameScreen.cpp @@ -350,8 +350,6 @@ void CSaveGameScreen::SetUIText() { x68_textpane_choice3->TextSupport().SetText(opt3Str); - m_touchBar->SetUIOpts(opt0Str, opt1Str, opt2Str); - x5c_textpane_choice0->SetIsSelectable(opt0 != -1); x60_textpane_choice1->SetIsSelectable(opt1 != -1); x64_textpane_choice2->SetIsSelectable(opt2 != -1); @@ -597,13 +595,6 @@ void CSaveGameScreen::DoSelectionChange([[maybe_unused]] CGuiTableGroup* caller, void CSaveGameScreen::ProcessUserInput(const CFinalInput& input) { if (x50_loadedFrame != nullptr) { x50_loadedFrame->ProcessUserInput(input); - - int tbOpt = m_touchBar->PopOption(); - if (tbOpt != -1) { - x58_tablegroup_choices->SetUserSelection(tbOpt); - SetUIColors(); - DoAdvance(x58_tablegroup_choices); - } } } @@ -637,7 +628,7 @@ const CGameState::GameFileStateInfo* CSaveGameScreen::GetGameData(int idx) const } CSaveGameScreen::CSaveGameScreen(ESaveContext saveCtx, u64 serial) -: x0_saveCtx(saveCtx), x8_serial(serial), m_touchBar(NewSaveUITouchBar()) { +: x0_saveCtx(saveCtx), x8_serial(serial) { x14_txtrSaveBanner = g_SimplePool->GetObj("TXTR_SaveBanner"); x20_txtrSaveIcon0 = g_SimplePool->GetObj("TXTR_SaveIcon0"); x2c_txtrSaveIcon1 = g_SimplePool->GetObj("TXTR_SaveIcon1"); diff --git a/Runtime/MP1/CSaveGameScreen.hpp b/Runtime/MP1/CSaveGameScreen.hpp index b6550a968..c3dc92649 100644 --- a/Runtime/MP1/CSaveGameScreen.hpp +++ b/Runtime/MP1/CSaveGameScreen.hpp @@ -7,7 +7,6 @@ #include "Runtime/CToken.hpp" #include "Runtime/GuiSys/CGuiFrame.hpp" #include "Runtime/MP1/CMemoryCardDriver.hpp" -#include "Runtime/MP1/CSaveGameScreenTouchBar.hpp" #include "Runtime/RetroTypes.hpp" namespace metaforce { @@ -85,8 +84,6 @@ private: bool x92_savingDisabled = false; bool x93_inGame; - std::unique_ptr m_touchBar; - void ContinueWithoutSaving(); public: diff --git a/Runtime/MP1/CSaveGameScreenTouchBar.cpp b/Runtime/MP1/CSaveGameScreenTouchBar.cpp deleted file mode 100644 index 4fdc85806..000000000 --- a/Runtime/MP1/CSaveGameScreenTouchBar.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "Runtime/MP1/CSaveGameScreenTouchBar.hpp" - -namespace metaforce::MP1 { - -int CSaveGameScreenTouchBar::PopOption() { return -1; } -void CSaveGameScreenTouchBar::SetUIOpts(std::u16string_view opt0, std::u16string_view opt1, std::u16string_view opt2) {} - -//#ifndef __APPLE__ -std::unique_ptr NewSaveUITouchBar() { return std::make_unique(); } -//#endif - -} // namespace metaforce::MP1 diff --git a/Runtime/MP1/CSaveGameScreenTouchBar.hpp b/Runtime/MP1/CSaveGameScreenTouchBar.hpp deleted file mode 100644 index 181a817b7..000000000 --- a/Runtime/MP1/CSaveGameScreenTouchBar.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace metaforce::MP1 { - -class CSaveGameScreenTouchBar { -public: - virtual ~CSaveGameScreenTouchBar() = default; - virtual int PopOption(); - virtual void SetUIOpts(std::u16string_view opt0, std::u16string_view opt1, std::u16string_view opt2); -}; - -std::unique_ptr NewSaveUITouchBar(); - -} // namespace metaforce::MP1 diff --git a/Runtime/MP1/CSaveGameScreenTouchBarMac.mm b/Runtime/MP1/CSaveGameScreenTouchBarMac.mm deleted file mode 100644 index 7ac17930d..000000000 --- a/Runtime/MP1/CSaveGameScreenTouchBarMac.mm +++ /dev/null @@ -1,101 +0,0 @@ -#include "CSaveGameScreenTouchBar.hpp" -#include "GameGlobalObjects.hpp" -#include "MP1/MP1.hpp" -#include - -#if !__has_feature(objc_arc) -#error ARC Required -#endif - -@interface SaveGameScreenTouchBar : NSObject { -@public - NSString *_opts[3]; - int _opt; -} -- (IBAction)onOpt0:(id)sender; -- (IBAction)onOpt1:(id)sender; -- (IBAction)onOpt2:(id)sender; -@end - -@implementation SaveGameScreenTouchBar -- (NSTouchBar *)makeTouchBar { - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items = @[ @"saveUIGroup" ]; - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - touchBar.principalItemIdentifier = @"saveUIGroup"; - return touchBar; -} -- (NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier { - if ([identifier isEqualToString:@"saveUIGroup"]) { - NSGroupTouchBarItem *item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items; - items = [NSMutableArray arrayWithCapacity:3]; - [items addObject:@"back"]; - for (int i = 0; i < 3 && _opts[i]; ++i) - [items addObject:[NSString stringWithFormat:@"opt%d", i]]; - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - item.groupTouchBar = touchBar; - return item; - } else if ([identifier isEqualToString:@"opt0"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:_opts[0] target:self action:@selector(onOpt0:)]; - item.view = button; - return item; - } else if ([identifier isEqualToString:@"opt1"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:_opts[1] target:self action:@selector(onOpt1:)]; - item.view = button; - return item; - } else if ([identifier isEqualToString:@"opt2"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:_opts[2] target:self action:@selector(onOpt2:)]; - item.view = button; - return item; - } - return nil; -} -- (IBAction)onOpt0:(id)sender { - _opt = 0; -} -- (IBAction)onOpt1:(id)sender { - _opt = 1; -} -- (IBAction)onOpt2:(id)sender { - _opt = 2; -} -@end - -namespace metaforce::MP1 { - -class CSaveGameScreenTouchBarMac : public CSaveGameScreenTouchBar { - SaveGameScreenTouchBar *m_touchBar; - -public: - CSaveGameScreenTouchBarMac() { - m_touchBar = [SaveGameScreenTouchBar new]; - m_touchBar->_opt = -1; - } - int PopOption() { - if (m_touchBar->_opt != -1) { - int opt = m_touchBar->_opt; - m_touchBar->_opt = -1; - return opt; - } - return -1; - } - void SetUIOpts(std::u16string_view opt0, std::u16string_view opt1, std::u16string_view opt2) { - m_touchBar->_opts[0] = opt0.size() ? [NSString stringWithUTF8String:hecl::Char16ToUTF8(opt0).c_str()] : nil; - m_touchBar->_opts[1] = opt1.size() ? [NSString stringWithUTF8String:hecl::Char16ToUTF8(opt1).c_str()] : nil; - m_touchBar->_opts[2] = opt2.size() ? [NSString stringWithUTF8String:hecl::Char16ToUTF8(opt2).c_str()] : nil; - g_Main->GetMainWindow()->setTouchBarProvider((__bridge_retained void *)m_touchBar); - } -}; - -std::unique_ptr NewSaveUITouchBar() { return std::make_unique(); } - -} diff --git a/Runtime/MP1/MP1.cpp b/Runtime/MP1/MP1.cpp index b81e0e032..433dc66b5 100644 --- a/Runtime/MP1/MP1.cpp +++ b/Runtime/MP1/MP1.cpp @@ -257,7 +257,7 @@ void CGameGlobalObjects::AddPaksAndFactories() { } if (CFactoryMgr* fmgr = g_ResFactory->GetFactoryMgr()) { - fmgr->AddFactory(FOURCC('TXTR'), FMemFactoryFunc(FTextureFactory)); + fmgr->AddFactory(FOURCC('TXTR'), FFactoryFunc(FTextureFactory)); fmgr->AddFactory(FOURCC('PART'), FFactoryFunc(FParticleFactory)); fmgr->AddFactory(FOURCC('FRME'), FFactoryFunc(RGuiFrameFactoryInGame)); fmgr->AddFactory(FOURCC('FONT'), FFactoryFunc(FRasterFontFactory)); diff --git a/Runtime/MP1/World/CThardus.cpp b/Runtime/MP1/World/CThardus.cpp index ec3c3f3c5..8c3fc98ae 100644 --- a/Runtime/MP1/World/CThardus.cpp +++ b/Runtime/MP1/World/CThardus.cpp @@ -1410,7 +1410,7 @@ void CThardus::RenderFlare(const CStateManager& mgr, float t) { CGraphics::SetModelMatrix(zeus::CTransform()); CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::One, ERglBlendFactor::One, ERglLogicOp::Clear); CGraphics::SetTevOp(0, CGraphics::sTevPass805a5ebc); - CGraphics::SetTevOp(1, CGraphics::sTevPass805a564c); + CGraphics::SetTevOp(1, CGraphics::skPassThru); CGraphics::SetDepthWriteMode(false, ERglEnum::Always, false); CGraphics::StreamColor(zeus::CColor(f1, f1)); CGraphics::StreamBegin(0xa0); diff --git a/Runtime/Particle/CElementGen.cpp b/Runtime/Particle/CElementGen.cpp index f643eb725..84464c31e 100644 --- a/Runtime/Particle/CElementGen.cpp +++ b/Runtime/Particle/CElementGen.cpp @@ -209,12 +209,13 @@ CElementGen::CElementGen(TToken gen, EModelOrientationType orie if (x26c_31_LINE) { CUVElement* texr = desc->x54_x40_TEXR.get(); - aurora::gfx::TextureHandle tex; - if (texr) - tex = texr->GetValueTexture(0).GetObj()->GetTexture(); + // TODO +// aurora::gfx::TextureHandle tex; +// if (texr) +// tex = texr->GetValueTexture(0).GetObj()->GetTexture(); int maxVerts = x90_MAXP; - m_lineRenderer.reset( - new CLineRenderer(CLineRenderer::EPrimitiveMode::Lines, maxVerts * 2, tex, x26c_26_AAPH, x26c_28_zTest)); +// m_lineRenderer.reset( +// new CLineRenderer(CLineRenderer::EPrimitiveMode::Lines, maxVerts * 2, tex, x26c_26_AAPH, x26c_28_zTest)); } else { m_shaderClass = CElementGenShaders::GetShaderClass(*this); } @@ -918,7 +919,7 @@ void CElementGen::RenderModels(const CActorLights* actorLights) { CParticle& target = x30_particles[0]; int partFrame = x74_curFrame - target.x28_startFrame; cachedTex = texr->GetValueTexture(partFrame).GetObj(); - cachedTex->Load(0, CTexture::EClampMode::Repeat); + cachedTex->Load(GX::TEXMAP0, EClampMode::Repeat); /* Shade as TEXC * RASC and TEXA * RASA */ if (moveRedToAlphaBuffer) { /* Color = Prev.rgb * Prev.a */ @@ -1043,7 +1044,7 @@ void CElementGen::RenderModels(const CActorLights* actorLights) { if (!texConst) { CTexture* tex = texr->GetValueTexture(x74_curFrame - particle.x28_startFrame).GetObj(); if (tex != cachedTex) { - tex->Load(0, CTexture::EClampMode::Repeat); + tex->Load(GX::TEXMAP0, EClampMode::Repeat); cachedTex = tex; } } @@ -1157,7 +1158,7 @@ void CElementGen::RenderLines() { CParticle& target = x30_particles[0]; int partFrame = x74_curFrame - target.x28_startFrame; cachedTex = texr->GetValueTexture(partFrame).GetObj(); - cachedTex->Load(0, CTexture::EClampMode::Repeat); + cachedTex->Load(GX::TEXMAP0, EClampMode::Repeat); /* Set TEXC * RASC */ @@ -1187,7 +1188,7 @@ void CElementGen::RenderLines() { if (!constTexr) { CTexture* tex = texr->GetValueTexture(partFrame).GetObj(); if (tex != cachedTex) { - tex->Load(0, CTexture::EClampMode::Repeat); + tex->Load(GX::TEXMAP0, EClampMode::Repeat); cachedTex = tex; } } @@ -1264,7 +1265,7 @@ void CElementGen::RenderParticles() { CParticle& target = x30_particles[0]; int partFrame = x74_curFrame - target.x28_startFrame; cachedTex = texr->GetValueTexture(partFrame).GetObj(); - cachedTex->Load(0, CTexture::EClampMode::Repeat); + cachedTex->Load(GX::TEXMAP0, EClampMode::Repeat); if (x338_moduColor != zeus::skBlack) { /* Add RASC * PREVC pass for MODU color loaded into channel mat-color */ @@ -1678,7 +1679,7 @@ void CElementGen::RenderParticlesIndirectTexture() { CParticle& firstParticle = x30_particles[0]; int partFrame = x74_curFrame - firstParticle.x28_startFrame; CTexture* cachedTex = texr->GetValueTexture(partFrame).GetObj(); - cachedTex->Load(0, CTexture::EClampMode::Repeat); + cachedTex->Load(GX::TEXMAP0, EClampMode::Repeat); SUVElementSet uvs = {0.f, 0.f, 1.f, 1.f}; bool constTexr = texr->HasConstantTexture(); @@ -1687,7 +1688,7 @@ void CElementGen::RenderParticlesIndirectTexture() { CUVElement* tind = desc->x58_x44_TIND.get(); CTexture* cachedIndTex = tind->GetValueTexture(partFrame).GetObj(); - cachedIndTex->Load(2, CTexture::EClampMode::Repeat); + cachedIndTex->Load(GX::TEXMAP2, EClampMode::Repeat); SUVElementSet uvsInd = {0.f, 0.f, 1.f, 1.f}; bool constIndTexr = tind->HasConstantTexture(); @@ -1734,7 +1735,7 @@ void CElementGen::RenderParticlesIndirectTexture() { if (!constTexr) { CTexture* tex = texr->GetValueTexture(thisPartFrame).GetObj(); if (tex != cachedTex) { - tex->Load(0, CTexture::EClampMode::Repeat); + tex->Load(GX::TEXMAP0, EClampMode::Repeat); cachedTex = tex; } } @@ -1742,7 +1743,7 @@ void CElementGen::RenderParticlesIndirectTexture() { if (!constIndTexr) { CTexture* tex = tind->GetValueTexture(thisPartFrame).GetObj(); if (tex != cachedIndTex) { - tex->Load(2, CTexture::EClampMode::Repeat); + tex->Load(GX::TEXMAP2, EClampMode::Repeat); cachedIndTex = tex; } } diff --git a/Runtime/Weapon/CPlasmaProjectile.cpp b/Runtime/Weapon/CPlasmaProjectile.cpp index c35185b2b..b2f7fb92f 100644 --- a/Runtime/Weapon/CPlasmaProjectile.cpp +++ b/Runtime/Weapon/CPlasmaProjectile.cpp @@ -60,7 +60,7 @@ CPlasmaProjectile::CPlasmaProjectile(const TToken& wDesc, st x51c_pulseGen->SetParticleEmission(false); // CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) { - m_renderObjs.emplace(x4e8_texture->GetTexture(), x4f4_glowTexture->GetTexture()); +// m_renderObjs.emplace(x4e8_texture->GetTexture(), x4f4_glowTexture->GetTexture()); // return true; // } BooTrace); } diff --git a/Runtime/World/CEnvFxManager.cpp b/Runtime/World/CEnvFxManager.cpp index 9781e0f61..c41cc7468 100644 --- a/Runtime/World/CEnvFxManager.cpp +++ b/Runtime/World/CEnvFxManager.cpp @@ -28,8 +28,9 @@ CEnvFxManagerGrid::CEnvFxManagerGrid(const zeus::CVector2i& position, const zeus , x1c_particles(std::move(initialParticles)) //, m_instBuf(parent.m_instPool.allocateBlock(CGraphics::g_BooFactory, reserve)) //, m_uniformBuf(parent.m_uniformPool.allocateBlock(CGraphics::g_BooFactory)) -, m_lineRenderer(CLineRenderer::EPrimitiveMode::Lines, reserve * 2, parent.x40_txtrEnvGradient->GetTexture(), - true, true) { +//, m_lineRenderer(CLineRenderer::EPrimitiveMode::Lines, reserve * 2, parent.x40_txtrEnvGradient->GetTexture(), +// true, true) +{ x1c_particles.reserve(reserve); CEnvFxShaders::BuildShaderDataBinding(parent, *this); } @@ -394,7 +395,7 @@ void CEnvFxManagerGrid::RenderSnowParticles(const zeus::CTransform& camXf) { } void CEnvFxManagerGrid::RenderRainParticles(const zeus::CTransform& camXf) { - m_lineRenderer.Reset(); +// m_lineRenderer.Reset(); const float zOffset = 2.f * (1.f - std::fabs(camXf.basis[2].dot(zeus::skUp))) + 1.f; const zeus::CColor color0(1.f, 10.f / 15.f); for (const auto& particle : x1c_particles) { @@ -403,10 +404,10 @@ void CEnvFxManagerGrid::RenderRainParticles(const zeus::CTransform& camXf) { pos1.z() += zOffset; const float uvy0 = pos0.z() * 10.f + m_uvyOffset; const float uvy1 = pos1.z() * 10.f + m_uvyOffset; - m_lineRenderer.AddVertex(pos0, zeus::skWhite, 1.f, {0.f, uvy0}); - m_lineRenderer.AddVertex(pos1, zeus::skClear, 1.f, {0.f, uvy1}); +// m_lineRenderer.AddVertex(pos0, zeus::skWhite, 1.f, {0.f, uvy0}); +// m_lineRenderer.AddVertex(pos1, zeus::skClear, 1.f, {0.f, uvy1}); } - m_lineRenderer.Render(false, zeus::CColor(1.f, 0.15f)); // g_Renderer->IsThermalVisorHotPass() +// m_lineRenderer.Render(false, zeus::CColor(1.f, 0.15f)); // g_Renderer->IsThermalVisorHotPass() } void CEnvFxManagerGrid::RenderUnderwaterParticles(const zeus::CTransform& camXf) { diff --git a/Runtime/World/CEnvFxManager.hpp b/Runtime/World/CEnvFxManager.hpp index 5f15e4a60..0b3f56803 100644 --- a/Runtime/World/CEnvFxManager.hpp +++ b/Runtime/World/CEnvFxManager.hpp @@ -60,7 +60,7 @@ class CEnvFxManagerGrid { // hecl::VertexBufferPool::Token m_instBuf; // hecl::UniformBufferPool::Token m_uniformBuf; - CLineRenderer m_lineRenderer; +// CLineRenderer m_lineRenderer; // // boo::ObjToken m_snowBinding; // boo::ObjToken m_underwaterBinding; diff --git a/Runtime/World/CFluidPlaneManager.cpp b/Runtime/World/CFluidPlaneManager.cpp index 971c22104..74ecae84d 100644 --- a/Runtime/World/CFluidPlaneManager.cpp +++ b/Runtime/World/CFluidPlaneManager.cpp @@ -135,7 +135,7 @@ void CFluidPlaneManager::SetupRippleMap() { curX += (1.f / 63.f); } - RippleMapTex = aurora::gfx::new_static_texture_2d(64, 64, 1, aurora::gfx::TextureFormat::R8, + RippleMapTex = aurora::gfx::new_static_texture_2d(64, 64, 1, ETexelFormat::R8PC, {reinterpret_cast(RippleValues.data()), 64 * 64}, "Ripple Map"); } diff --git a/Runtime/World/CProjectedShadow.cpp b/Runtime/World/CProjectedShadow.cpp index 1abaabe93..b74e89218 100644 --- a/Runtime/World/CProjectedShadow.cpp +++ b/Runtime/World/CProjectedShadow.cpp @@ -3,7 +3,7 @@ namespace metaforce { CProjectedShadow::CProjectedShadow(u32 w, u32 h, bool persistent) -: x0_texture(CTexture(ETexelFormat::I4, w, h, 1)), x81_persistent(persistent) {} +: x0_texture(CTexture(ETexelFormat::I4, w, h, 1, "Projected Shadow Texture")), x81_persistent(persistent) {} zeus::CAABox CProjectedShadow::CalculateRenderBounds() { return {}; } diff --git a/aurora/CMakeLists.txt b/aurora/CMakeLists.txt index 35abd4bd3..1996dcc5a 100644 --- a/aurora/CMakeLists.txt +++ b/aurora/CMakeLists.txt @@ -27,9 +27,11 @@ add_library(aurora STATIC lib/gfx/movie_player/shader.cpp lib/gfx/textured_quad/shader.cpp lib/gfx/colored_quad/shader.cpp + lib/gfx/stream.cpp + lib/gfx/texture_convert.cpp ) target_compile_definitions(aurora PRIVATE IMGUI_USER_CONFIG="imconfig_user.h") # IMGUI_USE_WCHAR32 -target_include_directories(aurora PUBLIC include ../ ) +target_include_directories(aurora PUBLIC include ../) target_include_directories(aurora PRIVATE ../imgui ../extern/imgui) target_include_directories(aurora PRIVATE ../extern/dawn/src diff --git a/aurora/include/aurora/common.hpp b/aurora/include/aurora/common.hpp index b2b779a66..b8f54686d 100644 --- a/aurora/include/aurora/common.hpp +++ b/aurora/include/aurora/common.hpp @@ -396,3 +396,68 @@ constexpr wzstring_view operator""_zsv(const wchar_t* str, std::size_t len) noex } // namespace zstring_view_literals } // namespace literals } // namespace aurora + +template +class Flags { +public: + using MaskType = typename std::underlying_type::type; + + // constructors + constexpr Flags() noexcept : m_mask(0) {} + + constexpr Flags(BitType bit) noexcept : m_mask(static_cast(bit)) {} + + constexpr Flags(Flags const& rhs) noexcept : m_mask(rhs.m_mask) {} + + constexpr explicit Flags(MaskType flags) noexcept : m_mask(flags) {} + + [[nodiscard]] constexpr bool IsSet(Flags const bit) const noexcept { return bool(*this & bit); } + + // relational operators + auto operator<=>(Flags const&) const noexcept = default; + + // logical operator + constexpr bool operator!() const noexcept { return !m_mask; } + + // bitwise operators + constexpr Flags operator&(Flags const& rhs) const noexcept { + return Flags(m_mask & rhs.m_mask); + } + + constexpr Flags operator|(Flags const& rhs) const noexcept { + return Flags(m_mask | rhs.m_mask); + } + + constexpr Flags operator^(Flags const& rhs) const noexcept { + return Flags(m_mask ^ rhs.m_mask); + } + + // assignment operators + constexpr Flags& operator=(Flags const& rhs) noexcept { + m_mask = rhs.m_mask; + return *this; + } + + constexpr Flags& operator|=(Flags const& rhs) noexcept { + m_mask |= rhs.m_mask; + return *this; + } + + constexpr Flags& operator&=(Flags const& rhs) noexcept { + m_mask &= rhs.m_mask; + return *this; + } + + constexpr Flags& operator^=(Flags const& rhs) noexcept { + m_mask ^= rhs.m_mask; + return *this; + } + + // cast operators + explicit constexpr operator bool() const noexcept { return m_mask != 0; } + + explicit constexpr operator MaskType() const noexcept { return m_mask; } + +private: + MaskType m_mask; +}; diff --git a/aurora/include/aurora/gfx.hpp b/aurora/include/aurora/gfx.hpp index f1b3e6287..7797d2838 100644 --- a/aurora/include/aurora/gfx.hpp +++ b/aurora/include/aurora/gfx.hpp @@ -2,6 +2,9 @@ #include "common.hpp" +// TODO make this shared? +#include "../../../Runtime/Graphics/GX.hpp" + #include #include @@ -79,6 +82,50 @@ enum class ERglAlphaOp { And = 0, Or = 1, Xor = 2, XNor = 3 }; enum class ERglEnum { Never = 0, Less = 1, Equal = 2, LEqual = 3, Greater = 4, NEqual = 5, GEqual = 6, Always = 7 }; +enum class ERglTevStage : u32 { + Stage0, + Stage1, + Stage2, + Stage3, + Stage4, + Stage5, + Stage6, + Stage7, + Stage8, + Stage9, + Stage10, + Stage11, + Stage12, + Stage13, + Stage14, + Stage15, + MAX +}; + +enum class ETexelFormat { + Invalid = -1, + I4 = 0, + I8 = 1, + IA4 = 2, + IA8 = 3, + C4 = 4, + C8 = 5, + C14X2 = 6, + RGB565 = 7, + RGB5A3 = 8, + RGBA8 = 9, + CMPR = 10, + // Metaforce addition: non-converting formats + RGBA8PC = 11, + R8PC = 12, +}; + +enum class EClampMode { + Clamp, + Repeat, + Mirror, +}; + struct CFogState { zeus::CColor m_color; float m_A = 0.f; @@ -86,6 +133,41 @@ struct CFogState { float m_C = 0.f; ERglFogMode m_mode; }; + +enum class EStreamFlagBits : u8 { + fHasNormal = 0x1, + fHasColor = 0x2, + fHasTexture = 0x3, +}; +using EStreamFlags = Flags; + +namespace CTevCombiners { +struct CTevOp { + bool x0_clamp = true; + GX::TevOp x4_op = GX::TevOp::TEV_ADD; + GX::TevBias x8_bias = GX::TevBias::TB_ZERO; + GX::TevScale xc_scale = GX::TevScale::CS_SCALE_1; + GX::TevRegID xc_regId = GX::TevRegID::TEVPREV; + + bool operator<=>(const CTevOp&) const = default; +}; +struct ColorPass { + GX::TevColorArg x0_a; + GX::TevColorArg x4_b; + GX::TevColorArg x8_c; + GX::TevColorArg xc_d; + + bool operator<=>(const ColorPass&) const = default; +}; +struct AlphaPass { + GX::TevAlphaArg x0_a; + GX::TevAlphaArg x4_b; + GX::TevAlphaArg x8_c; + GX::TevAlphaArg xc_d; + + bool operator<=>(const AlphaPass&) const = default; +}; +} // namespace CTevCombiners } // namespace metaforce namespace aurora::gfx { @@ -138,6 +220,16 @@ enum class ZComp : uint8_t { [[nodiscard]] bool get_dxt_compression_supported() noexcept; +void bind_texture(GX::TexMapID id, metaforce::EClampMode clamp) noexcept; +void update_tev_stage(metaforce::ERglTevStage stage, const metaforce::CTevCombiners::ColorPass& colPass, + const metaforce::CTevCombiners::AlphaPass& alphaPass, + const metaforce::CTevCombiners::CTevOp& colorOp, + const metaforce::CTevCombiners::CTevOp& alphaOp) noexcept; +void stream_begin(GX::Primitive primitive) noexcept; +void stream_vertex(metaforce::EStreamFlags flags, const zeus::CVector3f& pos, const zeus::CVector3f& nrm, + const zeus::CColor& color, const zeus::CVector2f& uv) noexcept; +void stream_end() noexcept; + // GX state void set_cull_mode(metaforce::ERglCullMode mode) noexcept; void set_blend_mode(metaforce::ERglBlendMode mode, metaforce::ERglBlendFactor src, metaforce::ERglBlendFactor dst, @@ -177,11 +269,12 @@ void queue_colored_quad_verts(CameraFilterType filter_type, ZComp z_comparison, void queue_colored_quad(CameraFilterType filter_type, ZComp z_comparison, bool z_test, const zeus::CColor& color, const zeus::CRectangle& rect, float z) noexcept; void queue_movie_player(const TextureHandle& tex_y, const TextureHandle& tex_u, const TextureHandle& tex_v, - const zeus::CColor& color, float h_pad, float v_pad) noexcept; + const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3, + const zeus::CVector3f& v4) noexcept; -TextureHandle new_static_texture_2d(uint32_t width, uint32_t height, uint32_t mips, TextureFormat format, +TextureHandle new_static_texture_2d(uint32_t width, uint32_t height, uint32_t mips, metaforce::ETexelFormat format, ArrayRef data, zstring_view label) noexcept; -TextureHandle new_dynamic_texture_2d(uint32_t width, uint32_t height, uint32_t mips, TextureFormat format, +TextureHandle new_dynamic_texture_2d(uint32_t width, uint32_t height, uint32_t mips, metaforce::ETexelFormat format, zstring_view label) noexcept; TextureHandle new_render_texture(uint32_t width, uint32_t height, uint32_t color_bind_count, uint32_t depth_bind_count, zstring_view label) noexcept; diff --git a/aurora/lib/gfx/common.cpp b/aurora/lib/gfx/common.cpp index 0df2a06d2..d1e91eb6d 100644 --- a/aurora/lib/gfx/common.cpp +++ b/aurora/lib/gfx/common.cpp @@ -203,8 +203,9 @@ PipelineRef pipeline_ref(colored_quad::PipelineConfig config) { } void queue_movie_player(const TextureHandle& tex_y, const TextureHandle& tex_u, const TextureHandle& tex_v, - const zeus::CColor& color, float h_pad, float v_pad) noexcept { - auto data = movie_player::make_draw_data(g_state.moviePlayer, tex_y, tex_u, tex_v, color, h_pad, v_pad); + const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3, + const zeus::CVector3f& v4) noexcept { + auto data = movie_player::make_draw_data(g_state.moviePlayer, tex_y, tex_u, tex_v, v1, v2, v3, v4); push_draw_command({.type = ShaderType::MoviePlayer, .moviePlayer = data}); } template <> diff --git a/aurora/lib/gfx/common.hpp b/aurora/lib/gfx/common.hpp index 89213e968..db4fbcf78 100644 --- a/aurora/lib/gfx/common.hpp +++ b/aurora/lib/gfx/common.hpp @@ -21,18 +21,38 @@ static inline XXH64_hash_t xxh3_hash(const T& input, XXH64_hash_t seed = 0) { class ByteBuffer { public: - ByteBuffer() = default; - explicit ByteBuffer(size_t capacity) : m_data(static_cast(calloc(1, capacity))), m_capacity(capacity) {} - - ~ByteBuffer() { + ByteBuffer() noexcept = default; + explicit ByteBuffer(size_t size) noexcept + : m_data(static_cast(calloc(1, size))), m_length(size), m_capacity(size) {} + ~ByteBuffer() noexcept { if (m_data != nullptr) { free(m_data); } } + ByteBuffer(ByteBuffer&& rhs) noexcept : m_data(rhs.m_data), m_length(rhs.m_length), m_capacity(rhs.m_capacity) { + rhs.m_data = nullptr; + rhs.m_length = 0; + rhs.m_capacity = 0; + } + ByteBuffer& operator=(ByteBuffer&& rhs) noexcept { + if (m_data != nullptr) { + free(m_data); + } + m_data = rhs.m_data; + m_length = rhs.m_length; + m_capacity = rhs.m_capacity; + rhs.m_data = nullptr; + rhs.m_length = 0; + rhs.m_capacity = 0; + return *this; + } + ByteBuffer(ByteBuffer const&) = delete; + ByteBuffer& operator=(ByteBuffer const&) = delete; - uint8_t* data() { return m_data; } - const uint8_t* data() const { return m_data; } - size_t size() const { return m_length; } + [[nodiscard]] uint8_t* data() noexcept { return m_data; } + [[nodiscard]] const uint8_t* data() const noexcept { return m_data; } + [[nodiscard]] size_t size() const noexcept { return m_length; } + [[nodiscard]] bool empty() const noexcept { return m_length == 0; } void append(const void* data, size_t size) { resize(m_length + size); @@ -136,9 +156,17 @@ struct TextureRef { wgpu::TextureView view; wgpu::Extent3D size; wgpu::TextureFormat format; + uint32_t mipCount; + metaforce::ETexelFormat gameFormat; - TextureRef(wgpu::Texture&& texture, wgpu::TextureView&& view, wgpu::Extent3D size, wgpu::TextureFormat format) - : texture(std::move(texture)), view(std::move(view)), size(size), format(format) {} + TextureRef(wgpu::Texture&& texture, wgpu::TextureView&& view, wgpu::Extent3D size, wgpu::TextureFormat format, + uint32_t mipCount, metaforce::ETexelFormat gameFormat = metaforce::ETexelFormat::Invalid) + : texture(std::move(texture)) + , view(std::move(view)) + , size(size) + , format(format) + , mipCount(mipCount) + , gameFormat(gameFormat) {} }; using PipelineRef = uint64_t; diff --git a/aurora/lib/gfx/movie_player/shader.cpp b/aurora/lib/gfx/movie_player/shader.cpp index 211099126..ec241ac4c 100644 --- a/aurora/lib/gfx/movie_player/shader.cpp +++ b/aurora/lib/gfx/movie_player/shader.cpp @@ -219,20 +219,21 @@ wgpu::RenderPipeline create_pipeline(const State& state, [[maybe_unused]] Pipeli } DrawData make_draw_data(const State& state, const TextureHandle& tex_y, const TextureHandle& tex_u, - const TextureHandle& tex_v, const zeus::CColor& color, float h_pad, float v_pad) { + const TextureHandle& tex_v, const zeus::CVector3f& v1, const zeus::CVector3f& v2, + const zeus::CVector3f& v3, const zeus::CVector3f& v4) { auto pipeline = pipeline_ref(PipelineConfig{}); const std::array verts{ - Vert{{-h_pad, v_pad, 0.f}, {0.0, 0.0}}, - Vert{{-h_pad, -v_pad, 0.f}, {0.0, 1.0}}, - Vert{{h_pad, v_pad, 0.f}, {1.0, 0.0}}, - Vert{{h_pad, -v_pad, 0.f}, {1.0, 1.0}}, + Vert{{v1.x(), v1.z(), v1.y()}, {0.0, 0.0}}, + Vert{{v2.x(), v2.z(), v2.y()}, {0.0, 1.0}}, + Vert{{v3.x(), v3.z(), v3.y()}, {1.0, 0.0}}, + Vert{{v4.x(), v4.z(), v4.y()}, {1.0, 1.0}}, }; const auto vertRange = push_verts(ArrayRef{verts}); const auto uniform = Uniform{ .xf = Mat4x4_Identity, - .color = color, + .color = zeus::skWhite, }; const auto uniformRange = push_uniform(uniform); diff --git a/aurora/lib/gfx/movie_player/shader.hpp b/aurora/lib/gfx/movie_player/shader.hpp index 9a4844341..c4a56b4f2 100644 --- a/aurora/lib/gfx/movie_player/shader.hpp +++ b/aurora/lib/gfx/movie_player/shader.hpp @@ -36,6 +36,7 @@ struct alignas(4) Uniform { State construct_state(); wgpu::RenderPipeline create_pipeline(const State& state, [[maybe_unused]] PipelineConfig config); DrawData make_draw_data(const State& state, const TextureHandle& tex_y, const TextureHandle& tex_u, - const TextureHandle& tex_v, const zeus::CColor& color, float h_pad, float v_pad); + const TextureHandle& tex_v, const zeus::CVector3f& v1, const zeus::CVector3f& v2, + const zeus::CVector3f& v3, const zeus::CVector3f& v4); void render(const State& state, const DrawData& data, const wgpu::RenderPassEncoder& pass); } // namespace aurora::gfx::movie_player diff --git a/aurora/lib/gfx/stream.cpp b/aurora/lib/gfx/stream.cpp new file mode 100644 index 000000000..37969088b --- /dev/null +++ b/aurora/lib/gfx/stream.cpp @@ -0,0 +1,15 @@ +#include "common.hpp" + +namespace aurora::gfx { +constexpr u32 maxTevStages = 2; +//static std::array sTevStages; + +void update_tev_stage(metaforce::ERglTevStage stage, const metaforce::CTevCombiners::ColorPass& colPass, + const metaforce::CTevCombiners::AlphaPass& alphaPass, + const metaforce::CTevCombiners::CTevOp& colorOp, + const metaforce::CTevCombiners::CTevOp& alphaOp) noexcept {} +void stream_begin(GX::Primitive primitive) noexcept {} +void stream_vertex(metaforce::EStreamFlags flags, const zeus::CVector3f& pos, const zeus::CVector3f& nrm, + const zeus::CColor& color, const zeus::CVector2f& uv) noexcept {} +void stream_end() noexcept {} +} // namespace aurora::gfx diff --git a/aurora/lib/gfx/texture.cpp b/aurora/lib/gfx/texture.cpp index f84ef6871..05b14c393 100644 --- a/aurora/lib/gfx/texture.cpp +++ b/aurora/lib/gfx/texture.cpp @@ -1,6 +1,7 @@ #include "common.hpp" #include "../gpu.hpp" +#include "texture_convert.hpp" #include #include @@ -11,24 +12,6 @@ static logvisor::Module Log("aurora::gfx"); using gpu::g_device; using gpu::g_queue; -static wgpu::TextureFormat to_wgpu(TextureFormat format) { - switch (format) { - case TextureFormat::RGBA8: - return wgpu::TextureFormat::RGBA8Unorm; - case TextureFormat::R8: - return wgpu::TextureFormat::R8Unorm; - case TextureFormat::R32Float: - return wgpu::TextureFormat::R32Float; - case TextureFormat::DXT1: - return wgpu::TextureFormat::BC1RGBAUnorm; - case TextureFormat::DXT3: - return wgpu::TextureFormat::BC3RGBAUnorm; - case TextureFormat::DXT5: - return wgpu::TextureFormat::BC5RGUnorm; - case TextureFormat::BPTC: - return wgpu::TextureFormat::BC7RGBAUnorm; - } -} struct TextureFormatInfo { uint8_t blockWidth; uint8_t blockHeight; @@ -55,10 +38,19 @@ static wgpu::Extent3D physical_size(wgpu::Extent3D size, TextureFormatInfo info) return {width, height, size.depthOrArrayLayers}; } -TextureHandle new_static_texture_2d(uint32_t width, uint32_t height, uint32_t mips, TextureFormat format, +TextureHandle new_static_texture_2d(uint32_t width, uint32_t height, uint32_t mips, metaforce::ETexelFormat format, ArrayRef data, zstring_view label) noexcept { auto handle = new_dynamic_texture_2d(width, height, mips, format, label); const TextureRef& ref = *handle.ref; + + ByteBuffer buffer; + if (ref.gameFormat != metaforce::ETexelFormat::Invalid) { + buffer = convert_texture(ref.gameFormat, ref.size.width, ref.size.height, ref.mipCount, data); + if (!buffer.empty()) { + data = {buffer.data(), buffer.size()}; + } + } + uint32_t offset = 0; for (uint32_t mip = 0; mip < mips; ++mip) { const auto mipSize = wgpu::Extent3D{ @@ -95,7 +87,7 @@ TextureHandle new_static_texture_2d(uint32_t width, uint32_t height, uint32_t mi return handle; } -TextureHandle new_dynamic_texture_2d(uint32_t width, uint32_t height, uint32_t mips, TextureFormat format, +TextureHandle new_dynamic_texture_2d(uint32_t width, uint32_t height, uint32_t mips, metaforce::ETexelFormat format, zstring_view label) noexcept { const auto wgpuFormat = to_wgpu(format); const auto size = wgpu::Extent3D{ @@ -118,7 +110,7 @@ TextureHandle new_dynamic_texture_2d(uint32_t width, uint32_t height, uint32_t m }; auto texture = g_device.CreateTexture(&textureDescriptor); auto textureView = texture.CreateView(&textureViewDescriptor); - return {std::make_shared(std::move(texture), std::move(textureView), size, wgpuFormat)}; + return {std::make_shared(std::move(texture), std::move(textureView), size, wgpuFormat, mips, format)}; } TextureHandle new_render_texture(uint32_t width, uint32_t height, uint32_t color_bind_count, uint32_t depth_bind_count, @@ -129,6 +121,15 @@ TextureHandle new_render_texture(uint32_t width, uint32_t height, uint32_t color // TODO accept mip/layer parameters void write_texture(const TextureHandle& handle, ArrayRef data) noexcept { const TextureRef& ref = *handle.ref; + + ByteBuffer buffer; + if (ref.gameFormat != metaforce::ETexelFormat::Invalid) { + buffer = convert_texture(ref.gameFormat, ref.size.width, ref.size.height, ref.mipCount, data); + if (!buffer.empty()) { + data = {buffer.data(), buffer.size()}; + } + } + const auto dstView = wgpu::ImageCopyTexture{ .texture = ref.texture, }; diff --git a/aurora/lib/gfx/texture_convert.cpp b/aurora/lib/gfx/texture_convert.cpp new file mode 100644 index 000000000..9d1839904 --- /dev/null +++ b/aurora/lib/gfx/texture_convert.cpp @@ -0,0 +1,536 @@ +#include "texture_convert.hpp" + +namespace aurora::gfx { +static logvisor::Module Log("aurora::gfx"); + +struct RGBA8 { + u8 r; + u8 g; + u8 b; + u8 a; +}; +struct DXT1Block { + u16 color1; + u16 color2; + std::array lines; +}; + +/* GX uses this upsampling technique to extract full 8-bit range */ +constexpr u8 Convert3To8(u8 v) { + /* Swizzle bits: 00000123 -> 12312312 */ + return static_cast((u32{v} << 5) | (u32{v} << 2) | (u32{v} >> 1)); +} + +constexpr u8 Convert4To8(u8 v) { + /* Swizzle bits: 00001234 -> 12341234 */ + return static_cast((u32{v} << 4) | u32{v}); +} + +constexpr u8 Convert5To8(u8 v) { + /* Swizzle bits: 00012345 -> 12345123 */ + return static_cast((u32{v} << 3) | (u32{v} >> 2)); +} + +constexpr u8 Convert6To8(u8 v) { + /* Swizzle bits: 00123456 -> 12345612 */ + return static_cast((u32{v} << 2) | (u32{v} >> 4)); +} + +static size_t ComputeMippedTexelCount(u32 w, u32 h, u32 mips) { + size_t ret = w * h; + for (u32 i = mips; i > 1; --i) { + if (w > 1) { + w /= 2; + } + if (h > 1) { + h /= 2; + } + ret += w * h; + } + return ret; +} + +static size_t ComputeMippedBlockCountDXT1(u32 w, u32 h, u32 mips) { + w /= 4; + h /= 4; + size_t ret = w * h; + for (u32 i = mips; i > 1; --i) { + if (w > 1) { + w /= 2; + } + if (h > 1) { + h /= 2; + } + ret += w * h; + } + return ret; +} + +static ByteBuffer BuildI4FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayRef data) { + const size_t texelCount = ComputeMippedTexelCount(width, height, mips); + ByteBuffer buf{sizeof(RGBA8) * texelCount}; + + uint32_t w = width; + uint32_t h = height; + auto* targetMip = reinterpret_cast(buf.data()); + const uint8_t* in = data.data(); + for (uint32_t mip = 0; mip < mips; ++mip) { + const uint32_t bwidth = (w + 7) / 8; + const uint32_t bheight = (h + 7) / 8; + for (uint32_t by = 0; by < bheight; ++by) { + const uint32_t baseY = by * 8; + for (uint32_t bx = 0; bx < bwidth; ++bx) { + const uint32_t baseX = bx * 8; + for (uint32_t y = 0; y < std::min(h, 8u); ++y) { + RGBA8* target = targetMip + (baseY + y) * w + baseX; + for (uint32_t x = 0; x < std::min(w, 8u); ++x) { + target[x].r = Convert4To8(in[x / 2] >> ((x & 1) ? 0 : 4) & 0xf); + target[x].g = target[x].r; + target[x].b = target[x].r; + target[x].a = target[x].r; + } + in += std::min(w / 4, 4); + } + } + } + targetMip += w * h; + if (w > 1) { + w /= 2; + } + if (h > 1) { + h /= 2; + } + } + + return buf; +} + +static ByteBuffer BuildI8FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayRef data) { + const size_t texelCount = ComputeMippedTexelCount(width, height, mips); + ByteBuffer buf{sizeof(RGBA8) * texelCount}; + + uint32_t w = width; + uint32_t h = height; + auto* targetMip = reinterpret_cast(buf.data()); + const uint8_t* in = data.data(); + for (uint32_t mip = 0; mip < mips; ++mip) { + const uint32_t bwidth = (w + 7) / 8; + const uint32_t bheight = (h + 3) / 4; + for (uint32_t by = 0; by < bheight; ++by) { + const uint32_t baseY = by * 4; + for (uint32_t bx = 0; bx < bwidth; ++bx) { + const uint32_t baseX = bx * 8; + for (uint32_t y = 0; y < 4; ++y) { + RGBA8* target = targetMip + (baseY + y) * w + baseX; + const auto n = std::min(w, 8u); + for (size_t x = 0; x < n; ++x) { + const auto v = in[x]; + target[x].r = v; + target[x].g = v; + target[x].b = v; + target[x].a = v; + } + in += n; + } + } + } + targetMip += w * h; + if (w > 1) { + w /= 2; + } + if (h > 1) { + h /= 2; + } + } + + return buf; +} + +ByteBuffer BuildIA4FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayRef data) { + const size_t texelCount = ComputeMippedTexelCount(width, height, mips); + ByteBuffer buf{sizeof(RGBA8) * texelCount}; + + uint32_t w = width; + uint32_t h = height; + RGBA8* targetMip = reinterpret_cast(buf.data()); + const uint8_t* in = data.data(); + for (uint32_t mip = 0; mip < mips; ++mip) { + const uint32_t bwidth = (w + 7) / 8; + const uint32_t bheight = (h + 3) / 4; + for (uint32_t by = 0; by < bheight; ++by) { + const uint32_t baseY = by * 4; + for (uint32_t bx = 0; bx < bwidth; ++bx) { + const uint32_t baseX = bx * 8; + for (uint32_t y = 0; y < 4; ++y) { + RGBA8* target = targetMip + (baseY + y) * w + baseX; + const auto n = std::min(w, 8u); + for (size_t x = 0; x < n; ++x) { + const u8 intensity = Convert4To8(in[x] >> 4 & 0xf); + target[x].r = intensity; + target[x].g = intensity; + target[x].b = intensity; + target[x].a = Convert4To8(in[x] & 0xf); + } + in += n; + } + } + } + targetMip += w * h; + if (w > 1) { + w /= 2; + } + if (h > 1) { + h /= 2; + } + } + + return buf; +} + +ByteBuffer BuildIA8FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayRef data) { + const size_t texelCount = ComputeMippedTexelCount(width, height, mips); + ByteBuffer buf{sizeof(RGBA8) * texelCount}; + + uint32_t w = width; + uint32_t h = height; + auto* targetMip = reinterpret_cast(buf.data()); + const auto* in = reinterpret_cast(data.data()); + for (uint32_t mip = 0; mip < mips; ++mip) { + const uint32_t bwidth = (w + 3) / 4; + const uint32_t bheight = (h + 3) / 4; + for (uint32_t by = 0; by < bheight; ++by) { + const uint32_t baseY = by * 4; + for (uint32_t bx = 0; bx < bwidth; ++bx) { + const uint32_t baseX = bx * 4; + for (uint32_t y = 0; y < 4; ++y) { + RGBA8* target = targetMip + (baseY + y) * w + baseX; + for (size_t x = 0; x < 4; ++x) { + const u8 intensity = in[x] >> 8; + target[x].r = intensity; + target[x].g = intensity; + target[x].b = intensity; + target[x].a = in[x] & 0xff; + } + in += 4; + } + } + } + targetMip += w * h; + if (w > 1) { + w /= 2; + } + if (h > 1) { + h /= 2; + } + } + + return buf; +} + +ByteBuffer BuildC4FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayRef data, RGBA8* palette) { + const size_t texelCount = ComputeMippedTexelCount(width, height, mips); + ByteBuffer buf{sizeof(RGBA8) * texelCount}; + + uint32_t w = width; + uint32_t h = height; + auto* targetMip = reinterpret_cast(buf.data()); + const uint8_t* in = data.data(); + for (uint32_t mip = 0; mip < mips; ++mip) { + const uint32_t bwidth = (w + 7) / 8; + const uint32_t bheight = (h + 7) / 8; + for (uint32_t by = 0; by < bheight; ++by) { + const uint32_t baseY = by * 8; + for (uint32_t bx = 0; bx < bwidth; ++bx) { + const uint32_t baseX = bx * 8; + for (uint32_t y = 0; y < 8; ++y) { + RGBA8* target = targetMip + (baseY + y) * w + baseX; + const auto n = std::min(w, 8u); + for (size_t x = 0; x < n; ++x) { + target[x] = palette[in[x / 2] >> ((x & 1) ? 0 : 4) & 0xf]; + } + in += n; + } + } + } + targetMip += w * h; + if (w > 1) { + w /= 2; + } + if (h > 1) { + h /= 2; + } + } + + return buf; +} + +ByteBuffer BuildC8FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayRef data, RGBA8* palette) { + const size_t texelCount = ComputeMippedTexelCount(width, height, mips); + ByteBuffer buf{sizeof(RGBA8) * texelCount}; + + uint32_t w = width; + uint32_t h = height; + auto* targetMip = reinterpret_cast(buf.data()); + const uint8_t* in = data.data(); + for (uint32_t mip = 0; mip < mips; ++mip) { + const uint32_t bwidth = (w + 7) / 8; + const uint32_t bheight = (h + 3) / 4; + for (uint32_t by = 0; by < bheight; ++by) { + const uint32_t baseY = by * 4; + for (uint32_t bx = 0; bx < bwidth; ++bx) { + const uint32_t baseX = bx * 8; + for (uint32_t y = 0; y < 4; ++y) { + RGBA8* target = targetMip + (baseY + y) * w + baseX; + const auto n = std::min(w, 8u); + for (size_t x = 0; x < n; ++x) { + target[x] = palette[in[x]]; + } + in += n; + } + } + } + targetMip += w * h; + if (w > 1) { + w /= 2; + } + if (h > 1) { + h /= 2; + } + } + + return buf; +} + +ByteBuffer BuildRGB565FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayRef data) { + const size_t texelCount = ComputeMippedTexelCount(width, height, mips); + ByteBuffer buf{sizeof(RGBA8) * texelCount}; + + uint32_t w = width; + uint32_t h = height; + auto* targetMip = reinterpret_cast(buf.data()); + const auto* in = reinterpret_cast(data.data()); + for (uint32_t mip = 0; mip < mips; ++mip) { + const uint32_t bwidth = (w + 3) / 4; + const uint32_t bheight = (h + 3) / 4; + for (uint32_t by = 0; by < bheight; ++by) { + const uint32_t baseY = by * 4; + for (uint32_t bx = 0; bx < bwidth; ++bx) { + const uint32_t baseX = bx * 4; + for (uint32_t y = 0; y < 4; ++y) { + RGBA8* target = targetMip + (baseY + y) * w + baseX; + for (size_t x = 0; x < 4; ++x) { + const auto texel = in[x]; + target[x].r = Convert5To8(texel >> 11 & 0x1f); + target[x].g = Convert6To8(texel >> 5 & 0x3f); + target[x].b = Convert5To8(texel & 0x1f); + target[x].a = 0xff; + } + in += 4; + } + } + } + targetMip += w * h; + if (w > 1) { + w /= 2; + } + if (h > 1) { + h /= 2; + } + } + + return buf; +} + +ByteBuffer BuildRGB5A3FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayRef data) { + size_t texelCount = ComputeMippedTexelCount(width, height, mips); + ByteBuffer buf{sizeof(RGBA8) * texelCount}; + + uint32_t w = width; + uint32_t h = height; + auto* targetMip = reinterpret_cast(buf.data()); + const auto* in = reinterpret_cast(data.data()); + for (uint32_t mip = 0; mip < mips; ++mip) { + const uint32_t bwidth = (w + 3) / 4; + const uint32_t bheight = (h + 3) / 4; + for (uint32_t by = 0; by < bheight; ++by) { + const uint32_t baseY = by * 4; + for (uint32_t bx = 0; bx < bwidth; ++bx) { + const uint32_t baseX = bx * 4; + for (uint32_t y = 0; y < 4; ++y) { + RGBA8* target = targetMip + (baseY + y) * w + baseX; + for (size_t x = 0; x < 4; ++x) { + const auto texel = in[x]; + if ((texel & 0x8000) != 0) { + target[x].r = Convert5To8(texel >> 10 & 0x1f); + target[x].g = Convert5To8(texel >> 5 & 0x1f); + target[x].b = Convert5To8(texel & 0x1f); + target[x].a = 0xff; + } else { + target[x].r = Convert4To8(texel >> 8 & 0xf); + target[x].g = Convert4To8(texel >> 4 & 0xf); + target[x].b = Convert4To8(texel & 0xf); + target[x].a = Convert3To8(texel >> 12 & 0x7); + } + } + in += 4; + } + } + } + targetMip += w * h; + if (w > 1) { + w /= 2; + } + if (h > 1) { + h /= 2; + } + } + + return buf; +} + +ByteBuffer BuildRGBA8FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayRef data) { + const size_t texelCount = ComputeMippedTexelCount(width, height, mips); + ByteBuffer buf{sizeof(RGBA8) * texelCount}; + + uint32_t w = width; + uint32_t h = height; + auto* targetMip = reinterpret_cast(buf.data()); + const uint8_t* in = data.data(); + for (uint32_t mip = 0; mip < mips; ++mip) { + const uint32_t bwidth = (w + 3) / 4; + const uint32_t bheight = (h + 3) / 4; + for (uint32_t by = 0; by < bheight; ++by) { + const uint32_t baseY = by * 4; + for (uint32_t bx = 0; bx < bwidth; ++bx) { + const uint32_t baseX = bx * 4; + for (uint32_t c = 0; c < 2; ++c) { + for (uint32_t y = 0; y < 4; ++y) { + RGBA8* target = targetMip + (baseY + y) * w + baseX; + for (size_t x = 0; x < 4; ++x) { + if (c != 0) { + target[x].g = in[x * 2]; + target[x].b = in[x * 2 + 1]; + } else { + target[x].a = in[x * 2]; + target[x].r = in[x * 2 + 1]; + } + } + in += 8; + } + } + } + } + targetMip += w * h; + if (w > 1) { + w /= 2; + } + if (h > 1) { + h /= 2; + } + } + + return buf; +} + +template +constexpr T bswap16(T val) noexcept { +#if __GNUC__ + return __builtin_bswap16(val); +#elif _WIN32 + return _byteswap_ushort(val); +#else + return (val = (val << 8) | ((val >> 8) & 0xFF)); +#endif +} + +ByteBuffer BuildDXT1FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayRef data) { + const size_t blockCount = ComputeMippedBlockCountDXT1(width, height, mips); + ByteBuffer buf{sizeof(DXT1Block) * blockCount}; + + uint32_t w = width / 4; + uint32_t h = height / 4; + auto* targetMip = reinterpret_cast(buf.data()); + const auto* in = reinterpret_cast(data.data()); + for (uint32_t mip = 0; mip < mips; ++mip) { + const uint32_t bwidth = (w + 1) / 2; + const uint32_t bheight = (h + 1) / 2; + for (uint32_t by = 0; by < bheight; ++by) { + const uint32_t baseY = by * 2; + for (uint32_t bx = 0; bx < bwidth; ++bx) { + const uint32_t baseX = bx * 2; + for (uint32_t y = 0; y < 2; ++y) { + DXT1Block* target = targetMip + (baseY + y) * w + baseX; + for (size_t x = 0; x < 2; ++x) { + target[x].color1 = bswap16(in[x].color1); + target[x].color2 = bswap16(in[x].color2); + for (size_t i = 0; i < 4; ++i) { + std::array ind; + const uint8_t packed = in[x].lines[i]; + ind[3] = packed & 0x3; + ind[2] = (packed >> 2) & 0x3; + ind[1] = (packed >> 4) & 0x3; + ind[0] = (packed >> 6) & 0x3; + target[x].lines[i] = ind[0] | (ind[1] << 2) | (ind[2] << 4) | (ind[3] << 6); + } + } + in += 2; + } + } + } + targetMip += w * h; + + if (w > 1) { + w /= 2; + } + if (h > 1) { + h /= 2; + } + } + + return buf; +} + +ByteBuffer convert_texture(metaforce::ETexelFormat format, uint32_t width, uint32_t height, uint32_t mips, + ArrayRef data) { + switch (format) { + case metaforce::ETexelFormat::RGBA8PC: + case metaforce::ETexelFormat::R8PC: + return {}; + case metaforce::ETexelFormat::Invalid: + Log.report(logvisor::Fatal, FMT_STRING("convert_texture: invalid format supplied")); + unreachable(); + case metaforce::ETexelFormat::I4: + return BuildI4FromGCN(width, height, mips, data); + case metaforce::ETexelFormat::I8: + return BuildI8FromGCN(width, height, mips, data); + case metaforce::ETexelFormat::IA4: + return BuildIA4FromGCN(width, height, mips, data); + case metaforce::ETexelFormat::IA8: + return BuildIA8FromGCN(width, height, mips, data); + case metaforce::ETexelFormat::C4: + Log.report(logvisor::Fatal, FMT_STRING("convert_texture: C4 unimplemented")); + unreachable(); + // return BuildC4FromGCN(width, height, mips, data); + case metaforce::ETexelFormat::C8: + Log.report(logvisor::Fatal, FMT_STRING("convert_texture: C8 unimplemented")); + unreachable(); + // return BuildC8FromGCN(width, height, mips, data); + case metaforce::ETexelFormat::C14X2: + Log.report(logvisor::Fatal, FMT_STRING("convert_texture: C14X2 unimplemented")); + unreachable(); + case metaforce::ETexelFormat::RGB565: + return BuildRGB565FromGCN(width, height, mips, data); + case metaforce::ETexelFormat::RGB5A3: + return BuildRGB5A3FromGCN(width, height, mips, data); + case metaforce::ETexelFormat::RGBA8: + return BuildRGBA8FromGCN(width, height, mips, data); + case metaforce::ETexelFormat::CMPR: + if (gpu::g_device.HasFeature(wgpu::FeatureName::TextureCompressionBC)) { + return BuildDXT1FromGCN(width, height, mips, data); + } else { + Log.report(logvisor::Fatal, FMT_STRING("convert_texture: TODO implement CMPR to RGBA")); + unreachable(); + } + } +} +} // namespace aurora::gfx diff --git a/aurora/lib/gfx/texture_convert.hpp b/aurora/lib/gfx/texture_convert.hpp new file mode 100644 index 000000000..1341e7534 --- /dev/null +++ b/aurora/lib/gfx/texture_convert.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include "common.hpp" + +#include "../gpu.hpp" + +namespace aurora::gfx { +static wgpu::TextureFormat to_wgpu(metaforce::ETexelFormat format) { + switch (format) { + case metaforce::ETexelFormat::C8: + case metaforce::ETexelFormat::R8PC: + return wgpu::TextureFormat::R8Unorm; + case metaforce::ETexelFormat::CMPR: + if (gpu::g_device.HasFeature(wgpu::FeatureName::TextureCompressionBC)) { + return wgpu::TextureFormat::BC1RGBAUnorm; + } + [[fallthrough]]; + default: + return wgpu::TextureFormat::RGBA8Unorm; + } +} + +ByteBuffer convert_texture(metaforce::ETexelFormat format, uint32_t width, uint32_t height, uint32_t mips, + ArrayRef data); +} // namespace aurora::gfx diff --git a/imgui/ImGuiEngine.cpp b/imgui/ImGuiEngine.cpp index 42098f83e..0c1085e09 100644 --- a/imgui/ImGuiEngine.cpp +++ b/imgui/ImGuiEngine.cpp @@ -31,12 +31,12 @@ void ImGuiEngine_Initialize(float scale) { ImGuiIO& io = ImGui::GetIO(); io.Fonts->Clear(); - auto* fontData = new uint8_t[NOTO_MONO_FONT_DECOMPRESSED_SZ]; + auto* fontData = ImGui::MemAlloc(NOTO_MONO_FONT_DECOMPRESSED_SZ); { auto stream = std::make_unique( static_cast(NOTO_MONO_FONT), NOTO_MONO_FONT_SZ, metaforce::CMemoryInStream::EOwnerShip::NotOwned); metaforce::CZipInputStream zipInputStream{std::move(stream)}; - zipInputStream.Get(fontData, NOTO_MONO_FONT_DECOMPRESSED_SZ); + zipInputStream.Get(static_cast(fontData), NOTO_MONO_FONT_DECOMPRESSED_SZ); } ImFontConfig fontConfig{};