summaryrefslogtreecommitdiffstatshomepage
path: root/src/frontend/mame/cheat.h
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2016-04-23 11:25:03 +0200
committer Miodrag Milanovic <mmicko@gmail.com>2016-04-23 11:26:47 +0200
commit1c726824f2b2cc7c6c03ff975e548b72f9b2c0a9 (patch)
tree020f20da5a8cd822065c1839bc7a53f826803a3d /src/frontend/mame/cheat.h
parent01657a63c13c79c5f045ba4ecb4c2fd7f7c5a1f8 (diff)
Split UI and frontend part from core [Miodrag Milanovic]
Diffstat (limited to 'src/frontend/mame/cheat.h')
-rw-r--r--src/frontend/mame/cheat.h337
1 files changed, 337 insertions, 0 deletions
diff --git a/src/frontend/mame/cheat.h b/src/frontend/mame/cheat.h
new file mode 100644
index 00000000000..dac90e17286
--- /dev/null
+++ b/src/frontend/mame/cheat.h
@@ -0,0 +1,337 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles
+/***************************************************************************
+
+ cheat.h
+
+ Cheat system.
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __CHEAT_H__
+#define __CHEAT_H__
+
+#include "debug/express.h"
+#include "ui/ui.h"
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+enum script_state
+{
+ SCRIPT_STATE_OFF = 0,
+ SCRIPT_STATE_ON,
+ SCRIPT_STATE_RUN,
+ SCRIPT_STATE_CHANGE,
+ SCRIPT_STATE_COUNT
+};
+DECLARE_ENUM_OPERATORS(script_state)
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+class cheat_manager;
+
+
+// ======================> number_and_format
+
+// helper class to remember a format along with a number
+class number_and_format
+{
+public:
+ // construction/destruction
+ number_and_format(UINT64 value = 0, int format = 0)
+ : m_value(value),
+ m_format(format) { }
+
+ // pass-through to look like a regular number
+ operator UINT64 &() { return m_value; }
+ operator const UINT64 &() const { return m_value; }
+
+ // format the number according to its format
+ std::string format() const;
+
+private:
+ // internal state
+ UINT64 m_value;
+ int m_format;
+};
+
+
+// ======================> cheat_parameter
+
+// a parameter for a cheat, which can be set in the UI
+class cheat_parameter
+{
+public:
+ // construction/destruction
+ cheat_parameter(cheat_manager &manager, symbol_table &symbols, const char *filename, xml_data_node &paramnode);
+
+ // queries
+ const char *text();
+ bool has_itemlist() const { return (m_itemlist.count() != 0); }
+ bool is_minimum() const { return (m_value == ((m_itemlist.count() == 0) ? m_minval : m_itemlist.first()->value())); }
+ bool is_maximum() const { return (m_value == ((m_itemlist.count() == 0) ? m_maxval : m_itemlist.last()->value())); }
+
+ // state setters
+ bool set_minimum_state();
+ bool set_prev_state();
+ bool set_next_state();
+
+ // actions
+ void save(emu_file &cheatfile) const;
+
+private:
+ // a single item in a parameter item list
+ class item
+ {
+ friend class simple_list<item>;
+
+ public:
+ // construction/destruction
+ item(const char *text, UINT64 value, int valformat)
+ : m_next(nullptr),
+ m_text(text),
+ m_value(value, valformat) { }
+
+ // getters
+ item *next() const { return m_next; }
+ const number_and_format &value() const { return m_value; }
+ const char *text() const { return m_text.c_str(); }
+
+ private:
+ // internal state
+ item * m_next; // next item in list
+ std::string m_text; // name of the item
+ number_and_format m_value; // value of the item
+ };
+
+ // internal state
+ number_and_format m_minval; // minimum value
+ number_and_format m_maxval; // maximum value
+ number_and_format m_stepval; // step value
+ UINT64 m_value; // live value of the parameter
+ std::string m_curtext; // holding for a value string
+ simple_list<item> m_itemlist; // list of items
+};
+
+
+// ======================> cheat_script
+
+// a script entry, specifying which state to execute under
+class cheat_script
+{
+ friend class simple_list<cheat_script>;
+
+public:
+ // construction/destruction
+ cheat_script(cheat_manager &manager, symbol_table &symbols, const char *filename, xml_data_node &scriptnode);
+
+ // getters
+ script_state state() const { return m_state; }
+
+ // actions
+ void execute(cheat_manager &manager, UINT64 &argindex);
+ void save(emu_file &cheatfile) const;
+
+private:
+ // an entry within the script
+ class script_entry
+ {
+ friend class simple_list<script_entry>;
+
+ public:
+ // construction/destruction
+ script_entry(cheat_manager &manager, symbol_table &symbols, const char *filename, xml_data_node &entrynode, bool isaction);
+
+ // getters
+ script_entry *next() const { return m_next; }
+
+ // actions
+ void execute(cheat_manager &manager, UINT64 &argindex);
+ void save(emu_file &cheatfile) const;
+
+ private:
+ // an argument for output
+ class output_argument
+ {
+ friend class simple_list<output_argument>;
+
+ public:
+ // construction/destruction
+ output_argument(cheat_manager &manager, symbol_table &symbols, const char *filename, xml_data_node &argnode);
+
+ // getters
+ output_argument *next() const { return m_next; }
+ int count() const { return m_count; }
+ int values(UINT64 &argindex, UINT64 *result);
+
+ // actions
+ void save(emu_file &cheatfile) const;
+
+ private:
+ // internal state
+ output_argument * m_next; // link to next argument
+ parsed_expression m_expression; // expression for argument
+ UINT64 m_count; // number of repetitions
+ };
+
+ // internal helpers
+ void validate_format(const char *filename, int line);
+
+ // internal state
+ script_entry * m_next; // link to next entry
+ parsed_expression m_condition; // condition under which this is executed
+ parsed_expression m_expression; // expression to execute
+ std::string m_format; // string format to print
+ simple_list<output_argument> m_arglist; // list of arguments
+ INT8 m_line; // which line to print on
+ UINT8 m_justify; // justification when printing
+
+ // constants
+ static const int MAX_ARGUMENTS = 32;
+ };
+
+ // internal state
+ simple_list<script_entry> m_entrylist; // list of actions to perform
+ script_state m_state; // which state this script is for
+};
+
+
+// ======================> cheat_entry
+
+// a single cheat
+class cheat_entry
+{
+ friend class simple_list<cheat_entry>;
+
+public:
+ // construction/destruction
+ cheat_entry(cheat_manager &manager, symbol_table &globaltable, const char *filename, xml_data_node &cheatnode);
+ ~cheat_entry();
+
+ // getters
+ cheat_manager &manager() const { return m_manager; }
+ cheat_entry *next() const { return m_next; }
+ script_state state() const { return m_state; }
+ const char *description() const { return m_description.c_str(); }
+ const char *comment() const { return m_comment.c_str(); }
+
+ // script detection
+ bool has_run_script() const { return (m_run_script != nullptr); }
+ bool has_on_script() const { return (m_on_script != nullptr); }
+ bool has_off_script() const { return (m_off_script != nullptr); }
+ bool has_change_script() const { return (m_change_script != nullptr); }
+
+ // script execution
+ void execute_off_script() { if (has_off_script()) m_off_script->execute(m_manager, m_argindex); }
+ void execute_on_script() { if (has_on_script()) m_on_script->execute(m_manager, m_argindex); }
+ void execute_run_script() { if (has_run_script()) m_run_script->execute(m_manager, m_argindex); }
+ void execute_change_script() { if (has_change_script()) m_change_script->execute(m_manager, m_argindex); }
+
+ // cheat classification
+ bool is_text_only() const { return (m_parameter == nullptr && !has_run_script() && !has_off_script() && !has_on_script()); }
+ bool is_oneshot() const { return (m_parameter == nullptr && !has_run_script() && !has_off_script() && has_on_script()); }
+ bool is_onoff() const { return (m_parameter == nullptr && (has_run_script() || (has_off_script() && has_on_script()))); }
+ bool is_value_parameter() const { return (m_parameter != nullptr && !m_parameter->has_itemlist()); }
+ bool is_itemlist_parameter() const { return (m_parameter != nullptr && m_parameter->has_itemlist()); }
+ bool is_oneshot_parameter() const { return (m_parameter != nullptr && !has_run_script() && !has_off_script() && has_change_script()); }
+ bool is_duplicate() const;
+
+ // actions
+ bool activate();
+ bool select_default_state();
+ bool select_previous_state();
+ bool select_next_state();
+ void save(emu_file &cheatfile) const;
+
+ // UI helpers
+ void menu_text(std::string &description, std::string &state, UINT32 &flags);
+
+ // per-frame update
+ void frame_update() { if (m_state == SCRIPT_STATE_RUN) execute_run_script(); }
+
+private:
+ // internal helpers
+ bool set_state(script_state newstate);
+ std::unique_ptr<cheat_script> &script_for_state(script_state state);
+
+ // internal state
+ cheat_manager & m_manager; // reference to our manager
+ cheat_entry * m_next; // next cheat entry
+ std::string m_description; // string description/menu title
+ std::string m_comment; // comment data
+ std::unique_ptr<cheat_parameter> m_parameter; // parameter
+ std::unique_ptr<cheat_script> m_on_script; // script to run when turning on
+ std::unique_ptr<cheat_script> m_off_script; // script to run when turning off
+ std::unique_ptr<cheat_script> m_change_script; // script to run when value changes
+ std::unique_ptr<cheat_script> m_run_script; // script to run each frame when on
+ symbol_table m_symbols; // symbol table for this cheat
+ script_state m_state; // current cheat state
+ UINT32 m_numtemp; // number of temporary variables
+ UINT64 m_argindex; // argument index variable
+
+ // constants
+ static const int DEFAULT_TEMP_VARIABLES = 10;
+};
+
+
+// ======================> cheat_manager
+
+// private machine-global data
+class cheat_manager
+{
+public:
+ // construction/destruction
+ cheat_manager(running_machine &machine);
+
+ // getters
+ running_machine &machine() const { return m_machine; }
+ bool enabled() const { return !m_disabled; }
+ const simple_list<cheat_entry> &entries() const { return m_cheatlist; }
+
+ // setters
+ void set_enable(bool enable = true);
+
+ // actions
+ void reload();
+ bool save_all(const char *filename);
+ void render_text(render_container &container);
+
+ // output helpers
+ std::string &get_output_astring(int row, int justify);
+
+ // global helpers
+ static std::string quote_expression(const parsed_expression &expression);
+ static UINT64 execute_frombcd(symbol_table &table, void *ref, int params, const UINT64 *param);
+ static UINT64 execute_tobcd(symbol_table &table, void *ref, int params, const UINT64 *param);
+
+private:
+ // internal helpers
+ void frame_update();
+ void load_cheats(const char *filename);
+
+ // internal state
+ running_machine & m_machine; // reference to our machine
+ simple_list<cheat_entry> m_cheatlist; // cheat list
+ UINT64 m_framecount; // frame count
+ std::vector<std::string> m_output; // array of output strings
+ std::vector<UINT8> m_justify; // justification for each string
+ UINT8 m_numlines; // number of lines available for output
+ INT8 m_lastline; // last line used for output
+ bool m_disabled; // true if the cheat engine is disabled
+ symbol_table m_symtable; // global symbol table
+
+ // constants
+ static constexpr int CHEAT_VERSION = 1;
+};
+
+
+#endif /* __CHEAT_H__ */