graphics-hook.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. #pragma once
  2. #include "graphics-hook-config.h"
  3. #ifdef _MSC_VER
  4. /* conversion from data/function pointer */
  5. #pragma warning(disable: 4152)
  6. #endif
  7. #include "../graphics-hook-info.h"
  8. #include <ipc-util/pipe.h>
  9. #include <psapi.h>
  10. #ifdef __cplusplus
  11. extern "C" {
  12. #else
  13. #if defined(_MSC_VER) && !defined(inline)
  14. #define inline __inline
  15. #endif
  16. #endif
  17. #define NUM_BUFFERS 3
  18. extern void hlog(const char *format, ...);
  19. extern void hlog_hr(const char *text, HRESULT hr);
  20. static inline const char *get_process_name(void);
  21. static inline HMODULE get_system_module(const char *module);
  22. static inline HMODULE load_system_library(const char *module);
  23. extern uint64_t os_gettime_ns(void);
  24. static inline bool capture_active(void);
  25. static inline bool capture_ready(void);
  26. static inline bool capture_should_stop(void);
  27. static inline bool capture_should_init(void);
  28. extern void shmem_copy_data(size_t idx, void *volatile data);
  29. extern bool shmem_texture_data_lock(int idx);
  30. extern void shmem_texture_data_unlock(int idx);
  31. extern bool hook_ddraw(void);
  32. extern bool hook_d3d8(void);
  33. extern bool hook_d3d9(void);
  34. extern bool hook_dxgi(void);
  35. extern bool hook_gl(void);
  36. extern void d3d10_capture(void *swap, void *backbuffer, bool capture_overlay);
  37. extern void d3d10_free(void);
  38. extern void d3d11_capture(void *swap, void *backbuffer, bool capture_overlay);
  39. extern void d3d11_free(void);
  40. #if COMPILE_D3D12_HOOK
  41. extern void d3d12_capture(void *swap, void *backbuffer, bool capture_overlay);
  42. extern void d3d12_free(void);
  43. #endif
  44. extern uint8_t *get_d3d1x_vertex_shader(size_t *size);
  45. extern uint8_t *get_d3d1x_pixel_shader(size_t *size);
  46. extern bool rehook_gl(void);
  47. extern bool capture_init_shtex(struct shtex_data **data, HWND window,
  48. uint32_t base_cx, uint32_t base_cy, uint32_t cx, uint32_t cy,
  49. uint32_t format, bool flip, uintptr_t handle);
  50. extern bool capture_init_shmem(struct shmem_data **data, HWND window,
  51. uint32_t base_cx, uint32_t base_cy, uint32_t cx, uint32_t cy,
  52. uint32_t pitch, uint32_t format, bool flip);
  53. extern void capture_free(void);
  54. extern struct hook_info *global_hook_info;
  55. struct vertex {
  56. struct {
  57. float x, y, z, w;
  58. } pos;
  59. struct {
  60. float u, v;
  61. } tex;
  62. };
  63. static inline bool duplicate_handle(HANDLE *dst, HANDLE src)
  64. {
  65. return !!DuplicateHandle(GetCurrentProcess(), src, GetCurrentProcess(),
  66. dst, 0, false, DUPLICATE_SAME_ACCESS);
  67. }
  68. static inline void *get_offset_addr(HMODULE module, uint32_t offset)
  69. {
  70. return (void*)((uintptr_t)module + (uintptr_t)offset);
  71. }
  72. /* ------------------------------------------------------------------------- */
  73. extern ipc_pipe_client_t pipe;
  74. extern HANDLE signal_restart;
  75. extern HANDLE signal_stop;
  76. extern HANDLE signal_ready;
  77. extern HANDLE signal_exit;
  78. extern HANDLE tex_mutexes[2];
  79. extern char system_path[MAX_PATH];
  80. extern char process_name[MAX_PATH];
  81. extern wchar_t keepalive_name[64];
  82. extern HWND dummy_window;
  83. extern volatile bool active;
  84. static inline const char *get_process_name(void)
  85. {
  86. return process_name;
  87. }
  88. static inline HMODULE get_system_module(const char *module)
  89. {
  90. char base_path[MAX_PATH];
  91. strcpy(base_path, system_path);
  92. strcat(base_path, "\\");
  93. strcat(base_path, module);
  94. return GetModuleHandleA(base_path);
  95. }
  96. static inline uint32_t module_size(HMODULE module)
  97. {
  98. MODULEINFO info;
  99. bool success = !!GetModuleInformation(GetCurrentProcess(), module,
  100. &info, sizeof(info));
  101. return success ? info.SizeOfImage : 0;
  102. }
  103. static inline HMODULE load_system_library(const char *name)
  104. {
  105. char base_path[MAX_PATH];
  106. HMODULE module;
  107. strcpy(base_path, system_path);
  108. strcat(base_path, "\\");
  109. strcat(base_path, name);
  110. module = GetModuleHandleA(base_path);
  111. if (module)
  112. return module;
  113. return LoadLibraryA(base_path);
  114. }
  115. static inline bool capture_alive(void)
  116. {
  117. HANDLE handle = OpenMutexW(SYNCHRONIZE, false, keepalive_name);
  118. CloseHandle(handle);
  119. if (handle)
  120. return true;
  121. return GetLastError() != ERROR_FILE_NOT_FOUND;
  122. }
  123. static inline bool capture_active(void)
  124. {
  125. return active;
  126. }
  127. static inline bool frame_ready(uint64_t interval)
  128. {
  129. static uint64_t last_time = 0;
  130. uint64_t elapsed;
  131. uint64_t t;
  132. if (!interval) {
  133. return true;
  134. }
  135. t = os_gettime_ns();
  136. elapsed = t - last_time;
  137. if (elapsed < interval) {
  138. return false;
  139. }
  140. last_time = (elapsed > interval * 2) ? t : last_time + interval;
  141. return true;
  142. }
  143. static inline bool capture_ready(void)
  144. {
  145. return capture_active() &&
  146. frame_ready(global_hook_info->frame_interval);
  147. }
  148. static inline bool capture_stopped(void)
  149. {
  150. return WaitForSingleObject(signal_stop, 0) == WAIT_OBJECT_0;
  151. }
  152. static inline bool capture_restarted(void)
  153. {
  154. return WaitForSingleObject(signal_restart, 0) == WAIT_OBJECT_0;
  155. }
  156. static inline bool capture_should_stop(void)
  157. {
  158. bool stop_requested = false;
  159. if (capture_active()) {
  160. static uint64_t last_keepalive_check = 0;
  161. uint64_t cur_time = os_gettime_ns();
  162. bool alive = true;
  163. if (cur_time - last_keepalive_check > 5000000000) {
  164. alive = capture_alive();
  165. last_keepalive_check = cur_time;
  166. }
  167. stop_requested = capture_stopped() || !alive;
  168. }
  169. return stop_requested;
  170. }
  171. extern bool init_pipe(void);
  172. static inline bool capture_should_init(void)
  173. {
  174. if (!capture_active() && capture_restarted()) {
  175. if (capture_alive()) {
  176. if (!ipc_pipe_client_valid(&pipe)) {
  177. init_pipe();
  178. }
  179. return true;
  180. }
  181. }
  182. return false;
  183. }
  184. #ifdef __cplusplus
  185. }
  186. #endif