12#ifdef DTTR_MODS_ENABLED
18#define DTTR_MIN_WINDOW_DIM 64
19#define BACKEND_COUNT SDL_arraysize(backend_candidates)
44 SDL_GetWindowSizeInPixels(
state->window, &
w, &
h);
46 const char *driver =
state->renderer ?
state->renderer->get_driver_name(
state)
56#ifdef DTTR_MODS_ENABLED
57 "102 Dalmatians - DttR - Modding - " DTTR_VERSION " - %s - %dx%d",
61 driver ? driver :
"unknown",
81 int width =
state->logical_width;
82 int height =
state->logical_height;
85 int window_px_width = 0;
86 int window_px_height = 0;
91 && SDL_GetWindowSizeInPixels(
96 if (window_px_width > target_width) {
97 target_width = window_px_width;
100 if (window_px_height > target_height) {
101 target_height = window_px_height;
106 width = target_width;
107 height = target_height;
111 const float scale = SDL_min(
112 (
float)target_width / (
float)lw,
113 (
float)target_height / (
float)lh
116 width = (int)((
float)lw * scale);
117 height = (int)((
float)lh * scale);
127 int rw =
state->width;
128 int rh =
state->height;
131 if (rw ==
state->width && rh ==
state->height) {
135 if (!
state->renderer->resize(
state, rw, rh)) {
136 DTTR_LOG_WARN(
"Failed to resize render targets to %dx%d", rw, rh);
146 state->texture_mutex = SDL_CreateMutex();
147 kv_init(
state->pending_upload_indices);
148 kv_init(
state->batch_records);
151 state->clear_color = (SDL_FColor){0, 0, 0, 1};
152 state->depth_test =
true;
153 state->depth_write =
true;
154 state->blend_enabled =
false;
165 state->viewport_x = 0;
166 state->viewport_y = 0;
169 state->viewport_min_z = 0.0f;
170 state->viewport_max_z = 1.0f;
172 state->initialized =
true;
173 state->gpu_thread_id = SDL_GetCurrentThreadID();
182 const SDL_PropertiesID props = SDL_GetWindowProperties(window);
183 return (HWND)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WIN32_HWND_POINTER,
NULL);
186#ifdef DTTR_MODS_ENABLED
189static float graphics_scale(uint32_t height) {
190 return height > 0 ? (
float)height / 480.0f : 1.0f;
199 SDL_GetWindowSizeInPixels(
state->window, &win_w, &win_h);
202 *
w = (uint32_t)((win_w > 0) ? win_w : (
state ?
state->width : 0));
203 *
h = (uint32_t)((win_h > 0) ? win_h : (
state ?
state->height : 0));
208 uint32_t window_w = 0;
209 uint32_t window_h = 0;
210 const uint32_t game_w = (uint32_t)(
state ?
state->width : 0);
211 const uint32_t game_h = (uint32_t)(
state ?
state->height : 0);
212 graphics_window_size(
state, &window_w, &window_h);
214 .frame_index =
state ?
state->frame_index : 0,
215 .window_w = window_w,
216 .window_h = window_h,
221 .scale = graphics_scale(game_h),
232 bool imgui_frame_active,
233 bool overlay_rendered
235 uint32_t window_w = 0;
236 uint32_t window_h = 0;
237 graphics_window_size(
state, &window_w, &window_h);
239 .frame_index =
state ?
state->frame_index : 0,
240 .window_w = window_w,
241 .window_h = window_h,
246 .scale = graphics_scale(game_h),
247 .imgui_frame_active = imgui_frame_active,
248 .overlay_rendered = overlay_rendered,
255 uint32_t window_w = 0;
256 uint32_t window_h = 0;
257 graphics_window_size(
state, &window_w, &window_h);
261 .window_w = window_w,
262 .window_h = window_h,
272 switch (
state->backend_type) {
288 .backend = graphics_backend(
state),
292 .render_w = (uint32_t)(
state ?
state->width : 0),
293 .render_h = (uint32_t)(
state ?
state->height : 0),
302static void call_present_mod(
308 bool imgui_frame_active,
309 bool overlay_rendered,
329static void call_graphics_mod(
355 bool imgui_frame_active,
356 bool overlay_rendered
376 bool imgui_frame_active,
377 bool overlay_rendered
430 (uint32_t)present->
x,
431 (uint32_t)present->
y,
432 (uint32_t)present->
w,
433 (uint32_t)present->
h,
442 bool overlay_rendered
446 (uint32_t)present->
x,
447 (uint32_t)present->
y,
448 (uint32_t)present->
w,
449 (uint32_t)present->
h,
458 if (!
state->window) {
463 SDL_DestroyWindow(
state->window);
489 if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) {
506 state->window = SDL_CreateWindow(
513 if (!
state->window) {
526 if (!SDL_SetWindowFullscreen(
state->window,
true)) {
527 DTTR_LOG_WARN(
"SDL_SetWindowFullscreen failed: %s", SDL_GetError());
540 msg = sdsnew(
"All graphics backends failed to initialize");
544 "Graphics backend '%s' failed to initialize. "
545 "It may not be supported on this system.",
568 if (
state->viewport_w <= 0 ||
state->viewport_h <= 0
569 || (
state->viewport_x == 0 &&
state->viewport_y == 0)) {
602 if (
state->frame_active) {
613 if (!
state->frame_active) {
622 const uint8_t *pixels,
629 if (!pixels || width <= 0 || height <= 0 ||
stride < (width * 4)) {
633 return state->renderer->present_video_frame_bgra(
state, pixels, width, height,
stride);
644 if (
state->renderer) {
649 if (
state->texture_mutex) {
650 SDL_DestroyMutex(
state->texture_mutex);
655 kv_destroy(
state->pending_upload_indices);
656 kv_destroy(
state->batch_records);
657 kv_init(
state->pending_upload_indices);
658 kv_init(
state->batch_records);
661 state->initialized =
false;
bool dttr_graphics_opengl_init(DTTR_BackendState *state)
static const char * get_driver_name(const DTTR_BackendState *state)
static const DTTR_RendererVtbl renderer
bool dttr_graphics_sdl3gpu_init(DTTR_BackendState *state)
DTTR_Graphics_COM_Direct3DDevice7 DWORD block DTTR_Graphics_COM_Direct3DDevice7 DWORD block DTTR_Graphics_COM_Direct3DDevice7 void void void void DWORD f DTTR_Graphics_COM_Direct3DDevice7 DWORD idx float
const DTTR_BackendState * state
DTTR_Graphics_COM_DirectDraw7 *self DWORD DWORD h
DTTR_Graphics_COM_DirectDraw7 *self DWORD w
void dttr_graphics_surface_texture_cache_reset()
DTTR_Graphics_COM_DirectDrawSurface7 DWORD flags void NULL
@ DTTR_GRAPHICS_API_OPENGL
@ DTTR_SCALING_METHOD_LOGICAL
const char * DTTR_Config_GraphicsAPIName(DTTR_GraphicsApi api)
Returns the config token for a graphics API selection.
@ DTTR_SCALING_MODE_STRETCH
void DTTR_Errors_ShowMessage(const char *title, const char *message)
#define DTTR_LOG_WARN(...)
#define DTTR_LOG_ERROR(...)
void(* DTTR_Mods_BeforePresentFn)(const DTTR_Mods_PresentContext *ctx)
struct SDL_Window SDL_Window
void(* DTTR_Mods_FrameBeginFn)(const DTTR_Mods_FrameContext *ctx)
void(* DTTR_Mods_GraphicsDeviceCreatedFn)(const DTTR_Mods_GraphicsContext *ctx)
DTTR_Mods_GraphicsBackend
@ DTTR_MODS_GRAPHICS_BACKEND_UNKNOWN
@ DTTR_MODS_GRAPHICS_BACKEND_SDL_GPU
@ DTTR_MODS_GRAPHICS_BACKEND_OPENGL
void(* DTTR_Mods_WindowCreatedFn)(const DTTR_Mods_WindowContext *ctx)
SDL_Window * dttr_graphics_get_window()
void dttr_graphics_set_logical_resolution(int width, int height)
SDL_GPUDevice * dttr_graphics_get_device()
static void select_render_resolution(const DTTR_BackendState *state, int *out_width, int *out_height)
HWND dttr_graphics_init()
static void refresh_render_resolution(DTTR_BackendState *state)
static HWND get_hwnd(SDL_Window *window)
void dttr_graphics_handle_window_resize(int width, int height)
static int clamp_dim(int value, int fallback)
void dttr_graphics_mod_present_rect_before(DTTR_BackendState *state, const DTTR_PresentRect *present)
#define DTTR_MIN_WINDOW_DIM
void dttr_graphics_mod_present_rect_after(DTTR_BackendState *state, const DTTR_PresentRect *present, bool overlay_rendered)
static void init_common_state(DTTR_BackendState *state)
static void update_window_title(const DTTR_BackendState *state)
static void destroy_window(DTTR_BackendState *state)
void dttr_graphics_begin_frame()
void dttr_graphics_cleanup()
bool dttr_graphics_present_video_frame_bgra(const uint8_t *pixels, int width, int height, int stride)
static const backend_candidate backend_candidates[]
void dttr_graphics_end_frame()
static backend_range select_backend_range(DTTR_GraphicsApi api)
static void dttr_graphics_mod_device_destroying(DTTR_BackendState *)
void dttr_graphics_mat4_identity(float *m)
#define DTTR_D3DTA_DIFFUSE
static void dttr_graphics_mod_window_resized(DTTR_BackendState *)
#define DTTR_D3DTOP_SELECTARG1
static void dttr_graphics_mod_device_lost(DTTR_BackendState *)
static void dttr_graphics_mod_before_game_frame(DTTR_BackendState *)
#define DTTR_D3DTA_TEXTURE
static void dttr_graphics_mod_device_restored(DTTR_BackendState *)
static void dttr_graphics_mod_before_present(DTTR_BackendState *, uint32_t, uint32_t, uint32_t, uint32_t, bool, bool)
static void dttr_graphics_mod_device_created(DTTR_BackendState *)
#define DTTR_D3DTOP_MODULATE
static void dttr_graphics_mod_window_destroying(DTTR_BackendState *)
DTTR_BackendState dttr_backend
static void dttr_graphics_mod_window_created(DTTR_BackendState *)
static void dttr_graphics_mod_after_present(DTTR_BackendState *, uint32_t, uint32_t, uint32_t, uint32_t, bool, bool)
static void dttr_graphics_mod_after_game_frame(DTTR_BackendState *)
static void dttr_graphics_mod_frame_begin(DTTR_BackendState *)
static void dttr_graphics_mod_frame_end(DTTR_BackendState *)
void dttr_mods_window_destroying(const DTTR_Mods_WindowContext *ctx)
void dttr_mods_after_game_frame(const DTTR_Mods_FrameContext *ctx)
void dttr_mods_frame_begin(const DTTR_Mods_FrameContext *ctx)
void dttr_mods_before_present(const DTTR_Mods_PresentContext *ctx)
void dttr_mods_graphics_device_destroying(const DTTR_Mods_GraphicsContext *ctx)
void dttr_mods_after_present(const DTTR_Mods_PresentContext *ctx)
void dttr_mods_window_resized(const DTTR_Mods_WindowContext *ctx)
void dttr_mods_frame_end(const DTTR_Mods_FrameContext *ctx)
void dttr_mods_graphics_device_created(const DTTR_Mods_GraphicsContext *ctx)
void dttr_mods_window_created(const DTTR_Mods_WindowContext *ctx)
void dttr_mods_before_game_frame(const DTTR_Mods_FrameContext *ctx)
void dttr_mods_graphics_device_restored(const DTTR_Mods_GraphicsContext *ctx)
void dttr_mods_graphics_device_lost(const DTTR_Mods_GraphicsContext *ctx)
Game-image placement within the present target, in target pixels.
bool(* init)(DTTR_BackendState *state)