Memory (constructor)
Declaration
explicit Memory(std::uint8_t* base);Views the memory that begins at
base (openrac_api.memory).Reference · SDK 1.11.0
openrac/mod.hpp. It is compiled into your mod; the game still sees only the C tabledetail), the Mod itself, the stack frame, and last the macro that writes a mod's entry points. Each item says which interface version added it; the layer itself needs only the table of the interface the mod was built for.#include "openrac/mod.hpp"
#include "openrac/games/rac1.hpp"static void load(openrac::Mod& mod) {
if (mod.game() != "rac1") throw openrac::Error("this mod is for Ratchet & Clank");
const bool trace = mod.setting<bool>("trace");
mod.hook<openrac::rac1::Hero_TurnToHeading>(
[](auto original, int32_t m, float accel, float damping, float limit) {
original(m, accel, damping, limit); // the game's own, or a mod's loaded earlier
});
mod.on_frame([] { /* once a game tick */ });
}
OPENRAC_MOD_CPP("my-mod", "0.1.0", load)explicit Memory(std::uint8_t* base);base (openrac_api.memory).template <class T> T read(gaddr address) const;T at address, copied out; T is a plain value (trivially copyable).template <class T> void write(gaddr address, const T& value) const;value to address; T is a plain value (trivially copyable). It does not mark anything the game caches: a value the game keeps elsewhere is the mod's to update.template <class T> T& ref(gaddr address) const;T at address as an lvalue. The address must be aligned for T, and the reference must not be kept across a level load (the level's program moves its globals).void* pointer(gaddr address) const;address.std::uint8_t* base() const;explicit Input(const openrac_input* state);state (openrac_api.input()'s result).const openrac_input& raw() const;bool held(int bind) const;bool pressed(int bind) const;float mouse_dx() const;float mouse_dy() const;float wheel_x() const;float wheel_y() const;bool focused() const;bool captured() const;bool overlay() const;std::uint32_t tick() const;bool has_pointer() const;float pointer_x() const;float pointer_y() const;bool pointer_inside() const;explicit MenuFrame(const openrac_menu_frame& frame);frame.bool held(std::uint32_t buttons) const;buttons is down now, or went down since the last frame.bool pressed(std::uint32_t buttons) const;bool opened() const;const openrac_menu_frame& raw() const;MenuPage(const openrac_api* api, openrac_mod* handle);api for the mod handle.void rect(int x, int y, int w, int h, std::uint32_t rgba) const;w by h pixels from (x, y), the top left, with rgba (OPENRAC_RGBA), blended.void text(int x, int y, int size, std::uint32_t rgba, const std::string& text) const;text (ASCII) from (x, y), its top left, at size (1 to 8) in rgba.void text_centred(int y, int size, std::uint32_t rgba, const std::string& text) const;text centred across the page, its top at y.static int text_width(std::string_view text, int size);text is at size, in pixels: its longest line's characters, without the last one's spacing column.template <class R, class... A>using fn = R (*)(A...);explicit Original(fn f);f that the replacement goes on to.R operator()(A... args) const;args, as the game would have called the hook point.fn get() const;static UiItem button(std::string label, bool enabled = true);enabled), a line of text the cursor passes over, and a choice of choices showing choice, which Left and Right step.static UiItem text(std::string label);static UiItem choice_of(std::string label, std::vector<std::string> choices, std::uint32_t choice);explicit UiEvent(const openrac_ui_event& event);std::uint32_t kind() const;bool is(std::uint32_t kind) const;kind.int item() const;int value() const;std::uint32_t tag() const;int cursor() const;const openrac_ui_event& raw() const;UiPage() = default;UiPage(const openrac_api* api, openrac_mod* handle, int id);id of the mod handle, through api.int id() const;void set(const UiContent& content) const;content on the page. Throws openrac::Error when refused (no such page).bool open() const;question on this page (answered by an OPENRAC_UI_ANSWER with tag), plays a menu sound (OPENRAC_UI_SOUND_*).bool back() const;bool confirm(const std::string& question, std::uint32_t tag = 0) const;bool sound(int sound) const;int cursor() const;item (an item the cursor takes).int set_cursor(int item) const;Mod(const openrac_api* api, openrac_mod* handle);const openrac_api& api() const;openrac_mod* handle() const;std::string_view game() const;static void load(openrac::Mod& mod) {
if (mod.game() != "rac1") throw openrac::Error("this mod is for Ratchet & Clank");void load(openrac::Mod& mod) {
// Refuse here rather than misbehave later: a mod written for one game reads its memory and
// takes its hook points, which another game does not have.
if (mod.game() != "rac1") {
throw openrac::Error("this mod is for Ratchet & Clank");
}std::string_view version() const;std::string_view platform() const;std::string_view openrac_version() const;unsigned api_major() const;unsigned api_minor() const;void log(LogLevel level, const std::string& text) const;text to the session's log at level, after the mod's id.void debug(const std::string& text) const;text to the log at the level the name says.void info(const std::string& text) const;mod.hook<openrac::rac1::Hero_TurnToHeading>(
[trace, &mod](auto original, int32_t m, float accel, float damping, float limit) {
if (trace) mod.info("turning");
original(m, accel, damping, limit);
}); mod.info(extra ? "loaded, with the extra" : "loaded");
}void warn(const std::string& text) const;void error(const std::string& text) const;void fail(const std::string& reason) const;template <class T> T setting(const char* key) const;const bool trace = mod.setting<bool>("trace");const bool extra = mod.setting<bool>("enabled_extra");template <class HookPoint, class F> void hook(F&& callable);callable, called as callable(original, args...). Throws openrac::Error when the port has no such hook point, a different signature, or the mod already took it. Only during load.mod.hook<openrac::rac1::Hero_TurnToHeading>(
[trace, &mod](auto original, int32_t m, float accel, float damping, float limit) {
if (trace) mod.info("turning");
original(m, accel, damping, limit);
});// A hook: the lambda gets the way on (the game's function, or a mod's loaded earlier) first,
// then the hook point's arguments. An exception thrown here is logged, and the original runs.
mod.hook<openrac::rac1::Hero_SetPlanarVelocity>([](auto original, float angle) {
// ... before the game's own ...
original(angle);
// ... after it ...
});template <class HookPoint> typename HookPoint::fn original() const;original), for calling it from elsewhere in the mod (another hook, a callback); nullptr before the hook is taken.template <class F> void on_frame(F&& callable);callable() after each game tick, in load order. Throws openrac::Error when refused. Only during load. mod.on_frame([] { /* after each game tick */ });
}// Once a game tick: read or change game memory through mod.memory().
mod.on_frame([] {});template <class F> void on_tick_boundary(F&& callable);callable(tick) after vertical-blank handlers. Snapshot calls are valid only here. Since 1.6; only during load.bool has_savestates() const;std::size_t savestate_size() const;void savestate_save(void* out, std::size_t size) const;void savestate_load(const void* data, std::size_t size) const;template <class F> void on_pad(F&& callable);callable(port, report, size) for each pad report, before the game reads it: the callable may change the report's bytes. Throws openrac::Error when refused. Only during load.template <class Fn> Fn function(const char* name) const;template <class Fn> Fn required_function(const char* name) const;template <class Fn> Fn function_at(gaddr address) const;bool has_input() const;Input input() const;void take_input(std::uint32_t devices);void capture_mouse(bool capture) const;bool has_views() const;const openrac_graphics &graphics() const;void on_views(const openrac_view_source &source);source asks for each frame (openrac_view_source, sdk/docs/views.md). Throws openrac::Error when refused. Only during load.void setup_vulkan(const openrac_vulkan_setup &setup);setup (openrac_vulkan_setup); the manifest says "vulkan_device": true. Throws openrac::Error when refused. Only during load.bool has_menu() const;template <class F> void menu_entry(const char* label, F&& callable);label to the game's front-end menu that opens a page drawn by callable(page, frame) each frame, which returns true to close it (MenuCallable). Throws openrac::Error when refused. Only during load.bool has_ui() const;template <class F> UiPage ui_page(F&& callable, std::uint32_t flags = 0);callable(page, event) (UiCallable), with flags (OPENRAC_UI_OWN_BACK). Throws openrac::Error when refused. Only during load.void ui_main_item(const char* after, const char* label, const UiPage& page);label to the title's main menu after its own after (OPENRAC_UI_NEW_GAME, _LOAD_GAME, _OPTIONS), opening page. Throws openrac::Error when refused. Only during load.bool has_play() const;openrac_play_status play_status() const;std::string level_name(int level) const;level, empty for none.bool hero_pose(openrac_pose& out) const;out; false when there is no hero now.int figure_create() const;bool figure_pose(int id, const openrac_pose& pose) const;id in pose (its size set here); false for a figure gone with its level (make another).bool figure_remove(int id) const;id out of the level; false for one gone already.int play_start(int level, const std::vector<std::uint8_t>& save =;level (no save), or save continued (in its own level, or level when 0 or more), after this frame. Returns OPENRAC_HOOK_OK, OPENRAC_HOOK_TAKEN (one is pending) or OPENRAC_HOOK_UNKNOWN (refused).int play_travel(int level) const;level after this frame; as play_start's results.std::vector<std::uint8_t> save_capture() const;int save_slot(int slot, openrac_save_info& out) const;slot holds, into out: 1 a save, 0 an empty slot, -1 past the last.std::vector<std::uint8_t> save_read(int slot) const;slot, for play_start; empty for none.bool has_api_11() const;std::string data_dir() const;int save_slot_current() const;bool has_world() const;std::vector<openrac_moby> moby_list() const;int moby_slot(int key) const;key, -1 for none.bool moby_drive(int slot, bool on = true) const;slot (or lets it go); false when refused.bool moby_pose(int slot, const openrac_moby& pose) const;bool moby_kill(int slot) const;int moby_spawn(int oclass, const openrac_moby& pose) const;int figure_slot(int id) const;id (-1: the hero's), -1 for none.void on_moby_update(openrac_moby_update_fn fn, void* user = nullptr);fn(slot, phase) returning true to skip it (before), and the watcher of the game's hits, fn(hit) returning true to take it back.user is passed on. Only during load; throws openrac::Error when refused.void on_moby_hit(openrac_hit_fn fn, void* user = nullptr);bool hero_stand_in(const float position[3], int figure) const;position with figure figure as his moby (-1: his own); false outside it.bool moby_hit(const openrac_hit& hit) const;hit (its size set here); false for no victim.void play_eyes(const std::vector<float>& xyz) const;add.int bolts(int add = 0) const;bool play_skip() const;bool has_held() const;bool hero_held(openrac_held& out) const;out; false when there is no hero now.bool figure_held(int id, const openrac_held& held) const;id wear and hold held (its size set here), each tick it is posed; false for a figure gone with its level.std::vector<openrac_shot> hero_shots() const;bool figure_shot(int id, const openrac_shot& shot) const;id fire shot (its size set here), hitting nothing in this game; false for a figure gone or a weapon the port cannot fire for one.bool has_notice() const;bool play_notice(const std::string& text) const;bool has_pause_items() const;void ui_pause_item(const char* label, const UiPage& page);label to the Options page of the pause menu in a level, opening page. Throws openrac::Error when refused. Only during load.bool has_scenes() const;int scene_playing(int* frame = nullptr) const;frame (when not null) gets how many of its frames have played.bool play_scene(int scene) const;scene from its start as the game's own trigger does, once the player is in control (-1 drops a request still waiting); false outside a level or for a port without scenes.bool has_moby_detail() const;bool moby_hide(int slot, bool hidden) const;slot from drawing (hidden) or shows it again; false for no moby there or a port without it.bool moby_deletion(int slot, openrac_moby_deletion& out) const;slot in this level load into out; false for none seen or a port without it.bool camera_position(float (&out)[3]) const;out (x, y, z); false outside a level or for a port without it.bool has_moby_run() const;bool moby_run(int slot, openrac_moby_run& out) const;slot (-1: none) in it, into out; false outside a level or for a port without it.int moby_slot_of(gaddr moby) const;moby (a hook point's argument), -1 none.bool play_overlay_pause(bool on) const;on; false for a game without it.Memory memory() const;// Once a game tick: read or change game memory through mod.memory().
mod.on_frame([] {});gaddr relocate(gaddr address) const;relocate) or level level's program's (relocate_level). Ask each time, because a level moves its globals.gaddr relocate_level(int level, gaddr address) const;int loaded_level() const;StackFrame(const Mod& mod, std::uint32_t size);size bytes (aligned to 16) on the game's stack through mod's table.~StackFrame();gaddr address() const;mod_id and mod_version are string literals.OPENRAC_MOD_CPP("my-mod", "0.1.0", load)Generated from sdk/include/openrac/mod.hpp at sdk-v1.11.0. Edit this page or report a problem.