
diff --git a/enhancements/widescreenv2_sm64.patch b/enhancements/widescreenv2_sm64.patch
new file mode 100644
index 0000000..d7f27ad
--- /dev/null
+++ b/enhancements/widescreenv2_sm64.patch
@@ -0,0 +1,198 @@
+diff --git a/include/text_strings.h.in b/include/text_strings.h.in
+index 749179b..3b23b41 100644
+--- a/include/text_strings.h.in
++++ b/include/text_strings.h.in
+@@ -24,6 +24,10 @@
+ // Ingame Menu
+ #define TEXT_PAUSE _("PAUSE") // Pause text, Castle Courses
+ #define TEXT_HUD_CONGRATULATIONS _("CONGRATULATIONS") // Course Complete Text, Bowser Courses
++#define TEXT_HUD_CURRENT_RATIO_43 _("CURRENT ASPECT RATIO: 4:3. PRESS L TO SWITCH TO 16:9")
++#define TEXT_HUD_CURRENT_RATIO_169 _("CURRENT ASPECT RATIO: 16:9. PRESS L TO SWITCH TO 4:3")
++#define TEXT_HUD_WIDE_INFO _("PLEASE CONFIGURE YOUR DISPLAY OR YOUR EMULATOR TO")
++#define TEXT_HUD_WIDE_INFO2 _("STRETCH THE IMAGE TO 16:9")
+ 
+ #if defined(VERSION_JP) || defined(VERSION_SH)
+ 
+diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c
+index 8190f88..deb69f5 100644
+--- a/src/game/ingame_menu.c
++++ b/src/game/ingame_menu.c
+@@ -34,6 +34,11 @@ s16 gDialogY; // D_8032F69C
+ s16 gCutsceneMsgXOffset;
+ s16 gCutsceneMsgYOffset;
+ s8 gRedCoinsCollected;
++u8 textCurrRatio43[] = { TEXT_HUD_CURRENT_RATIO_43 };
++u8 textCurrRatio169[] = { TEXT_HUD_CURRENT_RATIO_169 };
++u8 textWideInfo[] = { TEXT_HUD_WIDE_INFO };
++u8 textWideInfo2[] = { TEXT_HUD_WIDE_INFO2 };
++extern u8 widescreen = 0;
+ 
+ extern u8 gLastCompletedCourseNum;
+ extern u8 gLastCompletedStarNum;
+@@ -2266,6 +2271,14 @@ void render_pause_my_score_coins(void) {
+         print_generic_string(get_string_width(gTextCourseArr[gInGameLanguage]) + 51, 157, strCourseNum);
+ #else
+         print_generic_string(CRS_NUM_X1, 157, strCourseNum);
++        if (widescreen == 0) {
++            print_generic_string(10, 20, textCurrRatio43);
++        }
++        else {
++            print_generic_string(10, 20, textCurrRatio169);
++            print_generic_string(10, 200, textWideInfo);
++            print_generic_string(10, 180, textWideInfo2);
++        }
+ #endif
+ 
+         actName = segmented_to_virtual(actNameTbl[(gCurrCourseNum - 1) * 6 + gDialogCourseActNum - 1]);
+@@ -2557,10 +2570,25 @@ void render_pause_castle_main_strings(s16 x, s16 y) {
+             }
+         }
+     }
++    if (gPlayer1Controller->buttonPressed & L_TRIG){
++        if (widescreen == 0){
++                widescreen = 1;
++            }
++        else{
++                widescreen = 0;
++            }
++    }
+ 
+     gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
+     gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
+-
++    if (widescreen == 0) {
++        print_generic_string(10, 20, textCurrRatio43);
++    }
++    else {
++        print_generic_string(10, 20, textCurrRatio169);
++        print_generic_string(10, 200, textWideInfo);
++        print_generic_string(10, 180, textWideInfo2);
++    }
+     if (gDialogLineNum < COURSE_STAGES_COUNT) {
+         courseName = segmented_to_virtual(courseNameTbl[gDialogLineNum]);
+         render_pause_castle_course_stars(x, y, gCurrSaveFileNum - 1, gDialogLineNum);
+@@ -2626,6 +2654,14 @@ s16 render_pause_courses_and_castle(void) {
+             shade_screen();
+             render_pause_my_score_coins();
+             render_pause_red_coins();
++        if (gPlayer1Controller->buttonPressed & L_TRIG){
++                if (widescreen == 0){
++                    widescreen = 1;
++                }
++                else{
++                    widescreen = 0;
++                }
++            }
+ 
+             if (gMarioStates[0].action & ACT_FLAG_PAUSE_EXIT) {
+                 render_pause_course_options(99, 93, &gDialogLineNum, 15);
+diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c
+index 58238e8..aabdb85 100644
+--- a/src/game/rendering_graph_node.c
++++ b/src/game/rendering_graph_node.c
+@@ -10,6 +10,7 @@
+ #include "rendering_graph_node.h"
+ #include "shadow.h"
+ #include "sm64.h"
++#define WIDESCREEN
+ 
+ /**
+  * This file contains the code that processes the scene graph for rendering.
+@@ -235,6 +236,7 @@ static void geo_process_ortho_projection(struct GraphNodeOrthoProjection *node)
+ /**
+  * Process a perspective projection node.
+  */
++extern u8 widescreen;
+ static void geo_process_perspective(struct GraphNodePerspective *node) {
+     if (node->fnNode.func != NULL) {
+         node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node, gMatStack[gMatStackIndex]);
+@@ -246,7 +248,13 @@ static void geo_process_perspective(struct GraphNodePerspective *node) {
+ #ifdef VERSION_EU
+         f32 aspect = ((f32) gCurGraphNodeRoot->width / (f32) gCurGraphNodeRoot->height) * 1.1f;
+ #else
+-        f32 aspect = (f32) gCurGraphNodeRoot->width / (f32) gCurGraphNodeRoot->height;
++        f32 aspect;
++        if (widescreen == 1){
++            aspect = 1.775f;
++        }
++        else{
++            aspect = 1.33333f;
++        }
+ #endif
+ 
+         guPerspective(mtx, &perspNorm, node->fov, aspect, node->near, node->far, 1.0f);
+diff --git a/src/menu/file_select.c b/src/menu/file_select.c
+index c894797..dc759f7 100644
+--- a/src/menu/file_select.c
++++ b/src/menu/file_select.c
+@@ -2854,10 +2854,12 @@ Gfx *geo_file_select_strings_and_menu_cursor(s32 callContext, UNUSED struct Grap
+  * Relocates cursor position of the last save if the game goes back to the Mario Screen
+  * either completing a course choosing "SAVE & QUIT" or having a game over.
+  */
++extern u8 widescreen;
+ s32 lvl_init_menu_values_and_cursor_pos(UNUSED s32 arg, UNUSED s32 unused) {
+ #ifdef VERSION_EU
+     s8 fileNum;
+ #endif
++    widescreen = 0;
+     sSelectedButtonID = MENU_BUTTON_NONE;
+     sCurrentMenuLevel = MENU_LAYER_MAIN;
+     sTextBaseAlpha = 0;
+diff --git a/src/menu/star_select.c b/src/menu/star_select.c
+index 025dbf2..d6aaa7e 100644
+--- a/src/menu/star_select.c
++++ b/src/menu/star_select.c
+@@ -52,7 +52,7 @@ static s8 sSelectableStarIndex = 0;
+ 
+ // Act Selector menu timer that keeps counting until you choose an act.
+ static s32 sActSelectorMenuTimer = 0;
+-
++extern u8 widescreen;
+ /**
+  * Act Selector Star Type Loop Action
+  * Defines a select type for a star in the act selector.
+@@ -92,8 +92,15 @@ void bhv_act_selector_star_type_loop(void) {
+ void render_100_coin_star(u8 stars) {
+     if (stars & (1 << 6)) {
+         // If the 100 coin star has been collected, create a new star selector next to the coin score.
+-        sStarSelectorModels[6] = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_STAR,
+-                                                        bhvActSelectorStarType, 370, 24, -300, 0, 0, 0);
++        if (widescreen == 1){
++            sStarSelectorModels[6] = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_STAR,
++                                                            bhvActSelectorStarType, ((370*4.0f)/3), 24, -300, 0, 0, 0);
++        }
++        else{
++            sStarSelectorModels[6] = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_STAR,
++                                                            bhvActSelectorStarType, 370, 24, -300, 0, 0, 0);
++        }
++
+         sStarSelectorModels[6]->oStarSelectorSize = 0.8;
+         sStarSelectorModels[6]->oStarSelectorType = STAR_SELECTOR_100_COINS;
+     }
+@@ -147,11 +154,21 @@ void bhv_act_selector_init(void) {
+     }
+ 
+     // Render star selector objects
+-    for (i = 0; i < sVisibleStars; i++) {
+-        sStarSelectorModels[i] =
+-            spawn_object_abs_with_rot(gCurrentObject, 0, selectorModelIDs[i], bhvActSelectorStarType,
+-                                      75 + sVisibleStars * -75 + i * 152, 248, -300, 0, 0, 0);
+-        sStarSelectorModels[i]->oStarSelectorSize = 1.0f;
++    if (widescreen == 1) {
++        for (i = 0; i < sVisibleStars; i++) {
++            sStarSelectorModels[i] =
++                spawn_object_abs_with_rot(gCurrentObject, 0, selectorModelIDs[i], bhvActSelectorStarType,
++                                        (((75 + sVisibleStars * -75 + i * 152)*4.0f)/3), 248, -300, 0, 0, 0);
++            sStarSelectorModels[i]->oStarSelectorSize = 1.0f;
++        }
++    }
++    else {
++        for (i = 0; i < sVisibleStars; i++) {
++            sStarSelectorModels[i] =
++                spawn_object_abs_with_rot(gCurrentObject, 0, selectorModelIDs[i], bhvActSelectorStarType,
++                                        75 + sVisibleStars * -75 + i * 152, 248, -300, 0, 0, 0);
++            sStarSelectorModels[i]->oStarSelectorSize = 1.0f;
++        }
+     }
+ 
+     render_100_coin_star(stars);
diff --git a/enhancements/widescreenv2_ultrasm64.patch b/enhancements/widescreenv2_ultrasm64.patch
new file mode 100644
index 0000000..667e6e2
--- /dev/null
+++ b/enhancements/widescreenv2_ultrasm64.patch
@@ -0,0 +1,227 @@
+diff --git a/include/text_strings.h.in b/include/text_strings.h.in
+index 749179b..3b23b41 100644
+--- a/include/text_strings.h.in
++++ b/include/text_strings.h.in
+@@ -24,6 +24,10 @@
+ // Ingame Menu
+ #define TEXT_PAUSE _("PAUSE") // Pause text, Castle Courses
+ #define TEXT_HUD_CONGRATULATIONS _("CONGRATULATIONS") // Course Complete Text, Bowser Courses
++#define TEXT_HUD_CURRENT_RATIO_43 _("CURRENT ASPECT RATIO: 4:3. PRESS L TO SWITCH TO 16:9")
++#define TEXT_HUD_CURRENT_RATIO_169 _("CURRENT ASPECT RATIO: 16:9. PRESS L TO SWITCH TO 4:3")
++#define TEXT_HUD_WIDE_INFO _("PLEASE CONFIGURE YOUR DISPLAY OR YOUR EMULATOR TO")
++#define TEXT_HUD_WIDE_INFO2 _("STRETCH THE IMAGE TO 16:9")
+ 
+ #if defined(VERSION_JP) || defined(VERSION_SH)
+ 
+diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c
+index 9344738..37bc1d1 100644
+--- a/src/game/ingame_menu.c
++++ b/src/game/ingame_menu.c
+@@ -34,6 +34,11 @@ s16 gDialogY; // D_8032F69C
+ s16 gCutsceneMsgXOffset;
+ s16 gCutsceneMsgYOffset;
+ s8 gRedCoinsCollected;
++u8 textCurrRatio43[] = { TEXT_HUD_CURRENT_RATIO_43 };
++u8 textCurrRatio169[] = { TEXT_HUD_CURRENT_RATIO_169 };
++u8 textWideInfo[] = { TEXT_HUD_WIDE_INFO };
++u8 textWideInfo2[] = { TEXT_HUD_WIDE_INFO2 };
++extern s32 widescreen = 0;
+ 
+ extern u8 gLastCompletedCourseNum;
+ extern u8 gLastCompletedStarNum;
+@@ -1672,6 +1677,7 @@ s8 gDialogCourseActNum = 1;
+ #define DIAG_VAL2 240 // JP & US
+ #endif
+ 
++
+ void render_dialog_entries(void) {
+ #ifdef VERSION_EU
+     s8 lowerBound;
+@@ -1713,7 +1719,7 @@ void render_dialog_entries(void) {
+     switch (gDialogBoxState) {
+         case DIALOG_STATE_OPENING:
+             if (gDialogBoxOpenTimer == DEFAULT_DIALOG_BOX_ANGLE) {
+-                play_dialog_sound(gDialogID);
++                //play_dialog_sound(gDialogID);
+                 play_sound(SOUND_MENU_MESSAGE_APPEAR, gGlobalSoundSource);
+             }
+ 
+@@ -2199,6 +2205,7 @@ void render_pause_my_score_coins(void) {
+ #else
+     u8 textCourse[] = { TEXT_COURSE };
+     u8 textMyScore[] = { TEXT_MY_SCORE };
++
+ #endif
+     u8 textStar[] = { TEXT_STAR };
+     u8 textUnfilledStar[] = { TEXT_UNFILLED_STAR };
+@@ -2266,8 +2273,18 @@ void render_pause_my_score_coins(void) {
+         print_generic_string(get_string_width(gTextCourseArr[gInGameLanguage]) + 51, 157, strCourseNum);
+ #else
+         print_generic_string(CRS_NUM_X1, 157, strCourseNum);
++        if (widescreen == 0) {
++            print_generic_string(10, 20, textCurrRatio43);
++        }
++        else {
++            print_generic_string(10, 20, textCurrRatio169);
++            print_generic_string(10, 200, textWideInfo);
++            print_generic_string(10, 180, textWideInfo2);
++        }
++        
+ #endif
+ 
++
+         actName = segmented_to_virtual(actNameTbl[(gCurrCourseNum - 1) * 6 + gDialogCourseActNum - 1]);
+ 
+         if (starFlags & (1 << (gDialogCourseActNum - 1))) {
+@@ -2557,10 +2574,25 @@ void render_pause_castle_main_strings(s16 x, s16 y) {
+             }
+         }
+     }
+-
++    if (gPlayer1Controller->buttonPressed & L_TRIG){
++        if (widescreen == 0){
++                widescreen = 1;
++            }
++        else{
++                widescreen = 0;
++            }
++    }
+     gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
+     gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
+ 
++        if (widescreen == 0) {
++            print_generic_string(10, 20, textCurrRatio43);
++        }
++        else {
++            print_generic_string(10, 20, textCurrRatio169);
++            print_generic_string(10, 200, textWideInfo);
++            print_generic_string(10, 180, textWideInfo2);
++        }
+     if (gDialogLineNum < COURSE_STAGES_COUNT) {
+         courseName = segmented_to_virtual(courseNameTbl[gDialogLineNum]);
+         render_pause_castle_course_stars(x, y, gCurrSaveFileNum - 1, gDialogLineNum);
+@@ -2626,7 +2658,14 @@ s16 render_pause_courses_and_castle(void) {
+             shade_screen();
+             render_pause_my_score_coins();
+             render_pause_red_coins();
+-
++        if (gPlayer1Controller->buttonPressed & L_TRIG){
++                if (widescreen == 0){
++                    widescreen = 1;
++                }
++                else{
++                    widescreen = 0;
++                }
++            }
+             if (gMarioStates[0].action & ACT_FLAG_PAUSE_EXIT) {
+                 render_pause_course_options(99, 93, &gDialogLineNum, 15);
+             }
+diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c
+index 58238e8..5262fd3 100644
+--- a/src/game/rendering_graph_node.c
++++ b/src/game/rendering_graph_node.c
+@@ -10,6 +10,7 @@
+ #include "rendering_graph_node.h"
+ #include "shadow.h"
+ #include "sm64.h"
++#define WIDESCREEN
+ 
+ /**
+  * This file contains the code that processes the scene graph for rendering.
+@@ -235,6 +236,8 @@ static void geo_process_ortho_projection(struct GraphNodeOrthoProjection *node)
+ /**
+  * Process a perspective projection node.
+  */
++
++extern s32 widescreen;
+ static void geo_process_perspective(struct GraphNodePerspective *node) {
+     if (node->fnNode.func != NULL) {
+         node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node, gMatStack[gMatStackIndex]);
+@@ -246,7 +249,13 @@ static void geo_process_perspective(struct GraphNodePerspective *node) {
+ #ifdef VERSION_EU
+         f32 aspect = ((f32) gCurGraphNodeRoot->width / (f32) gCurGraphNodeRoot->height) * 1.1f;
+ #else
+-        f32 aspect = (f32) gCurGraphNodeRoot->width / (f32) gCurGraphNodeRoot->height;
++        f32 aspect;
++        if (widescreen == 1){
++            aspect = 1.775f;
++        }
++        else{
++            aspect = 1.33333f;
++        }
+ #endif
+ 
+         guPerspective(mtx, &perspNorm, node->fov, aspect, node->near, node->far, 1.0f);
+diff --git a/src/menu/file_select.c b/src/menu/file_select.c
+index 9437dcc..6ba1845 100644
+--- a/src/menu/file_select.c
++++ b/src/menu/file_select.c
+@@ -2854,10 +2854,12 @@ Gfx *geo_file_select_strings_and_menu_cursor(s32 callContext, UNUSED struct Grap
+  * Relocates cursor position of the last save if the game goes back to the Mario Screen
+  * either completing a course choosing "SAVE & QUIT" or having a game over.
+  */
++extern s32 widescreen;
+ s32 lvl_init_menu_values_and_cursor_pos(UNUSED s32 arg, UNUSED s32 unused) {
+ #ifdef VERSION_EU
+     s8 fileNum;
+ #endif
++    widescreen = 0;
+     sSelectedButtonID = MENU_BUTTON_NONE;
+     sCurrentMenuLevel = MENU_LAYER_MAIN;
+     sTextBaseAlpha = 0;
+diff --git a/src/menu/star_select.c b/src/menu/star_select.c
+index 07610fa..9664cc1 100644
+--- a/src/menu/star_select.c
++++ b/src/menu/star_select.c
+@@ -52,6 +52,7 @@ static s8 sSelectableStarIndex = 0;
+ 
+ // Act Selector menu timer that keeps counting until you choose an act.
+ static s32 sActSelectorMenuTimer = 0;
++extern s32 widescreen;
+ 
+ /**
+  * Act Selector Star Type Loop Action
+@@ -92,8 +93,14 @@ void bhv_act_selector_star_type_loop(void) {
+ void render_100_coin_star(u8 stars) {
+     if (stars & (1 << 6)) {
+         // If the 100 coin star has been collected, create a new star selector next to the coin score.
+-        sStarSelectorModels[6] = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_STAR,
+-                                                        bhvActSelectorStarType, 370, 24, -300, 0, 0, 0);
++        if (widescreen == 1){
++            sStarSelectorModels[6] = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_STAR,
++                                                            bhvActSelectorStarType, ((370*4.0f)/3), 24, -300, 0, 0, 0);
++        }
++        else{
++            sStarSelectorModels[6] = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_STAR,
++                                                            bhvActSelectorStarType, 370, 24, -300, 0, 0, 0);
++        }
+         sStarSelectorModels[6]->oStarSelectorSize = 0.8;
+         sStarSelectorModels[6]->oStarSelectorType = STAR_SELECTOR_100_COINS;
+     }
+@@ -147,11 +154,21 @@ void bhv_act_selector_init(void) {
+     }
+ 
+     // Render star selector objects
+-    for (i = 0; i < sVisibleStars; i++) {
+-        sStarSelectorModels[i] =
+-            spawn_object_abs_with_rot(gCurrentObject, 0, selectorModelIDs[i], bhvActSelectorStarType,
+-                                      75 + sVisibleStars * -75 + i * 152, 248, -300, 0, 0, 0);
+-        sStarSelectorModels[i]->oStarSelectorSize = 1.0f;
++    if (widescreen == 1) {
++        for (i = 0; i < sVisibleStars; i++) {
++            sStarSelectorModels[i] =
++                spawn_object_abs_with_rot(gCurrentObject, 0, selectorModelIDs[i], bhvActSelectorStarType,
++                                        (((75 + sVisibleStars * -75 + i * 152)*4.0f)/3), 248, -300, 0, 0, 0);
++            sStarSelectorModels[i]->oStarSelectorSize = 1.0f;
++        }
++    }
++    else {
++        for (i = 0; i < sVisibleStars; i++) {
++            sStarSelectorModels[i] =
++                spawn_object_abs_with_rot(gCurrentObject, 0, selectorModelIDs[i], bhvActSelectorStarType,
++                                        75 + sVisibleStars * -75 + i * 152, 248, -300, 0, 0, 0);
++            sStarSelectorModels[i]->oStarSelectorSize = 1.0f;
++        }
+     }
+ 
+     render_100_coin_star(stars);
diff --git a/include/config.h b/include/config.h
index 211a086..d1eb721 100644
--- a/include/config.h
+++ b/include/config.h
@@ -30,9 +30,9 @@
 // Border Height Define for NTSC Versions
 #ifdef TARGET_N64
 #ifndef VERSION_EU
-#define BORDER_HEIGHT 8
+#define BORDER_HEIGHT 0
 #else
-#define BORDER_HEIGHT 1
+#define BORDER_HEIGHT 0
 #endif
 #else
 // What's the point of having a border?
diff --git a/include/text_strings.h.in b/include/text_strings.h.in
index 749179b..3b23b41 100644
--- a/include/text_strings.h.in
+++ b/include/text_strings.h.in
@@ -24,6 +24,10 @@
 // Ingame Menu
 #define TEXT_PAUSE _("PAUSE") // Pause text, Castle Courses
 #define TEXT_HUD_CONGRATULATIONS _("CONGRATULATIONS") // Course Complete Text, Bowser Courses
+#define TEXT_HUD_CURRENT_RATIO_43 _("CURRENT ASPECT RATIO: 4:3. PRESS L TO SWITCH TO 16:9")
+#define TEXT_HUD_CURRENT_RATIO_169 _("CURRENT ASPECT RATIO: 16:9. PRESS L TO SWITCH TO 4:3")
+#define TEXT_HUD_WIDE_INFO _("PLEASE CONFIGURE YOUR DISPLAY OR YOUR EMULATOR TO")
+#define TEXT_HUD_WIDE_INFO2 _("STRETCH THE IMAGE TO 16:9")
 
 #if defined(VERSION_JP) || defined(VERSION_SH)
 
diff --git a/levels/castle_grounds/script.c b/levels/castle_grounds/script.c
index 626bece..b8191ea 100644
--- a/levels/castle_grounds/script.c
+++ b/levels/castle_grounds/script.c
@@ -132,6 +132,7 @@ const LevelScript level_castle_grounds_entry[] = {
     FREE_LEVEL_POOL(),
     MARIO_POS(/*area*/ 1, /*yaw*/ 180, /*pos*/ -1328, 260, 4664),
     CALL(/*arg*/ 0, /*func*/ lvl_init_or_update),
+    CALL(0, lvl_set_widescreen),
     CALL_LOOP(/*arg*/ 1, /*func*/ lvl_init_or_update),
     CLEAR_LEVEL(),
     SLEEP_BEFORE_EXIT(/*frames*/ 1),
diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c
index 8190f88..e4d0f32 100644
--- a/src/game/ingame_menu.c
+++ b/src/game/ingame_menu.c
@@ -34,6 +34,11 @@ s16 gDialogY; // D_8032F69C
 s16 gCutsceneMsgXOffset;
 s16 gCutsceneMsgYOffset;
 s8 gRedCoinsCollected;
+u8 textCurrRatio43[] = { TEXT_HUD_CURRENT_RATIO_43 };
+u8 textCurrRatio169[] = { TEXT_HUD_CURRENT_RATIO_169 };
+u8 textWideInfo[] = { TEXT_HUD_WIDE_INFO };
+u8 textWideInfo2[] = { TEXT_HUD_WIDE_INFO2 };
+u8 widescreen = 1;
 
 extern u8 gLastCompletedCourseNum;
 extern u8 gLastCompletedStarNum;
@@ -2266,6 +2271,24 @@ void render_pause_my_score_coins(void) {
         print_generic_string(get_string_width(gTextCourseArr[gInGameLanguage]) + 51, 157, strCourseNum);
 #else
         print_generic_string(CRS_NUM_X1, 157, strCourseNum);
+        if (widescreen == 0) {
+            if (COURSE_IS_MAIN_COURSE(gCurrCourseNum)) {
+                print_generic_string(10, 40, textCurrRatio43);
+            } else {
+                print_generic_string(10, 20, textCurrRatio43);
+            }
+            
+        }
+        else {
+            if (COURSE_IS_MAIN_COURSE(gCurrCourseNum)) {
+                print_generic_string(10, 40, textCurrRatio169);
+            } else {
+                print_generic_string(10, 20, textCurrRatio169);
+            }
+            
+            print_generic_string(10, 200, textWideInfo);
+            print_generic_string(10, 180, textWideInfo2);
+        }
 #endif
 
         actName = segmented_to_virtual(actNameTbl[(gCurrCourseNum - 1) * 6 + gDialogCourseActNum - 1]);
@@ -2557,10 +2580,25 @@ void render_pause_castle_main_strings(s16 x, s16 y) {
             }
         }
     }
+    if (gPlayer1Controller->buttonPressed & L_TRIG){
+        if (widescreen == 0){
+                widescreen = 1;
+            }
+        else{
+                widescreen = 0;
+            }
+    }
 
     gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
     gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
-
+    if (widescreen == 0) {
+        print_generic_string(10, 20, textCurrRatio43);
+    }
+    else {
+        print_generic_string(10, 20, textCurrRatio169);
+        print_generic_string(10, 200, textWideInfo);
+        print_generic_string(10, 180, textWideInfo2);
+    }
     if (gDialogLineNum < COURSE_STAGES_COUNT) {
         courseName = segmented_to_virtual(courseNameTbl[gDialogLineNum]);
         render_pause_castle_course_stars(x, y, gCurrSaveFileNum - 1, gDialogLineNum);
@@ -2626,6 +2664,14 @@ s16 render_pause_courses_and_castle(void) {
             shade_screen();
             render_pause_my_score_coins();
             render_pause_red_coins();
+        if (gPlayer1Controller->buttonPressed & L_TRIG){
+                if (widescreen == 0){
+                    widescreen = 1;
+                }
+                else{
+                    widescreen = 0;
+                }
+            }
 
             if (gMarioStates[0].action & ACT_FLAG_PAUSE_EXIT) {
                 render_pause_course_options(99, 93, &gDialogLineNum, 15);
diff --git a/src/game/level_update.c b/src/game/level_update.c
index 4ecb902..b2d6e53 100644
--- a/src/game/level_update.c
+++ b/src/game/level_update.c
@@ -1247,6 +1247,10 @@ s32 lvl_init_or_update(s16 initOrUpdate, UNUSED s32 unused) {
 
     return result;
 }
+extern u8 widescreen;
+void lvl_set_widescreen(void) {
+    widescreen = 1;
+}
 
 s32 lvl_init_from_save_file(UNUSED s16 arg0, s32 levelNum) {
 #ifdef VERSION_EU
diff --git a/src/game/level_update.h b/src/game/level_update.h
index 521b4ef..58d4e75 100644
--- a/src/game/level_update.h
+++ b/src/game/level_update.h
@@ -128,5 +128,6 @@ s32 lvl_init_from_save_file(UNUSED s16 arg0, s32 levelNum);
 s32 lvl_set_current_level(UNUSED s16 arg0, s32 levelNum);
 s32 lvl_play_the_end_screen_sound(UNUSED s16 arg0, UNUSED s32 arg1);
 void basic_update(UNUSED s16 *arg);
+void lvl_set_widescreen(void);
 
 #endif // LEVEL_UPDATE_H
diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c
index 58238e8..09a6c87 100644
--- a/src/game/rendering_graph_node.c
+++ b/src/game/rendering_graph_node.c
@@ -10,6 +10,7 @@
 #include "rendering_graph_node.h"
 #include "shadow.h"
 #include "sm64.h"
+#define WIDESCREEN
 
 /**
  * This file contains the code that processes the scene graph for rendering.
@@ -39,6 +40,7 @@
 s16 gMatStackIndex;
 Mat4 gMatStack[32];
 Mtx *gMatStackFixed[32];
+f32 aspect;
 
 /**
  * Animation nodes have state in global variables, so this struct captures
@@ -235,6 +237,7 @@ static void geo_process_ortho_projection(struct GraphNodeOrthoProjection *node)
 /**
  * Process a perspective projection node.
  */
+extern u8 widescreen;
 static void geo_process_perspective(struct GraphNodePerspective *node) {
     if (node->fnNode.func != NULL) {
         node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node, gMatStack[gMatStackIndex]);
@@ -246,7 +249,12 @@ static void geo_process_perspective(struct GraphNodePerspective *node) {
 #ifdef VERSION_EU
         f32 aspect = ((f32) gCurGraphNodeRoot->width / (f32) gCurGraphNodeRoot->height) * 1.1f;
 #else
-        f32 aspect = (f32) gCurGraphNodeRoot->width / (f32) gCurGraphNodeRoot->height;
+        if (widescreen == 1){
+            aspect = 1.775f;
+        }
+        else{
+            aspect = 1.33333f;
+        }
 #endif
 
         guPerspective(mtx, &perspNorm, node->fov, aspect, node->near, node->far, 1.0f);
@@ -755,7 +763,7 @@ static s32 obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) {
     // ! @bug The aspect ratio is not accounted for. When the fov value is 45,
     // the horizontal effective fov is actually 60 degrees, so you can see objects
     // visibly pop in or out at the edge of the screen.
-    halfFov = (gCurGraphNodeCamFrustum->fov / 2.0f + 1.0f) * 32768.0f / 180.0f + 0.5f;
+    halfFov = ((gCurGraphNodeCamFrustum->fov*aspect) / 2.0f + 1.0f) * 32768.0f / 180.0f + 0.5f;
 
     hScreenEdge = -matrix[3][2] * sins(halfFov) / coss(halfFov);
     // -matrix[3][2] is the depth, which gets multiplied by tan(halfFov) to get
diff --git a/src/menu/file_select.c b/src/menu/file_select.c
index c894797..94a3566 100644
--- a/src/menu/file_select.c
+++ b/src/menu/file_select.c
@@ -2854,10 +2854,12 @@ Gfx *geo_file_select_strings_and_menu_cursor(s32 callContext, UNUSED struct Grap
  * Relocates cursor position of the last save if the game goes back to the Mario Screen
  * either completing a course choosing "SAVE & QUIT" or having a game over.
  */
+extern u8 widescreen;
 s32 lvl_init_menu_values_and_cursor_pos(UNUSED s32 arg, UNUSED s32 unused) {
 #ifdef VERSION_EU
     s8 fileNum;
 #endif
+    widescreen = 0;
     sSelectedButtonID = MENU_BUTTON_NONE;
     sCurrentMenuLevel = MENU_LAYER_MAIN;
     sTextBaseAlpha = 0;
diff --git a/src/menu/star_select.c b/src/menu/star_select.c
index 025dbf2..4840898 100644
--- a/src/menu/star_select.c
+++ b/src/menu/star_select.c
@@ -52,7 +52,7 @@ static s8 sSelectableStarIndex = 0;
 
 // Act Selector menu timer that keeps counting until you choose an act.
 static s32 sActSelectorMenuTimer = 0;
-
+extern u8 widescreen;
 /**
  * Act Selector Star Type Loop Action
  * Defines a select type for a star in the act selector.
@@ -92,8 +92,15 @@ void bhv_act_selector_star_type_loop(void) {
 void render_100_coin_star(u8 stars) {
     if (stars & (1 << 6)) {
         // If the 100 coin star has been collected, create a new star selector next to the coin score.
-        sStarSelectorModels[6] = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_STAR,
-                                                        bhvActSelectorStarType, 370, 24, -300, 0, 0, 0);
+        if (widescreen == 1){
+            sStarSelectorModels[6] = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_STAR,
+                                                            bhvActSelectorStarType, ((370*4.0f)/3), 24, -300, 0, 0, 0);
+        }
+        else{
+            sStarSelectorModels[6] = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_STAR,
+                                                            bhvActSelectorStarType, 370, 24, -300, 0, 0, 0);
+        }
+
         sStarSelectorModels[6]->oStarSelectorSize = 0.8;
         sStarSelectorModels[6]->oStarSelectorType = STAR_SELECTOR_100_COINS;
     }
@@ -147,11 +154,21 @@ void bhv_act_selector_init(void) {
     }
 
     // Render star selector objects
-    for (i = 0; i < sVisibleStars; i++) {
-        sStarSelectorModels[i] =
-            spawn_object_abs_with_rot(gCurrentObject, 0, selectorModelIDs[i], bhvActSelectorStarType,
-                                      75 + sVisibleStars * -75 + i * 152, 248, -300, 0, 0, 0);
-        sStarSelectorModels[i]->oStarSelectorSize = 1.0f;
+    if (widescreen == 1) {
+        for (i = 0; i < sVisibleStars; i++) {
+            sStarSelectorModels[i] =
+                spawn_object_abs_with_rot(gCurrentObject, 0, selectorModelIDs[i], bhvActSelectorStarType,
+                                        (((75 + sVisibleStars * -75 + i * 152)*4.0f)/3), 248, -300, 0, 0, 0);
+            sStarSelectorModels[i]->oStarSelectorSize = 1.0f;
+        }
+    }
+    else {
+        for (i = 0; i < sVisibleStars; i++) {
+            sStarSelectorModels[i] =
+                spawn_object_abs_with_rot(gCurrentObject, 0, selectorModelIDs[i], bhvActSelectorStarType,
+                                        75 + sVisibleStars * -75 + i * 152, 248, -300, 0, 0, 0);
+            sStarSelectorModels[i]->oStarSelectorSize = 1.0f;
+        }
     }
 
     render_100_coin_star(stars);
