mirror of
https://github.com/LNH-team/pico-launcher.git
synced 2026-06-02 09:06:54 +02:00
Further work on support for cheats
Cheats can now be enabled/disabled and games can be launched with cheats
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include "SdFolderFactory.h"
|
||||
#include "services/settings/IAppSettingsService.h"
|
||||
#include "cheats/UsrCheatRepositoryFactory.h"
|
||||
#include "cheats/PicoLoaderCheatDataFactory.h"
|
||||
#include "RomBrowserController.h"
|
||||
|
||||
RomBrowserController::RomBrowserController(
|
||||
@@ -183,26 +184,9 @@ void RomBrowserController::HandleLaunchTrigger()
|
||||
LOG_DEBUG("RomBrowserStateTrigger::Launch\n");
|
||||
_ioTaskQueue->Enqueue([this] (const vu8& cancelRequested)
|
||||
{
|
||||
f_getcwd(_navigatePath, sizeof(_navigatePath) / sizeof(_navigatePath[0]));
|
||||
int idx = strlcat(_navigatePath, "/", sizeof(_navigatePath));
|
||||
if (_navigatePath[idx - 2] == '/')
|
||||
_navigatePath[idx - 1] = 0;
|
||||
strlcat(_navigatePath, _triggerFileInfo.GetFileName(), sizeof(_navigatePath));
|
||||
_appSettingsService->GetAppSettings().lastUsedFilePath = _navigatePath;
|
||||
_appSettingsService->Save();
|
||||
|
||||
auto loadParams = pload_getLoadParams();
|
||||
loadParams->savePath[0] = 0;
|
||||
loadParams->arguments[0] = 0;
|
||||
loadParams->argumentsLength = 0;
|
||||
if (_triggerFileInfo.GetFileType()->TrySetLaunchParameters(loadParams, _navigatePath))
|
||||
{
|
||||
gProcessManager.Goto<PicoLoaderProcess>();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_FATAL("Failed to set launch parameters.\n");
|
||||
}
|
||||
UpdateLastUsedFilepath();
|
||||
SetPicoLoaderParams();
|
||||
LoadCheats();
|
||||
return TaskResult<void>::Completed();
|
||||
});
|
||||
}
|
||||
@@ -212,3 +196,39 @@ void RomBrowserController::HandleChangeDisplayModeTrigger()
|
||||
LOG_DEBUG("RomBrowserStateTrigger::ChangeDisplayMode\n");
|
||||
_romBrowserViewModel = SharedPtr(new RomBrowserViewModel(this));
|
||||
}
|
||||
|
||||
void RomBrowserController::UpdateLastUsedFilepath()
|
||||
{
|
||||
f_getcwd(_navigatePath, sizeof(_navigatePath) / sizeof(_navigatePath[0]));
|
||||
int idx = strlcat(_navigatePath, "/", sizeof(_navigatePath));
|
||||
if (_navigatePath[idx - 2] == '/')
|
||||
{
|
||||
_navigatePath[idx - 1] = 0;
|
||||
}
|
||||
strlcat(_navigatePath, _triggerFileInfo.GetFileName(), sizeof(_navigatePath));
|
||||
_appSettingsService->GetAppSettings().lastUsedFilePath = _navigatePath;
|
||||
_appSettingsService->Save();
|
||||
}
|
||||
|
||||
void RomBrowserController::SetPicoLoaderParams() const
|
||||
{
|
||||
auto loadParams = pload_getLoadParams();
|
||||
loadParams->savePath[0] = 0;
|
||||
loadParams->arguments[0] = 0;
|
||||
loadParams->argumentsLength = 0;
|
||||
if (_triggerFileInfo.GetFileType()->TrySetLaunchParameters(loadParams, _navigatePath))
|
||||
{
|
||||
gProcessManager.Goto<PicoLoaderProcess>();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_FATAL("Failed to set launch parameters.\n");
|
||||
}
|
||||
}
|
||||
|
||||
void RomBrowserController::LoadCheats() const
|
||||
{
|
||||
auto cheats = _cheatRepository->GetCheatsForGame(_triggerFileInfo.GetFastFileRef());
|
||||
auto cheatData = PicoLoaderCheatDataFactory().CreateCheatData(cheats);
|
||||
pload_setCheatData(cheatData);
|
||||
}
|
||||
|
||||
@@ -74,4 +74,7 @@ private:
|
||||
void HandleFolderLoadDoneTrigger();
|
||||
void HandleLaunchTrigger();
|
||||
void HandleChangeDisplayModeTrigger();
|
||||
void UpdateLastUsedFilepath();
|
||||
void SetPicoLoaderParams() const;
|
||||
void LoadCheats() const;
|
||||
};
|
||||
|
||||
@@ -3,57 +3,16 @@
|
||||
#include "fat/File.h"
|
||||
#include "CheatsViewModel.h"
|
||||
|
||||
#define CRCPOLY 0xEDB88320
|
||||
|
||||
static u32 crc32(const void* buffer, u32 length)
|
||||
{
|
||||
u32 crc = ~0u;
|
||||
const u8* p = (u8*)buffer;
|
||||
while (length--)
|
||||
{
|
||||
crc ^= *p++;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY : 0);
|
||||
}
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
CheatsViewModel::CheatsViewModel(const FileInfo& romFileInfo, IRomBrowserController* romBrowserController)
|
||||
: _romFileInfo(romFileInfo), _romBrowserController(romBrowserController)
|
||||
{
|
||||
_categoryStack.fill(nullptr);
|
||||
_loadCheatsTask = _romBrowserController->GetIoTaskQueue()->Enqueue([this] (const vu8& cancelRequested)
|
||||
{
|
||||
LOG_DEBUG("%s\n", _romFileInfo.GetFileName());
|
||||
auto file = std::make_unique<File>();
|
||||
file->Open(_romFileInfo.GetFastFileRef(), FA_READ);
|
||||
auto headerBuffer = std::make_unique_for_overwrite<u8[]>(512);
|
||||
if (!file->ReadExact(headerBuffer.get(), 512))
|
||||
{
|
||||
LOG_ERROR("Could not read rom header\n");
|
||||
return TaskResult<void>::Failed();
|
||||
}
|
||||
file->Close();
|
||||
|
||||
if (cancelRequested)
|
||||
{
|
||||
return TaskResult<void>::Canceled();
|
||||
}
|
||||
|
||||
u32 gameCode = *(u32*)(headerBuffer.get() + 0xC);
|
||||
u32 crc = crc32(headerBuffer.get(), 512);
|
||||
headerBuffer.reset();
|
||||
|
||||
if (cancelRequested)
|
||||
{
|
||||
return TaskResult<void>::Canceled();
|
||||
}
|
||||
|
||||
_cheats = _romBrowserController->GetCheatRepository().GetCheatsForGame(gameCode, crc);
|
||||
_cheats = _romBrowserController->GetCheatRepository().GetCheatsForGame(_romFileInfo.GetFastFileRef());
|
||||
if (_cheats)
|
||||
{
|
||||
_categoryStack[0] = _cheats.get();
|
||||
_state = State::DisplayCheats;
|
||||
}
|
||||
else
|
||||
@@ -64,3 +23,64 @@ CheatsViewModel::CheatsViewModel(const FileInfo& romFileInfo, IRomBrowserControl
|
||||
return TaskResult<void>::Completed();
|
||||
});
|
||||
}
|
||||
|
||||
void CheatsViewModel::ItemActivated()
|
||||
{
|
||||
auto cheatCategory = GetCurrentCheatCategory();
|
||||
u32 numberOfCategories = 0;
|
||||
auto categories = cheatCategory->GetCategories(numberOfCategories);
|
||||
u32 numberOfCheats = 0;
|
||||
auto cheats = cheatCategory->GetCheats(numberOfCheats);
|
||||
|
||||
if (_selectedItem < (int)numberOfCategories)
|
||||
{
|
||||
// Category activated
|
||||
if (_categoryStackLevel + 1 != _categoryStack.size())
|
||||
{
|
||||
_categoryStack[++_categoryStackLevel] = &categories[_selectedItem];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Toggle cheat on/off
|
||||
auto& cheat = cheats[_selectedItem - numberOfCategories];
|
||||
bool isEnabled = !cheat.GetIsCheatActive();
|
||||
if (isEnabled && cheatCategory->GetIsMaxOneCheatActive())
|
||||
{
|
||||
for (u32 i = 0; i < numberOfCheats; i++)
|
||||
{
|
||||
cheats[i].SetIsCheatActive(false);
|
||||
}
|
||||
}
|
||||
cheat.SetIsCheatActive(isEnabled);
|
||||
_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
void CheatsViewModel::Back()
|
||||
{
|
||||
if (_categoryStackLevel == 0)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
_categoryStack[_categoryStackLevel--] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CheatsViewModel::Close()
|
||||
{
|
||||
if (_changed)
|
||||
{
|
||||
// Save which cheats are enabled/disabled
|
||||
_romBrowserController->GetIoTaskQueue()->Enqueue(
|
||||
[romBrowserController = _romBrowserController, cheats = move(_cheats)] (const vu8& cancelRequested)
|
||||
{
|
||||
romBrowserController->GetCheatRepository().UpdateEnabledCheatsForGame(cheats);
|
||||
return TaskResult<void>::Completed();
|
||||
});
|
||||
}
|
||||
|
||||
_romBrowserController->HideGameInfo();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include "core/task/TaskQueue.h"
|
||||
#include "cheats/GameCheats.h"
|
||||
@@ -18,13 +19,15 @@ public:
|
||||
|
||||
CheatsViewModel(const FileInfo& romFileInfo, IRomBrowserController* romBrowserController);
|
||||
|
||||
void Close()
|
||||
{
|
||||
_romBrowserController->HideGameInfo();
|
||||
}
|
||||
void ItemActivated();
|
||||
void Back();
|
||||
void Close();
|
||||
|
||||
State GetState() const { return _state; }
|
||||
const GameCheats* GetCheats() const { return _cheats.get(); }
|
||||
const ICheatCategory* GetCurrentCheatCategory() const { return _categoryStack[_categoryStackLevel]; }
|
||||
|
||||
constexpr int GetSelectedItem() const { return _selectedItem; }
|
||||
void SetSelectedItem(int selectedItem) { _selectedItem = selectedItem; }
|
||||
|
||||
private:
|
||||
FileInfo _romFileInfo;
|
||||
@@ -32,4 +35,8 @@ private:
|
||||
QueueTask<void> _loadCheatsTask;
|
||||
std::unique_ptr<GameCheats> _cheats;
|
||||
State _state = State::Loading;
|
||||
int _selectedItem = -1;
|
||||
bool _changed = false;
|
||||
u32 _categoryStackLevel = 0;
|
||||
std::array<const ICheatCategory*, 8> _categoryStack;
|
||||
};
|
||||
|
||||
@@ -6,14 +6,16 @@
|
||||
#include "gui/OamBuilder.h"
|
||||
#include "CheatListItemView.h"
|
||||
|
||||
#define ICON_X 20
|
||||
#define ICON_Y 3
|
||||
#define ICON_X 4
|
||||
#define ICON_Y 4
|
||||
|
||||
#define NAME_LABEL_X 40
|
||||
#define NAME_LABEL_Y 4
|
||||
#define NAME_LABEL_X 24
|
||||
#define NAME_LABEL_Y 5
|
||||
|
||||
CheatListItemView::CheatListItemView(const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository)
|
||||
CheatListItemView::CheatListItemView(const VramOffsets& vramOffsets,
|
||||
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository)
|
||||
: _nameLabel(200, 16, 64, fontRepository->GetFont(FontType::Regular10))
|
||||
, _vramOffsets(vramOffsets)
|
||||
, _materialColorScheme(materialColorScheme)
|
||||
{
|
||||
_nameLabel.SetEllipsis(true);
|
||||
@@ -22,15 +24,57 @@ CheatListItemView::CheatListItemView(const MaterialColorScheme* materialColorSch
|
||||
|
||||
void CheatListItemView::Update()
|
||||
{
|
||||
_nameLabel.SetPosition(NAME_LABEL_X, _position.y + NAME_LABEL_Y);
|
||||
_nameLabel.SetPosition(_position.x + NAME_LABEL_X, _position.y + NAME_LABEL_Y);
|
||||
if (_cheat != nullptr)
|
||||
{
|
||||
_iconVramOffset = _cheat->GetIsCheatActive()
|
||||
? _vramOffsets.checkboxCheckedIconVramOffset
|
||||
: _vramOffsets.checkboxUncheckedIconVramOffset;
|
||||
}
|
||||
ViewContainer::Update();
|
||||
}
|
||||
|
||||
void CheatListItemView::Draw(GraphicsContext& graphicsContext)
|
||||
{
|
||||
if (!graphicsContext.IsVisible(GetBounds()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto backColor = _materialColorScheme->GetColor(md::sys::color::surfaceContainerLow);
|
||||
if (IsFocused())
|
||||
{
|
||||
auto selectorFullColor = _materialColorScheme->GetColor(md::sys::color::onSurface);
|
||||
backColor = RgbMixer::Lerp(backColor, selectorFullColor, 10, 100);
|
||||
}
|
||||
|
||||
_nameLabel.SetBackgroundColor(backColor);
|
||||
_nameLabel.SetForegroundColor(_materialColorScheme->onSurface);
|
||||
|
||||
if (IsFocused())
|
||||
{
|
||||
u32 selectorPaletteRow = graphicsContext.GetPaletteManager().AllocRow(
|
||||
GradientPalette(backColor, backColor),
|
||||
_position.y, _position.y + 24);
|
||||
auto selectorOam = graphicsContext.GetOamManager().AllocOams(4);
|
||||
OamBuilder::OamWithSize<64, 32>(_position.x, _position.y, _vramOffsets.cheatSelectorVramOffset >> 7)
|
||||
.WithPalette16(selectorPaletteRow)
|
||||
.WithPriority(graphicsContext.GetPriority())
|
||||
.Build(selectorOam[0]);
|
||||
OamBuilder::OamWithSize<64, 32>(_position.x + 64, _position.y, _vramOffsets.cheatSelectorVramOffset >> 7)
|
||||
.WithPalette16(selectorPaletteRow)
|
||||
.WithPriority(graphicsContext.GetPriority())
|
||||
.Build(selectorOam[1]);
|
||||
OamBuilder::OamWithSize<64, 32>(_position.x + 2 * 64, _position.y, _vramOffsets.cheatSelectorVramOffset >> 7)
|
||||
.WithPalette16(selectorPaletteRow)
|
||||
.WithPriority(graphicsContext.GetPriority())
|
||||
.Build(selectorOam[2]);
|
||||
OamBuilder::OamWithSize<64, 32>(_position.x + 2 * 64 + 32, _position.y, _vramOffsets.cheatSelectorVramOffset >> 7)
|
||||
.WithPalette16(selectorPaletteRow)
|
||||
.WithPriority(graphicsContext.GetPriority())
|
||||
.Build(selectorOam[3]);
|
||||
}
|
||||
|
||||
ViewContainer::Draw(graphicsContext);
|
||||
|
||||
if (graphicsContext.IsVisible(Rectangle(_position.x + ICON_X, _position.y + ICON_Y, 16, 16)))
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
#include "gui/views/ViewContainer.h"
|
||||
#include "gui/views/Label2DView.h"
|
||||
#include "cheats/CheatCategory.h"
|
||||
#include "cheats/Cheat.h"
|
||||
|
||||
class MaterialColorScheme;
|
||||
class IFontRepository;
|
||||
@@ -8,14 +10,22 @@ class IFontRepository;
|
||||
class CheatListItemView : public ViewContainer
|
||||
{
|
||||
public:
|
||||
CheatListItemView(const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository);
|
||||
struct VramOffsets
|
||||
{
|
||||
u32 folderIconVramOffset = 0;
|
||||
u32 checkboxUncheckedIconVramOffset = 0;
|
||||
u32 checkboxCheckedIconVramOffset = 0;
|
||||
u32 cheatSelectorVramOffset = 0;
|
||||
};
|
||||
|
||||
CheatListItemView(const VramOffsets& vramOffsets, const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository);
|
||||
|
||||
void Update() override;
|
||||
void Draw(GraphicsContext& graphicsContext) override;
|
||||
|
||||
Rectangle GetBounds() const override
|
||||
{
|
||||
return Rectangle(_position.x, _position.y, 256, 24);
|
||||
return Rectangle(_position.x, _position.y, 224, 24);
|
||||
}
|
||||
|
||||
void SetName(const char* name)
|
||||
@@ -23,13 +33,23 @@ public:
|
||||
_nameLabel.SetText(name);
|
||||
}
|
||||
|
||||
void SetIcon(u32 iconVramOffset)
|
||||
void SetCategory(const CheatCategory* cheatCategory)
|
||||
{
|
||||
_iconVramOffset = iconVramOffset;
|
||||
_cheat = nullptr;
|
||||
_nameLabel.SetText(cheatCategory->GetName());
|
||||
_iconVramOffset = _vramOffsets.folderIconVramOffset;
|
||||
}
|
||||
|
||||
void SetCheat(const Cheat* cheat)
|
||||
{
|
||||
_cheat = cheat;
|
||||
_nameLabel.SetText(_cheat->GetName());
|
||||
}
|
||||
|
||||
private:
|
||||
Label2DView _nameLabel;
|
||||
u32 _iconVramOffset = 0;
|
||||
VramOffsets _vramOffsets;
|
||||
const MaterialColorScheme* _materialColorScheme;
|
||||
u32 _iconVramOffset = 0;
|
||||
const Cheat* _cheat = nullptr;
|
||||
};
|
||||
|
||||
@@ -7,30 +7,30 @@
|
||||
class CheatsAdapter : public RecyclerAdapter
|
||||
{
|
||||
public:
|
||||
CheatsAdapter(const CheatCategory* categories, u32 numberOfCategories, const Cheat* cheats, u32 numberOfCheats,
|
||||
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository,
|
||||
u32 folderIconVramOffset, u32 checkboxUncheckedIconVramOffset, u32 checkboxCheckedIconVramOffset)
|
||||
: _categories(categories), _numberOfCategories(numberOfCategories), _cheats(cheats), _numberOfCheats(numberOfCheats)
|
||||
, _materialColorScheme(materialColorScheme), _fontRepository(fontRepository)
|
||||
, _folderIconVramOffset(folderIconVramOffset)
|
||||
, _checkboxUncheckedIconVramOffset(checkboxUncheckedIconVramOffset)
|
||||
, _checkboxCheckedIconVramOffset(checkboxCheckedIconVramOffset) { }
|
||||
CheatsAdapter(const ICheatCategory* cheatCategory, const MaterialColorScheme* materialColorScheme,
|
||||
const IFontRepository* fontRepository, const CheatListItemView::VramOffsets& vramOffsets)
|
||||
: _cheatCategory(cheatCategory), _materialColorScheme(materialColorScheme)
|
||||
, _fontRepository(fontRepository), _vramOffsets(vramOffsets) { }
|
||||
|
||||
u32 GetItemCount() const override
|
||||
{
|
||||
return _numberOfCategories + _numberOfCheats;
|
||||
u32 numberOfCategories = 0;
|
||||
_cheatCategory->GetCategories(numberOfCategories);
|
||||
u32 numberOfCheats = 0;
|
||||
_cheatCategory->GetCheats(numberOfCheats);
|
||||
return numberOfCategories + numberOfCheats;
|
||||
}
|
||||
|
||||
void GetViewSize(int& width, int& height) const override
|
||||
{
|
||||
width = 256;
|
||||
width = 224;
|
||||
height = 24;
|
||||
}
|
||||
|
||||
View* CreateView() const override
|
||||
{
|
||||
LOG_DEBUG("CheatsAdapter::CreateView\n");
|
||||
return new CheatListItemView(_materialColorScheme, _fontRepository);
|
||||
return new CheatListItemView(_vramOffsets, _materialColorScheme, _fontRepository);
|
||||
}
|
||||
|
||||
void DestroyView(View* view) const override
|
||||
@@ -43,16 +43,18 @@ public:
|
||||
{
|
||||
LOG_DEBUG("CheatsAdapter::BindView\n");
|
||||
auto listItemView = static_cast<CheatListItemView*>(view);
|
||||
if ((u32)index < _numberOfCategories)
|
||||
u32 numberOfCategories = 0;
|
||||
auto categories = _cheatCategory->GetCategories(numberOfCategories);
|
||||
if ((u32)index < numberOfCategories)
|
||||
{
|
||||
listItemView->SetName(_categories[index].GetName());
|
||||
listItemView->SetIcon(_folderIconVramOffset);
|
||||
listItemView->SetCategory(&categories[index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
index -= _numberOfCategories;
|
||||
listItemView->SetName(_cheats[index].GetName());
|
||||
listItemView->SetIcon(_cheats[index].GetIsCheatActive() ? _checkboxCheckedIconVramOffset : _checkboxUncheckedIconVramOffset);
|
||||
index -= numberOfCategories;
|
||||
u32 numberOfCheats = 0;
|
||||
auto cheats = _cheatCategory->GetCheats(numberOfCheats);
|
||||
listItemView->SetCheat(&cheats[index]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,13 +64,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
const CheatCategory* _categories;
|
||||
u32 _numberOfCategories;
|
||||
const Cheat* _cheats;
|
||||
u32 _numberOfCheats;
|
||||
const ICheatCategory* _cheatCategory;
|
||||
const MaterialColorScheme* _materialColorScheme;
|
||||
const IFontRepository* _fontRepository;
|
||||
u32 _folderIconVramOffset;
|
||||
u32 _checkboxUncheckedIconVramOffset;
|
||||
u32 _checkboxCheckedIconVramOffset;
|
||||
CheatListItemView::VramOffsets _vramOffsets;
|
||||
};
|
||||
|
||||
@@ -4,27 +4,34 @@
|
||||
#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(0, 36, 256, 124, RecyclerView::Mode::VerticalList)
|
||||
, _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);
|
||||
AddChildTail(_cheatListRecycler.get());
|
||||
}
|
||||
|
||||
void CheatsBottomSheetView::InitVram(const VramContext& vramContext)
|
||||
@@ -34,17 +41,21 @@ void CheatsBottomSheetView::InitVram(const VramContext& vramContext)
|
||||
const auto objVramManager = vramContext.GetObjVramManager();
|
||||
if (objVramManager)
|
||||
{
|
||||
_folderIconVramOffset = objVramManager->Alloc(folderIconTilesLen);
|
||||
_vramOffsets.folderIconVramOffset = objVramManager->Alloc(folderIconTilesLen);
|
||||
dma_ntrCopy32(3, folderIconTiles,
|
||||
objVramManager->GetVramAddress(_folderIconVramOffset), folderIconTilesLen);
|
||||
objVramManager->GetVramAddress(_vramOffsets.folderIconVramOffset), folderIconTilesLen);
|
||||
|
||||
_checkboxUncheckedIconVramOffset = objVramManager->Alloc(checkboxUncheckedTilesLen);
|
||||
_vramOffsets.checkboxUncheckedIconVramOffset = objVramManager->Alloc(checkboxUncheckedTilesLen);
|
||||
dma_ntrCopy32(3, checkboxUncheckedTiles,
|
||||
objVramManager->GetVramAddress(_checkboxUncheckedIconVramOffset), checkboxUncheckedTilesLen);
|
||||
objVramManager->GetVramAddress(_vramOffsets.checkboxUncheckedIconVramOffset), checkboxUncheckedTilesLen);
|
||||
|
||||
_checkboxCheckedIconVramOffset = objVramManager->Alloc(checkboxCheckedTilesLen);
|
||||
_vramOffsets.checkboxCheckedIconVramOffset = objVramManager->Alloc(checkboxCheckedTilesLen);
|
||||
dma_ntrCopy32(3, checkboxCheckedTiles,
|
||||
objVramManager->GetVramAddress(_checkboxCheckedIconVramOffset), checkboxCheckedTilesLen);
|
||||
objVramManager->GetVramAddress(_vramOffsets.checkboxCheckedIconVramOffset), checkboxCheckedTilesLen);
|
||||
|
||||
_vramOffsets.cheatSelectorVramOffset = objVramManager->Alloc(cheatSelectorTilesLen);
|
||||
dma_ntrCopy32(3, cheatSelectorTiles,
|
||||
objVramManager->GetVramAddress(_vramOffsets.cheatSelectorVramOffset), cheatSelectorTilesLen);
|
||||
}
|
||||
|
||||
_objVramManager = vramContext.GetObjVramManager();
|
||||
@@ -53,27 +64,24 @@ void CheatsBottomSheetView::InitVram(const VramContext& vramContext)
|
||||
void CheatsBottomSheetView::Update()
|
||||
{
|
||||
_titleLabel.SetPosition(TITLE_LABEL_X, _position.y + TITLE_LABEL_Y);
|
||||
_cheatListRecycler.SetPosition(0, _position.y + 36);
|
||||
_cheatListRecycler->SetPosition(LIST_X, _position.y + LIST_Y);
|
||||
if (_viewModel->GetState() == CheatsViewModel::State::DisplayCheats)
|
||||
{
|
||||
if (_cheatsAdapter == nullptr)
|
||||
{
|
||||
LOG_DEBUG("Setting adapter\n");
|
||||
auto gameCheats = _viewModel->GetCheats();
|
||||
u32 numberOfCategories = 0;
|
||||
auto categories = gameCheats->GetCheatCategories(numberOfCategories);
|
||||
u32 numberOfCheats = 0;
|
||||
auto cheats = gameCheats->GetCheats(numberOfCheats);
|
||||
_cheatsAdapter = new CheatsAdapter(categories, numberOfCategories, cheats, numberOfCheats,
|
||||
_materialColorScheme, _fontRepository, _folderIconVramOffset,
|
||||
_checkboxUncheckedIconVramOffset, _checkboxCheckedIconVramOffset);
|
||||
_cheatListRecycler.SetAdapter(_cheatsAdapter);
|
||||
_cheatListRecycler.InitVram(VramContext(nullptr, _objVramManager, nullptr, nullptr));
|
||||
_cheatListRecycler.Focus(*_focusManager);
|
||||
LOG_DEBUG("Setting adapter done\n");
|
||||
_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)
|
||||
@@ -81,12 +89,36 @@ void CheatsBottomSheetView::Draw(GraphicsContext& graphicsContext)
|
||||
graphicsContext.SetClipArea(GetBounds());
|
||||
u32 oldPrio = graphicsContext.SetPriority(1);
|
||||
{
|
||||
_titleLabel.SetBackgroundColor(_materialColorScheme->GetColor(md::sys::color::surfaceContainerLow));
|
||||
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.SetClipArea(_cheatListRecycler.GetBounds());
|
||||
_cheatListRecycler.Draw(graphicsContext);
|
||||
// BottomSheetView::Draw(graphicsContext);
|
||||
}
|
||||
graphicsContext.SetPriority(oldPrio);
|
||||
graphicsContext.ResetClipArea();
|
||||
@@ -94,10 +126,48 @@ void CheatsBottomSheetView::Draw(GraphicsContext& graphicsContext)
|
||||
|
||||
bool CheatsBottomSheetView::HandleInput(const InputProvider& inputProvider, FocusManager& focusManager)
|
||||
{
|
||||
if (inputProvider.Triggered(InputKey::B))
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "gui/views/RecyclerView.h"
|
||||
#include "romBrowser/viewModels/CheatsViewModel.h"
|
||||
#include "CheatsAdapter.h"
|
||||
#include "CheatListItemView.h"
|
||||
|
||||
class MaterialColorScheme;
|
||||
class IFontRepository;
|
||||
@@ -17,6 +18,15 @@ public:
|
||||
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository,
|
||||
FocusManager* focusManager);
|
||||
|
||||
~CheatsBottomSheetView() override
|
||||
{
|
||||
_cheatListRecycler.reset();
|
||||
if (_cheatsAdapter != nullptr)
|
||||
{
|
||||
delete _cheatsAdapter;
|
||||
}
|
||||
}
|
||||
|
||||
void InitVram(const VramContext& vramContext) override;
|
||||
void Update() override;
|
||||
void Draw(GraphicsContext& graphicsContext) override;
|
||||
@@ -24,19 +34,20 @@ public:
|
||||
|
||||
void Focus(FocusManager& focusManager) override
|
||||
{
|
||||
_cheatListRecycler.Focus(focusManager);
|
||||
_cheatListRecycler->Focus(focusManager);
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<CheatsViewModel> _viewModel;
|
||||
Label2DView _titleLabel;
|
||||
RecyclerView _cheatListRecycler;
|
||||
std::unique_ptr<RecyclerView> _cheatListRecycler;
|
||||
CheatsAdapter* _cheatsAdapter = nullptr;
|
||||
const MaterialColorScheme* _materialColorScheme;
|
||||
const IFontRepository* _fontRepository;
|
||||
IVramManager* _objVramManager;
|
||||
FocusManager* _focusManager;
|
||||
u32 _folderIconVramOffset = 0;
|
||||
u32 _checkboxUncheckedIconVramOffset = 0;
|
||||
u32 _checkboxCheckedIconVramOffset = 0;
|
||||
CheatListItemView::VramOffsets _vramOffsets;
|
||||
u32 _savedVramState = 0;
|
||||
|
||||
void UpdateCheatList();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user