Allow `AREngine` to be used independently of `ARCodeFile` (#2108)
* Make `EmuInstance::cheatFile` use a `unique_ptr` - Fixes a memory leak, as the cheat file wasn't cleaned up in the destructor * Split `AREngine` and `ARCodeFile` apart - Suitable for frontends that have their own way of storing cheats - Store the cheats in `AREngine` in a `std::vector` - Apparently cheats are _supposed_ to be executed each frame; I didn't understand this until recently
This commit is contained in:
parent
f3f6a6a194
commit
c6bf5d5181
|
@ -33,17 +33,26 @@ ARCodeFile::ARCodeFile(const std::string& filename)
|
|||
{
|
||||
Filename = filename;
|
||||
|
||||
Error = false;
|
||||
|
||||
Categories.clear();
|
||||
|
||||
if (!Load())
|
||||
Error = true;
|
||||
}
|
||||
|
||||
ARCodeFile::~ARCodeFile()
|
||||
std::vector<ARCode> ARCodeFile::GetCodes() const noexcept
|
||||
{
|
||||
Categories.clear();
|
||||
if (Error)
|
||||
return {};
|
||||
|
||||
std::vector<ARCode> codes;
|
||||
|
||||
for (const ARCodeCat& cat : Categories)
|
||||
{
|
||||
for (const ARCode& code : cat.Codes)
|
||||
{
|
||||
codes.push_back(code);
|
||||
}
|
||||
}
|
||||
|
||||
return codes;
|
||||
}
|
||||
|
||||
bool ARCodeFile::Load()
|
||||
|
|
|
@ -48,14 +48,16 @@ class ARCodeFile
|
|||
{
|
||||
public:
|
||||
ARCodeFile(const std::string& filename);
|
||||
~ARCodeFile();
|
||||
~ARCodeFile() noexcept = default;
|
||||
|
||||
bool Error;
|
||||
[[nodiscard]] std::vector<ARCode> GetCodes() const noexcept;
|
||||
|
||||
bool Error = false;
|
||||
|
||||
bool Load();
|
||||
bool Save();
|
||||
|
||||
ARCodeCatList Categories;
|
||||
ARCodeCatList Categories {};
|
||||
|
||||
private:
|
||||
std::string Filename;
|
||||
|
|
|
@ -31,7 +31,6 @@ using Platform::LogLevel;
|
|||
|
||||
AREngine::AREngine(melonDS::NDS& nds) : NDS(nds)
|
||||
{
|
||||
CodeFile = nullptr;
|
||||
}
|
||||
|
||||
#define case16(x) \
|
||||
|
@ -388,19 +387,12 @@ void AREngine::RunCheat(const ARCode& arcode)
|
|||
|
||||
void AREngine::RunCheats()
|
||||
{
|
||||
if (!CodeFile) return;
|
||||
if (Cheats.empty()) return;
|
||||
|
||||
for (ARCodeCatList::iterator i = CodeFile->Categories.begin(); i != CodeFile->Categories.end(); i++)
|
||||
for (const ARCode& code : Cheats)
|
||||
{
|
||||
ARCodeCat& cat = *i;
|
||||
|
||||
for (ARCodeList::iterator j = cat.Codes.begin(); j != cat.Codes.end(); j++)
|
||||
{
|
||||
ARCode& code = *j;
|
||||
|
||||
if (code.Enabled)
|
||||
RunCheat(code);
|
||||
}
|
||||
if (code.Enabled)
|
||||
RunCheat(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#ifndef ARENGINE_H
|
||||
#define ARENGINE_H
|
||||
|
||||
#include <vector>
|
||||
#include "ARCodeFile.h"
|
||||
|
||||
namespace melonDS
|
||||
|
@ -29,14 +30,13 @@ class AREngine
|
|||
public:
|
||||
AREngine(melonDS::NDS& nds);
|
||||
|
||||
ARCodeFile* GetCodeFile() { return CodeFile; }
|
||||
void SetCodeFile(ARCodeFile* file) { CodeFile = file; }
|
||||
|
||||
std::vector<ARCode> Cheats {};
|
||||
private:
|
||||
friend class ARM;
|
||||
void RunCheats();
|
||||
void RunCheat(const ARCode& arcode);
|
||||
private:
|
||||
|
||||
melonDS::NDS& NDS;
|
||||
ARCodeFile* CodeFile; // AR code file - frontend is responsible for managing this
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -686,12 +686,8 @@ void EmuInstance::undoStateLoad()
|
|||
|
||||
void EmuInstance::unloadCheats()
|
||||
{
|
||||
if (cheatFile)
|
||||
{
|
||||
delete cheatFile;
|
||||
cheatFile = nullptr;
|
||||
nds->AREngine.SetCodeFile(nullptr);
|
||||
}
|
||||
cheatFile = nullptr; // cleaned up by unique_ptr
|
||||
nds->AREngine.Cheats.clear();
|
||||
}
|
||||
|
||||
void EmuInstance::loadCheats()
|
||||
|
@ -701,9 +697,16 @@ void EmuInstance::loadCheats()
|
|||
std::string filename = getAssetPath(false, globalCfg.GetString("CheatFilePath"), ".mch");
|
||||
|
||||
// TODO: check for error (malformed cheat file, ...)
|
||||
cheatFile = new ARCodeFile(filename);
|
||||
cheatFile = std::make_unique<ARCodeFile>(filename);
|
||||
|
||||
nds->AREngine.SetCodeFile(cheatsOn ? cheatFile : nullptr);
|
||||
if (cheatsOn)
|
||||
{
|
||||
nds->AREngine.Cheats = cheatFile->GetCodes();
|
||||
}
|
||||
else
|
||||
{
|
||||
nds->AREngine.Cheats.clear();
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<ARM9BIOSImage> EmuInstance::loadARM9BIOS() noexcept
|
||||
|
@ -1013,12 +1016,14 @@ void EmuInstance::enableCheats(bool enable)
|
|||
{
|
||||
cheatsOn = enable;
|
||||
if (cheatFile)
|
||||
nds->AREngine.SetCodeFile(cheatsOn ? cheatFile : nullptr);
|
||||
nds->AREngine.Cheats = cheatFile->GetCodes();
|
||||
else
|
||||
nds->AREngine.Cheats.clear();
|
||||
}
|
||||
|
||||
ARCodeFile* EmuInstance::getCheatFile()
|
||||
{
|
||||
return cheatFile;
|
||||
return cheatFile.get();
|
||||
}
|
||||
|
||||
void EmuInstance::setBatteryLevels()
|
||||
|
|
|
@ -256,7 +256,7 @@ private:
|
|||
bool savestateLoaded;
|
||||
std::string previousSaveFile;
|
||||
|
||||
melonDS::ARCodeFile* cheatFile;
|
||||
std::unique_ptr<melonDS::ARCodeFile> cheatFile;
|
||||
bool cheatsOn;
|
||||
|
||||
SDL_AudioDeviceID audioDevice;
|
||||
|
|
Loading…
Reference in New Issue