From bef63c3cd14bdd35d4339b3f1593ffe1d77c8639 Mon Sep 17 00:00:00 2001 From: Agent X <44549182+Agent-11@users.noreply.github.com> Date: Sun, 16 Apr 2023 23:10:09 -0400 Subject: [PATCH] Forced 4:3 (#346) Turn on forced 4:3 in Options -> Display Forced 4:3 activates in-game and doesn't affect the pause menu but does apply to the game's viewport and mods using DJUI I've made complete sure this is mod compatible with both RESOLUTION_N64 as well as RESOLUTION_DJUI Also fixed a small discrepancy with how object count text was rendered on the crash screen. --- lang/English.ini | 1 + lang/French.ini | 1 + lang/German.ini | 1 + lang/Portuguese.ini | 1 + lang/Spanish.ini | 1 + src/game/area.c | 6 ++++ src/game/game_init.c | 7 ++-- src/game/hud.c | 60 +++++++++++++++++++------------- src/game/hud.h | 4 +++ src/game/ingame_menu.c | 5 +-- src/game/screen_transition.c | 25 +++++++------ src/game/skybox.c | 15 ++++---- src/pc/configfile.c | 2 ++ src/pc/configfile.h | 1 + src/pc/crash_handler.c | 2 +- src/pc/djui/djui_hud_utils.c | 9 +++-- src/pc/djui/djui_panel_display.c | 2 ++ src/pc/lua/smlua_hooks.c | 3 +- 18 files changed, 98 insertions(+), 48 deletions(-) diff --git a/lang/English.ini b/lang/English.ini index 20d539caa..7c78aa93d 100644 --- a/lang/English.ini +++ b/lang/English.ini @@ -111,6 +111,7 @@ C_RIGHT = "C Right" [DISPLAY] DISPLAY = "DISPLAY" FULLSCREEN = "Fullscreen" +FORCE_4BY3 = "Force 4:3" PRELOAD_TEXTURES = "Preload Textures" VSYNC = "VSync" UNCAPPED_FRAMERATE = "Uncapped Framerate" diff --git a/lang/French.ini b/lang/French.ini index 13657930e..07f85f99b 100644 --- a/lang/French.ini +++ b/lang/French.ini @@ -111,6 +111,7 @@ C_RIGHT = "C Droite" [DISPLAY] DISPLAY = "AFFICHAGE" FULLSCREEN = "Plein Écran" +FORCE_4BY3 = "Force 4:3" PRELOAD_TEXTURES = "Textures Préchargées" VSYNC = "VSync" UNCAPPED_FRAMERATE = "FPS Illimités" diff --git a/lang/German.ini b/lang/German.ini index 56695824c..05277a728 100644 --- a/lang/German.ini +++ b/lang/German.ini @@ -111,6 +111,7 @@ C_RIGHT = "C Rechts" [DISPLAY] DISPLAY = "DISPLAY" FULLSCREEN = "Vollbildmodus" +FORCE_4BY3 = "Gewalt 4:3" PRELOAD_TEXTURES = "Texturen vorladen" VSYNC = "VSync" UNCAPPED_FRAMERATE = "Unbegrenzte Framerate" diff --git a/lang/Portuguese.ini b/lang/Portuguese.ini index d4ccaf905..7a00cd563 100644 --- a/lang/Portuguese.ini +++ b/lang/Portuguese.ini @@ -111,6 +111,7 @@ C_RIGHT = "C RIGHT" [DISPLAY] DISPLAY = "VÍDEO" FULLSCREEN = "Tela Cheia" +FORCE_4BY3 = "Força 4:3" PRELOAD_TEXTURES = "Texturas Precarregadas" VSYNC = "VSync" UNCAPPED_FRAMERATE = "Taxa de Quadros Limitado" diff --git a/lang/Spanish.ini b/lang/Spanish.ini index c0287fd0b..e3c8f46a9 100644 --- a/lang/Spanish.ini +++ b/lang/Spanish.ini @@ -111,6 +111,7 @@ C_RIGHT = "C Derecha" [DISPLAY] DISPLAY = "PANTALLA" FULLSCREEN = "Pantalla completa" +FORCE_4BY3 = "Fuerza 4:3" PRELOAD_TEXTURES = "Precargar texturas" VSYNC = "Sincronización vertical" UNCAPPED_FRAMERATE = "FPS sin límite" diff --git a/src/game/area.c b/src/game/area.c index bb1688afa..ca3b566f0 100644 --- a/src/game/area.c +++ b/src/game/area.c @@ -471,6 +471,12 @@ void render_game(void) { } } + if (use_forced_4by3()) { + gDPSetFillColor(gDisplayListHead++, GPACK_RGBA5551(0, 0, 0, 1)); + gDPFillRectangle(gDisplayListHead++, GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(0), 0, 0, SCREEN_HEIGHT); + gDPFillRectangle(gDisplayListHead++, SCREEN_WIDTH, 0, GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(0), SCREEN_HEIGHT); + } + D_8032CE74 = NULL; D_8032CE78 = NULL; } diff --git a/src/game/game_init.c b/src/game/game_init.c index 097695830..0cbace7d1 100644 --- a/src/game/game_init.c +++ b/src/game/game_init.c @@ -27,6 +27,7 @@ #ifdef BETTERCAMERA #include "bettercamera.h" #endif +#include "hud.h" // FIXME: I'm not sure all of these variables belong in this file, but I don't // know of a good way to split them @@ -172,8 +173,10 @@ void clear_viewport(Vp *viewport, s32 color) { s16 vpLrx = (viewport->vp.vtrans[0] + viewport->vp.vscale[0]) / 4 - 2; s16 vpLry = (viewport->vp.vtrans[1] + viewport->vp.vscale[1]) / 4 - 2; - vpUlx = GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(vpUlx); - vpLrx = GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(SCREEN_WIDTH - vpLrx); + if (!use_forced_4by3()) { + vpUlx = GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(vpUlx); + vpLrx = GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(SCREEN_WIDTH - vpLrx); + } gDPPipeSync(gDisplayListHead++); diff --git a/src/game/hud.c b/src/game/hud.c index 4b7d3e9f8..e4cfddf36 100644 --- a/src/game/hud.c +++ b/src/game/hud.c @@ -304,6 +304,18 @@ void render_hud_power_meter(void) { #define HUD_TOP_Y 209 #endif +bool use_forced_4by3(void) { + return configForce4By3 && !gDjuiInMainMenu; +} + +s32 gfx_dimensions_rect_from_left_edge(s32 v) { + return use_forced_4by3() ? v : GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(v); +} + +s32 gfx_dimensions_rect_from_right_edge(s32 v) { + return use_forced_4by3() ? SCREEN_WIDTH - v : GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(v); +} + /** * Renders the amount of lives Mario has. */ @@ -313,9 +325,9 @@ void render_hud_mario_lives(void) { #else char* displayHead = (gMarioStates[0].character) ? &gMarioStates[0].character->hudHead : ","; #endif - print_text(GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(22), HUD_TOP_Y, displayHead); // 'Mario Head' glyph - print_text(GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(38), HUD_TOP_Y, "*"); // 'X' glyph - print_text_fmt_int(GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(54), HUD_TOP_Y, "%d", gHudDisplay.lives); + print_text(gfx_dimensions_rect_from_left_edge(22), HUD_TOP_Y, displayHead); // 'Mario Head' glyph + print_text(gfx_dimensions_rect_from_left_edge(38), HUD_TOP_Y, "*"); // 'X' glyph + print_text_fmt_int(gfx_dimensions_rect_from_left_edge(54), HUD_TOP_Y, "%d", gHudDisplay.lives); } static void render_hud_icon(Vtx *vtx, const u8 *texture, u32 fmt, u32 siz, s32 texW, s32 texH, s32 x, s32 y, s32 w, s32 h, s32 tileX, s32 tileY, s32 tileW, s32 tileH) { @@ -365,12 +377,12 @@ void render_hud_cap_timer(void) { s32 capSeconds = (capTimer + 29) / 30; const u8 **capIcons = sHudCapIcons[capFlags]; gDPSetEnvColor(gDisplayListHead++, 0xFF, 0xFF, 0xFF, 0xFF); - render_hud_icon(NULL, capIcons[0], G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(22), HUD_TOP_Y - 4, 5, 16, 0, 0, 10, 32); - render_hud_icon(NULL, capIcons[1], G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(27), HUD_TOP_Y - 4, 3, 16, 10, 0, 6, 32); - render_hud_icon(NULL, capIcons[2], G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(30), HUD_TOP_Y - 4, 3, 16, 16, 0, 6, 32); - render_hud_icon(NULL, capIcons[3], G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(33), HUD_TOP_Y - 4, 5, 16, 22, 0, 10, 32); - print_text(GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(38), HUD_TOP_Y - 20, "*"); // 'X' glyph - print_text_fmt_int(GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(54), HUD_TOP_Y - 20, "%d", capSeconds); + render_hud_icon(NULL, capIcons[0], G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, gfx_dimensions_rect_from_left_edge(22), HUD_TOP_Y - 4, 5, 16, 0, 0, 10, 32); + render_hud_icon(NULL, capIcons[1], G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, gfx_dimensions_rect_from_left_edge(27), HUD_TOP_Y - 4, 3, 16, 10, 0, 6, 32); + render_hud_icon(NULL, capIcons[2], G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, gfx_dimensions_rect_from_left_edge(30), HUD_TOP_Y - 4, 3, 16, 16, 0, 6, 32); + render_hud_icon(NULL, capIcons[3], G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, gfx_dimensions_rect_from_left_edge(33), HUD_TOP_Y - 4, 5, 16, 22, 0, 10, 32); + print_text(gfx_dimensions_rect_from_left_edge(38), HUD_TOP_Y - 20, "*"); // 'X' glyph + print_text_fmt_int(gfx_dimensions_rect_from_left_edge(54), HUD_TOP_Y - 20, "%d", capSeconds); } } } @@ -427,7 +439,7 @@ void render_hud_red_coins_and_secrets_radar(void) { }; struct Object *redCoin = obj_get_nearest_object_with_behavior_id(m->marioObj, id_bhvRedCoin); if (redCoin) { - render_hud_radar(m, redCoin, sRedCoinTextures[(gGlobalTimer / 2) % 4], G_IM_FMT_IA, G_IM_SIZ_16b, 32, 32, GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(24), y, 0, 0, 32, 32, 0xFF, 0x00, 0x00); + render_hud_radar(m, redCoin, sRedCoinTextures[(gGlobalTimer / 2) % 4], G_IM_FMT_IA, G_IM_SIZ_16b, 32, 32, gfx_dimensions_rect_from_left_edge(24), y, 0, 0, 32, 32, 0xFF, 0x00, 0x00); y += 30; } } @@ -436,7 +448,7 @@ void render_hud_red_coins_and_secrets_radar(void) { if (gLevelValues.hudSecretsRadar) { struct Object *secret = obj_get_nearest_object_with_behavior_id(m->marioObj, id_bhvHiddenStarTrigger); if (secret) { - render_hud_radar(m, secret, texture_hud_char_S, G_IM_FMT_RGBA, G_IM_SIZ_16b, 16, 16, GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(24), y, 0, 0, 14, 16, 0xFF, 0xFF, 0xFF); + render_hud_radar(m, secret, texture_hud_char_S, G_IM_FMT_RGBA, G_IM_SIZ_16b, 16, 16, gfx_dimensions_rect_from_left_edge(24), y, 0, 0, 14, 16, 0xFF, 0xFF, 0xFF); y += 30; } } @@ -476,11 +488,11 @@ void render_hud_stars(void) { showX = 1; } - print_text(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(HUD_STARS_X), HUD_TOP_Y, "-"); // 'Star' glyph + print_text(gfx_dimensions_rect_from_right_edge(HUD_STARS_X), HUD_TOP_Y, "-"); // 'Star' glyph if (showX == 1) { - print_text(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(HUD_STARS_X) + 16, HUD_TOP_Y, "*"); // 'X' glyph + print_text(gfx_dimensions_rect_from_right_edge(HUD_STARS_X) + 16, HUD_TOP_Y, "*"); // 'X' glyph } - print_text_fmt_int((showX * 14) + GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(HUD_STARS_X - 16), + print_text_fmt_int((showX * 14) + gfx_dimensions_rect_from_right_edge(HUD_STARS_X - 16), HUD_TOP_Y, "%d", gHudDisplay.stars); } @@ -511,13 +523,13 @@ void render_hud_timer(void) { #ifdef VERSION_EU switch (eu_get_language()) { case LANGUAGE_ENGLISH: - print_text(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(150), 185, "TIME"); + print_text(gfx_dimensions_rect_from_right_edge(150), 185, "TIME"); break; case LANGUAGE_FRENCH: - print_text(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(155), 185, "TEMPS"); + print_text(gfx_dimensions_rect_from_right_edge(155), 185, "TEMPS"); break; case LANGUAGE_GERMAN: - print_text(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(150), 185, "ZEIT"); + print_text(gfx_dimensions_rect_from_right_edge(150), 185, "ZEIT"); break; } #endif @@ -526,14 +538,14 @@ void render_hud_timer(void) { timerFracSecs = ((timerValFrames - (timerMins * 1800) - (timerSecs * 30)) & 0xFFFF) / 3; #ifndef VERSION_EU - print_text(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(150), 185, "TIME"); + print_text(gfx_dimensions_rect_from_right_edge(150), 185, "TIME"); #endif - print_text_fmt_int(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(91), 185, "%0d", timerMins); - print_text_fmt_int(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(71), 185, "%02d", timerSecs); - print_text_fmt_int(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(37), 185, "%d", timerFracSecs); + print_text_fmt_int(gfx_dimensions_rect_from_right_edge(91), 185, "%0d", timerMins); + print_text_fmt_int(gfx_dimensions_rect_from_right_edge(71), 185, "%02d", timerSecs); + print_text_fmt_int(gfx_dimensions_rect_from_right_edge(37), 185, "%d", timerFracSecs); gSPDisplayList(gDisplayListHead++, dl_hud_img_begin); - render_hud_tex_lut(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(81), 32, (*hudLUT)[GLYPH_APOSTROPHE]); - render_hud_tex_lut(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(46), 32, (*hudLUT)[GLYPH_DOUBLE_QUOTE]); + render_hud_tex_lut(gfx_dimensions_rect_from_right_edge(81), 32, (*hudLUT)[GLYPH_APOSTROPHE]); + render_hud_tex_lut(gfx_dimensions_rect_from_right_edge(46), 32, (*hudLUT)[GLYPH_DOUBLE_QUOTE]); gSPDisplayList(gDisplayListHead++, dl_hud_img_end); } @@ -555,7 +567,7 @@ void render_hud_camera_status(void) { s32 y; cameraLUT = segmented_to_virtual(&main_hud_camera_lut); - x = GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(54); + x = gfx_dimensions_rect_from_right_edge(54); y = 205; if (sCameraHUD.status == CAM_STATUS_NONE) { diff --git a/src/game/hud.h b/src/game/hud.h index 1a2ed806a..acd52cc05 100644 --- a/src/game/hud.h +++ b/src/game/hud.h @@ -27,6 +27,10 @@ enum CameraHUDLut { extern u8 gOverrideHideHud; +bool use_forced_4by3(void); +extern s32 gfx_dimensions_rect_from_left_edge(s32 v); +extern s32 gfx_dimensions_rect_from_right_edge(s32 v); + void set_hud_camera_status(s16 status); void render_hud(void); diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index fd92244e0..e837118dd 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -33,6 +33,7 @@ #include "src/pc/djui/djui_panel_pause.h" #include "pc/utils/misc.h" #include "data/dynos_mgr_builtin_externs.h" +#include "hud.h" #ifdef BETTERCAMERA #include "bettercamera.h" #endif @@ -2332,7 +2333,7 @@ void change_dialog_camera_angle(void) { } void shade_screen(void) { - create_dl_translation_matrix(MENU_MTX_PUSH, GFX_DIMENSIONS_FROM_LEFT_EDGE(0), 240.0f, 0); + create_dl_translation_matrix(MENU_MTX_PUSH, gfx_dimensions_rect_from_left_edge(0), 240.0f, 0); // This is a bit weird. It reuses the dialog text box (width 130, height -80), // so scale to at least fit the screen. @@ -2380,7 +2381,7 @@ static inline void red_coins_print_glyph(s16 *x, u8 glyph, u8 width) { void render_pause_red_coins(void) { if (gCurrentArea->numRedCoins > 0) { u8 collected = gCurrentArea->numRedCoins - count_objects_with_behavior(bhvRedCoin); - s16 x = GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(38); + s16 x = gfx_dimensions_rect_from_left_edge(38); print_animated_red_coin(x - 8, 20); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); diff --git a/src/game/screen_transition.c b/src/game/screen_transition.c index 84bd3c4df..d5dfc2bc7 100644 --- a/src/game/screen_transition.c +++ b/src/game/screen_transition.c @@ -13,6 +13,7 @@ #include "segment2.h" #include "sm64.h" #include "pc/utils/misc.h" +#include "hud.h" u8 sTransitionColorFadeCount[4] = { 0 }; u16 sTransitionTextureFadeCount[2] = { 0 }; @@ -355,12 +356,14 @@ Gfx *render_cannon_circle_base(void) { make_vertex(verts, 1, SCREEN_WIDTH, 0, -1, 1152, 1824, 0, 0, 0, 255); make_vertex(verts, 2, SCREEN_WIDTH, SCREEN_HEIGHT, -1, 1152, 192, 0, 0, 0, 255); make_vertex(verts, 3, 0, SCREEN_HEIGHT, -1, -1152, 192, 0, 0, 0, 255); - - // Render black rectangles outside the 4:3 area. - make_vertex(verts, 4, GFX_DIMENSIONS_FROM_LEFT_EDGE(0), 0, -1, 0, 0, 0, 0, 0, 255); - make_vertex(verts, 5, GFX_DIMENSIONS_FROM_RIGHT_EDGE(0), 0, -1, 0, 0, 0, 0, 0, 255); - make_vertex(verts, 6, GFX_DIMENSIONS_FROM_RIGHT_EDGE(0), SCREEN_HEIGHT, -1, 0, 0, 0, 0, 0, 255); - make_vertex(verts, 7, GFX_DIMENSIONS_FROM_LEFT_EDGE(0), SCREEN_HEIGHT, -1, 0, 0, 0, 0, 0, 255); + + if (!use_forced_4by3()) { + // Render black rectangles outside the 4:3 area. + make_vertex(verts, 4, GFX_DIMENSIONS_FROM_LEFT_EDGE(0), 0, -1, 0, 0, 0, 0, 0, 255); + make_vertex(verts, 5, GFX_DIMENSIONS_FROM_RIGHT_EDGE(0), 0, -1, 0, 0, 0, 0, 0, 255); + make_vertex(verts, 6, GFX_DIMENSIONS_FROM_RIGHT_EDGE(0), SCREEN_HEIGHT, -1, 0, 0, 0, 0, 0, 255); + make_vertex(verts, 7, GFX_DIMENSIONS_FROM_LEFT_EDGE(0), SCREEN_HEIGHT, -1, 0, 0, 0, 0, 0, 255); + } gSPDisplayList(g++, dl_proj_mtx_fullscreen); gDPSetCombineMode(g++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); @@ -372,10 +375,12 @@ Gfx *render_cannon_circle_base(void) { gSPDisplayList(g++, dl_draw_quad_verts_0123); gSPTexture(g++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF); - gDPSetCombineMode(g++, G_CC_SHADE, G_CC_SHADE); - gSPVertex(g++, VIRTUAL_TO_PHYSICAL(verts + 4), 4, 4); - gSP2Triangles(g++, 4, 0, 3, 0, 4, 3, 7, 0); - gSP2Triangles(g++, 1, 5, 6, 0, 1, 6, 2, 0); + if (!use_forced_4by3()) { + gDPSetCombineMode(g++, G_CC_SHADE, G_CC_SHADE); + gSPVertex(g++, VIRTUAL_TO_PHYSICAL(verts + 4), 4, 4); + gSP2Triangles(g++, 4, 0, 3, 0, 4, 3, 7, 0); + gSP2Triangles(g++, 1, 5, 6, 0, 1, 6, 2, 0); + } gSPDisplayList(g++, dl_screen_transition_end); gSPEndDisplayList(g); diff --git a/src/game/skybox.c b/src/game/skybox.c index a0f6a2859..90f371df0 100644 --- a/src/game/skybox.c +++ b/src/game/skybox.c @@ -9,6 +9,7 @@ #include "save_file.h" #include "segment2.h" #include "sm64.h" +#include "hud.h" /** @@ -270,12 +271,14 @@ void *create_skybox_ortho_matrix(s8 player) { gBackgroundSkyboxMtx = mtx; } - f32 half_width = (4.0f / 3.0f) / GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_WIDTH / 2; - f32 center = (sSkyBoxInfo[player].scaledX + SCREEN_WIDTH / 2); - if (half_width < SCREEN_WIDTH / 2) { - // A wider screen than 4:3 - left = center - half_width; - right = center + half_width; + if (!use_forced_4by3()) { + f32 half_width = (4.0f / 3.0f) / GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_WIDTH / 2; + f32 center = (sSkyBoxInfo[player].scaledX + SCREEN_WIDTH / 2); + if (half_width < SCREEN_WIDTH / 2) { + // A wider screen than 4:3 + left = center - half_width; + right = center + half_width; + } } if (mtx != NULL) { diff --git a/src/pc/configfile.c b/src/pc/configfile.c index d95a0e56a..7f485b364 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -156,6 +156,7 @@ bool configDebugPrint = 0; bool configDebugInfo = 0; bool configDebugError = 0; char configLanguage[MAX_CONFIG_STRING] = ""; +bool configForce4By3 = false; static const struct ConfigOption options[] = { {.name = "fullscreen", .type = CONFIG_TYPE_BOOL, .boolValue = &configWindow.fullscreen}, @@ -264,6 +265,7 @@ static const struct ConfigOption options[] = { {.name = "debug_info", .type = CONFIG_TYPE_BOOL , .boolValue = &configDebugInfo}, {.name = "debug_error", .type = CONFIG_TYPE_BOOL , .boolValue = &configDebugError}, {.name = "language", .type = CONFIG_TYPE_STRING, .stringValue = (char*)&configLanguage, .maxStringLength = MAX_CONFIG_STRING}, + {.name = "force_4by3", .type = CONFIG_TYPE_BOOL, .boolValue = &configForce4By3}, }; // FunctionConfigOption functions diff --git a/src/pc/configfile.h b/src/pc/configfile.h index e074c0394..086a9e7b5 100644 --- a/src/pc/configfile.h +++ b/src/pc/configfile.h @@ -111,6 +111,7 @@ extern bool configDebugPrint; extern bool configDebugInfo; extern bool configDebugError; extern char configLanguage[]; +extern bool configForce4By3; void configfile_load(void); void configfile_save(const char *filename); diff --git a/src/pc/crash_handler.c b/src/pc/crash_handler.c index 030bc4ebb..5d307f7f6 100644 --- a/src/pc/crash_handler.c +++ b/src/pc/crash_handler.c @@ -455,7 +455,7 @@ static CRASH_HANDLER_TYPE crash_handler(EXCEPTION_POINTERS *ExceptionInfo) { crash_handler_add_info_int(&pText, 380, -4 + (8 * 0), "Id", (int)gPcDebug.id & 0xFF); crash_handler_add_info_int(&pText, 380, -4 + (8 * 1), "Ofs", (int)gPcDebug.bhvOffset & 0xFF); extern s16 gPrevFrameObjectCount; - crash_handler_add_info_int(&pText, 315, -4 + (8 * 4), "Objs", gPrevFrameObjectCount); + crash_handler_add_info_int(&pText, 380, -4 + (8 * 4), "Objs", gPrevFrameObjectCount); crash_handler_add_info_int(&pText, 380, -4 + (8 * 2), "Mods", gActiveMods.entryCount); diff --git a/src/pc/djui/djui_hud_utils.c b/src/pc/djui/djui_hud_utils.c index 6d2e1890b..9c7d2fd35 100644 --- a/src/pc/djui/djui_hud_utils.c +++ b/src/pc/djui/djui_hud_utils.c @@ -18,6 +18,7 @@ #include "djui_hud_utils.h" #include "djui_panel_pause.h" #include "game/camera.h" +#include "game/hud.h" static enum HudUtilsResolution sResolution = RESOLUTION_DJUI; @@ -62,7 +63,7 @@ static void djui_hud_position_translate(f32* x, f32* y) { if (sResolution == RESOLUTION_DJUI) { djui_gfx_position_translate(x, y); } else { - *x = GFX_DIMENSIONS_FROM_LEFT_EDGE(0) + *x; + *x = gfx_dimensions_rect_from_left_edge(0) + *x; *y = SCREEN_HEIGHT - *y; } } @@ -155,8 +156,12 @@ u32 djui_hud_get_screen_width(void) { u32 windowWidth, windowHeight; wm_api->get_dimensions(&windowWidth, &windowHeight); + if (use_forced_4by3() && sResolution == RESOLUTION_DJUI) { + windowWidth -= (GFX_DIMENSIONS_FROM_LEFT_EDGE(0) + GFX_DIMENSIONS_FROM_RIGHT_EDGE(0)); + } + return (sResolution == RESOLUTION_N64) - ? (GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_HEIGHT) + ? ((use_forced_4by3() ? (4.0f / 3.0f) : GFX_DIMENSIONS_ASPECT_RATIO) * SCREEN_HEIGHT) : (windowWidth / djui_gfx_get_scale()); } diff --git a/src/pc/djui/djui_panel_display.c b/src/pc/djui/djui_panel_display.c index 6bdb8e794..d3dc50b63 100644 --- a/src/pc/djui/djui_panel_display.c +++ b/src/pc/djui/djui_panel_display.c @@ -36,6 +36,8 @@ void djui_panel_display_create(struct DjuiBase* caller) { { djui_checkbox_create(body, DLANG(DISPLAY, FULLSCREEN), &configWindow.fullscreen, djui_panel_display_apply); + djui_checkbox_create(body, DLANG(DISPLAY, FORCE_4BY3), &configForce4By3, djui_panel_display_apply); + #ifdef EXTERNAL_DATA djui_checkbox_create(body, DLANG(DISPLAY, PRELOAD_TEXTURES), &configPrecacheRes, NULL); #endif diff --git a/src/pc/lua/smlua_hooks.c b/src/pc/lua/smlua_hooks.c index b8f766409..e18ebd644 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -4,6 +4,7 @@ #include "src/game/object_list_processor.h" #include "pc/djui/djui_chat_message.h" #include "pc/crash_handler.h" +#include "src/game/hud.h" #if defined(DEVELOPMENT) #include "../mods/mods.h" @@ -67,7 +68,7 @@ void lua_profiler_update_counters() { if ((c < '0' || c > '9') && (c < 'A' || c > 'Z')) c = ' '; text[j] = c; } - print_text(GFX_DIMENSIONS_FROM_LEFT_EDGE(4), y, text); + print_text(gfx_dimensions_rect_from_left_edge(4), y, text); } }