diff --git a/runtime/include/gpu_vk_renderer.h b/runtime/include/gpu_vk_renderer.h index 47820fa8..7b09ea66 100644 --- a/runtime/include/gpu_vk_renderer.h +++ b/runtime/include/gpu_vk_renderer.h @@ -52,6 +52,7 @@ void vk_renderer_restage_vram_after_savestate(void); * -1=MAILBOX. Tear-free prefers MAILBOX because the frontend already paces * frames; unsupported modes fall back to FIFO (always available). */ void vk_renderer_set_present_mode(int mode); +void vk_renderer_set_display_aspect(int num, int den); #ifdef __cplusplus } diff --git a/runtime/src/gpu_vk_renderer.c b/runtime/src/gpu_vk_renderer.c index cf85ebac..7ac92f3d 100644 --- a/runtime/src/gpu_vk_renderer.c +++ b/runtime/src/gpu_vk_renderer.c @@ -44,6 +44,7 @@ void vk_renderer_present_blank(void){} void vk_renderer_sync_cpu(void){} void vk_renderer_restage_vram_after_savestate(void){} void vk_renderer_set_present_mode(int m){(void)m;} +void vk_renderer_set_display_aspect(int n,int d){(void)n;(void)d;} int vk_perf_json(char *out,int cap,int count){(void)count; return cap>2?snprintf(out,cap,"[]"):0;} const GpuRenderBackend *vk_backend_get(void) { return 0; } @@ -63,6 +64,13 @@ const GpuRenderBackend *vk_backend_get(void) { return 0; } #define VRAM_W 1024 #define VRAM_H 512 +static int s_aspect_num = 4, s_aspect_den = 3; + +void vk_renderer_set_display_aspect(int num, int den) { + if (num <= 0 || den <= 0) { num = 4; den = 3; } + s_aspect_num = num; s_aspect_den = den; +} + /* ---- dynamic loader ---------------------------------------------------- */ /* vkGetInstanceProcAddr comes from SDL; everything else is loaded through it * (global/instance scope) or vkGetDeviceProcAddr (device scope). */ @@ -1690,7 +1698,7 @@ int vk_renderer_present_vram(int disp_x, int disp_y, int w, int h, VkOffset3D dst[2]; letterbox((int)s_sc_extent.width, (int)s_sc_extent.height, - force_4_3 ? 4 : 4, force_4_3 ? 3 : 3, dst); + force_4_3 ? 4 : s_aspect_num, force_4_3 ? 3 : s_aspect_den, dst); VkImageBlit blit = {0}; blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; @@ -1799,7 +1807,7 @@ void vk_renderer_present_cpu(const uint32_t *pixels, int src_w, int src_h, p_vkCmdClearColorImage(cb, sc, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &black, 1, &rng); VkOffset3D dst[2]; - letterbox((int)s_sc_extent.width, (int)s_sc_extent.height, 4, 3, dst); + letterbox((int)s_sc_extent.width, (int)s_sc_extent.height, force_4_3 ? 4 : s_aspect_num, force_4_3 ? 3 : s_aspect_den, dst); /* Short GP1(07h) bands: letterbox inside the 4:3 rect (see GL present). */ if (src_h > 0 && src_h < 240) { int box_h = dst[1].y - dst[0].y; diff --git a/runtime/src/main.cpp b/runtime/src/main.cpp index 0ddf5740..5d61970a 100644 --- a/runtime/src/main.cpp +++ b/runtime/src/main.cpp @@ -1743,6 +1743,7 @@ static void update_adaptive_widescreen() { g_video_aspect_num = num; g_video_aspect_den = den; gl_renderer_set_display_aspect(num, den); + vk_renderer_set_display_aspect(num, den); if (sdl_renderer) { g_logical_w = 480 * num * g_video_scale / den; SDL_RenderSetLogicalSize(sdl_renderer, g_logical_w, 480 * g_video_scale); @@ -14505,6 +14506,7 @@ session_reboot: * this aspect; native-wide fills it with a genuinely wider frame (no * stretch), squash mode stretches the 4:3 frame into it. */ gl_renderer_set_display_aspect(g_video_aspect_num, g_video_aspect_den); + vk_renderer_set_display_aspect(g_video_aspect_num, g_video_aspect_den); if (g_video_aspect_num * 3 != g_video_aspect_den * 4) { /* Hold widescreen off through the BIOS boot (authentic 4:3 logos); * the per-frame present path engages it at game entry. */