Files
pico-launcher/arm9/source/romBrowser/views/cheats/CheatsBottomSheetView.cpp
Gericom f54a379ff2 Further work on support for cheats
Cheats can now be enabled/disabled and games can be launched with cheats
2026-02-28 17:00:02 +01:00

174 lines
6.8 KiB
C++

#include "common.h"
#include "gui/GraphicsContext.h"
#include "themes/material/MaterialColorScheme.h"
#include "themes/IFontRepository.h"
#include "gui/input/InputProvider.h"
#include "gui/VramContext.h"
#include "gui/palette/GradientPalette.h"
#include "gui/OamBuilder.h"
#include "folderIcon.h"
#include "checkboxChecked.h"
#include "checkboxUnchecked.h"
#include "cheatSelector.h"
#include "gui/DescendingStackVramManager.h"
#include "CheatsBottomSheetView.h"
#define TITLE_LABEL_X 20
#define TITLE_LABEL_Y 16
#define LIST_X 16
#define LIST_Y 36
CheatsBottomSheetView::CheatsBottomSheetView(std::unique_ptr<CheatsViewModel> viewModel,
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository,
FocusManager* focusManager)
: _viewModel(std::move(viewModel))
, _titleLabel(128, 16, 25, fontRepository->GetFont(FontType::Medium11))
, _cheatListRecycler(std::make_unique<RecyclerView>(LIST_X, LIST_Y, 224, 124, RecyclerView::Mode::VerticalList))
, _materialColorScheme(materialColorScheme)
, _fontRepository(fontRepository)
, _focusManager(focusManager)
{
_titleLabel.SetText(u"Cheats");
AddChildTail(&_titleLabel);
AddChildTail(_cheatListRecycler.get());
}
void CheatsBottomSheetView::InitVram(const VramContext& vramContext)
{
BottomSheetView::InitVram(vramContext);
const auto objVramManager = vramContext.GetObjVramManager();
if (objVramManager)
{
_vramOffsets.folderIconVramOffset = objVramManager->Alloc(folderIconTilesLen);
dma_ntrCopy32(3, folderIconTiles,
objVramManager->GetVramAddress(_vramOffsets.folderIconVramOffset), folderIconTilesLen);
_vramOffsets.checkboxUncheckedIconVramOffset = objVramManager->Alloc(checkboxUncheckedTilesLen);
dma_ntrCopy32(3, checkboxUncheckedTiles,
objVramManager->GetVramAddress(_vramOffsets.checkboxUncheckedIconVramOffset), checkboxUncheckedTilesLen);
_vramOffsets.checkboxCheckedIconVramOffset = objVramManager->Alloc(checkboxCheckedTilesLen);
dma_ntrCopy32(3, checkboxCheckedTiles,
objVramManager->GetVramAddress(_vramOffsets.checkboxCheckedIconVramOffset), checkboxCheckedTilesLen);
_vramOffsets.cheatSelectorVramOffset = objVramManager->Alloc(cheatSelectorTilesLen);
dma_ntrCopy32(3, cheatSelectorTiles,
objVramManager->GetVramAddress(_vramOffsets.cheatSelectorVramOffset), cheatSelectorTilesLen);
}
_objVramManager = vramContext.GetObjVramManager();
}
void CheatsBottomSheetView::Update()
{
_titleLabel.SetPosition(TITLE_LABEL_X, _position.y + TITLE_LABEL_Y);
_cheatListRecycler->SetPosition(LIST_X, _position.y + LIST_Y);
if (_viewModel->GetState() == CheatsViewModel::State::DisplayCheats)
{
if (_cheatsAdapter == nullptr)
{
_cheatsAdapter = new CheatsAdapter(
_viewModel->GetCurrentCheatCategory(), _materialColorScheme, _fontRepository, _vramOffsets);
_cheatListRecycler->SetAdapter(_cheatsAdapter);
// Ugly hack
_savedVramState = ((DescendingStackVramManager*)_objVramManager)->GetState();
_cheatListRecycler->InitVram(VramContext(nullptr, _objVramManager, nullptr, nullptr));
_cheatListRecycler->Focus(*_focusManager);
}
}
BottomSheetView::Update();
_viewModel->SetSelectedItem(_cheatListRecycler->GetSelectedItem());
}
void CheatsBottomSheetView::Draw(GraphicsContext& graphicsContext)
{
graphicsContext.SetClipArea(GetBounds());
u32 oldPrio = graphicsContext.SetPriority(1);
{
graphicsContext.SetClipArea(_cheatListRecycler->GetBounds());
_cheatListRecycler->Draw(graphicsContext);
graphicsContext.SetClipArea(GetBounds());
auto backColor = _materialColorScheme->GetColor(md::sys::color::surfaceContainerLow);
u32 maskPaletteRow = graphicsContext.GetPaletteManager().AllocRow(
GradientPalette(backColor, backColor),
_position.y + LIST_Y - 24, _position.y + LIST_Y);
auto maskOam = graphicsContext.GetOamManager().AllocOams(4);
OamBuilder::OamWithSize<64, 32>(LIST_X, _position.y + LIST_Y - 24, _vramOffsets.cheatSelectorVramOffset >> 7)
.WithPalette16(maskPaletteRow)
.WithPriority(graphicsContext.GetPriority())
.Build(maskOam[0]);
OamBuilder::OamWithSize<64, 32>(LIST_X + 64, _position.y + LIST_Y - 24, _vramOffsets.cheatSelectorVramOffset >> 7)
.WithPalette16(maskPaletteRow)
.WithPriority(graphicsContext.GetPriority())
.Build(maskOam[1]);
OamBuilder::OamWithSize<64, 32>(LIST_X + 2 * 64, _position.y + LIST_Y - 24, _vramOffsets.cheatSelectorVramOffset >> 7)
.WithPalette16(maskPaletteRow)
.WithPriority(graphicsContext.GetPriority())
.Build(maskOam[2]);
OamBuilder::OamWithSize<64, 32>(LIST_X + 2 * 64 + 32, _position.y + LIST_Y - 24, _vramOffsets.cheatSelectorVramOffset >> 7)
.WithPalette16(maskPaletteRow)
.WithPriority(graphicsContext.GetPriority())
.Build(maskOam[3]);
_titleLabel.SetBackgroundColor(backColor);
_titleLabel.SetForegroundColor(_materialColorScheme->onSurface);
_titleLabel.Draw(graphicsContext);
}
graphicsContext.SetPriority(oldPrio);
graphicsContext.ResetClipArea();
}
bool CheatsBottomSheetView::HandleInput(const InputProvider& inputProvider, FocusManager& focusManager)
{
if (inputProvider.Triggered(InputKey::A))
{
if (focusManager.IsFocusInside(_cheatListRecycler.get()))
{
auto oldCategory = _viewModel->GetCurrentCheatCategory();
_viewModel->ItemActivated();
if (oldCategory != _viewModel->GetCurrentCheatCategory())
{
UpdateCheatList();
}
return true;
}
}
else if (inputProvider.Triggered(InputKey::B))
{
auto oldCategory = _viewModel->GetCurrentCheatCategory();
_viewModel->Back();
if (oldCategory != _viewModel->GetCurrentCheatCategory())
{
UpdateCheatList();
}
return true;
}
else if (inputProvider.Triggered(InputKey::Y))
{
_viewModel->Close();
return true;
}
return false;
}
void CheatsBottomSheetView::UpdateCheatList()
{
auto oldAdapter = _cheatsAdapter;
_cheatsAdapter = new CheatsAdapter(_viewModel->GetCurrentCheatCategory(), _materialColorScheme, _fontRepository, _vramOffsets);
_cheatListRecycler->SetAdapter(_cheatsAdapter);
delete oldAdapter;
// Ugly hack
((DescendingStackVramManager*)_objVramManager)->SetState(_savedVramState);
_cheatListRecycler->InitVram(VramContext(nullptr, _objVramManager, nullptr, nullptr));
_cheatListRecycler->Focus(*_focusManager);
}