Guest User

Untitled

a guest
Sep 12th, 2025
22
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.66 KB | Source Code | 0 0
  1. //#define _GNU_SOURCE
  2. #include <dlfcn.h>
  3. #include <stdio.h>
  4. #include <stdint.h>
  5. #include <stddef.h>
  6. #include <stdbool.h>
  7.  
  8. // Path to the real core
  9. #define REAL_CORE_PATH "./fbalpha2012_libretro.so"
  10.  
  11. // Global handle to the real core
  12. static void* real_core = nullptr;
  13.  
  14. static void (*real_video_cb)(const void*, unsigned, unsigned, size_t) = nullptr;
  15.  
  16. void hooked_video_cb(const void* data, unsigned width, unsigned height, size_t pitch) {
  17.     // Assume 32-bit ARGB8888 or XRGB8888 format (pitch = width * 4)
  18.     const uint32_t* pixels = reinterpret_cast<const uint32_t*>(data);
  19.     size_t pixel_count = pitch / 4 * height;
  20.  
  21.     fprintf(stderr, "[Video Dump] Frame %ux%u Pitch: %zu\n", width, height, pitch);
  22.  
  23.     for (unsigned y = 0; y < height; ++y) {
  24.         const uint32_t* row = (const uint32_t*)((const uint8_t*)data + y * pitch);
  25.         for (unsigned x = 0; x < width; ++x) {
  26.             uint32_t pixel = row[x];
  27.             // Print as #RRGGBB
  28.             uint8_t r = (pixel >> 16) & 0xFF;
  29.             uint8_t g = (pixel >> 8) & 0xFF;
  30.             uint8_t b = pixel & 0xFF;
  31.             // fprintf(stderr, "#%02X%02X%02X ", r, g, b);
  32.         }
  33.         // fprintf(stderr, "\n");
  34.     }
  35.  
  36.     // Call the original video callback to continue rendering
  37.     if (real_video_cb)
  38.         real_video_cb(data, width, height, pitch);
  39. }
  40.  
  41.  
  42. // Macro to load and cast symbols
  43. #define LOAD_SYM(name) \
  44.     real_##name = (decltype(real_##name))dlsym(real_core, "retro_" #name); \
  45.     if (!real_##name) fprintf(stderr, "[Shim] Failed to load symbol: retro_%s\n", #name);
  46.  
  47. // List of all functions to shim
  48. #define DECLARE_SYM(name, ret, ...) \
  49.     typedef ret (*name##_t)(__VA_ARGS__); \
  50.     static name##_t real_##name = nullptr;
  51.  
  52. // Forward declarations of retro_* functions
  53. DECLARE_SYM(init, void)
  54. DECLARE_SYM(deinit, void)
  55. DECLARE_SYM(api_version, unsigned)
  56. DECLARE_SYM(get_system_info, void, struct retro_system_info*)
  57. DECLARE_SYM(get_system_av_info, void, struct retro_system_av_info*)
  58. DECLARE_SYM(set_controller_port_device, void, unsigned, unsigned)
  59. DECLARE_SYM(reset, void)
  60. DECLARE_SYM(run, void)
  61. DECLARE_SYM(load_game, bool, const struct retro_game_info*)
  62. DECLARE_SYM(unload_game, void)
  63. DECLARE_SYM(get_region, unsigned)
  64. DECLARE_SYM(serialize_size, size_t)
  65. DECLARE_SYM(serialize, bool, void*, size_t)
  66. DECLARE_SYM(unserialize, bool, const void*, size_t)
  67. DECLARE_SYM(set_environment, void, bool (*)(unsigned, void*))
  68. DECLARE_SYM(set_video_refresh, void, void (*)(const void*, unsigned, unsigned, size_t))
  69. DECLARE_SYM(set_audio_sample, void, void (*)(int16_t, int16_t))
  70. DECLARE_SYM(set_audio_sample_batch, void, size_t (*)(const int16_t*, size_t))
  71. DECLARE_SYM(set_input_poll, void, void (*)())
  72. DECLARE_SYM(set_input_state, void, int (*)(unsigned, unsigned, unsigned, unsigned))
  73. DECLARE_SYM(load_game_special, bool, unsigned, const struct retro_game_info*, size_t)
  74. DECLARE_SYM(get_memory_data, void*, unsigned)
  75. DECLARE_SYM(get_memory_size, size_t, unsigned)
  76. DECLARE_SYM(cheat_reset, void)
  77. DECLARE_SYM(cheat_set, void, unsigned, bool, const char*)
  78.  
  79. // Constructor to load the real core
  80. __attribute__((constructor))
  81. static void on_load() {
  82.     fprintf(stderr, "[Shim] libretro_shim.so loaded\n");
  83.  
  84.     real_core = dlopen(REAL_CORE_PATH, RTLD_LAZY);
  85.     if (!real_core) {
  86.         fprintf(stderr, "[Shim] Failed to load real core: %s\n", dlerror());
  87.         return;
  88.     }
  89.  
  90.     // Load all required symbols
  91.     LOAD_SYM(init)
  92.     LOAD_SYM(deinit)
  93.     LOAD_SYM(api_version)
  94.     LOAD_SYM(get_system_info)
  95.     LOAD_SYM(get_system_av_info)
  96.     LOAD_SYM(set_controller_port_device)
  97.     LOAD_SYM(reset)
  98.     LOAD_SYM(run)
  99.     LOAD_SYM(load_game)
  100.     LOAD_SYM(unload_game)
  101.     LOAD_SYM(get_region)
  102.     LOAD_SYM(serialize_size)
  103.     LOAD_SYM(serialize)
  104.     LOAD_SYM(unserialize)
  105.     LOAD_SYM(set_environment)
  106.     LOAD_SYM(set_video_refresh)
  107.     LOAD_SYM(set_audio_sample)
  108.     LOAD_SYM(set_audio_sample_batch)
  109.     LOAD_SYM(set_input_poll)
  110.     LOAD_SYM(set_input_state)
  111.     LOAD_SYM(load_game_special)
  112.     LOAD_SYM(get_memory_data)
  113.     LOAD_SYM(get_memory_size)
  114.     LOAD_SYM(cheat_reset)
  115.     LOAD_SYM(cheat_set)
  116.  
  117.     fprintf(stderr, "[Shim] Core loaded and hooked successfully\n");
  118. }
  119.  
  120. // Forward all required libretro functions
  121.  
  122. extern "C" void retro_init()                    { real_init(); }
  123. extern "C" void retro_deinit()                  { real_deinit(); }
  124. extern "C" unsigned retro_api_version()         { return real_api_version(); }
  125. extern "C" void retro_get_system_info(struct retro_system_info* info) { real_get_system_info(info); }
  126. extern "C" void retro_get_system_av_info(struct retro_system_av_info* info) { real_get_system_av_info(info); }
  127. extern "C" void retro_set_controller_port_device(unsigned port, unsigned device) { real_set_controller_port_device(port, device); }
  128. extern "C" void retro_reset()                   { real_reset(); }
  129.  
  130. extern "C" void retro_run() {
  131.     real_run();
  132. }
  133.  
  134. extern "C" bool retro_load_game(const struct retro_game_info* info) { return real_load_game(info); }
  135. extern "C" void retro_unload_game()         { real_unload_game(); }
  136. extern "C" unsigned retro_get_region()      { return real_get_region(); }
  137. extern "C" size_t retro_serialize_size()    { return real_serialize_size(); }
  138. extern "C" bool retro_serialize(void* data, size_t size) { return real_serialize(data, size); }
  139. extern "C" bool retro_unserialize(const void* data, size_t size) { return real_unserialize(data, size); }
  140. extern "C" void retro_set_environment(bool (*cb)(unsigned, void*)) { real_set_environment(cb); }
  141. extern "C" void retro_set_video_refresh(void (*cb)(const void*, unsigned, unsigned, size_t)) {
  142.     fprintf(stderr, "[Shim] retro_set_video_refresh hooked\n");
  143.     real_video_cb = cb;
  144.     real_set_video_refresh(hooked_video_cb);
  145. }
  146.  
  147. extern "C" void retro_set_audio_sample(void (*cb)(int16_t, int16_t)) { real_set_audio_sample(cb); }
  148. extern "C" void retro_set_audio_sample_batch(size_t (*cb)(const int16_t*, size_t)) { real_set_audio_sample_batch(cb); }
  149. extern "C" void retro_set_input_poll(void (*cb)()) { real_set_input_poll(cb); }
  150. extern "C" void retro_set_input_state(int (*cb)(unsigned, unsigned, unsigned, unsigned)) { real_set_input_state(cb); }
  151. extern "C" bool retro_load_game_special(unsigned type, const struct retro_game_info* info, size_t num) {
  152.     return real_load_game_special(type, info, num);
  153. }
  154. extern "C" void* retro_get_memory_data(unsigned id) { return real_get_memory_data(id); }
  155. extern "C" size_t retro_get_memory_size(unsigned id) { return real_get_memory_size(id); }
  156. extern "C" void retro_cheat_reset() { real_cheat_reset(); }
  157. extern "C" void retro_cheat_set(unsigned index, bool enabled, const char* code) { real_cheat_set(index, enabled, code); }
  158.  
Add Comment
Please, Sign In to add comment