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;
|
Filename = filename;
|
||||||
|
|
||||||
Error = false;
|
|
||||||
|
|
||||||
Categories.clear();
|
|
||||||
|
|
||||||
if (!Load())
|
if (!Load())
|
||||||
Error = true;
|
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()
|
bool ARCodeFile::Load()
|
||||||
|
|
|
@ -48,14 +48,16 @@ class ARCodeFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ARCodeFile(const std::string& filename);
|
ARCodeFile(const std::string& filename);
|
||||||
~ARCodeFile();
|
~ARCodeFile() noexcept = default;
|
||||||
|
|
||||||
bool Error;
|
[[nodiscard]] std::vector<ARCode> GetCodes() const noexcept;
|
||||||
|
|
||||||
|
bool Error = false;
|
||||||
|
|
||||||
bool Load();
|
bool Load();
|
||||||
bool Save();
|
bool Save();
|
||||||
|
|
||||||
ARCodeCatList Categories;
|
ARCodeCatList Categories {};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string Filename;
|
std::string Filename;
|
||||||
|
|
|
@ -31,7 +31,6 @@ using Platform::LogLevel;
|
||||||
|
|
||||||
AREngine::AREngine(melonDS::NDS& nds) : NDS(nds)
|
AREngine::AREngine(melonDS::NDS& nds) : NDS(nds)
|
||||||
{
|
{
|
||||||
CodeFile = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define case16(x) \
|
#define case16(x) \
|
||||||
|
@ -388,19 +387,12 @@ void AREngine::RunCheat(const ARCode& arcode)
|
||||||
|
|
||||||
void AREngine::RunCheats()
|
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)
|
if (code.Enabled)
|
||||||
RunCheat(code);
|
RunCheat(code);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#ifndef ARENGINE_H
|
#ifndef ARENGINE_H
|
||||||
#define ARENGINE_H
|
#define ARENGINE_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
#include "ARCodeFile.h"
|
#include "ARCodeFile.h"
|
||||||
|
|
||||||
namespace melonDS
|
namespace melonDS
|
||||||
|
@ -29,14 +30,13 @@ class AREngine
|
||||||
public:
|
public:
|
||||||
AREngine(melonDS::NDS& nds);
|
AREngine(melonDS::NDS& nds);
|
||||||
|
|
||||||
ARCodeFile* GetCodeFile() { return CodeFile; }
|
std::vector<ARCode> Cheats {};
|
||||||
void SetCodeFile(ARCodeFile* file) { CodeFile = file; }
|
private:
|
||||||
|
friend class ARM;
|
||||||
void RunCheats();
|
void RunCheats();
|
||||||
void RunCheat(const ARCode& arcode);
|
void RunCheat(const ARCode& arcode);
|
||||||
private:
|
|
||||||
melonDS::NDS& NDS;
|
melonDS::NDS& NDS;
|
||||||
ARCodeFile* CodeFile; // AR code file - frontend is responsible for managing this
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -686,12 +686,8 @@ void EmuInstance::undoStateLoad()
|
||||||
|
|
||||||
void EmuInstance::unloadCheats()
|
void EmuInstance::unloadCheats()
|
||||||
{
|
{
|
||||||
if (cheatFile)
|
cheatFile = nullptr; // cleaned up by unique_ptr
|
||||||
{
|
nds->AREngine.Cheats.clear();
|
||||||
delete cheatFile;
|
|
||||||
cheatFile = nullptr;
|
|
||||||
nds->AREngine.SetCodeFile(nullptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuInstance::loadCheats()
|
void EmuInstance::loadCheats()
|
||||||
|
@ -701,9 +697,16 @@ void EmuInstance::loadCheats()
|
||||||
std::string filename = getAssetPath(false, globalCfg.GetString("CheatFilePath"), ".mch");
|
std::string filename = getAssetPath(false, globalCfg.GetString("CheatFilePath"), ".mch");
|
||||||
|
|
||||||
// TODO: check for error (malformed cheat file, ...)
|
// 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
|
std::unique_ptr<ARM9BIOSImage> EmuInstance::loadARM9BIOS() noexcept
|
||||||
|
@ -1013,12 +1016,14 @@ void EmuInstance::enableCheats(bool enable)
|
||||||
{
|
{
|
||||||
cheatsOn = enable;
|
cheatsOn = enable;
|
||||||
if (cheatFile)
|
if (cheatFile)
|
||||||
nds->AREngine.SetCodeFile(cheatsOn ? cheatFile : nullptr);
|
nds->AREngine.Cheats = cheatFile->GetCodes();
|
||||||
|
else
|
||||||
|
nds->AREngine.Cheats.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
ARCodeFile* EmuInstance::getCheatFile()
|
ARCodeFile* EmuInstance::getCheatFile()
|
||||||
{
|
{
|
||||||
return cheatFile;
|
return cheatFile.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuInstance::setBatteryLevels()
|
void EmuInstance::setBatteryLevels()
|
||||||
|
|
|
@ -256,7 +256,7 @@ private:
|
||||||
bool savestateLoaded;
|
bool savestateLoaded;
|
||||||
std::string previousSaveFile;
|
std::string previousSaveFile;
|
||||||
|
|
||||||
melonDS::ARCodeFile* cheatFile;
|
std::unique_ptr<melonDS::ARCodeFile> cheatFile;
|
||||||
bool cheatsOn;
|
bool cheatsOn;
|
||||||
|
|
||||||
SDL_AudioDeviceID audioDevice;
|
SDL_AudioDeviceID audioDevice;
|
||||||
|
|
Loading…
Reference in New Issue