mirror of
https://github.com/LNH-team/pico-launcher.git
synced 2026-06-02 09:06:54 +02:00
Change cheat implementation to show cheats in database order, fix some bugs
- AdvancedPaletteManager incorrectly handled negative y positions - FocusManager still had a pointer to a view that was destroyed in the cheats panel. After changing focus, memory got corrupted.
This commit is contained in:
@@ -1,63 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
/// @brief Class representing a single cheat.
|
|
||||||
class Cheat
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Cheat() { }
|
|
||||||
|
|
||||||
Cheat(const char* name, const char* description, u32* flagsPointer, const void* cheatData, u32 cheatDataLength)
|
|
||||||
: _name(name), _description(description), _flagsPointer(flagsPointer)
|
|
||||||
, _cheatData(cheatData), _cheatDataLength(cheatDataLength) { }
|
|
||||||
|
|
||||||
/// @brief Gets the name of this cheat.
|
|
||||||
/// @return A pointer to the name of this cheat.
|
|
||||||
const char* GetName() const
|
|
||||||
{
|
|
||||||
return _name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Gets the description of this cheat.
|
|
||||||
/// @return A pointer to the description of this cheat.
|
|
||||||
const char* GetDescription() const
|
|
||||||
{
|
|
||||||
return _description;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Gets a pointer to the data of this cheat.
|
|
||||||
/// @param cheatDataLength The length of the cheat data is returned in this reference.
|
|
||||||
/// @return A pointer to the cheat data.
|
|
||||||
/// This pointer is only valid for the lifetime of the \see GameCheats instance this cheat belongs to.
|
|
||||||
const void* GetCheatData(u32& cheatDataLength) const
|
|
||||||
{
|
|
||||||
cheatDataLength = _cheatDataLength;
|
|
||||||
return _cheatData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Gets whether this cheat is active (enabled) or not.
|
|
||||||
/// @return \c true when this cheat is active, or \c false when not active.
|
|
||||||
bool GetIsCheatActive() const
|
|
||||||
{
|
|
||||||
return ((*_flagsPointer >> 24) & 1) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Sets whether this cheat is active (enabled) or not.
|
|
||||||
/// @param isCheatActive \c true to enable this cheat, or \c false to disable this cheat.
|
|
||||||
void SetIsCheatActive(bool isCheatActive) const
|
|
||||||
{
|
|
||||||
u32 flags = *_flagsPointer;
|
|
||||||
flags &= ~(1 << 24);
|
|
||||||
if (isCheatActive)
|
|
||||||
{
|
|
||||||
flags |= 1 << 24;
|
|
||||||
}
|
|
||||||
*_flagsPointer = flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const char* _name = nullptr;
|
|
||||||
const char* _description = nullptr;
|
|
||||||
u32* _flagsPointer = nullptr;
|
|
||||||
const void* _cheatData = nullptr;
|
|
||||||
u32 _cheatDataLength = 0;
|
|
||||||
};
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <memory>
|
|
||||||
#include "ICheatCategory.h"
|
|
||||||
|
|
||||||
/// @brief Class representing a cheat category, containing sub-categories and cheats.
|
|
||||||
class CheatCategory : public ICheatCategory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CheatCategory() { }
|
|
||||||
|
|
||||||
CheatCategory(const char* name, const char* description, bool isMaxOneCheatActive,
|
|
||||||
CheatCategory* subCategories, u32 numberOfSubCategories, Cheat* cheats, u32 numberOfCheats)
|
|
||||||
: _name(name), _description(description), _isMaxOneCheatActive(isMaxOneCheatActive)
|
|
||||||
, _subCategories(subCategories), _numberOfSubCategories(numberOfSubCategories)
|
|
||||||
, _cheats(cheats), _numberOfCheats(numberOfCheats) { }
|
|
||||||
|
|
||||||
CheatCategory(CheatCategory& other) = delete;
|
|
||||||
CheatCategory& operator=(CheatCategory& other) = delete;
|
|
||||||
|
|
||||||
CheatCategory(CheatCategory&& other)
|
|
||||||
{
|
|
||||||
*this = std::move(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
CheatCategory& operator=(CheatCategory&& other)
|
|
||||||
{
|
|
||||||
_name = other._name;
|
|
||||||
other._name = nullptr;
|
|
||||||
_description = other._description;
|
|
||||||
other._description = nullptr;
|
|
||||||
_isMaxOneCheatActive = other._isMaxOneCheatActive;
|
|
||||||
other._isMaxOneCheatActive = false;
|
|
||||||
_subCategories = other._subCategories;
|
|
||||||
other._subCategories = nullptr;
|
|
||||||
_numberOfSubCategories = other._numberOfSubCategories;
|
|
||||||
other._numberOfSubCategories = 0;
|
|
||||||
_cheats = other._cheats;
|
|
||||||
other._cheats = nullptr;
|
|
||||||
_numberOfCheats = other._numberOfCheats;
|
|
||||||
other._numberOfCheats = 0;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~CheatCategory()
|
|
||||||
{
|
|
||||||
if (_subCategories != nullptr)
|
|
||||||
{
|
|
||||||
free(_subCategories);
|
|
||||||
}
|
|
||||||
if (_cheats != nullptr)
|
|
||||||
{
|
|
||||||
free(_cheats);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* GetName() const override
|
|
||||||
{
|
|
||||||
return _name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Gets the description of this cheat category.
|
|
||||||
/// @return A pointer to the description of this cheat category.
|
|
||||||
const char* GetDescription() const
|
|
||||||
{
|
|
||||||
return _description;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetIsMaxOneCheatActive() const override
|
|
||||||
{
|
|
||||||
return _isMaxOneCheatActive;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CheatCategory* GetCategories(u32& numberOfCategories) const override
|
|
||||||
{
|
|
||||||
numberOfCategories = _numberOfSubCategories;
|
|
||||||
return _subCategories;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Cheat* GetCheats(u32& numberOfCheats) const override
|
|
||||||
{
|
|
||||||
numberOfCheats = _numberOfCheats;
|
|
||||||
return _cheats;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const char* _name = nullptr;
|
|
||||||
const char* _description = nullptr;
|
|
||||||
bool _isMaxOneCheatActive = false;
|
|
||||||
CheatCategory* _subCategories = nullptr;
|
|
||||||
u32 _numberOfSubCategories = 0;
|
|
||||||
Cheat* _cheats = nullptr;
|
|
||||||
u32 _numberOfCheats = 0;
|
|
||||||
};
|
|
||||||
190
arm9/source/cheats/CheatEntry.h
Normal file
190
arm9/source/cheats/CheatEntry.h
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/// @brief Class representing a cheat or a cheat category.
|
||||||
|
class CheatEntry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// @brief Dummy empty constructor.
|
||||||
|
CheatEntry()
|
||||||
|
: _isCheatCategory(false), _flagsPointer(nullptr), _cheatData(nullptr), _cheatDataLength(0) { }
|
||||||
|
|
||||||
|
/// @brief Constructor for a cheat.
|
||||||
|
CheatEntry(const char* name, const char* description, u32* flagsPointer, const void* cheatData, u32 cheatDataLength)
|
||||||
|
: _name(name), _description(description), _isCheatCategory(false), _flagsPointer(flagsPointer)
|
||||||
|
, _cheatData(cheatData), _cheatDataLength(cheatDataLength) { }
|
||||||
|
|
||||||
|
/// @brief Constructor for a category.
|
||||||
|
CheatEntry(const char* name, const char* description, bool isMaxOneCheatActive, CheatEntry* subEntries, u32 numberOfSubEntries)
|
||||||
|
: _name(name), _description(description), _isCheatCategory(true), _isMaxOneCheatActive(isMaxOneCheatActive)
|
||||||
|
, _subEntries(subEntries), _numberOfSubEntries(numberOfSubEntries) { }
|
||||||
|
|
||||||
|
CheatEntry(const CheatEntry& other) = delete;
|
||||||
|
|
||||||
|
CheatEntry(CheatEntry&& other)
|
||||||
|
: _isCheatCategory(false), _flagsPointer(nullptr), _cheatData(nullptr), _cheatDataLength(0)
|
||||||
|
{
|
||||||
|
*this = std::move(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
~CheatEntry()
|
||||||
|
{
|
||||||
|
if (_isCheatCategory && _subEntries != nullptr)
|
||||||
|
{
|
||||||
|
delete[] _subEntries;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CheatEntry& operator=(const CheatEntry& other) = delete;
|
||||||
|
|
||||||
|
CheatEntry& operator=(CheatEntry&& other)
|
||||||
|
{
|
||||||
|
if (_isCheatCategory && _subEntries != nullptr)
|
||||||
|
{
|
||||||
|
delete[] _subEntries;
|
||||||
|
_subEntries = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
_name = other._name;
|
||||||
|
other._name = nullptr;
|
||||||
|
_description = other._description;
|
||||||
|
other._description = nullptr;
|
||||||
|
_isCheatCategory = other.IsCheatCategory();
|
||||||
|
if (_isCheatCategory)
|
||||||
|
{
|
||||||
|
_isMaxOneCheatActive = other._isMaxOneCheatActive;
|
||||||
|
_subEntries = other._subEntries;
|
||||||
|
other._subEntries = nullptr;
|
||||||
|
_numberOfSubEntries = other._numberOfSubEntries;
|
||||||
|
other._numberOfSubEntries = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_flagsPointer = other._flagsPointer;
|
||||||
|
other._flagsPointer = nullptr;
|
||||||
|
_cheatData = other._cheatData;
|
||||||
|
other._cheatData = nullptr;
|
||||||
|
_cheatDataLength = other._cheatDataLength;
|
||||||
|
other._cheatDataLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Gets the name of this cheat entry.
|
||||||
|
/// @return A pointer to the name of this cheat entry.
|
||||||
|
const char* GetName() const
|
||||||
|
{
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Gets the description of this cheat entry.
|
||||||
|
/// @return A pointer to the description of this cheat entry.
|
||||||
|
const char* GetDescription() const
|
||||||
|
{
|
||||||
|
return _description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief When this entry is a cheat, gets a pointer to the cheat data.
|
||||||
|
/// @param cheatDataLength The length of the cheat data is returned in this reference.
|
||||||
|
/// @return A pointer to the cheat data.
|
||||||
|
/// This pointer is only valid for the lifetime of the \see GameCheats instance this cheat belongs to.
|
||||||
|
/// If this entry is not a cheat, \c nullptr is returned.
|
||||||
|
const void* GetCheatData(u32& cheatDataLength) const
|
||||||
|
{
|
||||||
|
if (_isCheatCategory)
|
||||||
|
{
|
||||||
|
cheatDataLength = 0;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cheatDataLength = _cheatDataLength;
|
||||||
|
return _cheatData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Gets whether this entry is an active (enabled) cheat or not.
|
||||||
|
/// @return \c true when this entry is an active cheat, or \c false otherwise.
|
||||||
|
bool GetIsCheatActive() const
|
||||||
|
{
|
||||||
|
if (_isCheatCategory)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ((*_flagsPointer >> 24) & 1) == 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief If this entry is a cheat, sets whether this cheat is active (enabled) or not.
|
||||||
|
/// @param isCheatActive \c true to enable this cheat, or \c false to disable this cheat.
|
||||||
|
void SetIsCheatActive(bool isCheatActive) const
|
||||||
|
{
|
||||||
|
if (!_isCheatCategory)
|
||||||
|
{
|
||||||
|
u32 flags = *_flagsPointer;
|
||||||
|
flags &= ~(1 << 24);
|
||||||
|
if (isCheatActive)
|
||||||
|
{
|
||||||
|
flags |= 1 << 24;
|
||||||
|
}
|
||||||
|
*_flagsPointer = flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Indicates if this entry is a cheat category or not.
|
||||||
|
/// @return \c true when this entry is a cheat category, or \c false when this entry is a cheat.
|
||||||
|
bool IsCheatCategory() const
|
||||||
|
{
|
||||||
|
return _isCheatCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Indicates if this entry is a cheat category in which only one cheat is allowed to be on at a time or not.
|
||||||
|
/// @return \c true when this entry is a cheat category in which only one cheat is allowed
|
||||||
|
/// to be active at a time, or \c false otherwise.
|
||||||
|
bool GetIsMaxOneCheatActive() const
|
||||||
|
{
|
||||||
|
return _isCheatCategory && _isMaxOneCheatActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Gets the sub-entries of this entry.
|
||||||
|
/// @param numberOfSubEntries The number of sub-entries is returned through this reference.
|
||||||
|
/// @return A pointer to an array of entries. This may be \c nullptr when \p numberOfSubEntries is 0.
|
||||||
|
const CheatEntry* GetSubEntries(u32& numberOfSubEntries) const
|
||||||
|
{
|
||||||
|
if (_isCheatCategory)
|
||||||
|
{
|
||||||
|
numberOfSubEntries = _numberOfSubEntries;
|
||||||
|
return _subEntries;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
numberOfSubEntries = 0;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char* _name = nullptr;
|
||||||
|
const char* _description = nullptr;
|
||||||
|
bool _isCheatCategory;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
// For cheat
|
||||||
|
u32* _flagsPointer;
|
||||||
|
const void* _cheatData;
|
||||||
|
u32 _cheatDataLength;
|
||||||
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
// For category
|
||||||
|
bool _isMaxOneCheatActive;
|
||||||
|
CheatEntry* _subEntries;
|
||||||
|
u32 _numberOfSubEntries;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -1,48 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Cheat.h"
|
#include "CheatEntry.h"
|
||||||
#include "CheatCategory.h"
|
|
||||||
#include "ICheatCategory.h"
|
|
||||||
|
|
||||||
/// @brief Class holding the cheats for a game.
|
/// @brief Class holding the cheats for a game.
|
||||||
class GameCheats : public ICheatCategory
|
class GameCheats : public CheatEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GameCheats(std::unique_ptr<u8[]> cheatData, u32 cheatDataLength, u32 fileOffset, const char* gameName,
|
GameCheats(std::unique_ptr<u8[]> cheatData, u32 cheatDataLength, u32 fileOffset, const char* gameName,
|
||||||
CheatCategory* categories, u32 numberOfCategories, Cheat* cheats, u32 numberOfCheats)
|
CheatEntry* subEntries, u32 numberOfSubEntries)
|
||||||
: _cheatData(std::move(cheatData)), _cheatDataLength(cheatDataLength), _fileOffset(fileOffset), _gameName(gameName)
|
: CheatEntry(gameName, "", false, subEntries, numberOfSubEntries)
|
||||||
, _categories(categories), _numberOfCategories(numberOfCategories)
|
, _cheatData(std::move(cheatData)), _cheatDataLength(cheatDataLength)
|
||||||
, _cheats(cheats), _numberOfCheats(numberOfCheats) { }
|
, _fileOffset(fileOffset) { }
|
||||||
|
|
||||||
~GameCheats()
|
|
||||||
{
|
|
||||||
if (_categories != nullptr)
|
|
||||||
{
|
|
||||||
free(_categories);
|
|
||||||
}
|
|
||||||
if (_cheats != nullptr)
|
|
||||||
{
|
|
||||||
free(_cheats);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Gets the name of the game.
|
|
||||||
/// @return A pointer to the name of the game.
|
|
||||||
const char* GetGameName() const
|
|
||||||
{
|
|
||||||
return _gameName;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CheatCategory* GetCategories(u32& numberOfCategories) const override
|
|
||||||
{
|
|
||||||
numberOfCategories = _numberOfCategories;
|
|
||||||
return _categories;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Cheat* GetCheats(u32& numberOfCheats) const override
|
|
||||||
{
|
|
||||||
numberOfCheats = _numberOfCheats;
|
|
||||||
return _cheats;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Gets a pointer to the cheat data.
|
/// @brief Gets a pointer to the cheat data.
|
||||||
/// @param cheatDataLength The length of the cheat data is returned in this reference.
|
/// @param cheatDataLength The length of the cheat data is returned in this reference.
|
||||||
@@ -62,20 +29,4 @@ private:
|
|||||||
std::unique_ptr<u8[]> _cheatData;
|
std::unique_ptr<u8[]> _cheatData;
|
||||||
u32 _cheatDataLength;
|
u32 _cheatDataLength;
|
||||||
u32 _fileOffset;
|
u32 _fileOffset;
|
||||||
const char* _gameName;
|
|
||||||
CheatCategory* _categories;
|
|
||||||
u32 _numberOfCategories;
|
|
||||||
Cheat* _cheats;
|
|
||||||
u32 _numberOfCheats;
|
|
||||||
|
|
||||||
// From ICheatCategory
|
|
||||||
const char* GetName() const override
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetIsMaxOneCheatActive() const override
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
class CheatCategory;
|
|
||||||
class Cheat;
|
|
||||||
|
|
||||||
/// @brief Interface for a collection of cheats.
|
|
||||||
class ICheatCategory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~ICheatCategory() = default;
|
|
||||||
|
|
||||||
/// @brief Gets the name of this category.
|
|
||||||
/// @return The name of this category.
|
|
||||||
virtual const char* GetName() const = 0;
|
|
||||||
|
|
||||||
/// @brief Indicates if only one cheat in this category is allowed to be on or not.
|
|
||||||
/// @return \c true when only one cheat is allowed to be active in this category, or \c false otherwise.
|
|
||||||
virtual bool GetIsMaxOneCheatActive() const = 0;
|
|
||||||
|
|
||||||
/// @brief Gets the sub-categories of this category.
|
|
||||||
/// @param numberOfCategories The number of categories is returned through this reference.
|
|
||||||
/// @return A pointer to an array of categories. This may be \c nullptr when \p numberOfCategories is 0.
|
|
||||||
virtual const CheatCategory* GetCategories(u32& numberOfCategories) const;
|
|
||||||
|
|
||||||
/// @brief Gets the cheats in this category.
|
|
||||||
/// @param numberOfCheats The number of cheats is returned through this reference.
|
|
||||||
/// @return A pointer to an array of cheats. This may be \c nullptr when \p numberOfCheats is 0.
|
|
||||||
virtual const Cheat* GetCheats(u32& numberOfCheats) const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ICheatCategory() = default;
|
|
||||||
};
|
|
||||||
@@ -8,7 +8,7 @@ pload_cheats_t* PicoLoaderCheatDataFactory::CreateCheatData(const std::unique_pt
|
|||||||
if (gameCheats)
|
if (gameCheats)
|
||||||
{
|
{
|
||||||
u32 totalNumberOfCheats = 0;
|
u32 totalNumberOfCheats = 0;
|
||||||
u32 requiredSize = GetCheatCategoryRequiredSize(gameCheats.get(), totalNumberOfCheats);
|
u32 requiredSize = GetCheatEntryRequiredSize(gameCheats.get(), totalNumberOfCheats);
|
||||||
if (totalNumberOfCheats != 0)
|
if (totalNumberOfCheats != 0)
|
||||||
{
|
{
|
||||||
requiredSize += sizeof(u32) * 2;
|
requiredSize += sizeof(u32) * 2;
|
||||||
@@ -16,32 +16,32 @@ pload_cheats_t* PicoLoaderCheatDataFactory::CreateCheatData(const std::unique_pt
|
|||||||
cheatData->length = requiredSize;
|
cheatData->length = requiredSize;
|
||||||
cheatData->numberOfCheats = totalNumberOfCheats;
|
cheatData->numberOfCheats = totalNumberOfCheats;
|
||||||
u8* buffer = (u8*)&cheatData->firstCheat;
|
u8* buffer = (u8*)&cheatData->firstCheat;
|
||||||
GetCheatCategoryData(gameCheats.get(), buffer);
|
GetCheatEntryData(gameCheats.get(), buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cheatData;
|
return cheatData;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 PicoLoaderCheatDataFactory::GetCheatCategoryRequiredSize(const ICheatCategory* cheatCategory, u32& totalNumberOfCheats) const
|
u32 PicoLoaderCheatDataFactory::GetCheatEntryRequiredSize(const CheatEntry* cheatEntry, u32& totalNumberOfCheats) const
|
||||||
{
|
{
|
||||||
u32 requiredSize = 0;
|
u32 requiredSize = 0;
|
||||||
|
if (cheatEntry->IsCheatCategory())
|
||||||
u32 numberOfCategories = 0;
|
|
||||||
auto subCategories = cheatCategory->GetCategories(numberOfCategories);
|
|
||||||
for (u32 i = 0; i < numberOfCategories; i++)
|
|
||||||
{
|
{
|
||||||
requiredSize += GetCheatCategoryRequiredSize(&subCategories[i], totalNumberOfCheats);
|
u32 numberOfSubEntries = 0;
|
||||||
|
auto subEntries = cheatEntry->GetSubEntries(numberOfSubEntries);
|
||||||
|
for (u32 i = 0; i < numberOfSubEntries; i++)
|
||||||
|
{
|
||||||
|
requiredSize += GetCheatEntryRequiredSize(&subEntries[i], totalNumberOfCheats);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
u32 numberOfCheats = 0;
|
else
|
||||||
auto cheats = cheatCategory->GetCheats(numberOfCheats);
|
|
||||||
for (u32 i = 0; i < numberOfCheats; i++)
|
|
||||||
{
|
{
|
||||||
u32 cheatRequiredSize = GetCheatRequiredSize(&cheats[i]);
|
if (cheatEntry->GetIsCheatActive())
|
||||||
if (cheatRequiredSize != 0)
|
|
||||||
{
|
{
|
||||||
requiredSize += cheatRequiredSize;
|
u32 cheatDataLength = 0;
|
||||||
|
cheatEntry->GetCheatData(cheatDataLength);
|
||||||
|
requiredSize += sizeof(u32) + ((cheatDataLength + 7) & ~7);
|
||||||
totalNumberOfCheats++;
|
totalNumberOfCheats++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,43 +49,23 @@ u32 PicoLoaderCheatDataFactory::GetCheatCategoryRequiredSize(const ICheatCategor
|
|||||||
return requiredSize;
|
return requiredSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 PicoLoaderCheatDataFactory::GetCheatRequiredSize(const Cheat* cheat) const
|
void PicoLoaderCheatDataFactory::GetCheatEntryData(const CheatEntry* cheatEntry, u8*& buffer) const
|
||||||
{
|
{
|
||||||
if (cheat->GetIsCheatActive())
|
if (cheatEntry->IsCheatCategory())
|
||||||
{
|
{
|
||||||
u32 cheatDataLength = 0;
|
u32 numberOfSubEntries = 0;
|
||||||
cheat->GetCheatData(cheatDataLength);
|
auto subEntries = cheatEntry->GetSubEntries(numberOfSubEntries);
|
||||||
return sizeof(u32) + ((cheatDataLength + 7) & ~7);
|
for (u32 i = 0; i < numberOfSubEntries; i++)
|
||||||
|
{
|
||||||
|
GetCheatEntryData(&subEntries[i], buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return 0;
|
if (cheatEntry->GetIsCheatActive())
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PicoLoaderCheatDataFactory::GetCheatCategoryData(const ICheatCategory* cheatCategory, u8*& buffer) const
|
|
||||||
{
|
|
||||||
u32 numberOfCategories = 0;
|
|
||||||
auto subCategories = cheatCategory->GetCategories(numberOfCategories);
|
|
||||||
for (u32 i = 0; i < numberOfCategories; i++)
|
|
||||||
{
|
|
||||||
GetCheatCategoryData(&subCategories[i], buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 numberOfCheats = 0;
|
|
||||||
auto cheats = cheatCategory->GetCheats(numberOfCheats);
|
|
||||||
for (u32 i = 0; i < numberOfCheats; i++)
|
|
||||||
{
|
|
||||||
GetCheatData(&cheats[i], buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PicoLoaderCheatDataFactory::GetCheatData(const Cheat* cheat, u8*& buffer) const
|
|
||||||
{
|
|
||||||
if (cheat->GetIsCheatActive())
|
|
||||||
{
|
{
|
||||||
u32 cheatDataLength = 0;
|
u32 cheatDataLength = 0;
|
||||||
auto cheatData = cheat->GetCheatData(cheatDataLength);
|
auto cheatData = cheatEntry->GetCheatData(cheatDataLength);
|
||||||
u32 paddedCheatDataLength = (cheatDataLength + 7) & ~7;
|
u32 paddedCheatDataLength = (cheatDataLength + 7) & ~7;
|
||||||
*(u32*)buffer = paddedCheatDataLength;
|
*(u32*)buffer = paddedCheatDataLength;
|
||||||
buffer += sizeof(u32);
|
buffer += sizeof(u32);
|
||||||
@@ -97,3 +77,4 @@ void PicoLoaderCheatDataFactory::GetCheatData(const Cheat* cheat, u8*& buffer) c
|
|||||||
buffer += paddedCheatDataLength;
|
buffer += paddedCheatDataLength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ public:
|
|||||||
pload_cheats_t* CreateCheatData(const std::unique_ptr<GameCheats>& gameCheats) const;
|
pload_cheats_t* CreateCheatData(const std::unique_ptr<GameCheats>& gameCheats) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u32 GetCheatCategoryRequiredSize(const ICheatCategory* cheatCategory, u32& totalNumberOfCheats) const;
|
u32 GetCheatEntryRequiredSize(const CheatEntry* cheatEntry, u32& totalNumberOfCheats) const;
|
||||||
u32 GetCheatRequiredSize(const Cheat* cheat) const;
|
void GetCheatEntryData(const CheatEntry* cheatEntry, u8*& buffer) const;
|
||||||
void GetCheatCategoryData(const ICheatCategory* cheatCategory, u8*& buffer) const;
|
|
||||||
void GetCheatData(const Cheat* cheat, u8*& buffer) const;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -107,11 +107,8 @@ std::unique_ptr<GameCheats> UsrCheatRepository::GetCheatsForGame(u32 gameCode, u
|
|||||||
// master codes
|
// master codes
|
||||||
ptr += 8 * 4;
|
ptr += 8 * 4;
|
||||||
|
|
||||||
auto categories = (CheatCategory*)malloc(totalNumberOfItems * sizeof(CheatCategory));
|
auto entries = new CheatEntry[totalNumberOfItems];
|
||||||
u32 categoryCount = 0;
|
u32 entryCount = 0;
|
||||||
|
|
||||||
auto cheats = (Cheat*)malloc(totalNumberOfItems * sizeof(Cheat));
|
|
||||||
u32 cheatCount = 0;
|
|
||||||
|
|
||||||
while (ptr < cheatData.get() + cheatDataLength)
|
while (ptr < cheatData.get() + cheatDataLength)
|
||||||
{
|
{
|
||||||
@@ -119,21 +116,20 @@ std::unique_ptr<GameCheats> UsrCheatRepository::GetCheatsForGame(u32 gameCode, u
|
|||||||
bool isCategory = ((itemFlags >> 28) & 1) == 1;
|
bool isCategory = ((itemFlags >> 28) & 1) == 1;
|
||||||
if (isCategory)
|
if (isCategory)
|
||||||
{
|
{
|
||||||
ParseCategory(categories[categoryCount], ptr);
|
entries[entryCount++] = ParseCategory(ptr);
|
||||||
categoryCount++;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ParseCheat(cheats[cheatCount], ptr);
|
entries[entryCount++] = ParseCheat(ptr);
|
||||||
cheatCount++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
categories = (CheatCategory*)realloc(categories, categoryCount * sizeof(CheatCategory));
|
auto actualEntries = new CheatEntry[entryCount];
|
||||||
cheats = (Cheat*)realloc(cheats, cheatCount * sizeof(Cheat));
|
std::move(entries, entries + entryCount, actualEntries);
|
||||||
|
delete[] entries;
|
||||||
|
|
||||||
return std::make_unique<GameCheats>(
|
return std::make_unique<GameCheats>(
|
||||||
std::move(cheatData), cheatDataLength, index->offset, gameName, categories, categoryCount, cheats, cheatCount);
|
std::move(cheatData), cheatDataLength, index->offset, gameName, actualEntries, entryCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
const usr_cheat_index_entry_t* UsrCheatRepository::FindIndex(u32 gameCode, u32 headerCrc32) const
|
const usr_cheat_index_entry_t* UsrCheatRepository::FindIndex(u32 gameCode, u32 headerCrc32) const
|
||||||
@@ -162,7 +158,7 @@ const usr_cheat_index_entry_t* UsrCheatRepository::FindIndex(u32 gameCode, u32 h
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UsrCheatRepository::ParseCategory(CheatCategory& category, u8*& ptr) const
|
CheatEntry UsrCheatRepository::ParseCategory(u8*& ptr) const
|
||||||
{
|
{
|
||||||
// flags
|
// flags
|
||||||
u32 itemFlags = *(u32*)ptr;
|
u32 itemFlags = *(u32*)ptr;
|
||||||
@@ -181,35 +177,25 @@ void UsrCheatRepository::ParseCategory(CheatCategory& category, u8*& ptr) const
|
|||||||
// padding
|
// padding
|
||||||
ptr = (u8*)(((u32)ptr + 3) & ~3); // 32-bit align
|
ptr = (u8*)(((u32)ptr + 3) & ~3); // 32-bit align
|
||||||
|
|
||||||
auto categories = (CheatCategory*)malloc(numberOfItems * sizeof(CheatCategory));
|
auto entries = new CheatEntry[numberOfItems];
|
||||||
u32 categoryCount = 0;
|
|
||||||
|
|
||||||
auto cheats = (Cheat*)malloc(numberOfItems * sizeof(Cheat));
|
|
||||||
u32 cheatCount = 0;
|
|
||||||
|
|
||||||
for (u32 i = 0; i < numberOfItems; i++)
|
for (u32 i = 0; i < numberOfItems; i++)
|
||||||
{
|
{
|
||||||
u32 itemFlags = *(u32*)ptr;
|
u32 itemFlags = *(u32*)ptr;
|
||||||
bool isCategory = ((itemFlags >> 28) & 1) == 1;
|
bool isCategory = ((itemFlags >> 28) & 1) == 1;
|
||||||
if (isCategory)
|
if (isCategory)
|
||||||
{
|
{
|
||||||
ParseCategory(categories[categoryCount], ptr);
|
entries[i] = ParseCategory(ptr);
|
||||||
categoryCount++;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ParseCheat(cheats[cheatCount], ptr);
|
entries[i] = ParseCheat(ptr);
|
||||||
cheatCount++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
categories = (CheatCategory*)realloc(categories, categoryCount * sizeof(CheatCategory));
|
return CheatEntry(itemName, itemDescription, isMaxOneCheatActive, entries, numberOfItems);
|
||||||
cheats = (Cheat*)realloc(cheats, cheatCount * sizeof(Cheat));
|
|
||||||
|
|
||||||
new (&category) CheatCategory (itemName, itemDescription, isMaxOneCheatActive, categories, categoryCount, cheats, cheatCount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UsrCheatRepository::ParseCheat(Cheat& cheat, u8*& ptr) const
|
CheatEntry UsrCheatRepository::ParseCheat(u8*& ptr) const
|
||||||
{
|
{
|
||||||
// flags
|
// flags
|
||||||
u32* flagsPtr = (u32*)ptr;
|
u32* flagsPtr = (u32*)ptr;
|
||||||
@@ -230,8 +216,10 @@ void UsrCheatRepository::ParseCheat(Cheat& cheat, u8*& ptr) const
|
|||||||
u32 numberOfCodeWords = *(u32*)ptr;
|
u32 numberOfCodeWords = *(u32*)ptr;
|
||||||
ptr += 4;
|
ptr += 4;
|
||||||
|
|
||||||
new (&cheat) Cheat(itemName, itemDescription, flagsPtr, ptr, numberOfCodeWords * 4);
|
const void* cheatData = ptr;
|
||||||
|
|
||||||
// code
|
// code
|
||||||
ptr += numberOfCodeWords * 4;
|
ptr += numberOfCodeWords * 4;
|
||||||
|
|
||||||
|
return CheatEntry(itemName, itemDescription, flagsPtr, cheatData, numberOfCodeWords * 4);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,6 @@ private:
|
|||||||
|
|
||||||
std::unique_ptr<GameCheats> GetCheatsForGame(u32 gameCode, u32 headerCrc32) const;
|
std::unique_ptr<GameCheats> GetCheatsForGame(u32 gameCode, u32 headerCrc32) const;
|
||||||
const usr_cheat_index_entry_t* FindIndex(u32 gameCode, u32 headerCrc32) const;
|
const usr_cheat_index_entry_t* FindIndex(u32 gameCode, u32 headerCrc32) const;
|
||||||
void ParseCategory(CheatCategory& category, u8*& ptr) const;
|
CheatEntry ParseCategory(u8*& ptr) const;
|
||||||
void ParseCheat(Cheat& cheat, u8*& ptr) const;
|
CheatEntry ParseCheat(u8*& ptr) const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -89,14 +89,8 @@ u32 AdvancedPaletteManagerBase::TryMerge(PaletteRow* rows, const PaletteRow& new
|
|||||||
|
|
||||||
u32 AdvancedPaletteManagerBase::AllocRowInternal(PaletteRow* rows, const IPalette& palette, int yStart, int yEnd)
|
u32 AdvancedPaletteManagerBase::AllocRowInternal(PaletteRow* rows, const IPalette& palette, int yStart, int yEnd)
|
||||||
{
|
{
|
||||||
if (yStart < 0)
|
yStart = std::clamp(yStart, 0, 192);
|
||||||
{
|
yEnd = std::clamp(yEnd, 0, 192);
|
||||||
yStart = 0;
|
|
||||||
}
|
|
||||||
if (yEnd > 192)
|
|
||||||
{
|
|
||||||
yEnd = 192;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 newIdx = _usedRows;
|
u32 newIdx = _usedRows;
|
||||||
PaletteRow& newRow = rows[newIdx];
|
PaletteRow& newRow = rows[newIdx];
|
||||||
|
|||||||
@@ -33,39 +33,40 @@ void CheatsViewModel::ActivateSelectedItem()
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto cheatCategory = GetCurrentCheatCategory();
|
auto cheatCategory = GetCurrentCheatCategory();
|
||||||
u32 numberOfCategories = 0;
|
u32 numberOfSubEntries = 0;
|
||||||
auto categories = cheatCategory->GetCategories(numberOfCategories);
|
auto subEntries = cheatCategory->GetSubEntries(numberOfSubEntries);
|
||||||
u32 numberOfCheats = 0;
|
|
||||||
auto cheats = cheatCategory->GetCheats(numberOfCheats);
|
|
||||||
|
|
||||||
if (numberOfCategories + numberOfCheats == 0)
|
if (numberOfSubEntries == 0)
|
||||||
{
|
{
|
||||||
// There is nothing to activate
|
// There is nothing to activate
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_selectedItem < (int)numberOfCategories)
|
auto& entry = subEntries[_selectedItem];
|
||||||
|
if (entry.IsCheatCategory())
|
||||||
{
|
{
|
||||||
// Category activated
|
// Category activated
|
||||||
if (_categoryStackLevel + 1 != _categoryStack.size())
|
if (_categoryStackLevel + 1 != _categoryStack.size())
|
||||||
{
|
{
|
||||||
_categoryStack[++_categoryStackLevel] = { &categories[_selectedItem], (u32)_selectedItem };
|
_categoryStack[++_categoryStackLevel] = { &entry, (u32)_selectedItem };
|
||||||
_selectedItem = 0;
|
_selectedItem = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Toggle cheat on/off
|
// Toggle cheat on/off
|
||||||
auto& cheat = cheats[_selectedItem - numberOfCategories];
|
bool isEnabled = !entry.GetIsCheatActive();
|
||||||
bool isEnabled = !cheat.GetIsCheatActive();
|
|
||||||
if (isEnabled && cheatCategory->GetIsMaxOneCheatActive())
|
if (isEnabled && cheatCategory->GetIsMaxOneCheatActive())
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < numberOfCheats; i++)
|
for (u32 i = 0; i < numberOfSubEntries; i++)
|
||||||
{
|
{
|
||||||
cheats[i].SetIsCheatActive(false);
|
if (!subEntries[i].IsCheatCategory())
|
||||||
|
{
|
||||||
|
subEntries[i].SetIsCheatActive(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cheat.SetIsCheatActive(isEnabled);
|
}
|
||||||
|
entry.SetIsCheatActive(isEnabled);
|
||||||
_changed = true;
|
_changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,23 +112,24 @@ void CheatsViewModel::DisableAllCheats()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheatsViewModel::DisableAllCheats(const ICheatCategory* cheatCategory)
|
void CheatsViewModel::DisableAllCheats(const CheatEntry* cheatCategory)
|
||||||
{
|
{
|
||||||
u32 numberOfCategories = 0;
|
u32 numberOfSubEntries = 0;
|
||||||
auto categories = cheatCategory->GetCategories(numberOfCategories);
|
auto subEntries = cheatCategory->GetSubEntries(numberOfSubEntries);
|
||||||
for (u32 i = 0; i < numberOfCategories; i++)
|
for (u32 i = 0; i < numberOfSubEntries; i++)
|
||||||
{
|
{
|
||||||
DisableAllCheats(&categories[i]);
|
auto& entry = subEntries[i];
|
||||||
|
if (entry.IsCheatCategory())
|
||||||
|
{
|
||||||
|
DisableAllCheats(&entry);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
u32 numberOfCheats = 0;
|
|
||||||
auto cheats = cheatCategory->GetCheats(numberOfCheats);
|
|
||||||
for (u32 i = 0; i < numberOfCheats; i++)
|
|
||||||
{
|
{
|
||||||
if (cheats[i].GetIsCheatActive())
|
if (entry.GetIsCheatActive())
|
||||||
{
|
{
|
||||||
cheats[i].SetIsCheatActive(false);
|
entry.SetIsCheatActive(false);
|
||||||
_changed = true;
|
_changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public:
|
|||||||
|
|
||||||
/// @brief Gets the current cheat category.
|
/// @brief Gets the current cheat category.
|
||||||
/// @return The current cheat category.
|
/// @return The current cheat category.
|
||||||
const ICheatCategory* GetCurrentCheatCategory() const { return _categoryStack[_categoryStackLevel].cheatCategory; }
|
const CheatEntry* GetCurrentCheatCategory() const { return _categoryStack[_categoryStackLevel].cheatCategory; }
|
||||||
|
|
||||||
/// @brief Gets the index of the selected item.
|
/// @brief Gets the index of the selected item.
|
||||||
/// @return The index of the selected item.
|
/// @return The index of the selected item.
|
||||||
@@ -64,7 +64,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
struct CategoryStackEntry
|
struct CategoryStackEntry
|
||||||
{
|
{
|
||||||
const ICheatCategory* cheatCategory;
|
const CheatEntry* cheatCategory;
|
||||||
u32 index;
|
u32 index;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -78,5 +78,5 @@ private:
|
|||||||
u32 _categoryStackLevel = 0;
|
u32 _categoryStackLevel = 0;
|
||||||
std::array<CategoryStackEntry, 8> _categoryStack;
|
std::array<CategoryStackEntry, 8> _categoryStack;
|
||||||
|
|
||||||
void DisableAllCheats(const ICheatCategory* cheatCategory);
|
void DisableAllCheats(const CheatEntry* cheatCategory);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ CheatListItemView::CheatListItemView(const VramOffsets& vramOffsets,
|
|||||||
void CheatListItemView::Update()
|
void CheatListItemView::Update()
|
||||||
{
|
{
|
||||||
_nameLabel.SetPosition(_position.x + NAME_LABEL_X, _position.y + NAME_LABEL_Y);
|
_nameLabel.SetPosition(_position.x + NAME_LABEL_X, _position.y + NAME_LABEL_Y);
|
||||||
if (_cheat != nullptr)
|
if (_cheatEntry != nullptr && !_cheatEntry->IsCheatCategory())
|
||||||
{
|
{
|
||||||
_iconVramOffset = _cheat->GetIsCheatActive()
|
_iconVramOffset = _cheatEntry->GetIsCheatActive()
|
||||||
? _vramOffsets.checkboxCheckedIconVramOffset
|
? _vramOffsets.checkboxCheckedIconVramOffset
|
||||||
: _vramOffsets.checkboxUncheckedIconVramOffset;
|
: _vramOffsets.checkboxUncheckedIconVramOffset;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "gui/views/ViewContainer.h"
|
#include "gui/views/ViewContainer.h"
|
||||||
#include "gui/views/Label2DView.h"
|
#include "gui/views/Label2DView.h"
|
||||||
#include "cheats/CheatCategory.h"
|
#include "cheats/CheatEntry.h"
|
||||||
#include "cheats/Cheat.h"
|
|
||||||
|
|
||||||
class MaterialColorScheme;
|
class MaterialColorScheme;
|
||||||
class IFontRepository;
|
class IFontRepository;
|
||||||
@@ -34,17 +33,14 @@ public:
|
|||||||
_nameLabel.SetText(name);
|
_nameLabel.SetText(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetCategory(const CheatCategory* cheatCategory)
|
void SetEntry(const CheatEntry* cheatEntry)
|
||||||
|
{
|
||||||
|
_cheatEntry = cheatEntry;
|
||||||
|
_nameLabel.SetText(cheatEntry->GetName());
|
||||||
|
if (cheatEntry->IsCheatCategory())
|
||||||
{
|
{
|
||||||
_cheat = nullptr;
|
|
||||||
_nameLabel.SetText(cheatCategory->GetName());
|
|
||||||
_iconVramOffset = _vramOffsets.folderIconVramOffset;
|
_iconVramOffset = _vramOffsets.folderIconVramOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetCheat(const Cheat* cheat)
|
|
||||||
{
|
|
||||||
_cheat = cheat;
|
|
||||||
_nameLabel.SetText(_cheat->GetName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -52,5 +48,5 @@ private:
|
|||||||
VramOffsets _vramOffsets;
|
VramOffsets _vramOffsets;
|
||||||
const MaterialColorScheme* _materialColorScheme;
|
const MaterialColorScheme* _materialColorScheme;
|
||||||
u32 _iconVramOffset = 0;
|
u32 _iconVramOffset = 0;
|
||||||
const Cheat* _cheat = nullptr;
|
const CheatEntry* _cheatEntry = nullptr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,25 +1,22 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "gui/views/RecyclerAdapter.h"
|
#include "gui/views/RecyclerAdapter.h"
|
||||||
#include "cheats/CheatCategory.h"
|
#include "cheats/CheatEntry.h"
|
||||||
#include "cheats/Cheat.h"
|
|
||||||
#include "CheatListItemView.h"
|
#include "CheatListItemView.h"
|
||||||
|
|
||||||
/// @brief Recycler adapter for cheats.
|
/// @brief Recycler adapter for cheats.
|
||||||
class CheatsAdapter : public RecyclerAdapter
|
class CheatsAdapter : public RecyclerAdapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CheatsAdapter(const ICheatCategory* cheatCategory, const MaterialColorScheme* materialColorScheme,
|
CheatsAdapter(const CheatEntry* cheatCategory, const MaterialColorScheme* materialColorScheme,
|
||||||
const IFontRepository* fontRepository, const CheatListItemView::VramOffsets& vramOffsets)
|
const IFontRepository* fontRepository, const CheatListItemView::VramOffsets& vramOffsets)
|
||||||
: _cheatCategory(cheatCategory), _materialColorScheme(materialColorScheme)
|
: _cheatCategory(cheatCategory), _materialColorScheme(materialColorScheme)
|
||||||
, _fontRepository(fontRepository), _vramOffsets(vramOffsets) { }
|
, _fontRepository(fontRepository), _vramOffsets(vramOffsets) { }
|
||||||
|
|
||||||
u32 GetItemCount() const override
|
u32 GetItemCount() const override
|
||||||
{
|
{
|
||||||
u32 numberOfCategories = 0;
|
u32 numberOfSubEntries = 0;
|
||||||
_cheatCategory->GetCategories(numberOfCategories);
|
_cheatCategory->GetSubEntries(numberOfSubEntries);
|
||||||
u32 numberOfCheats = 0;
|
return numberOfSubEntries;
|
||||||
_cheatCategory->GetCheats(numberOfCheats);
|
|
||||||
return numberOfCategories + numberOfCheats;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetViewSize(int& width, int& height) const override
|
void GetViewSize(int& width, int& height) const override
|
||||||
@@ -41,19 +38,9 @@ public:
|
|||||||
void BindView(View* view, int index) const override
|
void BindView(View* view, int index) const override
|
||||||
{
|
{
|
||||||
auto listItemView = static_cast<CheatListItemView*>(view);
|
auto listItemView = static_cast<CheatListItemView*>(view);
|
||||||
u32 numberOfCategories = 0;
|
u32 numberOfSubEntries = 0;
|
||||||
auto categories = _cheatCategory->GetCategories(numberOfCategories);
|
auto subEntries = _cheatCategory->GetSubEntries(numberOfSubEntries);
|
||||||
if ((u32)index < numberOfCategories)
|
listItemView->SetEntry(&subEntries[index]);
|
||||||
{
|
|
||||||
listItemView->SetCategory(&categories[index]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
index -= numberOfCategories;
|
|
||||||
u32 numberOfCheats = 0;
|
|
||||||
auto cheats = _cheatCategory->GetCheats(numberOfCheats);
|
|
||||||
listItemView->SetCheat(&cheats[index]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReleaseView(View* view, int index) const override
|
void ReleaseView(View* view, int index) const override
|
||||||
@@ -62,7 +49,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const ICheatCategory* _cheatCategory;
|
const CheatEntry* _cheatCategory;
|
||||||
const MaterialColorScheme* _materialColorScheme;
|
const MaterialColorScheme* _materialColorScheme;
|
||||||
const IFontRepository* _fontRepository;
|
const IFontRepository* _fontRepository;
|
||||||
CheatListItemView::VramOffsets _vramOffsets;
|
CheatListItemView::VramOffsets _vramOffsets;
|
||||||
|
|||||||
@@ -237,6 +237,9 @@ bool CheatsBottomSheetView::HandleInput(const InputProvider& inputProvider, Focu
|
|||||||
|
|
||||||
void CheatsBottomSheetView::UpdateCheatList()
|
void CheatsBottomSheetView::UpdateCheatList()
|
||||||
{
|
{
|
||||||
|
// Need to unfocus first, otherwise the focus manager still contains a pointer to a view that is going to be destroyed
|
||||||
|
_focusManager->Unfocus();
|
||||||
|
|
||||||
auto oldAdapter = _cheatsAdapter;
|
auto oldAdapter = _cheatsAdapter;
|
||||||
_cheatsAdapter = new CheatsAdapter(
|
_cheatsAdapter = new CheatsAdapter(
|
||||||
_viewModel->GetCurrentCheatCategory(), _materialColorScheme, _fontRepository, _vramOffsets);
|
_viewModel->GetCurrentCheatCategory(), _materialColorScheme, _fontRepository, _vramOffsets);
|
||||||
@@ -261,21 +264,8 @@ void CheatsBottomSheetView::UpdateDescriptionText()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto cheatCategory = _viewModel->GetCurrentCheatCategory();
|
auto cheatCategory = _viewModel->GetCurrentCheatCategory();
|
||||||
u32 numberOfCategories = 0;
|
u32 numberOfSubEntries = 0;
|
||||||
auto categories = cheatCategory->GetCategories(numberOfCategories);
|
auto subEntries = cheatCategory->GetSubEntries(numberOfSubEntries);
|
||||||
u32 numberOfCheats = 0;
|
_descriptionLabel.SetText(subEntries[selectedItem].GetDescription());
|
||||||
auto cheats = cheatCategory->GetCheats(numberOfCheats);
|
|
||||||
if ((u32)selectedItem < numberOfCategories)
|
|
||||||
{
|
|
||||||
_descriptionLabel.SetText(categories[selectedItem].GetDescription());
|
|
||||||
}
|
|
||||||
else if ((u32)selectedItem < numberOfCategories + numberOfCheats)
|
|
||||||
{
|
|
||||||
_descriptionLabel.SetText(cheats[selectedItem - numberOfCategories].GetDescription());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_descriptionLabel.SetText("");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user