From 8eaebcf4b39a65db6d256c583e2224453fe4bebd Mon Sep 17 00:00:00 2001 From: Fancy2209 <64917206+Fancy2209@users.noreply.github.com> Date: Tue, 4 Feb 2025 12:33:58 -0100 Subject: [PATCH 01/26] Adds WIP Widescreen Support --- src/render/ogc/SDL_render_ogc.c | 2 +- src/video/ogc/SDL_ogcgxcommon.c | 8 ++-- src/video/ogc/SDL_ogcgxcommon.h | 4 +- src/video/ogc/SDL_ogcmouse.c | 12 ++++-- src/video/ogc/SDL_ogcvideo.c | 73 +++++++++++++++++++++++++++++---- 5 files changed, 79 insertions(+), 20 deletions(-) diff --git a/src/render/ogc/SDL_render_ogc.c b/src/render/ogc/SDL_render_ogc.c index ece76c7fcde78..fa75318f331cf 100644 --- a/src/render/ogc/SDL_render_ogc.c +++ b/src/render/ogc/SDL_render_ogc.c @@ -427,7 +427,7 @@ static int OGC_RenderSetViewPort(SDL_Renderer *renderer, SDL_RenderCommand *cmd) { const SDL_Rect *viewport = &cmd->data.viewport.rect; - OGC_set_viewport(viewport->x, viewport->y, viewport->w, viewport->h); + OGC_set_viewport(viewport->x, viewport->y, viewport->w, viewport->h, viewport->w); return 0; } diff --git a/src/video/ogc/SDL_ogcgxcommon.c b/src/video/ogc/SDL_ogcgxcommon.c index 56c017f271763..39346c4b63256 100644 --- a/src/video/ogc/SDL_ogcgxcommon.c +++ b/src/video/ogc/SDL_ogcgxcommon.c @@ -40,7 +40,7 @@ static const f32 tex_pos[] __attribute__((aligned(32))) = { 1.0, }; -void OGC_set_viewport(int x, int y, int w, int h) +void OGC_set_viewport(int x, int y, int w, int h, int orthoWidth) { Mtx44 proj; @@ -48,11 +48,11 @@ void OGC_set_viewport(int x, int y, int w, int h) GX_SetScissor(x, y, w, h); // matrix, t, b, l, r, n, f - guOrtho(proj, 0, h, 0, w, 0, 1); + guOrtho(proj, 0, h, 0, orthoWidth, 0, 1); GX_LoadProjectionMtx(proj, GX_ORTHOGRAPHIC); } -void OGC_draw_init(int w, int h) +void OGC_draw_init(int w, int h, int orthoWidth) { Mtx mv; @@ -86,7 +86,7 @@ void OGC_draw_init(int w, int h) GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE); GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); - OGC_set_viewport(0, 0, w, h); + OGC_set_viewport(0, 0, w, h, orthoWidth); GX_InvVtxCache(); // update vertex cache } diff --git a/src/video/ogc/SDL_ogcgxcommon.h b/src/video/ogc/SDL_ogcgxcommon.h index 1b2ed5b321e71..be026c6c2de8e 100644 --- a/src/video/ogc/SDL_ogcgxcommon.h +++ b/src/video/ogc/SDL_ogcgxcommon.h @@ -29,8 +29,8 @@ #define GX_COLOR_AS_U32(c) *((u32*)&c) -void OGC_draw_init(int w, int h); -void OGC_set_viewport(int x, int y, int w, int h); +void OGC_draw_init(int w, int h, int orthoWidth); +void OGC_set_viewport(int x, int y, int w, int h, int orthoWidth); void OGC_load_texture(void *texels, int w, int h, u8 gx_format, SDL_ScaleMode scale_mode); diff --git a/src/video/ogc/SDL_ogcmouse.c b/src/video/ogc/SDL_ogcmouse.c index 7f750ec7e0fe7..c34d3adb60093 100644 --- a/src/video/ogc/SDL_ogcmouse.c +++ b/src/video/ogc/SDL_ogcmouse.c @@ -29,6 +29,7 @@ #include "SDL_ogcgxcommon.h" #include "SDL_ogcmouse.h" #include "SDL_ogcpixels.h" +#include "SDL_ogcvideo.h" #include "../SDL_sysvideo.h" #include "../../render/SDL_sysrender.h" @@ -175,7 +176,7 @@ void OGC_draw_cursor(_THIS) SDL_Mouse *mouse = SDL_GetMouse(); OGC_CursorData *curdata; Mtx mv; - int screen_w, screen_h; + int screen_w, screen_h, viewport_w; float angle = 0.0f; if (!mouse || !mouse->cursor_shown || @@ -191,7 +192,8 @@ void OGC_draw_cursor(_THIS) if (!data->ir.valid) return; } - screen_w = _this->displays[0].current_mode.w; + viewport_w = _this->displays[0].current_mode.w; + screen_w = ((SDL_VideoData *)_this->displays[0].current_mode.driverdata)->vmode->fbWidth; screen_h = _this->displays[0].current_mode.h; curdata = mouse->cur_cursor->driverdata; @@ -200,6 +202,7 @@ void OGC_draw_cursor(_THIS) guMtxIdentity(mv); guMtxScaleApply(mv, mv, screen_w / 640.0f, screen_h / 480.0f, 1.0f); + if (angle != 0.0f) { Mtx rot; guMtxRotDeg(rot, 'z', angle); @@ -208,7 +211,7 @@ void OGC_draw_cursor(_THIS) guMtxTransApply(mv, mv, mouse->x, mouse->y, 0); GX_LoadPosMtxImm(mv, GX_PNMTX1); - OGC_set_viewport(0, 0, screen_w, screen_h); + OGC_set_viewport(0, 0, screen_w, screen_h, viewport_w); GX_ClearVtxDesc(); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); @@ -240,7 +243,8 @@ void OGC_draw_cursor(_THIS) SDL_Renderer *renderer = SDL_GetRenderer(_this->windows); if (renderer) { OGC_set_viewport(renderer->viewport.x, renderer->viewport.y, - renderer->viewport.w, renderer->viewport.h); + renderer->viewport.w, renderer->viewport.h, + renderer->viewport.w); } } } diff --git a/src/video/ogc/SDL_ogcvideo.c b/src/video/ogc/SDL_ogcvideo.c index a1c32b96d4657..c474af20671e4 100644 --- a/src/video/ogc/SDL_ogcvideo.c +++ b/src/video/ogc/SDL_ogcvideo.c @@ -41,6 +41,7 @@ #include #include #include +#include #include @@ -51,6 +52,7 @@ /* A video mode with a 320 width; we'll build it programmatically. */ static GXRModeObj s_mode320; +static GXRModeObj s_mode704; static const GXRModeObj *s_ntsc_modes[] = { &TVNtsc240Ds, @@ -85,14 +87,14 @@ static const GXRModeObj *s_pal_modes[] = { static int OGC_VideoInit(_THIS); static void OGC_VideoQuit(_THIS); -static void init_display_mode(SDL_DisplayMode *mode, const GXRModeObj *vmode) +static void init_display_mode(SDL_DisplayMode *mode, const GXRModeObj *vmode, int width) { u32 format = VI_FORMAT_FROM_MODE(vmode->viTVMode); /* Use a fake 32-bpp desktop mode */ SDL_zero(*mode); mode->format = SDL_PIXELFORMAT_ARGB8888; - mode->w = vmode->fbWidth; + mode->w = width; mode->h = vmode->efbHeight; switch (format) { case VI_DEBUG: @@ -142,18 +144,48 @@ static void add_supported_modes(SDL_VideoDisplay *display, u32 tv_format) * take care of the horizontal scale for us. */ memcpy(&s_mode320, gx_modes[0], sizeof(s_mode320)); s_mode320.fbWidth = 320; - init_display_mode(&mode, &s_mode320); + init_display_mode(&mode, &s_mode320, s_mode320.fbWidth); SDL_AddDisplayMode(display, &mode); + // libogc uses 640 for the viWidth, but this does not work well for Widescreen + // as such we extend the viWidth to 704 on a new videomode + // TODO: Currently ony added on wii if it's widescreen, + // but should work on GC and a 4:3 Wii + // testing needed + + #ifdef __wii__ + if(CONF_GetAspectRatio() == CONF_ASPECT_16_9) + { + memcpy(&s_mode704, gx_modes[1], sizeof(s_mode704)); + s_mode704.viWidth = 704; + + // set Center point + if (&s_mode704 == &TVPal576IntDfScale || &s_mode704 == &TVPal576ProgScale) + { + s_mode704.viXOrigin = (VI_MAX_WIDTH_PAL - s_mode704.viWidth) / 2; + s_mode704.viYOrigin = (VI_MAX_HEIGHT_PAL - s_mode704.viHeight) / 2; + } + else + { + s_mode704.viXOrigin = (VI_MAX_WIDTH_NTSC - s_mode704.viWidth) / 2; + s_mode704.viYOrigin = (VI_MAX_HEIGHT_NTSC - s_mode704.viHeight) / 2; + } + + // Widescreen is anamorphic, so we provide a different width for the ortho projection + init_display_mode(&mode, &s_mode704, 854); + SDL_AddDisplayMode(display, &mode); + } + #endif + /* Now add all the "standard" modes from libogc */ while (*gx_modes) { - init_display_mode(&mode, *gx_modes); + init_display_mode(&mode, *gx_modes, (*gx_modes)->fbWidth); SDL_AddDisplayMode(display, &mode); gx_modes++; } } -static void setup_video_mode(_THIS, GXRModeObj *vmode) +static void setup_video_mode(_THIS, GXRModeObj *vmode, int orthoWidth) { SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; @@ -180,7 +212,7 @@ static void setup_video_mode(_THIS, GXRModeObj *vmode) GX_SetFieldMode(vmode->field_rendering, ((vmode->viHeight == 2 * vmode->xfbHeight) ? GX_ENABLE : GX_DISABLE)); - OGC_draw_init(vmode->fbWidth, vmode->efbHeight); + OGC_draw_init(vmode->fbWidth, vmode->efbHeight, orthoWidth); } static int OGC_SetDisplayMode(_THIS, SDL_VideoDisplay *display, @@ -195,7 +227,7 @@ static int OGC_SetDisplayMode(_THIS, SDL_VideoDisplay *display, if (videodata->xfb[1]) free(MEM_K1_TO_K0(videodata->xfb[1])); - setup_video_mode(_this, vmode); + setup_video_mode(_this, vmode, mode->w); return 0; } @@ -277,12 +309,30 @@ int OGC_VideoInit(_THIS) VIDEO_Init(); vmode = VIDEO_GetPreferredMode(NULL); + vmode->viWidth = 704; + + // set Center point + if (&s_mode704 == &TVPal576IntDfScale || &s_mode704 == &TVPal576ProgScale) + { + vmode->viXOrigin = (VI_MAX_WIDTH_PAL - vmode->viWidth) / 2; + vmode->viYOrigin = (VI_MAX_HEIGHT_PAL - vmode->viHeight) / 2; + } + else + { + vmode->viXOrigin = (VI_MAX_WIDTH_NTSC - vmode->viWidth) / 2; + vmode->viYOrigin = (VI_MAX_HEIGHT_NTSC - vmode->viHeight) / 2; + } videodata->gp_fifo = memalign(32, DEFAULT_FIFO_SIZE); memset(videodata->gp_fifo, 0, DEFAULT_FIFO_SIZE); GX_Init(videodata->gp_fifo, DEFAULT_FIFO_SIZE); - setup_video_mode(_this, vmode); + #ifdef __wii__ + if(CONF_GetAspectRatio() == CONF_ASPECT_16_9) + setup_video_mode(_this, vmode, 854); + else + #endif + setup_video_mode(_this, vmode, vmode->fbWidth); GX_SetCopyClear(background, GX_MAX_Z24); GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR); @@ -293,7 +343,12 @@ int OGC_VideoInit(_THIS) GX_Flush(); - init_display_mode(&mode, vmode); + #ifdef __wii__ + if(CONF_GetAspectRatio() == CONF_ASPECT_16_9) + init_display_mode(&mode, vmode, 854); + else + #endif + init_display_mode(&mode, vmode, vmode->fbWidth); if (SDL_AddBasicVideoDisplay(&mode) < 0) { return -1; } From 37151df0f1351092730b5425e426a3f914109070 Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Tue, 4 Feb 2025 15:06:17 -0100 Subject: [PATCH 02/26] Fix Cursor --- src/video/ogc/SDL_ogcmouse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/ogc/SDL_ogcmouse.c b/src/video/ogc/SDL_ogcmouse.c index c34d3adb60093..70764fee9f069 100644 --- a/src/video/ogc/SDL_ogcmouse.c +++ b/src/video/ogc/SDL_ogcmouse.c @@ -193,7 +193,7 @@ void OGC_draw_cursor(_THIS) } viewport_w = _this->displays[0].current_mode.w; - screen_w = ((SDL_VideoData *)_this->displays[0].current_mode.driverdata)->vmode->fbWidth; + screen_w = (viewport_w == 854) ? 640 : _this->displays[0].current_mode.w; screen_h = _this->displays[0].current_mode.h; curdata = mouse->cur_cursor->driverdata; From 62191d5bb82fdfa0cb2a6c7fe2d7ff0ca3ff9ba7 Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Tue, 4 Feb 2025 15:16:08 -0100 Subject: [PATCH 03/26] Add orthoWidth to draw init log --- .vscode/settings.json | 9 +++++++++ src/video/ogc/SDL_ogcgxcommon.c | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000000..feee5b2f51f5b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "files.associations": { + "*.wog2": "json", + "array": "c", + "vector": "c", + "xstring": "c", + "xutility": "c" + } +} \ No newline at end of file diff --git a/src/video/ogc/SDL_ogcgxcommon.c b/src/video/ogc/SDL_ogcgxcommon.c index 39346c4b63256..9bad8d26f718e 100644 --- a/src/video/ogc/SDL_ogcgxcommon.c +++ b/src/video/ogc/SDL_ogcgxcommon.c @@ -56,7 +56,7 @@ void OGC_draw_init(int w, int h, int orthoWidth) { Mtx mv; - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "OGC_draw_init called with %d, %d", w, h); + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "OGC_draw_init called with %d, %d, %d", w, h, orthoWidth); guMtxIdentity(mv); /* Ideally we would use 0.5 to center the coordinates on the pixels, but From 19e2688366695a7a68663cc948036d5870720120 Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Tue, 4 Feb 2025 15:16:25 -0100 Subject: [PATCH 04/26] Delete accidentally commited file --- .vscode/settings.json | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index feee5b2f51f5b..0000000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "files.associations": { - "*.wog2": "json", - "array": "c", - "vector": "c", - "xstring": "c", - "xutility": "c" - } -} \ No newline at end of file From e1f2bfd1fb73708fcea9e6821a6b4ced409a4351 Mon Sep 17 00:00:00 2001 From: Fancy2209 <64917206+Fancy2209@users.noreply.github.com> Date: Wed, 5 Feb 2025 09:19:13 -0100 Subject: [PATCH 05/26] Fix orthoWidth in Renderer --- src/render/ogc/SDL_render_ogc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/render/ogc/SDL_render_ogc.c b/src/render/ogc/SDL_render_ogc.c index fa75318f331cf..808cad52805f1 100644 --- a/src/render/ogc/SDL_render_ogc.c +++ b/src/render/ogc/SDL_render_ogc.c @@ -426,7 +426,13 @@ static int OGC_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL static int OGC_RenderSetViewPort(SDL_Renderer *renderer, SDL_RenderCommand *cmd) { const SDL_Rect *viewport = &cmd->data.viewport.rect; - + #ifdef __wii__ + if(CONF_GetAspectRatio() == CONF_ASPECT_16_9) + // Correct the orthographic projection width for widescreen, + 64 is because the viWidth is set to 704 + // 704 is 64 pixels wider than 640, so we have account for that strech + OGC_set_viewport(viewport->x, viewport->y, viewport->w, viewport->h, (viewport->h * 16.0f / 9.0f) + 64); + else + #endif OGC_set_viewport(viewport->x, viewport->y, viewport->w, viewport->h, viewport->w); return 0; } From 6570d3497eb0583c7818cbe111d537e9dd572023 Mon Sep 17 00:00:00 2001 From: Fancy2209 <64917206+Fancy2209@users.noreply.github.com> Date: Wed, 5 Feb 2025 09:21:51 -0100 Subject: [PATCH 06/26] Add missing include --- src/render/ogc/SDL_render_ogc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/render/ogc/SDL_render_ogc.c b/src/render/ogc/SDL_render_ogc.c index 808cad52805f1..6e219b6e696d2 100644 --- a/src/render/ogc/SDL_render_ogc.c +++ b/src/render/ogc/SDL_render_ogc.c @@ -33,6 +33,7 @@ #include #include #include +#include #define MAX_EFB_WIDTH 640 #define MAX_EFB_HEIGHT 528 From 4a73bb74b01a07d2ddf1c24726fa2410c659132d Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Wed, 5 Feb 2025 16:38:22 -0100 Subject: [PATCH 07/26] Remove resizing from Renderer, doesn't work properly --- src/render/ogc/SDL_render_ogc.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/render/ogc/SDL_render_ogc.c b/src/render/ogc/SDL_render_ogc.c index 6e219b6e696d2..0c4c92b183b68 100644 --- a/src/render/ogc/SDL_render_ogc.c +++ b/src/render/ogc/SDL_render_ogc.c @@ -28,12 +28,12 @@ #include "../../video/ogc/SDL_ogcgxcommon.h" #include "../../video/ogc/SDL_ogcpixels.h" #include "../../video/ogc/SDL_ogcvideo.h" +#include #include #include #include #include -#include #define MAX_EFB_WIDTH 640 #define MAX_EFB_HEIGHT 528 @@ -427,13 +427,6 @@ static int OGC_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL static int OGC_RenderSetViewPort(SDL_Renderer *renderer, SDL_RenderCommand *cmd) { const SDL_Rect *viewport = &cmd->data.viewport.rect; - #ifdef __wii__ - if(CONF_GetAspectRatio() == CONF_ASPECT_16_9) - // Correct the orthographic projection width for widescreen, + 64 is because the viWidth is set to 704 - // 704 is 64 pixels wider than 640, so we have account for that strech - OGC_set_viewport(viewport->x, viewport->y, viewport->w, viewport->h, (viewport->h * 16.0f / 9.0f) + 64); - else - #endif OGC_set_viewport(viewport->x, viewport->y, viewport->w, viewport->h, viewport->w); return 0; } From fc6993155f2c212854d229d6b13548fdc875e60d Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Wed, 5 Feb 2025 17:42:39 -0100 Subject: [PATCH 08/26] Fix SDL Renderer and OGC_set_viewport Stuff was setting the viewport and scissor to 854 Renderer now only adjusts projection if it's trying to set the viewport to 640*480 (this feels like not the intended way but I haven't found a better one) --- src/render/ogc/SDL_render_ogc.c | 3 ++- src/video/ogc/SDL_ogcgxcommon.c | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/render/ogc/SDL_render_ogc.c b/src/render/ogc/SDL_render_ogc.c index 0c4c92b183b68..197210c7e08b6 100644 --- a/src/render/ogc/SDL_render_ogc.c +++ b/src/render/ogc/SDL_render_ogc.c @@ -427,7 +427,8 @@ static int OGC_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL static int OGC_RenderSetViewPort(SDL_Renderer *renderer, SDL_RenderCommand *cmd) { const SDL_Rect *viewport = &cmd->data.viewport.rect; - OGC_set_viewport(viewport->x, viewport->y, viewport->w, viewport->h, viewport->w); + OGC_set_viewport(viewport->x, viewport->y, viewport->w, viewport->h, + viewport->w==640 ? (viewport->h*16.0f/9.0f)+1 : viewport->w); return 0; } diff --git a/src/video/ogc/SDL_ogcgxcommon.c b/src/video/ogc/SDL_ogcgxcommon.c index 9bad8d26f718e..19520b7204066 100644 --- a/src/video/ogc/SDL_ogcgxcommon.c +++ b/src/video/ogc/SDL_ogcgxcommon.c @@ -43,9 +43,10 @@ static const f32 tex_pos[] __attribute__((aligned(32))) = { void OGC_set_viewport(int x, int y, int w, int h, int orthoWidth) { Mtx44 proj; + SDL_Log("%d %d %d %d %d", x, y, w, h, orthoWidth); - GX_SetViewport(x, y, w, h, 0, 1); - GX_SetScissor(x, y, w, h); + GX_SetViewport(x, y, w > 640 ? 640 : w, h, 0, 1); + GX_SetScissor(x, y, w > 640 ? 640 : w, h); // matrix, t, b, l, r, n, f guOrtho(proj, 0, h, 0, orthoWidth, 0, 1); From ab853980f724435b5a1ab8947fb873ed7ad93125 Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Wed, 5 Feb 2025 17:47:57 -0100 Subject: [PATCH 09/26] Remove debug logging --- src/video/ogc/SDL_ogcgxcommon.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/ogc/SDL_ogcgxcommon.c b/src/video/ogc/SDL_ogcgxcommon.c index 19520b7204066..1b7630a037e8c 100644 --- a/src/video/ogc/SDL_ogcgxcommon.c +++ b/src/video/ogc/SDL_ogcgxcommon.c @@ -43,7 +43,6 @@ static const f32 tex_pos[] __attribute__((aligned(32))) = { void OGC_set_viewport(int x, int y, int w, int h, int orthoWidth) { Mtx44 proj; - SDL_Log("%d %d %d %d %d", x, y, w, h, orthoWidth); GX_SetViewport(x, y, w > 640 ? 640 : w, h, 0, 1); GX_SetScissor(x, y, w > 640 ? 640 : w, h); From d6efcad8e68cfe764453a8c585d71c159946583c Mon Sep 17 00:00:00 2001 From: Fancy2209 <64917206+Fancy2209@users.noreply.github.com> Date: Wed, 5 Feb 2025 19:48:34 -0100 Subject: [PATCH 10/26] Update src/render/ogc/SDL_render_ogc.c Co-authored-by: Alberto Mardegan --- src/render/ogc/SDL_render_ogc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/ogc/SDL_render_ogc.c b/src/render/ogc/SDL_render_ogc.c index 197210c7e08b6..f5841ee39e111 100644 --- a/src/render/ogc/SDL_render_ogc.c +++ b/src/render/ogc/SDL_render_ogc.c @@ -428,7 +428,7 @@ static int OGC_RenderSetViewPort(SDL_Renderer *renderer, SDL_RenderCommand *cmd) { const SDL_Rect *viewport = &cmd->data.viewport.rect; OGC_set_viewport(viewport->x, viewport->y, viewport->w, viewport->h, - viewport->w==640 ? (viewport->h*16.0f/9.0f)+1 : viewport->w); + viewport->w==640 ? (viewport->h*16.0f/9.0f)+1 : viewport->w); return 0; } From 4dc34dba23fca6d7dd0cf9a1f4729c9e8ff665bd Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Wed, 5 Feb 2025 20:56:23 -0100 Subject: [PATCH 11/26] Apply reviews --- src/video/ogc/SDL_ogcgxcommon.c | 24 ++++++-- src/video/ogc/SDL_ogcgxcommon.h | 4 +- src/video/ogc/SDL_ogcmouse.c | 12 ++-- src/video/ogc/SDL_ogcvideo.c | 106 +++++++++++++++----------------- 4 files changed, 80 insertions(+), 66 deletions(-) diff --git a/src/video/ogc/SDL_ogcgxcommon.c b/src/video/ogc/SDL_ogcgxcommon.c index 1b7630a037e8c..af06f529d39b4 100644 --- a/src/video/ogc/SDL_ogcgxcommon.c +++ b/src/video/ogc/SDL_ogcgxcommon.c @@ -40,23 +40,37 @@ static const f32 tex_pos[] __attribute__((aligned(32))) = { 1.0, }; -void OGC_set_viewport(int x, int y, int w, int h, int orthoWidth) +/* On Widescreen if we pass the intended viewport width, the output will be streched + * due to the fact the Wii's Widescreen is anamorphic, for this reason, we passs + * a width value adjusted for widescreen, so we can modify the ortographic projection + * of the viewport to allow the screen size to be displayed properly in widescreen + * For example: If an app wants to output at 640x480, + * it will be streched unless the projection is setup for 854x480, + * so we pass 854 on widthAdjustedForWidescreen + * + * The reason why we can't just check for the active aspect ratio + * is that if the app is using SDL Renderer with a different logical size + * from the window, it'd set the viewport to a size, than when we render we set it to another + * and the image ends up distorted. +void OGC_set_viewport(int x, int y, int w, int h, int widthAdjustedForWidescreen) { Mtx44 proj; + // Since the SDL GX_SetViewport(x, y, w > 640 ? 640 : w, h, 0, 1); GX_SetScissor(x, y, w > 640 ? 640 : w, h); // matrix, t, b, l, r, n, f - guOrtho(proj, 0, h, 0, orthoWidth, 0, 1); + guOrtho(proj, 0, h, 0, widthAdjustedForWidescreen, 0, 1); GX_LoadProjectionMtx(proj, GX_ORTHOGRAPHIC); } -void OGC_draw_init(int w, int h, int orthoWidth) +// takes in w, h and widthAdjustedForWidescreen to pass to OGC_set_viewport +void OGC_draw_init(int w, int h, int widthAdjustedForWidescreen) { Mtx mv; - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "OGC_draw_init called with %d, %d, %d", w, h, orthoWidth); + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "OGC_draw_init called with %d, %d, %d", w, h, widthAdjustedForWidescreen); guMtxIdentity(mv); /* Ideally we would use 0.5 to center the coordinates on the pixels, but @@ -86,7 +100,7 @@ void OGC_draw_init(int w, int h, int orthoWidth) GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE); GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); - OGC_set_viewport(0, 0, w, h, orthoWidth); + OGC_set_viewport(0, 0, w, h, widthAdjustedForWidescreen); GX_InvVtxCache(); // update vertex cache } diff --git a/src/video/ogc/SDL_ogcgxcommon.h b/src/video/ogc/SDL_ogcgxcommon.h index be026c6c2de8e..200f683ac5aa1 100644 --- a/src/video/ogc/SDL_ogcgxcommon.h +++ b/src/video/ogc/SDL_ogcgxcommon.h @@ -29,8 +29,8 @@ #define GX_COLOR_AS_U32(c) *((u32*)&c) -void OGC_draw_init(int w, int h, int orthoWidth); -void OGC_set_viewport(int x, int y, int w, int h, int orthoWidth); +void OGC_draw_init(int w, int h, int widthAdjustedForWidescreen); +void OGC_set_viewport(int x, int y, int w, int h, int widthAdjustedForWidescreen); void OGC_load_texture(void *texels, int w, int h, u8 gx_format, SDL_ScaleMode scale_mode); diff --git a/src/video/ogc/SDL_ogcmouse.c b/src/video/ogc/SDL_ogcmouse.c index 70764fee9f069..65c8dd43f1a19 100644 --- a/src/video/ogc/SDL_ogcmouse.c +++ b/src/video/ogc/SDL_ogcmouse.c @@ -176,7 +176,7 @@ void OGC_draw_cursor(_THIS) SDL_Mouse *mouse = SDL_GetMouse(); OGC_CursorData *curdata; Mtx mv; - int screen_w, screen_h, viewport_w; + int screen_w, screen_h; float angle = 0.0f; if (!mouse || !mouse->cursor_shown || @@ -192,8 +192,7 @@ void OGC_draw_cursor(_THIS) if (!data->ir.valid) return; } - viewport_w = _this->displays[0].current_mode.w; - screen_w = (viewport_w == 854) ? 640 : _this->displays[0].current_mode.w; + screen_w = _this->displays[0].current_mode.w; screen_h = _this->displays[0].current_mode.h; curdata = mouse->cur_cursor->driverdata; @@ -211,7 +210,12 @@ void OGC_draw_cursor(_THIS) guMtxTransApply(mv, mv, mouse->x, mouse->y, 0); GX_LoadPosMtxImm(mv, GX_PNMTX1); - OGC_set_viewport(0, 0, screen_w, screen_h, viewport_w); + #ifdef __wii__ + if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) + OGC_set_viewport(0, 0, screen_w, screen_h, ((int)(screen_h * 16.0f / 9.0f)) + 1); + else + #endif + OGC_set_viewport(0, 0, screen_w, screen_h, screen_w); GX_ClearVtxDesc(); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); diff --git a/src/video/ogc/SDL_ogcvideo.c b/src/video/ogc/SDL_ogcvideo.c index c474af20671e4..14f90aece8b61 100644 --- a/src/video/ogc/SDL_ogcvideo.c +++ b/src/video/ogc/SDL_ogcvideo.c @@ -38,10 +38,10 @@ #include #include +#include #include #include #include -#include #include @@ -87,14 +87,18 @@ static const GXRModeObj *s_pal_modes[] = { static int OGC_VideoInit(_THIS); static void OGC_VideoQuit(_THIS); -static void init_display_mode(SDL_DisplayMode *mode, const GXRModeObj *vmode, int width) +static void init_display_mode(SDL_DisplayMode *mode, const GXRModeObj *vmode) { u32 format = VI_FORMAT_FROM_MODE(vmode->viTVMode); /* Use a fake 32-bpp desktop mode */ SDL_zero(*mode); mode->format = SDL_PIXELFORMAT_ARGB8888; - mode->w = width; + + if (vmode->viWidth == 704) + mode->w = ((int)(vmode->fbWidth / 16.0f * 9.0f) + 1); + else + mode->w = vmode->fbWidth; mode->h = vmode->efbHeight; switch (format) { case VI_DEBUG: @@ -108,7 +112,7 @@ static void init_display_mode(SDL_DisplayMode *mode, const GXRModeObj *vmode, in mode->refresh_rate = 50; break; } - mode->driverdata = (GXRModeObj*)vmode; + mode->driverdata = (GXRModeObj *)vmode; } static void add_supported_modes(SDL_VideoDisplay *display, u32 tv_format) @@ -152,40 +156,36 @@ static void add_supported_modes(SDL_VideoDisplay *display, u32 tv_format) // TODO: Currently ony added on wii if it's widescreen, // but should work on GC and a 4:3 Wii // testing needed - - #ifdef __wii__ - if(CONF_GetAspectRatio() == CONF_ASPECT_16_9) - { - memcpy(&s_mode704, gx_modes[1], sizeof(s_mode704)); - s_mode704.viWidth = 704; - - // set Center point - if (&s_mode704 == &TVPal576IntDfScale || &s_mode704 == &TVPal576ProgScale) - { - s_mode704.viXOrigin = (VI_MAX_WIDTH_PAL - s_mode704.viWidth) / 2; - s_mode704.viYOrigin = (VI_MAX_HEIGHT_PAL - s_mode704.viHeight) / 2; - } - else - { - s_mode704.viXOrigin = (VI_MAX_WIDTH_NTSC - s_mode704.viWidth) / 2; - s_mode704.viYOrigin = (VI_MAX_HEIGHT_NTSC - s_mode704.viHeight) / 2; - } - - // Widescreen is anamorphic, so we provide a different width for the ortho projection - init_display_mode(&mode, &s_mode704, 854); - SDL_AddDisplayMode(display, &mode); + +#ifdef __wii__ + if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) { + memcpy(&s_mode704, gx_modes[1], sizeof(s_mode704)); + s_mode704.viWidth = 704; + + // set Center point + if (&s_mode704 == &TVPal576IntDfScale || &s_mode704 == &TVPal576ProgScale) { + s_mode704.viXOrigin = (VI_MAX_WIDTH_PAL - s_mode704.viWidth) / 2; + s_mode704.viYOrigin = (VI_MAX_HEIGHT_PAL - s_mode704.viHeight) / 2; + } else { + s_mode704.viXOrigin = (VI_MAX_WIDTH_NTSC - s_mode704.viWidth) / 2; + s_mode704.viYOrigin = (VI_MAX_HEIGHT_NTSC - s_mode704.viHeight) / 2; + } + + // Widescreen is anamorphic, so we provide a different width for the ortho projection + init_display_mode(&mode, &s_mode704); + SDL_AddDisplayMode(display, &mode); } - #endif +#endif /* Now add all the "standard" modes from libogc */ while (*gx_modes) { - init_display_mode(&mode, *gx_modes, (*gx_modes)->fbWidth); + init_display_mode(&mode, *gx_modes); SDL_AddDisplayMode(display, &mode); gx_modes++; } } -static void setup_video_mode(_THIS, GXRModeObj *vmode, int orthoWidth) +static void setup_video_mode(_THIS, GXRModeObj *vmode, int widthAdjustedForWidescreen) { SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; @@ -202,7 +202,8 @@ static void setup_video_mode(_THIS, GXRModeObj *vmode, int orthoWidth) VIDEO_Flush(); VIDEO_WaitVSync(); - if (vmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync(); + if (vmode->viTVMode & VI_NON_INTERLACE) + VIDEO_WaitVSync(); /* Setup the EFB -> XFB copy operation */ GX_SetDispCopySrc(0, 0, vmode->fbWidth, vmode->efbHeight); @@ -212,7 +213,7 @@ static void setup_video_mode(_THIS, GXRModeObj *vmode, int orthoWidth) GX_SetFieldMode(vmode->field_rendering, ((vmode->viHeight == 2 * vmode->xfbHeight) ? GX_ENABLE : GX_DISABLE)); - OGC_draw_init(vmode->fbWidth, vmode->efbHeight, orthoWidth); + OGC_draw_init(vmode->fbWidth, vmode->efbHeight, widthAdjustedForWidescreen); } static int OGC_SetDisplayMode(_THIS, SDL_VideoDisplay *display, @@ -309,29 +310,29 @@ int OGC_VideoInit(_THIS) VIDEO_Init(); vmode = VIDEO_GetPreferredMode(NULL); - vmode->viWidth = 704; - - // set Center point - if (&s_mode704 == &TVPal576IntDfScale || &s_mode704 == &TVPal576ProgScale) - { - vmode->viXOrigin = (VI_MAX_WIDTH_PAL - vmode->viWidth) / 2; - vmode->viYOrigin = (VI_MAX_HEIGHT_PAL - vmode->viHeight) / 2; - } - else - { - vmode->viXOrigin = (VI_MAX_WIDTH_NTSC - vmode->viWidth) / 2; - vmode->viYOrigin = (VI_MAX_HEIGHT_NTSC - vmode->viHeight) / 2; - } - +#ifdef __wii__ + if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) { + vmode->viWidth = 704; + + // set Center point + if (&s_mode704 == &TVPal576IntDfScale || &s_mode704 == &TVPal576ProgScale) { + vmode->viXOrigin = (VI_MAX_WIDTH_PAL - vmode->viWidth) / 2; + vmode->viYOrigin = (VI_MAX_HEIGHT_PAL - vmode->viHeight) / 2; + } else { + vmode->viXOrigin = (VI_MAX_WIDTH_NTSC - vmode->viWidth) / 2; + vmode->viYOrigin = (VI_MAX_HEIGHT_NTSC - vmode->viHeight) / 2; + } + } +#endif videodata->gp_fifo = memalign(32, DEFAULT_FIFO_SIZE); memset(videodata->gp_fifo, 0, DEFAULT_FIFO_SIZE); GX_Init(videodata->gp_fifo, DEFAULT_FIFO_SIZE); - #ifdef __wii__ - if(CONF_GetAspectRatio() == CONF_ASPECT_16_9) - setup_video_mode(_this, vmode, 854); +#ifdef __wii__ + if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) + setup_video_mode(_this, vmode, 854); else - #endif +#endif setup_video_mode(_this, vmode, vmode->fbWidth); GX_SetCopyClear(background, GX_MAX_Z24); @@ -343,12 +344,7 @@ int OGC_VideoInit(_THIS) GX_Flush(); - #ifdef __wii__ - if(CONF_GetAspectRatio() == CONF_ASPECT_16_9) - init_display_mode(&mode, vmode, 854); - else - #endif - init_display_mode(&mode, vmode, vmode->fbWidth); + init_display_mode(&mode, vmode); if (SDL_AddBasicVideoDisplay(&mode) < 0) { return -1; } From 016de5ff7ef1af7d853b39c5efa7083b3dc563a9 Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Wed, 5 Feb 2025 21:01:30 -0100 Subject: [PATCH 12/26] Close comment --- src/video/ogc/SDL_ogcgxcommon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/ogc/SDL_ogcgxcommon.c b/src/video/ogc/SDL_ogcgxcommon.c index af06f529d39b4..e7e8941338b6c 100644 --- a/src/video/ogc/SDL_ogcgxcommon.c +++ b/src/video/ogc/SDL_ogcgxcommon.c @@ -51,7 +51,7 @@ static const f32 tex_pos[] __attribute__((aligned(32))) = { * The reason why we can't just check for the active aspect ratio * is that if the app is using SDL Renderer with a different logical size * from the window, it'd set the viewport to a size, than when we render we set it to another - * and the image ends up distorted. + * and the image ends up distorted. */ void OGC_set_viewport(int x, int y, int w, int h, int widthAdjustedForWidescreen) { Mtx44 proj; From a5d6187c5eb2bba6819d93ffd5652d877ab12668 Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Wed, 5 Feb 2025 21:02:09 -0100 Subject: [PATCH 13/26] Expand comment --- src/video/ogc/SDL_ogcgxcommon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/ogc/SDL_ogcgxcommon.c b/src/video/ogc/SDL_ogcgxcommon.c index e7e8941338b6c..990171c73b545 100644 --- a/src/video/ogc/SDL_ogcgxcommon.c +++ b/src/video/ogc/SDL_ogcgxcommon.c @@ -51,7 +51,7 @@ static const f32 tex_pos[] __attribute__((aligned(32))) = { * The reason why we can't just check for the active aspect ratio * is that if the app is using SDL Renderer with a different logical size * from the window, it'd set the viewport to a size, than when we render we set it to another - * and the image ends up distorted. */ + * and the image ends up distorted, an example of this is VVVVVV. */ void OGC_set_viewport(int x, int y, int w, int h, int widthAdjustedForWidescreen) { Mtx44 proj; From 7fc3f5c8168c2649b1630be550ace568afa9cc93 Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Wed, 5 Feb 2025 21:02:44 -0100 Subject: [PATCH 14/26] Fix build --- src/video/ogc/SDL_ogcvideo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/ogc/SDL_ogcvideo.c b/src/video/ogc/SDL_ogcvideo.c index 14f90aece8b61..54aa9c3856d3e 100644 --- a/src/video/ogc/SDL_ogcvideo.c +++ b/src/video/ogc/SDL_ogcvideo.c @@ -148,7 +148,7 @@ static void add_supported_modes(SDL_VideoDisplay *display, u32 tv_format) * take care of the horizontal scale for us. */ memcpy(&s_mode320, gx_modes[0], sizeof(s_mode320)); s_mode320.fbWidth = 320; - init_display_mode(&mode, &s_mode320, s_mode320.fbWidth); + init_display_mode(&mode, &s_mode320); SDL_AddDisplayMode(display, &mode); // libogc uses 640 for the viWidth, but this does not work well for Widescreen From 052e287a528a891e8373fd0e38c22b96d35bcf17 Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Wed, 5 Feb 2025 21:04:45 -0100 Subject: [PATCH 15/26] Fix Widescreen Vide Mode Width Calculation --- src/video/ogc/SDL_ogcvideo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/ogc/SDL_ogcvideo.c b/src/video/ogc/SDL_ogcvideo.c index 54aa9c3856d3e..ac5126b004016 100644 --- a/src/video/ogc/SDL_ogcvideo.c +++ b/src/video/ogc/SDL_ogcvideo.c @@ -96,7 +96,7 @@ static void init_display_mode(SDL_DisplayMode *mode, const GXRModeObj *vmode) mode->format = SDL_PIXELFORMAT_ARGB8888; if (vmode->viWidth == 704) - mode->w = ((int)(vmode->fbWidth / 16.0f * 9.0f) + 1); + mode->w = ((int)(vmode->fbWidth * 16.0f / 9.0f) + 1); else mode->w = vmode->fbWidth; mode->h = vmode->efbHeight; From 027d5d252043b4ad123cd4ca76cf02f76bdf2b46 Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Wed, 5 Feb 2025 21:09:22 -0100 Subject: [PATCH 16/26] Fix mouse Widescreen Viewport --- src/video/ogc/SDL_ogcmouse.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/video/ogc/SDL_ogcmouse.c b/src/video/ogc/SDL_ogcmouse.c index 65c8dd43f1a19..dc65f2e274354 100644 --- a/src/video/ogc/SDL_ogcmouse.c +++ b/src/video/ogc/SDL_ogcmouse.c @@ -212,7 +212,8 @@ void OGC_draw_cursor(_THIS) #ifdef __wii__ if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) - OGC_set_viewport(0, 0, screen_w, screen_h, ((int)(screen_h * 16.0f / 9.0f)) + 1); + // Calculations to allow the mouse + OGC_set_viewport(0, 0, screen_w > 640 ? 640 : screen_w, screen_h, ((int)(screen_h * 16.0f / 9.0f)) + 1); else #endif OGC_set_viewport(0, 0, screen_w, screen_h, screen_w); From 5219b8fafa4263709e3bb7afe21107ba01a47ede Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Wed, 5 Feb 2025 21:11:59 -0100 Subject: [PATCH 17/26] Revert ogcmouse changes, simply swap the names of screen_w and viewport_w --- src/video/ogc/SDL_ogcmouse.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/video/ogc/SDL_ogcmouse.c b/src/video/ogc/SDL_ogcmouse.c index dc65f2e274354..459fe6d5a0c92 100644 --- a/src/video/ogc/SDL_ogcmouse.c +++ b/src/video/ogc/SDL_ogcmouse.c @@ -176,7 +176,7 @@ void OGC_draw_cursor(_THIS) SDL_Mouse *mouse = SDL_GetMouse(); OGC_CursorData *curdata; Mtx mv; - int screen_w, screen_h; + int viewport_w, screen_h, screen_w; float angle = 0.0f; if (!mouse || !mouse->cursor_shown || @@ -193,6 +193,7 @@ void OGC_draw_cursor(_THIS) } screen_w = _this->displays[0].current_mode.w; + viewport_w = (screen_w == 854) ? 640 : _this->displays[0].current_mode.w; screen_h = _this->displays[0].current_mode.h; curdata = mouse->cur_cursor->driverdata; @@ -200,7 +201,7 @@ void OGC_draw_cursor(_THIS) SDL_ScaleModeNearest); guMtxIdentity(mv); - guMtxScaleApply(mv, mv, screen_w / 640.0f, screen_h / 480.0f, 1.0f); + guMtxScaleApply(mv, mv, viewport_w / 640.0f, screen_h / 480.0f, 1.0f); if (angle != 0.0f) { Mtx rot; @@ -210,13 +211,7 @@ void OGC_draw_cursor(_THIS) guMtxTransApply(mv, mv, mouse->x, mouse->y, 0); GX_LoadPosMtxImm(mv, GX_PNMTX1); - #ifdef __wii__ - if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) - // Calculations to allow the mouse - OGC_set_viewport(0, 0, screen_w > 640 ? 640 : screen_w, screen_h, ((int)(screen_h * 16.0f / 9.0f)) + 1); - else - #endif - OGC_set_viewport(0, 0, screen_w, screen_h, screen_w); + OGC_set_viewport(0, 0, viewport_w, screen_h, screen_w); GX_ClearVtxDesc(); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); From d1b37b45236a35aa8b6560a68e7c2a2a916d693a Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Wed, 5 Feb 2025 22:34:17 -0100 Subject: [PATCH 18/26] Assorted Fixes Fix 4:3 Make mouse actually unstreched on 16:9 Fix SDL_DisplayMode 16:9 width (for real this time) --- .vscode/settings.json | 6 ++++++ src/render/ogc/SDL_render_ogc.c | 10 ++++++++-- src/video/ogc/SDL_ogcgxcommon.c | 6 +++--- src/video/ogc/SDL_ogcmouse.c | 12 ++++++++---- src/video/ogc/SDL_ogcvideo.c | 6 ++++-- 5 files changed, 29 insertions(+), 11 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000000..61eb45f5b294f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "files.associations": { + "*.wog2": "json", + "xutility": "c" + } +} \ No newline at end of file diff --git a/src/render/ogc/SDL_render_ogc.c b/src/render/ogc/SDL_render_ogc.c index f5841ee39e111..38938d8641558 100644 --- a/src/render/ogc/SDL_render_ogc.c +++ b/src/render/ogc/SDL_render_ogc.c @@ -427,8 +427,14 @@ static int OGC_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL static int OGC_RenderSetViewPort(SDL_Renderer *renderer, SDL_RenderCommand *cmd) { const SDL_Rect *viewport = &cmd->data.viewport.rect; - OGC_set_viewport(viewport->x, viewport->y, viewport->w, viewport->h, - viewport->w==640 ? (viewport->h*16.0f/9.0f)+1 : viewport->w); + #ifdef __wii__ + if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) + OGC_set_viewport(viewport->x, viewport->y, viewport->w, viewport->h, + viewport->w==640 ? (viewport->h*16.0f/9.0f)+1 : viewport->w); + else + #endif + OGC_set_viewport(viewport->x, viewport->y, viewport->w, viewport->h, viewport->w); + return 0; } diff --git a/src/video/ogc/SDL_ogcgxcommon.c b/src/video/ogc/SDL_ogcgxcommon.c index 990171c73b545..30d933fb53707 100644 --- a/src/video/ogc/SDL_ogcgxcommon.c +++ b/src/video/ogc/SDL_ogcgxcommon.c @@ -54,11 +54,11 @@ static const f32 tex_pos[] __attribute__((aligned(32))) = { * and the image ends up distorted, an example of this is VVVVVV. */ void OGC_set_viewport(int x, int y, int w, int h, int widthAdjustedForWidescreen) { + SDL_Log("OGC_set_viewport: %d %d %d %d %d", x, y, w, h, widthAdjustedForWidescreen); Mtx44 proj; - // Since the SDL - GX_SetViewport(x, y, w > 640 ? 640 : w, h, 0, 1); - GX_SetScissor(x, y, w > 640 ? 640 : w, h); + GX_SetViewport(x, y, (w > 640) ? 640 : w, h, 0, 1); + GX_SetScissor(x, y, (w > 640) ? 640 : w, h); // matrix, t, b, l, r, n, f guOrtho(proj, 0, h, 0, widthAdjustedForWidescreen, 0, 1); diff --git a/src/video/ogc/SDL_ogcmouse.c b/src/video/ogc/SDL_ogcmouse.c index 459fe6d5a0c92..972c7f4ffb23f 100644 --- a/src/video/ogc/SDL_ogcmouse.c +++ b/src/video/ogc/SDL_ogcmouse.c @@ -176,7 +176,7 @@ void OGC_draw_cursor(_THIS) SDL_Mouse *mouse = SDL_GetMouse(); OGC_CursorData *curdata; Mtx mv; - int viewport_w, screen_h, screen_w; + int screen_w, screen_h; float angle = 0.0f; if (!mouse || !mouse->cursor_shown || @@ -193,7 +193,6 @@ void OGC_draw_cursor(_THIS) } screen_w = _this->displays[0].current_mode.w; - viewport_w = (screen_w == 854) ? 640 : _this->displays[0].current_mode.w; screen_h = _this->displays[0].current_mode.h; curdata = mouse->cur_cursor->driverdata; @@ -201,7 +200,12 @@ void OGC_draw_cursor(_THIS) SDL_ScaleModeNearest); guMtxIdentity(mv); - guMtxScaleApply(mv, mv, viewport_w / 640.0f, screen_h / 480.0f, 1.0f); +#ifdef __wii__ + if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) + guMtxScaleApply(mv, mv, screen_w / 854.0f, screen_h / 480.0f, 1.0f); + else +#endif + guMtxScaleApply(mv, mv, screen_w / 640.0f, screen_h / 480.0f, 1.0f); if (angle != 0.0f) { Mtx rot; @@ -211,7 +215,7 @@ void OGC_draw_cursor(_THIS) guMtxTransApply(mv, mv, mouse->x, mouse->y, 0); GX_LoadPosMtxImm(mv, GX_PNMTX1); - OGC_set_viewport(0, 0, viewport_w, screen_h, screen_w); + OGC_set_viewport(0, 0, screen_w, screen_h, screen_w); GX_ClearVtxDesc(); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); diff --git a/src/video/ogc/SDL_ogcvideo.c b/src/video/ogc/SDL_ogcvideo.c index ac5126b004016..6097ec9ecdfe3 100644 --- a/src/video/ogc/SDL_ogcvideo.c +++ b/src/video/ogc/SDL_ogcvideo.c @@ -95,9 +95,11 @@ static void init_display_mode(SDL_DisplayMode *mode, const GXRModeObj *vmode) SDL_zero(*mode); mode->format = SDL_PIXELFORMAT_ARGB8888; - if (vmode->viWidth == 704) - mode->w = ((int)(vmode->fbWidth * 16.0f / 9.0f) + 1); + #ifdef __wii__ + if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) + mode->w = ((int)(vmode->fbWidth * 16.0f / 9.0f)) + 1; else + #endif mode->w = vmode->fbWidth; mode->h = vmode->efbHeight; switch (format) { From 412eb51913c28b8f38b029321595169db275e8dc Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Wed, 5 Feb 2025 22:36:23 -0100 Subject: [PATCH 19/26] Delete .vscode --- .vscode/settings.json | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 61eb45f5b294f..0000000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "files.associations": { - "*.wog2": "json", - "xutility": "c" - } -} \ No newline at end of file From e254a96c6a834cb7091564b622299cefdbdf6ae1 Mon Sep 17 00:00:00 2001 From: Fancy2209 <64917206+Fancy2209@users.noreply.github.com> Date: Thu, 6 Feb 2025 19:22:23 -0100 Subject: [PATCH 20/26] Better region check when setting the video mode center point Co-authored-by: Alberto Mardegan --- src/video/ogc/SDL_ogcvideo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/ogc/SDL_ogcvideo.c b/src/video/ogc/SDL_ogcvideo.c index 6097ec9ecdfe3..cdf24e738c7e1 100644 --- a/src/video/ogc/SDL_ogcvideo.c +++ b/src/video/ogc/SDL_ogcvideo.c @@ -165,7 +165,7 @@ static void add_supported_modes(SDL_VideoDisplay *display, u32 tv_format) s_mode704.viWidth = 704; // set Center point - if (&s_mode704 == &TVPal576IntDfScale || &s_mode704 == &TVPal576ProgScale) { + if (VI_FORMAT_FROM_MODE(s_mode704.viTVMode) == VI_PAL) { s_mode704.viXOrigin = (VI_MAX_WIDTH_PAL - s_mode704.viWidth) / 2; s_mode704.viYOrigin = (VI_MAX_HEIGHT_PAL - s_mode704.viHeight) / 2; } else { From 072708b7170f14885e0fefed64f55180d5305e81 Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Fri, 7 Feb 2025 18:37:34 -0100 Subject: [PATCH 21/26] Make code much cleaner --- src/render/ogc/SDL_render_ogc.c | 10 +--- src/video/ogc/SDL_ogcgxcommon.c | 24 ++------- src/video/ogc/SDL_ogcgxcommon.h | 4 +- src/video/ogc/SDL_ogcmouse.c | 15 ++++-- src/video/ogc/SDL_ogcvideo.c | 87 +++++++++++++-------------------- 5 files changed, 52 insertions(+), 88 deletions(-) diff --git a/src/render/ogc/SDL_render_ogc.c b/src/render/ogc/SDL_render_ogc.c index 38938d8641558..04226bed7a7ab 100644 --- a/src/render/ogc/SDL_render_ogc.c +++ b/src/render/ogc/SDL_render_ogc.c @@ -427,14 +427,8 @@ static int OGC_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL static int OGC_RenderSetViewPort(SDL_Renderer *renderer, SDL_RenderCommand *cmd) { const SDL_Rect *viewport = &cmd->data.viewport.rect; - #ifdef __wii__ - if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) - OGC_set_viewport(viewport->x, viewport->y, viewport->w, viewport->h, - viewport->w==640 ? (viewport->h*16.0f/9.0f)+1 : viewport->w); - else - #endif - OGC_set_viewport(viewport->x, viewport->y, viewport->w, viewport->h, viewport->w); - + + OGC_set_viewport(viewport->x, viewport->y, viewport->w, viewport->h); return 0; } diff --git a/src/video/ogc/SDL_ogcgxcommon.c b/src/video/ogc/SDL_ogcgxcommon.c index 30d933fb53707..39f56316748cc 100644 --- a/src/video/ogc/SDL_ogcgxcommon.c +++ b/src/video/ogc/SDL_ogcgxcommon.c @@ -40,37 +40,23 @@ static const f32 tex_pos[] __attribute__((aligned(32))) = { 1.0, }; -/* On Widescreen if we pass the intended viewport width, the output will be streched - * due to the fact the Wii's Widescreen is anamorphic, for this reason, we passs - * a width value adjusted for widescreen, so we can modify the ortographic projection - * of the viewport to allow the screen size to be displayed properly in widescreen - * For example: If an app wants to output at 640x480, - * it will be streched unless the projection is setup for 854x480, - * so we pass 854 on widthAdjustedForWidescreen - * - * The reason why we can't just check for the active aspect ratio - * is that if the app is using SDL Renderer with a different logical size - * from the window, it'd set the viewport to a size, than when we render we set it to another - * and the image ends up distorted, an example of this is VVVVVV. */ -void OGC_set_viewport(int x, int y, int w, int h, int widthAdjustedForWidescreen) +void OGC_set_viewport(int x, int y, int w, int h) { - SDL_Log("OGC_set_viewport: %d %d %d %d %d", x, y, w, h, widthAdjustedForWidescreen); Mtx44 proj; GX_SetViewport(x, y, (w > 640) ? 640 : w, h, 0, 1); GX_SetScissor(x, y, (w > 640) ? 640 : w, h); // matrix, t, b, l, r, n, f - guOrtho(proj, 0, h, 0, widthAdjustedForWidescreen, 0, 1); + guOrtho(proj, 0, h, 0, w, 0, 1); GX_LoadProjectionMtx(proj, GX_ORTHOGRAPHIC); } -// takes in w, h and widthAdjustedForWidescreen to pass to OGC_set_viewport -void OGC_draw_init(int w, int h, int widthAdjustedForWidescreen) +void OGC_draw_init(int w, int h) { Mtx mv; - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "OGC_draw_init called with %d, %d, %d", w, h, widthAdjustedForWidescreen); + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "OGC_draw_init called with %d, %d", w, h); guMtxIdentity(mv); /* Ideally we would use 0.5 to center the coordinates on the pixels, but @@ -100,7 +86,7 @@ void OGC_draw_init(int w, int h, int widthAdjustedForWidescreen) GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE); GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); - OGC_set_viewport(0, 0, w, h, widthAdjustedForWidescreen); + OGC_set_viewport(0, 0, w, h); GX_InvVtxCache(); // update vertex cache } diff --git a/src/video/ogc/SDL_ogcgxcommon.h b/src/video/ogc/SDL_ogcgxcommon.h index 200f683ac5aa1..1b2ed5b321e71 100644 --- a/src/video/ogc/SDL_ogcgxcommon.h +++ b/src/video/ogc/SDL_ogcgxcommon.h @@ -29,8 +29,8 @@ #define GX_COLOR_AS_U32(c) *((u32*)&c) -void OGC_draw_init(int w, int h, int widthAdjustedForWidescreen); -void OGC_set_viewport(int x, int y, int w, int h, int widthAdjustedForWidescreen); +void OGC_draw_init(int w, int h); +void OGC_set_viewport(int x, int y, int w, int h); void OGC_load_texture(void *texels, int w, int h, u8 gx_format, SDL_ScaleMode scale_mode); diff --git a/src/video/ogc/SDL_ogcmouse.c b/src/video/ogc/SDL_ogcmouse.c index 972c7f4ffb23f..7f50c2e3fcef8 100644 --- a/src/video/ogc/SDL_ogcmouse.c +++ b/src/video/ogc/SDL_ogcmouse.c @@ -196,8 +196,14 @@ void OGC_draw_cursor(_THIS) screen_h = _this->displays[0].current_mode.h; curdata = mouse->cur_cursor->driverdata; - OGC_load_texture(curdata->texels, curdata->w, curdata->h, GX_TF_RGBA8, - SDL_ScaleModeNearest); + #ifdef __wii__ + if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) + OGC_load_texture(curdata->texels, curdata->w, curdata->h, GX_TF_RGBA8, + SDL_ScaleModeLinear); + else + #endif + OGC_load_texture(curdata->texels, curdata->w, curdata->h, GX_TF_RGBA8, + SDL_ScaleModeNearest); guMtxIdentity(mv); #ifdef __wii__ @@ -215,7 +221,7 @@ void OGC_draw_cursor(_THIS) guMtxTransApply(mv, mv, mouse->x, mouse->y, 0); GX_LoadPosMtxImm(mv, GX_PNMTX1); - OGC_set_viewport(0, 0, screen_w, screen_h, screen_w); + OGC_set_viewport(0, 0, screen_w, screen_h); GX_ClearVtxDesc(); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); @@ -247,8 +253,7 @@ void OGC_draw_cursor(_THIS) SDL_Renderer *renderer = SDL_GetRenderer(_this->windows); if (renderer) { OGC_set_viewport(renderer->viewport.x, renderer->viewport.y, - renderer->viewport.w, renderer->viewport.h, - renderer->viewport.w); + renderer->viewport.w, renderer->viewport.h); } } } diff --git a/src/video/ogc/SDL_ogcvideo.c b/src/video/ogc/SDL_ogcvideo.c index 6097ec9ecdfe3..11c259066ecae 100644 --- a/src/video/ogc/SDL_ogcvideo.c +++ b/src/video/ogc/SDL_ogcvideo.c @@ -52,7 +52,6 @@ /* A video mode with a 320 width; we'll build it programmatically. */ static GXRModeObj s_mode320; -static GXRModeObj s_mode704; static const GXRModeObj *s_ntsc_modes[] = { &TVNtsc240Ds, @@ -96,11 +95,12 @@ static void init_display_mode(SDL_DisplayMode *mode, const GXRModeObj *vmode) mode->format = SDL_PIXELFORMAT_ARGB8888; #ifdef __wii__ - if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) - mode->w = ((int)(vmode->fbWidth * 16.0f / 9.0f)) + 1; - else + if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) { + mode->w = vmode->fbWidth * 16.0f / 9.0f; + mode->w = (mode->w + 1) & ~1; + } #endif - mode->w = vmode->fbWidth; + mode->w = vmode->fbWidth; mode->h = vmode->efbHeight; switch (format) { case VI_DEBUG: @@ -114,7 +114,7 @@ static void init_display_mode(SDL_DisplayMode *mode, const GXRModeObj *vmode) mode->refresh_rate = 50; break; } - mode->driverdata = (GXRModeObj *)vmode; + mode->driverdata = (GXRModeObj*)vmode; } static void add_supported_modes(SDL_VideoDisplay *display, u32 tv_format) @@ -153,32 +153,6 @@ static void add_supported_modes(SDL_VideoDisplay *display, u32 tv_format) init_display_mode(&mode, &s_mode320); SDL_AddDisplayMode(display, &mode); - // libogc uses 640 for the viWidth, but this does not work well for Widescreen - // as such we extend the viWidth to 704 on a new videomode - // TODO: Currently ony added on wii if it's widescreen, - // but should work on GC and a 4:3 Wii - // testing needed - -#ifdef __wii__ - if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) { - memcpy(&s_mode704, gx_modes[1], sizeof(s_mode704)); - s_mode704.viWidth = 704; - - // set Center point - if (&s_mode704 == &TVPal576IntDfScale || &s_mode704 == &TVPal576ProgScale) { - s_mode704.viXOrigin = (VI_MAX_WIDTH_PAL - s_mode704.viWidth) / 2; - s_mode704.viYOrigin = (VI_MAX_HEIGHT_PAL - s_mode704.viHeight) / 2; - } else { - s_mode704.viXOrigin = (VI_MAX_WIDTH_NTSC - s_mode704.viWidth) / 2; - s_mode704.viYOrigin = (VI_MAX_HEIGHT_NTSC - s_mode704.viHeight) / 2; - } - - // Widescreen is anamorphic, so we provide a different width for the ortho projection - init_display_mode(&mode, &s_mode704); - SDL_AddDisplayMode(display, &mode); - } -#endif - /* Now add all the "standard" modes from libogc */ while (*gx_modes) { init_display_mode(&mode, *gx_modes); @@ -187,10 +161,24 @@ static void add_supported_modes(SDL_VideoDisplay *display, u32 tv_format) } } -static void setup_video_mode(_THIS, GXRModeObj *vmode, int widthAdjustedForWidescreen) +static void setup_video_mode(_THIS, GXRModeObj *vmode) { SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + // TODO: Should I make this only happen if the aspect ratio isn't 4:3? + if(vmode->viWidth == 240 || vmode->viWidth == 640) + vmode->viWidth = vmode->viWidth + (VI_MAX_WIDTH_NTSC - 640); + + // set Center point + if (VI_FORMAT_FROM_MODE(vmode->viTVMode) == VI_PAL) { + vmode->viXOrigin = (VI_MAX_WIDTH_PAL - vmode->viWidth) / 2; + vmode->viYOrigin = (VI_MAX_HEIGHT_PAL - vmode->viHeight) / 2; + } else { + vmode->viXOrigin = (VI_MAX_WIDTH_NTSC - vmode->viWidth) / 2; + vmode->viYOrigin = (VI_MAX_HEIGHT_NTSC - vmode->viHeight) / 2; + } + + VIDEO_SetBlack(true); VIDEO_Configure(vmode); @@ -215,7 +203,7 @@ static void setup_video_mode(_THIS, GXRModeObj *vmode, int widthAdjustedForWides GX_SetFieldMode(vmode->field_rendering, ((vmode->viHeight == 2 * vmode->xfbHeight) ? GX_ENABLE : GX_DISABLE)); - OGC_draw_init(vmode->fbWidth, vmode->efbHeight, widthAdjustedForWidescreen); + OGC_draw_init(vmode->fbWidth, vmode->efbHeight); } static int OGC_SetDisplayMode(_THIS, SDL_VideoDisplay *display, @@ -230,7 +218,7 @@ static int OGC_SetDisplayMode(_THIS, SDL_VideoDisplay *display, if (videodata->xfb[1]) free(MEM_K1_TO_K0(videodata->xfb[1])); - setup_video_mode(_this, vmode, mode->w); + setup_video_mode(_this, vmode); return 0; } @@ -312,30 +300,21 @@ int OGC_VideoInit(_THIS) VIDEO_Init(); vmode = VIDEO_GetPreferredMode(NULL); -#ifdef __wii__ - if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) { - vmode->viWidth = 704; - - // set Center point - if (&s_mode704 == &TVPal576IntDfScale || &s_mode704 == &TVPal576ProgScale) { - vmode->viXOrigin = (VI_MAX_WIDTH_PAL - vmode->viWidth) / 2; - vmode->viYOrigin = (VI_MAX_HEIGHT_PAL - vmode->viHeight) / 2; - } else { - vmode->viXOrigin = (VI_MAX_WIDTH_NTSC - vmode->viWidth) / 2; - vmode->viYOrigin = (VI_MAX_HEIGHT_NTSC - vmode->viHeight) / 2; - } + vmode->viWidth = VI_MAX_WIDTH_NTSC; // VI_MAX_WIDTH is the same for all regions + // set Center point + if (VI_FORMAT_FROM_MODE(vmode->viTVMode) == VI_PAL) { + vmode->viXOrigin = (VI_MAX_WIDTH_PAL - vmode->viWidth) / 2; + vmode->viYOrigin = (VI_MAX_HEIGHT_PAL - vmode->viHeight) / 2; + } else { + vmode->viXOrigin = (VI_MAX_WIDTH_NTSC - vmode->viWidth) / 2; + vmode->viYOrigin = (VI_MAX_HEIGHT_NTSC - vmode->viHeight) / 2; } -#endif + videodata->gp_fifo = memalign(32, DEFAULT_FIFO_SIZE); memset(videodata->gp_fifo, 0, DEFAULT_FIFO_SIZE); GX_Init(videodata->gp_fifo, DEFAULT_FIFO_SIZE); -#ifdef __wii__ - if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) - setup_video_mode(_this, vmode, 854); - else -#endif - setup_video_mode(_this, vmode, vmode->fbWidth); + setup_video_mode(_this, vmode); GX_SetCopyClear(background, GX_MAX_Z24); GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR); From 40e5e4787cc38932def14ad27d3ef7ce2d842bec Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Fri, 7 Feb 2025 18:43:57 -0100 Subject: [PATCH 22/26] Remove unused header --- src/render/ogc/SDL_render_ogc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/render/ogc/SDL_render_ogc.c b/src/render/ogc/SDL_render_ogc.c index 04226bed7a7ab..ece76c7fcde78 100644 --- a/src/render/ogc/SDL_render_ogc.c +++ b/src/render/ogc/SDL_render_ogc.c @@ -28,7 +28,6 @@ #include "../../video/ogc/SDL_ogcgxcommon.h" #include "../../video/ogc/SDL_ogcpixels.h" #include "../../video/ogc/SDL_ogcvideo.h" -#include #include #include From 984d25b121554b7c2c3ed5cf4780f320f099d495 Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Fri, 7 Feb 2025 21:19:32 -0100 Subject: [PATCH 23/26] Add SDL_OGC_ASPECT_RATIO Because who doesn't want to make a Wii App that outputs at 21:9? --- src/video/ogc/SDL_ogcgxcommon.c | 21 +++++++++++++++++++++ src/video/ogc/SDL_ogcgxcommon.h | 1 + src/video/ogc/SDL_ogcmouse.c | 15 ++++++--------- src/video/ogc/SDL_ogcvideo.c | 16 +++++++++------- 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/src/video/ogc/SDL_ogcgxcommon.c b/src/video/ogc/SDL_ogcgxcommon.c index 39f56316748cc..49f884615ea91 100644 --- a/src/video/ogc/SDL_ogcgxcommon.c +++ b/src/video/ogc/SDL_ogcgxcommon.c @@ -28,6 +28,7 @@ #include #include #include +#include static const f32 tex_pos[] __attribute__((aligned(32))) = { 0.0, @@ -40,6 +41,26 @@ static const f32 tex_pos[] __attribute__((aligned(32))) = { 1.0, }; +bool OGC_get_aspect_ratio_dimensions(float *w, float *h) +{ + const char *ratioString; + ratioString = SDL_getenv("SDL_OGC_ASPECT_RATIO"); + + if(ratioString == NULL) { + #ifdef __wii__ + if(CONF_GetAspectRatio() == CONF_ASPECT_16_9) { + *w = 16.0f; + *h = 9.0f; + return true; + } + #endif + *w = 4.0f; + *h = 3.0f; + return true; + } else if(SDL_sscanf(ratioString, "%f:%f", w, h) == 2) return true; + return false; +} + void OGC_set_viewport(int x, int y, int w, int h) { Mtx44 proj; diff --git a/src/video/ogc/SDL_ogcgxcommon.h b/src/video/ogc/SDL_ogcgxcommon.h index 1b2ed5b321e71..d752093b13391 100644 --- a/src/video/ogc/SDL_ogcgxcommon.h +++ b/src/video/ogc/SDL_ogcgxcommon.h @@ -30,6 +30,7 @@ #define GX_COLOR_AS_U32(c) *((u32*)&c) void OGC_draw_init(int w, int h); +bool OGC_get_aspect_ratio_dimensions(float *w, float *h); void OGC_set_viewport(int x, int y, int w, int h); void OGC_load_texture(void *texels, int w, int h, u8 gx_format, SDL_ScaleMode scale_mode); diff --git a/src/video/ogc/SDL_ogcmouse.c b/src/video/ogc/SDL_ogcmouse.c index 7f50c2e3fcef8..8e4a95020ae24 100644 --- a/src/video/ogc/SDL_ogcmouse.c +++ b/src/video/ogc/SDL_ogcmouse.c @@ -179,6 +179,10 @@ void OGC_draw_cursor(_THIS) int screen_w, screen_h; float angle = 0.0f; + float aspect_w = 4.0f; + float aspect_h = 3.0f; + OGC_get_aspect_ratio_dimensions(&aspect_w, &aspect_h); + if (!mouse || !mouse->cursor_shown || !mouse->cur_cursor || !mouse->cur_cursor->driverdata) { return; @@ -196,22 +200,15 @@ void OGC_draw_cursor(_THIS) screen_h = _this->displays[0].current_mode.h; curdata = mouse->cur_cursor->driverdata; - #ifdef __wii__ - if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) + if (aspect_w > 4.0f && aspect_h > 3.0f) OGC_load_texture(curdata->texels, curdata->w, curdata->h, GX_TF_RGBA8, SDL_ScaleModeLinear); else - #endif OGC_load_texture(curdata->texels, curdata->w, curdata->h, GX_TF_RGBA8, SDL_ScaleModeNearest); guMtxIdentity(mv); -#ifdef __wii__ - if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) - guMtxScaleApply(mv, mv, screen_w / 854.0f, screen_h / 480.0f, 1.0f); - else -#endif - guMtxScaleApply(mv, mv, screen_w / 640.0f, screen_h / 480.0f, 1.0f); + guMtxScaleApply(mv, mv, screen_w / (480.0f * aspect_w / aspect_h), screen_h / 480.0f, 1.0f); if (angle != 0.0f) { Mtx rot; diff --git a/src/video/ogc/SDL_ogcvideo.c b/src/video/ogc/SDL_ogcvideo.c index 11c259066ecae..d09f9b52e4455 100644 --- a/src/video/ogc/SDL_ogcvideo.c +++ b/src/video/ogc/SDL_ogcvideo.c @@ -88,20 +88,22 @@ static void OGC_VideoQuit(_THIS); static void init_display_mode(SDL_DisplayMode *mode, const GXRModeObj *vmode) { + float aspect_w = 4.0f; + float aspect_h = 3.0f; + OGC_get_aspect_ratio_dimensions(&aspect_w, &aspect_h); + u32 format = VI_FORMAT_FROM_MODE(vmode->viTVMode); /* Use a fake 32-bpp desktop mode */ SDL_zero(*mode); mode->format = SDL_PIXELFORMAT_ARGB8888; - #ifdef __wii__ - if (CONF_GetAspectRatio() == CONF_ASPECT_16_9) { - mode->w = vmode->fbWidth * 16.0f / 9.0f; - mode->w = (mode->w + 1) & ~1; - } - #endif - mode->w = vmode->fbWidth; mode->h = vmode->efbHeight; + if (aspect_w > 4.0f && aspect_h > 3.0f) { + mode->w = mode->h * aspect_w / aspect_h; + mode->w = (mode->w + 1) & ~1; + } else + mode->w = vmode->fbWidth; switch (format) { case VI_DEBUG: case VI_NTSC: From ad259a734aba40dfc339f69c34fefc8067638bad Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Sat, 8 Feb 2025 23:26:21 -0100 Subject: [PATCH 24/26] Make OGC_get_aspect_ratio return a float and scale the mouse only based on the height --- src/video/ogc/SDL_ogcgxcommon.c | 20 ++++++++------------ src/video/ogc/SDL_ogcgxcommon.h | 2 +- src/video/ogc/SDL_ogcmouse.c | 8 +++----- src/video/ogc/SDL_ogcvideo.c | 22 +++------------------- 4 files changed, 15 insertions(+), 37 deletions(-) diff --git a/src/video/ogc/SDL_ogcgxcommon.c b/src/video/ogc/SDL_ogcgxcommon.c index 49f884615ea91..fe56bc8af8a3c 100644 --- a/src/video/ogc/SDL_ogcgxcommon.c +++ b/src/video/ogc/SDL_ogcgxcommon.c @@ -41,24 +41,20 @@ static const f32 tex_pos[] __attribute__((aligned(32))) = { 1.0, }; -bool OGC_get_aspect_ratio_dimensions(float *w, float *h) +float OGC_get_aspect_ratio() { const char *ratioString; - ratioString = SDL_getenv("SDL_OGC_ASPECT_RATIO"); + float w, h; + ratioString = getenv("SDL_OGC_ASPECT_RATIO"); if(ratioString == NULL) { #ifdef __wii__ - if(CONF_GetAspectRatio() == CONF_ASPECT_16_9) { - *w = 16.0f; - *h = 9.0f; - return true; - } + if(CONF_GetAspectRatio() == CONF_ASPECT_16_9) + return 16.0f / 9.0f; #endif - *w = 4.0f; - *h = 3.0f; - return true; - } else if(SDL_sscanf(ratioString, "%f:%f", w, h) == 2) return true; - return false; + return 4.0f / 3.0f; + } else if(sscanf(ratioString, "%f:%f", w, h) == 2) + return w/h; } void OGC_set_viewport(int x, int y, int w, int h) diff --git a/src/video/ogc/SDL_ogcgxcommon.h b/src/video/ogc/SDL_ogcgxcommon.h index d752093b13391..14e0de9af20c1 100644 --- a/src/video/ogc/SDL_ogcgxcommon.h +++ b/src/video/ogc/SDL_ogcgxcommon.h @@ -30,7 +30,7 @@ #define GX_COLOR_AS_U32(c) *((u32*)&c) void OGC_draw_init(int w, int h); -bool OGC_get_aspect_ratio_dimensions(float *w, float *h); +float OGC_get_aspect_ratio(); void OGC_set_viewport(int x, int y, int w, int h); void OGC_load_texture(void *texels, int w, int h, u8 gx_format, SDL_ScaleMode scale_mode); diff --git a/src/video/ogc/SDL_ogcmouse.c b/src/video/ogc/SDL_ogcmouse.c index 8e4a95020ae24..6c105ecb5411b 100644 --- a/src/video/ogc/SDL_ogcmouse.c +++ b/src/video/ogc/SDL_ogcmouse.c @@ -179,9 +179,7 @@ void OGC_draw_cursor(_THIS) int screen_w, screen_h; float angle = 0.0f; - float aspect_w = 4.0f; - float aspect_h = 3.0f; - OGC_get_aspect_ratio_dimensions(&aspect_w, &aspect_h); + float aspect_ratio = OGC_get_aspect_ratio(); if (!mouse || !mouse->cursor_shown || !mouse->cur_cursor || !mouse->cur_cursor->driverdata) { @@ -200,7 +198,7 @@ void OGC_draw_cursor(_THIS) screen_h = _this->displays[0].current_mode.h; curdata = mouse->cur_cursor->driverdata; - if (aspect_w > 4.0f && aspect_h > 3.0f) + if (aspect_ratio != 4.0f/3.0f) OGC_load_texture(curdata->texels, curdata->w, curdata->h, GX_TF_RGBA8, SDL_ScaleModeLinear); else @@ -208,7 +206,7 @@ void OGC_draw_cursor(_THIS) SDL_ScaleModeNearest); guMtxIdentity(mv); - guMtxScaleApply(mv, mv, screen_w / (480.0f * aspect_w / aspect_h), screen_h / 480.0f, 1.0f); + guMtxScaleApply(mv, mv, screen_h / 480.0f, screen_h / 480.0f, 1.0f); if (angle != 0.0f) { Mtx rot; diff --git a/src/video/ogc/SDL_ogcvideo.c b/src/video/ogc/SDL_ogcvideo.c index d09f9b52e4455..97fcbe01b142a 100644 --- a/src/video/ogc/SDL_ogcvideo.c +++ b/src/video/ogc/SDL_ogcvideo.c @@ -88,9 +88,7 @@ static void OGC_VideoQuit(_THIS); static void init_display_mode(SDL_DisplayMode *mode, const GXRModeObj *vmode) { - float aspect_w = 4.0f; - float aspect_h = 3.0f; - OGC_get_aspect_ratio_dimensions(&aspect_w, &aspect_h); + float aspect = OGC_get_aspect_ratio(); u32 format = VI_FORMAT_FROM_MODE(vmode->viTVMode); @@ -99,8 +97,8 @@ static void init_display_mode(SDL_DisplayMode *mode, const GXRModeObj *vmode) mode->format = SDL_PIXELFORMAT_ARGB8888; mode->h = vmode->efbHeight; - if (aspect_w > 4.0f && aspect_h > 3.0f) { - mode->w = mode->h * aspect_w / aspect_h; + if (aspect != 4.0f/3.0f) { + mode->w = mode->h * aspect; mode->w = (mode->w + 1) & ~1; } else mode->w = vmode->fbWidth; @@ -167,20 +165,6 @@ static void setup_video_mode(_THIS, GXRModeObj *vmode) { SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; - // TODO: Should I make this only happen if the aspect ratio isn't 4:3? - if(vmode->viWidth == 240 || vmode->viWidth == 640) - vmode->viWidth = vmode->viWidth + (VI_MAX_WIDTH_NTSC - 640); - - // set Center point - if (VI_FORMAT_FROM_MODE(vmode->viTVMode) == VI_PAL) { - vmode->viXOrigin = (VI_MAX_WIDTH_PAL - vmode->viWidth) / 2; - vmode->viYOrigin = (VI_MAX_HEIGHT_PAL - vmode->viHeight) / 2; - } else { - vmode->viXOrigin = (VI_MAX_WIDTH_NTSC - vmode->viWidth) / 2; - vmode->viYOrigin = (VI_MAX_HEIGHT_NTSC - vmode->viHeight) / 2; - } - - VIDEO_SetBlack(true); VIDEO_Configure(vmode); From 04d02189914f270af7b125b8be1eb795ababd8a8 Mon Sep 17 00:00:00 2001 From: Fancy2209 <64917206+Fancy2209@users.noreply.github.com> Date: Wed, 27 Aug 2025 19:30:08 +0000 Subject: [PATCH 25/26] Fix rebasing --- src/video/ogc/SDL_ogcmouse.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/video/ogc/SDL_ogcmouse.c b/src/video/ogc/SDL_ogcmouse.c index 6d008ccc434ec..6e3bda25650cc 100644 --- a/src/video/ogc/SDL_ogcmouse.c +++ b/src/video/ogc/SDL_ogcmouse.c @@ -29,7 +29,6 @@ #include "SDL_ogcgxcommon.h" #include "SDL_ogcmouse.h" #include "SDL_ogcpixels.h" -#include "SDL_ogcvideo.h" #include "../SDL_sysvideo.h" #include "../../render/SDL_sysrender.h" @@ -311,10 +310,9 @@ void OGC_draw_cursor(_THIS) OGC_load_texture(curdata->texels, curdata->w, curdata->h, GX_TF_RGBA8, SDL_ScaleModeNearest); - - guMtxIdentity(mv); - guMtxScaleApply(mv, mv, screen_h / 480.0f, screen_h / 480.0f, 1.0f); + guMtxIdentity(mv); + guMtxScaleApply(mv, mv, screen_w / 640.0f, screen_h / 480.0f, 1.0f); if (angle != 0.0f) { Mtx rot; guMtxRotDeg(rot, 'z', angle); From 9563a94456918b663fb0fdaf68ea76937fa523f3 Mon Sep 17 00:00:00 2001 From: Fancy2209 <64917206+Fancy2209@users.noreply.github.com> Date: Wed, 27 Aug 2025 19:35:48 +0000 Subject: [PATCH 26/26] Modify vmode only if not 4/3 --- src/video/ogc/SDL_ogcvideo.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/video/ogc/SDL_ogcvideo.c b/src/video/ogc/SDL_ogcvideo.c index c0e48b9d0649c..12a6e21419801 100644 --- a/src/video/ogc/SDL_ogcvideo.c +++ b/src/video/ogc/SDL_ogcvideo.c @@ -296,14 +296,17 @@ int OGC_VideoInit(_THIS) VIDEO_Init(); vmode = VIDEO_GetPreferredMode(NULL); - vmode->viWidth = VI_MAX_WIDTH_NTSC; // VI_MAX_WIDTH is the same for all regions - // set Center point - if (VI_FORMAT_FROM_MODE(vmode->viTVMode) == VI_PAL) { - vmode->viXOrigin = (VI_MAX_WIDTH_PAL - vmode->viWidth) / 2; - vmode->viYOrigin = (VI_MAX_HEIGHT_PAL - vmode->viHeight) / 2; - } else { - vmode->viXOrigin = (VI_MAX_WIDTH_NTSC - vmode->viWidth) / 2; - vmode->viYOrigin = (VI_MAX_HEIGHT_NTSC - vmode->viHeight) / 2; + if(OGC_get_aspect_ratio() != (4.0f / 3.0f)) + { + vmode->viWidth = VI_MAX_WIDTH_NTSC; // VI_MAX_WIDTH is the same for all regions + // set Center point + if (VI_FORMAT_FROM_MODE(vmode->viTVMode) == VI_PAL) { + vmode->viXOrigin = (VI_MAX_WIDTH_PAL - vmode->viWidth) / 2; + vmode->viYOrigin = (VI_MAX_HEIGHT_PAL - vmode->viHeight) / 2; + } else { + vmode->viXOrigin = (VI_MAX_WIDTH_NTSC - vmode->viWidth) / 2; + vmode->viYOrigin = (VI_MAX_HEIGHT_NTSC - vmode->viHeight) / 2; + } } videodata->gp_fifo = memalign(32, DEFAULT_FIFO_SIZE);