Unverified Commit 0b9f8dde authored by RobLoach's avatar RobLoach Committed by GitHub
Browse files

Merge pull request #288 from libretro/cheats

Add Cheat support
parents 05101f13 6a1a89de
......@@ -4,6 +4,10 @@ All notable changes to [ChaiLove](https://github.com/RobLoach/ChaiLove) will be
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## 0.25.0 - Unreleased
### Features
- Added Cheat support
## 0.24.0 - 2018-09-03
### Features
- Update to use libretro-common audio
......
......@@ -240,3 +240,21 @@ bool ChaiLove::loadstate(const std::string& data) {
}
return false;
}
/**
* Invoke the script cheatreset hook.
*/
void ChaiLove::cheatreset() {
if (script != NULL) {
script->cheatreset();
}
}
/**
* Invoke the script cheatset hook.
*/
void ChaiLove::cheatset(int index, bool enabled, const std::string& code) {
if (script != NULL) {
script->cheatset(index, enabled, code);
}
}
......@@ -111,6 +111,8 @@ class ChaiLove {
void reset();
std::string savestate();
bool loadstate(const std::string& data);
void cheatreset();
void cheatset(int index, bool enabled, const std::string& code);
uint32_t *videoBuffer = NULL;
SDL_Surface* screen = NULL;
......
......@@ -285,16 +285,19 @@ bool retro_unserialize(const void *data, size_t size) {
* libretro callback; Reset the enabled cheats.
*/
void retro_cheat_reset(void) {
// Nothing.
if (ChaiLove::hasInstance()) {
ChaiLove::getInstance()->cheatreset();
}
}
/**
* libretro callback; Set the given cheat.
*/
void retro_cheat_set(unsigned index, bool enabled, const char *code) {
(void)index;
(void)enabled;
(void)code;
if (ChaiLove::hasInstance()) {
std::string codeString(code);
ChaiLove::getInstance()->cheatset(index, enabled, codeString);
}
}
/**
......
......@@ -462,7 +462,7 @@ script::script(const std::string& file) {
haskeyreleased = false;
}
try {
chailoadstate = chai.eval<std::function<bool(std::string)> >("loadstate");
chailoadstate = chai.eval<std::function<bool(const std::string&)> >("loadstate");
}
catch (const std::exception& e) {
std::cout << "[ChaiLove] [script] loadstate() " << e.what() << std::endl;
......@@ -475,6 +475,20 @@ script::script(const std::string& file) {
std::cout << "[ChaiLove] [script] savestate() " << e.what() << std::endl;
hassavestate = false;
}
try {
chaicheatreset = chai.eval<std::function<void()> >("cheatreset");
}
catch (const std::exception& e) {
std::cout << "[ChaiLove] [script] cheatreset() Warning: " << e.what() << std::endl;
hascheatreset = false;
}
try {
chaicheatset = chai.eval<std::function<void(int, bool, const std::string&)> >("cheatset");
}
catch (const std::exception& e) {
std::cout << "[ChaiLove] [script] cheatset() Warning: " << e.what() << std::endl;
hascheatset = false;
}
try {
chaiexit = chai.eval<std::function<void()> >("exit");
}
......@@ -695,6 +709,34 @@ bool script::loadstate(const std::string& data) {
return false;
}
void script::cheatreset() {
#ifdef __HAVE_CHAISCRIPT__
if (hascheatreset) {
try {
chaicheatreset();
}
catch (const std::exception& e) {
std::cout << "[ChaiLove] [script] Failed to call cheatreset(): " << e.what() << std::endl;
hascheatreset = false;
}
}
#endif
}
void script::cheatset(int index, bool enabled, const std::string& code) {
#ifdef __HAVE_CHAISCRIPT__
if (hascheatreset) {
try {
chaicheatset(index, enabled, code);
}
catch (const std::exception& e) {
std::cout << "[ChaiLove] [script] Failed to call cheatset(): " << e.what() << std::endl;
hascheatset = false;
}
}
#endif
}
void script::exit() {
#ifdef __HAVE_CHAISCRIPT__
if (hasexit) {
......
......@@ -373,6 +373,47 @@ class script {
*/
bool loadstate(const std::string& data);
/**
* Called when requested to reset the state of all the cheats to their default state.
*
* ### Example
*
* @code
* global invincible = false
*
* def cheatreset() {
* invincible = false
* }
* @endcode
*
* @see cheatset
*/
void cheatreset();
/**
* Called when requested to enable or disable a cheat.
*
* @param index The index of the cheat.
* @param enabled Whether the cheat is to be enabled or disabled.
* @param code The code for the cheat.
*
* ### Example
*
* @code
* global invincible = false
*
* def cheatset(index, enabled, code) {
* if (code == "invincible") {
* // Enable or disable invincibility
* invincible = enabled
* }
* }
* @endcode
*
* @see cheatreset
*/
void cheatset(int index, bool enabled, const std::string& code);
/**
* Callback function triggered when the game is closed.
*
......@@ -397,7 +438,9 @@ class script {
std::function<void()> chaidraw;
std::function<void()> chaiexit;
std::function<void()> chaireset;
std::function<bool(std::string)> chailoadstate;
std::function<void(int, bool, const std::string&)> chaicheatset;
std::function<void()> chaicheatreset;
std::function<bool(const std::string&)> chailoadstate;
std::function<std::string()> chaisavestate;
std::function<void(int, const std::string&)> chaijoystickpressed;
std::function<void(int, const std::string&)> chaijoystickreleased;
......@@ -421,6 +464,8 @@ class script {
bool hasload = true;
bool hasconf = true;
bool hasreset = true;
bool hascheatreset = true;
bool hascheatset = true;
#endif
std::string replaceString(std::string subject, const std::string& search, const std::string& replace);
......
/**
* Cheat Test
*
* retroarch -L chailove_libretro.so test/sound.chai
*/
global lastcheatcode
def load() {
lastcheatcode = "Enter a cheat code!"
}
def draw() {
love.graphics.print(lastcheatcode, 20, 100)
}
def cheatset(index, enabled, code) {
print("Cheat Test: Cheat Toggle")
print("Index: " + to_string(index))
print("Enabled: " + to_string(enabled))
print("Code: " + to_string(code))
if (enabled) {
lastcheatcode = code + " Enabled"
}
else {
lastcheatcode = code + " Disabled"
}
}
def cheatreset() {
print("Cheat Test: Cheat Reset")
lastcheatcode = "Cheats have been reset"
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment