Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //#define _GNU_SOURCE
- #include <dlfcn.h>
- #include <stdio.h>
- #include <stdint.h>
- #include <stddef.h>
- #include <stdbool.h>
- // Path to the real core
- #define REAL_CORE_PATH "./fbalpha2012_libretro.so"
- // Global handle to the real core
- static void* real_core = nullptr;
- static void (*real_video_cb)(const void*, unsigned, unsigned, size_t) = nullptr;
- void hooked_video_cb(const void* data, unsigned width, unsigned height, size_t pitch) {
- // Assume 32-bit ARGB8888 or XRGB8888 format (pitch = width * 4)
- const uint32_t* pixels = reinterpret_cast<const uint32_t*>(data);
- size_t pixel_count = pitch / 4 * height;
- fprintf(stderr, "[Video Dump] Frame %ux%u Pitch: %zu\n", width, height, pitch);
- for (unsigned y = 0; y < height; ++y) {
- const uint32_t* row = (const uint32_t*)((const uint8_t*)data + y * pitch);
- for (unsigned x = 0; x < width; ++x) {
- uint32_t pixel = row[x];
- // Print as #RRGGBB
- uint8_t r = (pixel >> 16) & 0xFF;
- uint8_t g = (pixel >> 8) & 0xFF;
- uint8_t b = pixel & 0xFF;
- // fprintf(stderr, "#%02X%02X%02X ", r, g, b);
- }
- // fprintf(stderr, "\n");
- }
- // Call the original video callback to continue rendering
- if (real_video_cb)
- real_video_cb(data, width, height, pitch);
- }
- // Macro to load and cast symbols
- #define LOAD_SYM(name) \
- real_##name = (decltype(real_##name))dlsym(real_core, "retro_" #name); \
- if (!real_##name) fprintf(stderr, "[Shim] Failed to load symbol: retro_%s\n", #name);
- // List of all functions to shim
- #define DECLARE_SYM(name, ret, ...) \
- typedef ret (*name##_t)(__VA_ARGS__); \
- static name##_t real_##name = nullptr;
- // Forward declarations of retro_* functions
- DECLARE_SYM(init, void)
- DECLARE_SYM(deinit, void)
- DECLARE_SYM(api_version, unsigned)
- DECLARE_SYM(get_system_info, void, struct retro_system_info*)
- DECLARE_SYM(get_system_av_info, void, struct retro_system_av_info*)
- DECLARE_SYM(set_controller_port_device, void, unsigned, unsigned)
- DECLARE_SYM(reset, void)
- DECLARE_SYM(run, void)
- DECLARE_SYM(load_game, bool, const struct retro_game_info*)
- DECLARE_SYM(unload_game, void)
- DECLARE_SYM(get_region, unsigned)
- DECLARE_SYM(serialize_size, size_t)
- DECLARE_SYM(serialize, bool, void*, size_t)
- DECLARE_SYM(unserialize, bool, const void*, size_t)
- DECLARE_SYM(set_environment, void, bool (*)(unsigned, void*))
- DECLARE_SYM(set_video_refresh, void, void (*)(const void*, unsigned, unsigned, size_t))
- DECLARE_SYM(set_audio_sample, void, void (*)(int16_t, int16_t))
- DECLARE_SYM(set_audio_sample_batch, void, size_t (*)(const int16_t*, size_t))
- DECLARE_SYM(set_input_poll, void, void (*)())
- DECLARE_SYM(set_input_state, void, int (*)(unsigned, unsigned, unsigned, unsigned))
- DECLARE_SYM(load_game_special, bool, unsigned, const struct retro_game_info*, size_t)
- DECLARE_SYM(get_memory_data, void*, unsigned)
- DECLARE_SYM(get_memory_size, size_t, unsigned)
- DECLARE_SYM(cheat_reset, void)
- DECLARE_SYM(cheat_set, void, unsigned, bool, const char*)
- // Constructor to load the real core
- __attribute__((constructor))
- static void on_load() {
- fprintf(stderr, "[Shim] libretro_shim.so loaded\n");
- real_core = dlopen(REAL_CORE_PATH, RTLD_LAZY);
- if (!real_core) {
- fprintf(stderr, "[Shim] Failed to load real core: %s\n", dlerror());
- return;
- }
- // Load all required symbols
- LOAD_SYM(init)
- LOAD_SYM(deinit)
- LOAD_SYM(api_version)
- LOAD_SYM(get_system_info)
- LOAD_SYM(get_system_av_info)
- LOAD_SYM(set_controller_port_device)
- LOAD_SYM(reset)
- LOAD_SYM(run)
- LOAD_SYM(load_game)
- LOAD_SYM(unload_game)
- LOAD_SYM(get_region)
- LOAD_SYM(serialize_size)
- LOAD_SYM(serialize)
- LOAD_SYM(unserialize)
- LOAD_SYM(set_environment)
- LOAD_SYM(set_video_refresh)
- LOAD_SYM(set_audio_sample)
- LOAD_SYM(set_audio_sample_batch)
- LOAD_SYM(set_input_poll)
- LOAD_SYM(set_input_state)
- LOAD_SYM(load_game_special)
- LOAD_SYM(get_memory_data)
- LOAD_SYM(get_memory_size)
- LOAD_SYM(cheat_reset)
- LOAD_SYM(cheat_set)
- fprintf(stderr, "[Shim] Core loaded and hooked successfully\n");
- }
- // Forward all required libretro functions
- extern "C" void retro_init() { real_init(); }
- extern "C" void retro_deinit() { real_deinit(); }
- extern "C" unsigned retro_api_version() { return real_api_version(); }
- extern "C" void retro_get_system_info(struct retro_system_info* info) { real_get_system_info(info); }
- extern "C" void retro_get_system_av_info(struct retro_system_av_info* info) { real_get_system_av_info(info); }
- extern "C" void retro_set_controller_port_device(unsigned port, unsigned device) { real_set_controller_port_device(port, device); }
- extern "C" void retro_reset() { real_reset(); }
- extern "C" void retro_run() {
- real_run();
- }
- extern "C" bool retro_load_game(const struct retro_game_info* info) { return real_load_game(info); }
- extern "C" void retro_unload_game() { real_unload_game(); }
- extern "C" unsigned retro_get_region() { return real_get_region(); }
- extern "C" size_t retro_serialize_size() { return real_serialize_size(); }
- extern "C" bool retro_serialize(void* data, size_t size) { return real_serialize(data, size); }
- extern "C" bool retro_unserialize(const void* data, size_t size) { return real_unserialize(data, size); }
- extern "C" void retro_set_environment(bool (*cb)(unsigned, void*)) { real_set_environment(cb); }
- extern "C" void retro_set_video_refresh(void (*cb)(const void*, unsigned, unsigned, size_t)) {
- fprintf(stderr, "[Shim] retro_set_video_refresh hooked\n");
- real_video_cb = cb;
- real_set_video_refresh(hooked_video_cb);
- }
- extern "C" void retro_set_audio_sample(void (*cb)(int16_t, int16_t)) { real_set_audio_sample(cb); }
- extern "C" void retro_set_audio_sample_batch(size_t (*cb)(const int16_t*, size_t)) { real_set_audio_sample_batch(cb); }
- extern "C" void retro_set_input_poll(void (*cb)()) { real_set_input_poll(cb); }
- extern "C" void retro_set_input_state(int (*cb)(unsigned, unsigned, unsigned, unsigned)) { real_set_input_state(cb); }
- extern "C" bool retro_load_game_special(unsigned type, const struct retro_game_info* info, size_t num) {
- return real_load_game_special(type, info, num);
- }
- extern "C" void* retro_get_memory_data(unsigned id) { return real_get_memory_data(id); }
- extern "C" size_t retro_get_memory_size(unsigned id) { return real_get_memory_size(id); }
- extern "C" void retro_cheat_reset() { real_cheat_reset(); }
- extern "C" void retro_cheat_set(unsigned index, bool enabled, const char* code) { real_cheat_set(index, enabled, code); }
Add Comment
Please, Sign In to add comment