diff --git a/360/main.c b/360/main.c index b7ffdd431b..f28d1c2c26 100644 --- a/360/main.c +++ b/360/main.c @@ -136,6 +136,7 @@ static void set_default_settings (void) g_settings.rewind_enable = false; g_settings.video.vsync = true; g_settings.video.smooth = true; + g_settings.video.aspect_ratio = -1.0f; ssnes_default_keybind_lut[SNES_DEVICE_ID_JOYPAD_B] = ssnes_platform_keybind_lut[XDK360_DEVICE_ID_JOYPAD_A]; ssnes_default_keybind_lut[SNES_DEVICE_ID_JOYPAD_Y] = ssnes_platform_keybind_lut[XDK360_DEVICE_ID_JOYPAD_X]; @@ -168,7 +169,13 @@ static void set_default_settings (void) g_console.mode_switch = MODE_MENU; g_console.screen_orientation = ORIENTATION_NORMAL; g_console.throttle_enable = true; + g_console.aspect_ratio_index = 0; + strlcpy(g_console.aspect_ratio_name, "4:3", sizeof(g_console.aspect_ratio_name)); strlcpy(g_console.default_rom_startup_dir, "game:", sizeof(g_console.default_rom_startup_dir)); + g_console.custom_viewport_width = 0; + g_console.custom_viewport_height = 0; + g_console.custom_viewport_x = 0; + g_console.custom_viewport_y = 0; //g_extern g_extern.state_slot = 0; @@ -311,12 +318,15 @@ static void init_settings (bool load_libsnes_path) CONFIG_GET_BOOL(rewind_enable, "rewind_enable"); CONFIG_GET_BOOL(video.smooth, "video_smooth"); CONFIG_GET_BOOL(video.vsync, "video_vsync"); + CONFIG_GET_FLOAT(video.aspect_ratio, "video_aspect_ratio"); // g_console CONFIG_GET_BOOL_CONSOLE(throttle_enable, "throttle_enable"); CONFIG_GET_BOOL_CONSOLE(gamma_correction_enable, "gamma_correction_enable"); CONFIG_GET_STRING_CONSOLE(default_rom_startup_dir, "default_rom_startup_dir"); + CONFIG_GET_INT_CONSOLE(aspect_ratio_index, "aspect_ratio_index"); CONFIG_GET_INT_CONSOLE(screen_orientation, "screen_orientation"); + CONFIG_GET_STRING_CONSOLE(aspect_ratio_name, "aspect_ratio_name"); // g_extern CONFIG_GET_INT_EXTERN(state_slot, "state_slot"); @@ -347,7 +357,13 @@ static void save_settings (void) config_set_string(conf, "default_rom_startup_dir", g_console.default_rom_startup_dir); config_set_bool(conf, "gamma_correction_enable", g_console.gamma_correction_enable); config_set_bool(conf, "throttle_enable", g_console.throttle_enable); + config_set_int(conf, "aspect_ratio_index", g_console.aspect_ratio_index); + config_set_int(conf, "custom_viewport_width", g_console.custom_viewport_width); + config_set_int(conf, "custom_viewport_height", g_console.custom_viewport_height); + config_set_int(conf, "custom_viewport_x", g_console.custom_viewport_x); + config_set_int(conf, "custom_viewport_y", g_console.custom_viewport_y); config_set_int(conf, "screen_orientation", g_console.screen_orientation); + config_set_string(conf, "aspect_ratio_name", g_console.aspect_ratio_name); // g_extern config_set_int(conf, "state_slot", g_extern.state_slot); diff --git a/360/menu.cpp b/360/menu.cpp index 111712bf09..610140e9ac 100644 --- a/360/menu.cpp +++ b/360/menu.cpp @@ -193,6 +193,17 @@ HRESULT CSSNESQuickMenu::OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled ) m_quickmenulist.SetText(MENU_ITEM_HARDWARE_FILTERING, set_filter_element(g_settings.video.smooth)); break; case MENU_ITEM_KEEP_ASPECT_RATIO: + { + if(g_console.aspect_ratio_index < LAST_ASPECT_RATIO) + g_console.aspect_ratio_index++; + else + g_console.aspect_ratio_index = 0; + + xdk360_set_aspect_ratio(g_console.aspect_ratio_index); + wchar_t aspectstr[512]; + swprintf(aspectstr, L"Aspect Ratio: %s", g_console.aspect_ratio_name); + m_quickmenulist.SetText(MENU_ITEM_KEEP_ASPECT_RATIO, aspectstr); + } break; case MENU_ITEM_OVERSCAN_AMOUNT: break; diff --git a/360/xdk360_video.cpp b/360/xdk360_video.cpp index 7ff51bfbd9..6b909d3cfe 100644 --- a/360/xdk360_video.cpp +++ b/360/xdk360_video.cpp @@ -89,6 +89,126 @@ static void xdk360_gfx_free(void * data) free(vid); } +static void set_viewport(bool force_full) +{ + xdk360_video_t *vid = (xdk360_video_t*)g_d3d; + + DWORD width = vid->video_mode.fIsHiDef ? 1280 : 640; + DWORD height = vid->video_mode.fIsHiDef ? 1280 : 640; + DWORD m_viewport_x_temp, m_viewport_y_temp, m_viewport_width_temp, m_viewport_height_temp; + float m_zNear, m_zFar; + + m_viewport_x_temp = 0; + m_viewport_y_temp = 0; + m_viewport_width_temp = width; + m_viewport_height_temp = height; + + m_zNear = -1.0f; + m_zFar = 1.0f; + + if (!force_full) + { + float desired_aspect = g_settings.video.aspect_ratio; + float device_aspect = (float)width / height; + float delta = (desired_aspect / device_aspect - 1.0) / 2.0 + 0.5; + + // If the aspect ratios of screen and desired aspect ratio are sufficiently equal (floating point stuff), + //if(g_console.aspect_ratio_index == ASPECT_RATIO_CUSTOM) + //{ + // m_viewport_x_temp = g_console.custom_viewport_x; + // m_viewport_y_temp = g_console.custom_viewport_y; + // m_viewport_width_temp = g_console.custom_viewport_width; + // m_viewport_height_temp = g_console.custom_viewport_height; + //} + if (device_aspect > desired_aspect) + { + m_viewport_x_temp = (int)(width * (0.5 - delta)); + m_viewport_width_temp = (int)(2.0 * width * delta); + width = (unsigned)(2.0 * width * delta); + } + else + { + m_viewport_y_temp = (int)(height * (0.5 - delta)); + m_viewport_height_temp = (int)(2.0 * height * delta); + height = (unsigned)(2.0 * height * delta); + } + } + + D3DVIEWPORT9 vp = {0}; + vp.Width = m_viewport_x_temp; + vp.Height = m_viewport_y_temp; + vp.MinZ = m_zNear; + vp.MaxZ = m_zFar; + D3DDevice_SetViewport(vid->xdk360_render_device, &vp); + + //if(gl->overscan_enable && !force_full) + //{ + // m_left = -gl->overscan_amount/2; + // m_right = 1 + gl->overscan_amount/2; + // m_bottom = -gl->overscan_amount/2; + //} +} + +void xdk360_set_aspect_ratio(uint32_t aspectratio_index) +{ + switch(aspectratio_index) + { + case ASPECT_RATIO_4_3: + g_settings.video.aspect_ratio = 1.33333333333; + strlcpy(g_console.aspect_ratio_name, "4:3", sizeof(g_console.aspect_ratio_name)); + break; + case ASPECT_RATIO_5_4: + g_settings.video.aspect_ratio = 1.25; + strlcpy(g_console.aspect_ratio_name, "5:4", sizeof(g_console.aspect_ratio_name)); + break; + case ASPECT_RATIO_8_7: + g_settings.video.aspect_ratio = 1.14287142857; + strlcpy(g_console.aspect_ratio_name, "8:7", sizeof(g_console.aspect_ratio_name)); + break; + case ASPECT_RATIO_16_9: + g_settings.video.aspect_ratio = 1.777778; + strlcpy(g_console.aspect_ratio_name, "16:9", sizeof(g_console.aspect_ratio_name)); + break; + case ASPECT_RATIO_16_10: + g_settings.video.aspect_ratio = 1.6; + strlcpy(g_console.aspect_ratio_name, "16:10", sizeof(g_console.aspect_ratio_name)); + break; + case ASPECT_RATIO_16_15: + g_settings.video.aspect_ratio = 3.2; + strlcpy(g_console.aspect_ratio_name, "16:15", sizeof(g_console.aspect_ratio_name)); + break; + case ASPECT_RATIO_19_14: + g_settings.video.aspect_ratio = 1.35714285714; + strlcpy(g_console.aspect_ratio_name, "19:14", sizeof(g_console.aspect_ratio_name)); + break; + case ASPECT_RATIO_2_1: + g_settings.video.aspect_ratio = 2.0; + strlcpy(g_console.aspect_ratio_name, "2:1", sizeof(g_console.aspect_ratio_name)); + break; + case ASPECT_RATIO_3_2: + g_settings.video.aspect_ratio = 1.5; + strlcpy(g_console.aspect_ratio_name, "3:2", sizeof(g_console.aspect_ratio_name)); + break; + case ASPECT_RATIO_3_4: + g_settings.video.aspect_ratio = 1.5; + strlcpy(g_console.aspect_ratio_name, "3:4", sizeof(g_console.aspect_ratio_name)); + break; + case ASPECT_RATIO_1_1: + g_settings.video.aspect_ratio = 1.0; + strlcpy(g_console.aspect_ratio_name, "1:1", sizeof(g_console.aspect_ratio_name)); + break; + case ASPECT_RATIO_AUTO: + strlcpy(g_console.aspect_ratio_name, "(Auto)", sizeof(g_console.aspect_ratio_name)); + break; + case ASPECT_RATIO_CUSTOM: + strlcpy(g_console.aspect_ratio_name, "(Custom)", sizeof(g_console.aspect_ratio_name)); + break; + } + g_settings.video.force_aspect = false; + set_viewport(false); +} + + static void *xdk360_gfx_init(const video_info_t *video, const input_driver_t **input, void **input_data) { HRESULT ret; diff --git a/360/xdk360_video.h b/360/xdk360_video.h index b73f02ece6..b4c5871e61 100644 --- a/360/xdk360_video.h +++ b/360/xdk360_video.h @@ -19,6 +19,7 @@ #ifndef _XDK360_VIDEO_H #define _XDK360_VIDEO_H +#include #include "fonts.h" typedef struct { @@ -56,6 +57,25 @@ typedef struct xdk360_video XVIDEO_MODE video_mode; } xdk360_video_t; +enum +{ + ASPECT_RATIO_4_3, + ASPECT_RATIO_5_4, + ASPECT_RATIO_8_7, + ASPECT_RATIO_16_9, + ASPECT_RATIO_16_10, + ASPECT_RATIO_16_15, + ASPECT_RATIO_19_14, + ASPECT_RATIO_2_1, + ASPECT_RATIO_3_2, + ASPECT_RATIO_3_4, + ASPECT_RATIO_1_1, + ASPECT_RATIO_AUTO, + ASPECT_RATIO_CUSTOM +}; + +#define LAST_ASPECT_RATIO ASPECT_RATIO_CUSTOM + #define IS_TIMER_NOT_EXPIRED() (g_frame_count < g_console.timer_expiration_frame_count) #define IS_TIMER_EXPIRED() (!(IS_TIMER_NOT_EXPIRED())) #define SET_TIMER_EXPIRATION(value) g_console.timer_expiration_frame_count = g_frame_count + value; @@ -63,6 +83,7 @@ typedef struct xdk360_video void xdk360_video_init(void); void xdk360_video_deinit(void); void xdk360_video_set_vsync(bool vsync); +void xdk360_set_aspect_ratio(uint32_t aspectratio_index); extern unsigned g_frame_count; extern void *g_d3d;