From 670da875e7556b3e15eeb80475c022d81ef5847d Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 3 Aug 2012 03:24:36 +0200 Subject: [PATCH 001/492] (Xbox 1) Bring Xbox 1 menu code more inline with that of PS3 --- console/rarch_console.h | 2 +- gfx/fonts/xdk1_xfonts.c | 4 + ps3/frontend/menu-entries.h | 2 + ps3/frontend/menu.c | 17 +++- xbox1/frontend/menu.cpp | 173 ++++++++++++++++++++++++++++++------ 5 files changed, 171 insertions(+), 27 deletions(-) diff --git a/console/rarch_console.h b/console/rarch_console.h index d5072bf15c..8db82600b1 100644 --- a/console/rarch_console.h +++ b/console/rarch_console.h @@ -46,9 +46,9 @@ enum { MENU_ITEM_SCREENSHOT_MODE, MENU_ITEM_RESET, MENU_ITEM_RETURN_TO_GAME, -#ifdef __CELLOS_LV2__ MENU_ITEM_RETURN_TO_MENU, MENU_ITEM_CHANGE_LIBRETRO, +#ifdef HAVE_MULTIMAN MENU_ITEM_RETURN_TO_MULTIMAN, #endif MENU_ITEM_RETURN_TO_DASHBOARD diff --git a/gfx/fonts/xdk1_xfonts.c b/gfx/fonts/xdk1_xfonts.c index e3e6836951..264eb63961 100644 --- a/gfx/fonts/xdk1_xfonts.c +++ b/gfx/fonts/xdk1_xfonts.c @@ -30,10 +30,14 @@ void xfonts_render_msg_pre(xdk_d3d_video_t *d3d) void xfonts_render_msg_place(xdk_d3d_video_t *d3d, float x, float y, float scale, const char *msg) { + xfonts_render_msg_pre(d3d); + wchar_t str[256]; convert_char_to_wchar(str, msg, sizeof(str)); d3d->debug_font->TextOut(d3d->pFrontBuffer, str, (unsigned)-1, x, y); d3d->debug_font->TextOut(d3d->pBackBuffer, str, (unsigned)-1, x, y); + + xfonts_render_msg_post(d3d); } void xfonts_render_msg_post(xdk_d3d_video_t *d3d) diff --git a/ps3/frontend/menu-entries.h b/ps3/frontend/menu-entries.h index be0e9a3b7c..728d5e42be 100644 --- a/ps3/frontend/menu-entries.h +++ b/ps3/frontend/menu-entries.h @@ -651,6 +651,7 @@ item ingame_menu_settings[MENU_ITEM_LAST] = "INFO - Press LEFT or RIGHT to change the [Rotation] settings.\nPress START to reset back to default values.", WHITE, }, +#ifdef __CELLOS_LV2__ { MENU_ITEM_SCALE_FACTOR, "Scale Factor", @@ -661,6 +662,7 @@ item ingame_menu_settings[MENU_ITEM_LAST] = "INFO - Press LEFT or RIGHT to change the [Scaling] settings.\nPress START to reset back to default values.", WHITE, }, +#endif { MENU_ITEM_RESIZE_MODE, "Resize Mode", diff --git a/ps3/frontend/menu.c b/ps3/frontend/menu.c index 1d5eb5d510..7f68aceed7 100644 --- a/ps3/frontend/menu.c +++ b/ps3/frontend/menu.c @@ -110,6 +110,7 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), ps3_get_resolution_label(g_console.supported_resolutions[g_console.current_resolution_index])); break; #endif +#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) case SETTING_SHADER_PRESETS: set_setting_label_color(items,true, currentsetting); fill_pathname_base(fname, g_console.cgp_path, sizeof(fname)); @@ -126,6 +127,7 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current set_setting_label_color(items,strcmp(g_settings.video.second_pass_shader, default_paths.shader_file) == 0, currentsetting); break; +#endif case SETTING_FONT_SIZE: set_setting_label_color(items,g_console.menu_font_size == 1.0f, currentsetting); snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "%f", g_console.menu_font_size); @@ -185,18 +187,22 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Normal"); items[currentsetting].text_color = GREEN; break; +#ifdef HAVE_RSOUND case SOUND_MODE_RSOUND: snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - [Sound Output] is set to 'RSound' - the sound will be streamed over the\n network to the RSound audio server." ); snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "RSound"); items[currentsetting].text_color = ORANGE; break; +#endif +#ifdef HAVE_HEADSET case SOUND_MODE_HEADSET: snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - [Sound Output] is set to 'USB/Bluetooth Headset' - sound will\n be output through the headset"); snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "USB/Bluetooth Headset"); items[currentsetting].text_color = ORANGE; break; +#endif default: break; } @@ -898,6 +904,7 @@ static void set_keybind_digital(uint64_t default_retro_joypad_id, uint64_t input rarch_input_set_keybind(currently_selected_controller_menu, keybind_action, default_retro_joypad_id); } +#ifdef __CELLOS_LV2__ static void rarch_filename_input_and_save (unsigned filename_type) { bool filename_entered = false; @@ -979,12 +986,13 @@ static void rarch_filename_input_and_save (unsigned filename_type) } } } - +#endif static void producesettingentry(menu *current_menu, item *items, unsigned switchvalue, uint64_t input) { switch(switchvalue) { +#ifdef __CELLOS_LV2__ case SETTING_CHANGE_RESOLUTION: if(input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) rarch_settings_change(S_RESOLUTION_NEXT); @@ -1024,6 +1032,8 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch } break; */ +#endif +#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) case SETTING_SHADER_PRESETS: if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { @@ -1064,6 +1074,7 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch menu_stack_refresh(items, current_menu); } break; +#endif case SETTING_FONT_SIZE: if(input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) { @@ -1238,12 +1249,14 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch #endif } break; +#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) case SETTING_SAVE_SHADER_PRESET: if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) rarch_filename_input_and_save(SHADER_PRESET_FILE); break; case SETTING_APPLY_SHADER_PRESET_ON_STARTUP: break; +#endif case SETTING_DEFAULT_VIDEO_ALL: break; case SETTING_SOUND_MODE: @@ -1270,6 +1283,7 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch rarch_console_rsound_stop(); } break; +#ifdef HAVE_RSOUND case SETTING_RSOUND_SERVER_IP_ADDRESS: if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { @@ -1291,6 +1305,7 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) strlcpy(g_settings.audio.device, "0.0.0.0", sizeof(g_settings.audio.device)); break; +#endif case SETTING_DEFAULT_AUDIO_ALL: break; case SETTING_EMU_CURRENT_SAVE_STATE_SLOT: diff --git a/xbox1/frontend/menu.cpp b/xbox1/frontend/menu.cpp index 083f98a3d1..26cb6867da 100644 --- a/xbox1/frontend/menu.cpp +++ b/xbox1/frontend/menu.cpp @@ -18,7 +18,11 @@ #include "RetroLaunch/Surface.h" #include "../../ps3/frontend/menu.h" +#include "../../ps3/frontend/menu-entries.h" #include "../../console/fileio/file_browser.h" + +#include "../../console/rarch_console.h" + #include "../../gfx/fonts/xdk1_xfonts.h" #define NUM_ENTRY_PER_PAGE 17 @@ -36,8 +40,8 @@ menu menuStack[10]; int menuStackindex = 0; -filebrowser_t *browser; -filebrowser_t *tmpBrowser; +filebrowser_t browser; +filebrowser_t tmpBrowser; static unsigned currently_selected_controller_menu = 0; // Rom selector panel with coords @@ -529,8 +533,67 @@ static void menu_stack_push(item *items, unsigned menu_id) menu_stack_refresh(items, current_menu); } -static void display_menubar(void) +static void display_menubar(menu *current_menu) { + DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; + filebrowser_t *fb = &browser; + char current_path[256], rarch_version[128]; + + float x_position = m_menuMainRomListPos_x; + float current_y_position = m_menuMainRomListPos_y; + float font_size = m_menuMainRomListPos_y; + + snprintf(rarch_version, sizeof(rarch_version), "v%s", PACKAGE_VERSION); + + switch(current_menu->enum_id) + { + case GENERAL_VIDEO_MENU: + render_msg_place_func(x_position, 0.03f, font_size, WHITE, "NEXT ->"); + break; + case GENERAL_AUDIO_MENU: + case EMU_GENERAL_MENU: + case EMU_VIDEO_MENU: + case EMU_AUDIO_MENU: + case PATH_MENU: + render_msg_place_func(x_position, 0.03f, font_size, WHITE, "<- PREV | NEXT ->"); + break; + case CONTROLS_MENU: + case INGAME_MENU_RESIZE: + case SHADER_CHOICE: + case PRESET_CHOICE: + case BORDER_CHOICE: + case LIBRETRO_CHOICE: + case INPUT_PRESET_CHOICE: + case PATH_SAVESTATES_DIR_CHOICE: + case PATH_DEFAULT_ROM_DIR_CHOICE: + case PATH_CHEATS_DIR_CHOICE: + case PATH_SRAM_DIR_CHOICE: + render_msg_place_func(x_position, 0.03f, font_size, WHITE, "<- PREV"); + break; + default: + break; + } + + switch(current_menu->enum_id) + { + case SHADER_CHOICE: + case PRESET_CHOICE: + case BORDER_CHOICE: + case LIBRETRO_CHOICE: + case INPUT_PRESET_CHOICE: + case PATH_SAVESTATES_DIR_CHOICE: + case PATH_DEFAULT_ROM_DIR_CHOICE: + case PATH_CHEATS_DIR_CHOICE: + case PATH_SRAM_DIR_CHOICE: + fb = &tmpBrowser; + case FILE_BROWSER_MENU: + snprintf(current_path, sizeof(current_path), "PATH: %s", filebrowser_get_current_dir(fb)); + render_msg_place_func(x_position, current_y_position, /* size */0, /* color */0, current_path); + break; + default: + break; + } + //Render background image d3d_surface_render(&m_menuMainBG, MENU_MAIN_BG_X, MENU_MAIN_BG_Y, m_menuMainBG.m_imageInfo.Width, m_menuMainBG.m_imageInfo.Height); @@ -567,7 +630,8 @@ static void browser_update(filebrowser_t * b, uint16_t input, const char *extens static void browser_render(filebrowser_t *b, float current_x, float current_y, float y_spacing) { - xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; + DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; + unsigned file_count = b->current_dir.list->size; unsigned current_index, page_number, page_base, i; float currentX, currentY, ySpacing; @@ -593,9 +657,7 @@ static void browser_render(filebrowser_t *b, float current_x, float current_y, f if(strcmp(current_pathname, b->current_dir.list->elems[i].data) == 0) d3d_surface_render(&m_menuMainRomSelectPanel, currentX, currentY, ROM_PANEL_WIDTH, ROM_PANEL_HEIGHT); - xfonts_render_msg_pre(d3d); - xfonts_render_msg_place(d3d, currentX, currentY, 0 /* scale */, rom_basename); - xfonts_render_msg_post(d3d); + xfonts_render_msg_place(device_ptr, currentX, currentY, 0 /* scale */, rom_basename); } } @@ -616,11 +678,11 @@ static void menu_romselect_iterate(filebrowser_t *filebrowser, menu_romselect_ac } } -static void select_rom(uint16_t input) +static void select_rom(item *items, menu *current_menu, uint64_t input) { xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; - browser_update(browser, input, rarch_console_get_rom_ext()); + browser_update(&browser, input, rarch_console_get_rom_ext()); menu_romselect_action_t action = MENU_ROMSELECT_ACTION_NOOP; @@ -633,33 +695,29 @@ static void select_rom(uint16_t input) } if (action != MENU_ROMSELECT_ACTION_NOOP) - menu_romselect_iterate(browser, action); + menu_romselect_iterate(&browser, action); - display_menubar(); + display_menubar(current_menu); //Display some text //Center the text (hardcoded) int xpos = width == 640 ? 65 : 400; int ypos = width == 640 ? 430 : 670; - xfonts_render_msg_pre(d3d); xfonts_render_msg_place(d3d, xpos, ypos, 0 /* scale */, m_title); - xfonts_render_msg_post(d3d); } int menu_init(void) { xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; - browser = (filebrowser_t*)malloc(sizeof(filebrowser_t)); - tmpBrowser = (filebrowser_t*)malloc(sizeof(filebrowser_t)); - // Set libretro filename and version to variable struct retro_system_info info; retro_get_system_info(&info); const char *id = info.library_name ? info.library_name : "Unknown"; snprintf(m_title, sizeof(m_title), "Libretro core: %s %s", id, info.library_version); + // Set file cache size XSetFileCacheSize(8 * 1024 * 1024); @@ -670,9 +728,10 @@ int menu_init(void) xbox_io_mount("F:", "Harddisk0\\Partition6"); xbox_io_mount("G:", "Harddisk0\\Partition7"); - strlcpy(browser->extensions, rarch_console_get_rom_ext(), sizeof(browser->extensions)); - filebrowser_set_root(browser, g_console.default_rom_startup_dir); - filebrowser_iterate(browser, FILEBROWSER_ACTION_RESET); + strlcpy(browser.extensions, rarch_console_get_rom_ext(), sizeof(browser.extensions)); + menu_stack_push(menu_items, FILE_BROWSER_MENU); + filebrowser_set_root_and_ext(&browser, rarch_console_get_rom_ext(), g_console.default_rom_startup_dir); + filebrowser_set_root(&tmpBrowser, "/"); width = d3d->d3dpp.BackBufferWidth; @@ -703,11 +762,9 @@ int menu_init(void) void menu_free(void) { - filebrowser_free(browser); - filebrowser_free(tmpBrowser); + filebrowser_free(&browser); + filebrowser_free(&tmpBrowser); - free(browser); - free(tmpBrowser); d3d_surface_free(&m_menuMainBG); d3d_surface_free(&m_menuMainRomSelectPanel); } @@ -717,6 +774,10 @@ void menu_loop(void) DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; g_console.menu_enable = true; + device_ptr->block_swap = true; + + if(g_console.ingame_menu_enable) + menu_stack_push(ingame_menu_settings, INGAME_MENU); do { @@ -724,6 +785,7 @@ void menu_loop(void) uint64_t input_state_first_frame = 0; uint64_t input_state = 0; static bool first_held = false; + menu *current_menu = menu_stack_get_current_ptr(); input_ptr.poll(NULL); @@ -836,8 +898,64 @@ void menu_loop(void) device_ptr->d3d_render_device->SetFlickerFilter(1); device_ptr->d3d_render_device->SetSoftDisplayFilter(1); - select_rom(trig_state); - browser_render(browser, m_menuMainRomListPos_x, m_menuMainRomListPos_y, 20); + filebrowser_t * fb = &browser; + + switch(current_menu->enum_id) + { + case FILE_BROWSER_MENU: + select_rom(menu_items, current_menu, trig_state); + fb = &browser; + break; + case GENERAL_VIDEO_MENU: + case GENERAL_AUDIO_MENU: + case EMU_GENERAL_MENU: + case EMU_VIDEO_MENU: + case EMU_AUDIO_MENU: + case PATH_MENU: + case CONTROLS_MENU: + //select_setting(menu_items, current_menu, trig_state); + break; + case SHADER_CHOICE: + case PRESET_CHOICE: + case BORDER_CHOICE: + case LIBRETRO_CHOICE: + case INPUT_PRESET_CHOICE: + //select_file(menu_items, current_menu, trig_state); + fb = &tmpBrowser; + break; + case PATH_SAVESTATES_DIR_CHOICE: + case PATH_DEFAULT_ROM_DIR_CHOICE: + case PATH_CHEATS_DIR_CHOICE: + case PATH_SRAM_DIR_CHOICE: + //select_directory(menu_items, current_menu, trig_state); + fb = &tmpBrowser; + break; + case INGAME_MENU: + //if(g_console.ingame_menu_enable) + //ingame_menu(menu_items, current_menu, trig_state); + break; + case INGAME_MENU_RESIZE: + //ingame_menu_resize(menu_items, current_menu, trig_state); + break; + case INGAME_MENU_SCREENSHOT: + //ingame_menu_screenshot(menu_items, current_menu, trig_state); + break; + } + + float x_position = m_menuMainRomListPos_x; + float starting_y_position = m_menuMainRomListPos_y; + float y_position_increment = 20; + + switch(current_menu->category_id) + { + case CATEGORY_FILEBROWSER: + browser_render(fb, x_position, starting_y_position, y_position_increment); + break; + case CATEGORY_SETTINGS: + case CATEGORY_INGAME_MENU: + default: + break; + } old_state = input_state_first_frame; @@ -873,5 +991,10 @@ void menu_loop(void) device_ptr->d3d_render_device->Present(NULL, NULL, NULL, NULL); }while(g_console.menu_enable); + if(g_console.ingame_menu_enable) + menu_stack_decrement(); + + device_ptr->block_swap = false; + g_console.ingame_menu_enable = false; } From c96608eadc038f1b99f1ebab94bd2a1f1afd71c4 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 3 Aug 2012 03:46:01 +0200 Subject: [PATCH 002/492] (PS3) Make position values interchangeable between platform ports --- ps3/frontend/menu.c | 22 +++++++++++----------- ps3/frontend/menu.h | 6 ++++++ xbox1/frontend/menu.cpp | 10 +++++----- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/ps3/frontend/menu.c b/ps3/frontend/menu.c index 7f68aceed7..5bce4f2865 100644 --- a/ps3/frontend/menu.c +++ b/ps3/frontend/menu.c @@ -364,7 +364,7 @@ static void menu_stack_refresh (item *items, menu *current_menu) int page, i, j; float increment; float increment_step = 0.03f; - float x_position = 0.09f; + float x_position = POSITION_X; page = 0; j = 0; @@ -557,7 +557,7 @@ static void display_menubar(menu *current_menu) filebrowser_t *fb = &browser; char current_path[256], rarch_version[128]; - float x_position = 0.09f; + float x_position = POSITION_X; float font_size = 0.91f; snprintf(rarch_version, sizeof(rarch_version), "v%s", PACKAGE_VERSION); @@ -705,7 +705,7 @@ static void select_file(item *items, menu *current_menu, uint64_t input) bool ret = true; - float x_position = 0.09f; + float x_position = POSITION_X; float comment_y_position = 0.83f; float comment_two_y_position = 0.91f; float font_size = 0.91f; @@ -813,7 +813,7 @@ static void select_directory(item *items, menu *current_menu, uint64_t input) bool ret = true; DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; - float x_position = 0.09f; + float x_position = POSITION_X; float comment_y_position = 0.83f; float comment_two_y_position = 0.91f; float font_size = 0.91f; @@ -1619,7 +1619,7 @@ static void select_setting(item *items, menu *current_menu, uint64_t input) char msg[256]; DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; - float x_position = 0.09f; + float x_position = POSITION_X; float x_position_center = 0.5f; float comment_y_position = 0.83f; float comment_two_y_position = 0.91f; @@ -1638,7 +1638,7 @@ static void select_setting(item *items, menu *current_menu, uint64_t input) action = SETTINGS_ACTION_UP; if(action != SETTINGS_ACTION_NOOP) - settings_iterate(current_menu, items, action); + settings_iterate(current_menu, items, action); producesettingentry(current_menu, items, current_menu->selected, input); @@ -1693,7 +1693,7 @@ static void select_rom(item *items, menu *current_menu, uint64_t input) { DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; - float x_position = 0.09f; + float x_position = POSITION_X; float comment_y_position = 0.83f; float font_size = 0.91f; float comment_two_y_position = 0.91f; @@ -1741,7 +1741,7 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; - float x_position = 0.09f; + float x_position = POSITION_X; float x_position_center = 0.5f; float font_size = 0.91f; @@ -1905,7 +1905,7 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) static unsigned menuitem_colors[MENU_ITEM_LAST]; DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; - float x_position = 0.09f; + float x_position = POSITION_X; float y_position = 0.16f; float comment_y_position = 0.83f; float font_size = 0.91f; @@ -2316,8 +2316,8 @@ void menu_loop(void) break; } - float x_position = 0.09f; - float starting_y_position = 0.10f; + float x_position = POSITION_X; + float starting_y_position = POSITION_Y_START; float y_position_increment = 0.035f; switch(current_menu->category_id) diff --git a/ps3/frontend/menu.h b/ps3/frontend/menu.h index 0e143af36b..7bade689f4 100644 --- a/ps3/frontend/menu.h +++ b/ps3/frontend/menu.h @@ -25,6 +25,9 @@ #define render_msg_pre_func() gl_render_msg_pre(DEVICE_PTR) #define render_msg_place_func(xpos, ypos, scale, color, msg) gl_render_msg_place(xpos, ypos, scale, color, msg) #define render_msg_post_func() gl_render_msg_post(DEVICE_PTR) + +#define POSITION_X 0.09f +#define POSITION_Y_START 0.10f #elif defined(_XBOX1) #define DEVICE_CAST xdk_d3d_video_t* #define input_ptr input_xinput @@ -33,6 +36,9 @@ #define render_msg_pre_func() xfonts_render_msg_pre(DEVICE_PTR) #define render_msg_place_func(xpos, ypos, scale, color, msg) xfonts_render_msg_place(DEVICE_PTR, xpos, ypos, scale, msg) #define render_msg_post_func() xfonts_render_msg_post(DEVICE_PTR) + +#define POSITION_X m_menuMainRomListPos_x +#define POSITION_Y_START m_menuMainRomListPos_y #endif typedef struct diff --git a/xbox1/frontend/menu.cpp b/xbox1/frontend/menu.cpp index 26cb6867da..b2fefb41f4 100644 --- a/xbox1/frontend/menu.cpp +++ b/xbox1/frontend/menu.cpp @@ -349,7 +349,7 @@ static void menu_stack_refresh (item *items, menu *current_menu) int page, i, j; float increment; float increment_step = 0.03f; - float x_position = 0.09f; + float x_position = POSITION_X; page = 0; j = 0; @@ -539,8 +539,8 @@ static void display_menubar(menu *current_menu) filebrowser_t *fb = &browser; char current_path[256], rarch_version[128]; - float x_position = m_menuMainRomListPos_x; - float current_y_position = m_menuMainRomListPos_y; + float x_position = POSITION_X; + float current_y_position = POSITION_Y_START; float font_size = m_menuMainRomListPos_y; snprintf(rarch_version, sizeof(rarch_version), "v%s", PACKAGE_VERSION); @@ -942,8 +942,8 @@ void menu_loop(void) break; } - float x_position = m_menuMainRomListPos_x; - float starting_y_position = m_menuMainRomListPos_y; + float x_position = POSITION_X; + float starting_y_position = POSITION_Y_START; float y_position_increment = 20; switch(current_menu->category_id) From 7cc14a6c4da22ac8a0cbd79ebd29b00737bdb463 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 3 Aug 2012 04:09:38 +0200 Subject: [PATCH 003/492] (Xbox 1) Menu tweaks --- console/griffin/griffin.c | 2 +- xbox1/frontend/{menu.cpp => menu.c} | 36 ++++++++++++++++------------- 2 files changed, 21 insertions(+), 17 deletions(-) rename xbox1/frontend/{menu.cpp => menu.c} (99%) diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index 4bbed782be..fa061d613c 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -284,7 +284,7 @@ MENU #if defined(_XBOX360) #include "../../360/frontend-xdk/menu.cpp" #elif defined(_XBOX1) -#include "../../xbox1/frontend/menu.cpp" +#include "../../xbox1/frontend/menu.c" #include "../../xbox1/frontend/RetroLaunch/IoSupport.cpp" #include "../../xbox1/frontend/RetroLaunch/Surface.cpp" #elif defined(GEKKO) diff --git a/xbox1/frontend/menu.cpp b/xbox1/frontend/menu.c similarity index 99% rename from xbox1/frontend/menu.cpp rename to xbox1/frontend/menu.c index b2fefb41f4..6861bc11f0 100644 --- a/xbox1/frontend/menu.cpp +++ b/xbox1/frontend/menu.c @@ -23,6 +23,7 @@ #include "../../console/rarch_console.h" +#ifdef _XBOX1 #include "../../gfx/fonts/xdk1_xfonts.h" #define NUM_ENTRY_PER_PAGE 17 @@ -37,13 +38,7 @@ #define MENU_MAIN_BG_X 0 #define MENU_MAIN_BG_Y 0 -menu menuStack[10]; -int menuStackindex = 0; - -filebrowser_t browser; -filebrowser_t tmpBrowser; -static unsigned currently_selected_controller_menu = 0; - +int xpos, ypos; // Rom selector panel with coords d3d_surface_t m_menuMainRomSelectPanel; // Background image with coords @@ -56,6 +51,15 @@ int m_menuMainRomListPos_y; // Backbuffer width, height int width; int height; +#endif + +menu menuStack[10]; +int menuStackindex = 0; + +filebrowser_t browser; +filebrowser_t tmpBrowser; +static unsigned currently_selected_controller_menu = 0; + char m_title[128]; static uint64_t old_state = 0; @@ -588,7 +592,7 @@ static void display_menubar(menu *current_menu) fb = &tmpBrowser; case FILE_BROWSER_MENU: snprintf(current_path, sizeof(current_path), "PATH: %s", filebrowser_get_current_dir(fb)); - render_msg_place_func(x_position, current_y_position, /* size */0, /* color */0, current_path); + render_msg_place_func(x_position, current_y_position, 0, 0, current_path); break; default: break; @@ -657,7 +661,7 @@ static void browser_render(filebrowser_t *b, float current_x, float current_y, f if(strcmp(current_pathname, b->current_dir.list->elems[i].data) == 0) d3d_surface_render(&m_menuMainRomSelectPanel, currentX, currentY, ROM_PANEL_WIDTH, ROM_PANEL_HEIGHT); - xfonts_render_msg_place(device_ptr, currentX, currentY, 0 /* scale */, rom_basename); + render_msg_place_func(currentX, currentY, 0, 0, rom_basename); } } @@ -680,7 +684,7 @@ static void menu_romselect_iterate(filebrowser_t *filebrowser, menu_romselect_ac static void select_rom(item *items, menu *current_menu, uint64_t input) { - xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; + DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; browser_update(&browser, input, rarch_console_get_rom_ext()); @@ -698,13 +702,8 @@ static void select_rom(item *items, menu *current_menu, uint64_t input) menu_romselect_iterate(&browser, action); display_menubar(current_menu); - - //Display some text - //Center the text (hardcoded) - int xpos = width == 640 ? 65 : 400; - int ypos = width == 640 ? 430 : 670; - xfonts_render_msg_place(d3d, xpos, ypos, 0 /* scale */, m_title); + render_msg_place_func(xpos, ypos, 0, 0, m_title); } int menu_init(void) @@ -754,6 +753,11 @@ int menu_init(void) // Load rom selector panel d3d_surface_new(&m_menuMainRomSelectPanel, "D:\\Media\\menuMainRomSelectPanel.png"); + + //Display some text + //Center the text (hardcoded) + xpos = width == 640 ? 65 : 400; + ypos = width == 640 ? 430 : 670; g_console.mode_switch = MODE_MENU; From dc21864405b4c83fadbcaa90ff16eff7db18f6c0 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 3 Aug 2012 04:39:37 +0200 Subject: [PATCH 004/492] (Xbox 1) Create more context functions for XDK --- console/griffin/hook.h | 2 -- gfx/context/ps3_ctx.c | 2 +- gfx/context/xdk_ctx.c | 12 +++++++++++- xbox1/frontend/menu.c | 5 ++--- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/console/griffin/hook.h b/console/griffin/hook.h index d8aa70bb29..045dff26e0 100644 --- a/console/griffin/hook.h +++ b/console/griffin/hook.h @@ -41,7 +41,6 @@ #define video_set_aspect_ratio_func(aspectratio_idx) gfx_ctx_set_aspect_ratio(driver.video_data, aspectratio_idx) #define gfx_ctx_window_has_focus() (true) -#define gfx_ctx_swap_buffers() (psglSwap()) #define input_init_func() ps3_input_initialize() #define input_poll_func() ps3_input_poll(driver.input_data) @@ -69,7 +68,6 @@ #define video_set_aspect_ratio_func(aspectratio_idx) gfx_ctx_set_aspect_ratio(driver.video_data, aspectratio_idx) #define gfx_ctx_window_has_focus() (true) -#define gfx_ctx_swap_buffers() (d3d->d3d_render_device->Present(NULL, NULL, NULL, NULL)) #define input_init_func() xinput_input_init() #define input_poll_func() xinput_input_poll(driver.input_data) diff --git a/gfx/context/ps3_ctx.c b/gfx/context/ps3_ctx.c index 3d4b307cc2..2c187b849d 100644 --- a/gfx/context/ps3_ctx.c +++ b/gfx/context/ps3_ctx.c @@ -99,12 +99,12 @@ bool gfx_ctx_window_has_focus(void) { return true; } +#endif void gfx_ctx_swap_buffers(void) { psglSwap(); } -#endif void gfx_ctx_clear(void) { diff --git a/gfx/context/xdk_ctx.c b/gfx/context/xdk_ctx.c index c57567133d..c1728bc679 100644 --- a/gfx/context/xdk_ctx.c +++ b/gfx/context/xdk_ctx.c @@ -59,13 +59,23 @@ void gfx_ctx_check_window(bool *quit, void gfx_ctx_set_resize(unsigned width, unsigned height) { } -#ifndef HAVE_GRIFFIN void gfx_ctx_swap_buffers(void) { xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; +#ifdef _XBOX1 + d3d->d3d_render_device->EndScene(); +#endif d3d->d3d_render_device->Present(NULL, NULL, NULL, NULL); } +void gfx_ctx_clear(void) +{ + xdk_d3d_video_t *device_ptr = (xdk_d3d_video_t*)driver.video_data; + device_ptr->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, + D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0); +} + +#ifndef HAVE_GRIFFIN bool gfx_ctx_window_has_focus(void) { return true; diff --git a/xbox1/frontend/menu.c b/xbox1/frontend/menu.c index 6861bc11f0..deaf863be1 100644 --- a/xbox1/frontend/menu.c +++ b/xbox1/frontend/menu.c @@ -990,9 +990,8 @@ void menu_loop(void) { SET_TIMER_EXPIRATION(device_ptr, 30); } - - device_ptr->d3d_render_device->EndScene(); - device_ptr->d3d_render_device->Present(NULL, NULL, NULL, NULL); + + gfx_ctx_swap_buffers(); }while(g_console.menu_enable); if(g_console.ingame_menu_enable) From bb4a516f6fdc3b8855737b61223505c257f5c2b1 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 3 Aug 2012 06:20:43 +0200 Subject: [PATCH 005/492] (Xbox 1) Uses gfx_ctx_clear now --- xbox1/frontend/menu.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/xbox1/frontend/menu.c b/xbox1/frontend/menu.c index deaf863be1..b1cc3b8b61 100644 --- a/xbox1/frontend/menu.c +++ b/xbox1/frontend/menu.c @@ -893,14 +893,16 @@ void menu_loop(void) trig_state = input_state; //second input frame set as current frame } } - - device_ptr->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, - D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0); + + gfx_ctx_clear(); + +#ifdef _XBOX1 device_ptr->frame_count++; device_ptr->d3d_render_device->BeginScene(); device_ptr->d3d_render_device->SetFlickerFilter(1); device_ptr->d3d_render_device->SetSoftDisplayFilter(1); +#endif filebrowser_t * fb = &browser; From 8a5641a585b27c13b468ef79976b14e8e3c6cc89 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 3 Aug 2012 06:24:19 +0200 Subject: [PATCH 006/492] (Xbox 1) Add BeginScene to gfx_ctx_clear --- gfx/context/xdk_ctx.c | 5 +++++ xbox1/frontend/menu.c | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gfx/context/xdk_ctx.c b/gfx/context/xdk_ctx.c index c1728bc679..55fc4e768a 100644 --- a/gfx/context/xdk_ctx.c +++ b/gfx/context/xdk_ctx.c @@ -73,6 +73,11 @@ void gfx_ctx_clear(void) xdk_d3d_video_t *device_ptr = (xdk_d3d_video_t*)driver.video_data; device_ptr->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0); +#ifdef _XBOX1 + device_ptr->d3d_render_device->BeginScene(); + device_ptr->d3d_render_device->SetFlickerFilter(1); + device_ptr->d3d_render_device->SetSoftDisplayFilter(1); +#endif } #ifndef HAVE_GRIFFIN diff --git a/xbox1/frontend/menu.c b/xbox1/frontend/menu.c index b1cc3b8b61..1ff3134f83 100644 --- a/xbox1/frontend/menu.c +++ b/xbox1/frontend/menu.c @@ -895,13 +895,8 @@ void menu_loop(void) } gfx_ctx_clear(); - #ifdef _XBOX1 device_ptr->frame_count++; - - device_ptr->d3d_render_device->BeginScene(); - device_ptr->d3d_render_device->SetFlickerFilter(1); - device_ptr->d3d_render_device->SetSoftDisplayFilter(1); #endif filebrowser_t * fb = &browser; From 9123da72ae65f90cb261bb8d41fc120a0a8f0172 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 3 Aug 2012 06:34:33 +0200 Subject: [PATCH 007/492] (PS3/Xbox 1) Make menu code usable for both PS3/360 --- ps3/frontend/menu.c | 6 ++-- xbox1/frontend/menu.c | 81 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 72 insertions(+), 15 deletions(-) diff --git a/ps3/frontend/menu.c b/ps3/frontend/menu.c index 5bce4f2865..eba68f2239 100644 --- a/ps3/frontend/menu.c +++ b/ps3/frontend/menu.c @@ -63,7 +63,7 @@ filebrowser_t tmpBrowser; unsigned set_shader = 0; static unsigned currently_selected_controller_menu = 0; static char strw_buffer[PATH_MAX]; -char core_text[256]; +char m_title[256]; static uint64_t old_state = 0; @@ -612,7 +612,7 @@ static void display_menubar(menu *current_menu) } render_msg_place_func(x_position, 0.05f, 1.4f, WHITE, current_menu->title); - render_msg_place_func(0.3f, 0.06f, 0.82f, WHITE, core_text); + render_msg_place_func(0.3f, 0.06f, 0.82f, WHITE, m_title); render_msg_place_func(0.8f, 0.12f, 0.82f, WHITE, rarch_version); render_msg_post_func(); } @@ -2126,7 +2126,7 @@ void menu_init (void) struct retro_system_info info; retro_get_system_info(&info); const char *id = info.library_name ? info.library_name : "Unknown"; - snprintf(core_text, sizeof(core_text), "Libretro core: %s %s", id, info.library_version); + snprintf(m_title, sizeof(m_title), "Libretro core: %s %s", id, info.library_version); menu_stack_push(menu_items, FILE_BROWSER_MENU); filebrowser_set_root_and_ext(&browser, rarch_console_get_rom_ext(), default_paths.filebrowser_startup_dir); diff --git a/xbox1/frontend/menu.c b/xbox1/frontend/menu.c index 1ff3134f83..e0077065dc 100644 --- a/xbox1/frontend/menu.c +++ b/xbox1/frontend/menu.c @@ -545,7 +545,11 @@ static void display_menubar(menu *current_menu) float x_position = POSITION_X; float current_y_position = POSITION_Y_START; +#ifdef _XBOX1 float font_size = m_menuMainRomListPos_y; +#else + float font_size = 0.91f; +#endif snprintf(rarch_version, sizeof(rarch_version), "v%s", PACKAGE_VERSION); @@ -592,15 +596,26 @@ static void display_menubar(menu *current_menu) fb = &tmpBrowser; case FILE_BROWSER_MENU: snprintf(current_path, sizeof(current_path), "PATH: %s", filebrowser_get_current_dir(fb)); +#ifdef _XBOX1 render_msg_place_func(x_position, current_y_position, 0, 0, current_path); +#else + render_msg_place_func(x_position, 0.09f, FONT_SIZE, YELLOW, current_path); +#endif break; default: break; } +#ifdef _XBOX1 //Render background image d3d_surface_render(&m_menuMainBG, MENU_MAIN_BG_X, MENU_MAIN_BG_Y, m_menuMainBG.m_imageInfo.Width, m_menuMainBG.m_imageInfo.Height); +#else + render_msg_place_func(x_position, 0.05f, 1.4f, WHITE, current_menu->title); + render_msg_place_func(0.3f, 0.06f, 0.82f, WHITE, m_title); + render_msg_place_func(0.8f, 0.12f, 0.82f, WHITE, rarch_version); + render_msg_post_func(); +#endif } static void browser_update(filebrowser_t * b, uint16_t input, const char *extensions) @@ -624,6 +639,7 @@ static void browser_update(filebrowser_t * b, uint16_t input, const char *extens else if (input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) { action = FILEBROWSER_ACTION_RESET; + //TODO - Dehardcode this filebrowser_set_root(b, "/"); strlcpy(b->extensions, extensions, sizeof(b->extensions)); } @@ -654,32 +670,44 @@ static void browser_render(filebrowser_t *b, float current_x, float current_y, f fill_pathname_base(fname_tmp, b->current_dir.list->elems[i].data, sizeof(fname_tmp)); currentY = currentY + ySpacing; - const char *rom_basename = fname_tmp; - +#ifdef _XBOX1 //check if this is the currently selected file const char *current_pathname = filebrowser_get_current_path(b); if(strcmp(current_pathname, b->current_dir.list->elems[i].data) == 0) d3d_surface_render(&m_menuMainRomSelectPanel, currentX, currentY, ROM_PANEL_WIDTH, ROM_PANEL_HEIGHT); - render_msg_place_func(currentX, currentY, 0, 0, rom_basename); + render_msg_place_func(currentX, currentY, 0, 0, fname_tmp); +#else + render_msg_place_func(currentX, currentY, FONT_SIZE, i == current_index ? RED : b->current_dir.list->elems[i].attr.b ? GREEN : WHITE, fname_tmp); + render_msg_post_func(); +#endif } +#ifndef _XBOX1 + render_msg_post_func(); +#endif } static void menu_romselect_iterate(filebrowser_t *filebrowser, menu_romselect_action_t action) { + bool ret = true; + switch(action) { case MENU_ROMSELECT_ACTION_OK: if(filebrowser_get_current_path_isdir(filebrowser)) - filebrowser_iterate(filebrowser, FILEBROWSER_ACTION_OK); - else + ret = filebrowser_iterate(filebrowser, FILEBROWSER_ACTION_OK); + else rarch_console_load_game_wrap(filebrowser_get_current_path(filebrowser), g_console.zip_extract_mode, S_DELAY_45); break; case MENU_ROMSELECT_ACTION_GOTO_SETTINGS: + menu_stack_push(items, GENERAL_VIDEO_MENU); break; default: break; } + + if(!ret) + rarch_settings_msg(S_MSG_DIR_LOADING_ERROR, S_DELAY_180); } static void select_rom(item *items, menu *current_menu, uint64_t input) @@ -716,7 +744,15 @@ int menu_init(void) const char *id = info.library_name ? info.library_name : "Unknown"; snprintf(m_title, sizeof(m_title), "Libretro core: %s %s", id, info.library_version); + menu_stack_push(menu_items, FILE_BROWSER_MENU); + filebrowser_set_root_and_ext(&browser, rarch_console_get_rom_ext(), g_console.default_rom_startup_dir); +#ifdef _XBOX1 + filebrowser_set_root(&tmpBrowser, "D:"); +#else + filebrowser_set_root(&tmpBrowser, "/"); +#endif +#ifdef _XBOX1 // Set file cache size XSetFileCacheSize(8 * 1024 * 1024); @@ -727,11 +763,6 @@ int menu_init(void) xbox_io_mount("F:", "Harddisk0\\Partition6"); xbox_io_mount("G:", "Harddisk0\\Partition7"); - strlcpy(browser.extensions, rarch_console_get_rom_ext(), sizeof(browser.extensions)); - menu_stack_push(menu_items, FILE_BROWSER_MENU); - filebrowser_set_root_and_ext(&browser, rarch_console_get_rom_ext(), g_console.default_rom_startup_dir); - filebrowser_set_root(&tmpBrowser, "/"); - width = d3d->d3dpp.BackBufferWidth; // Quick hack to properly center the romlist in 720p, @@ -758,8 +789,7 @@ int menu_init(void) //Center the text (hardcoded) xpos = width == 640 ? 65 : 400; ypos = width == 640 ? 430 : 670; - - g_console.mode_switch = MODE_MENU; +#endif return 0; } @@ -769,8 +799,10 @@ void menu_free(void) filebrowser_free(&browser); filebrowser_free(&tmpBrowser); +#ifdef _XBOX1 d3d_surface_free(&m_menuMainBG); d3d_surface_free(&m_menuMainRomSelectPanel); +#endif } void menu_loop(void) @@ -898,6 +930,20 @@ void menu_loop(void) #ifdef _XBOX1 device_ptr->frame_count++; #endif + + if(current_menu->enum_id == INGAME_MENU_RESIZE && (trig_state & RETRO_DEVICE_ID_JOYPAD_Y) || current_menu->enum_id == INGAME_MENU_SCREENSHOT) + { +#ifdef __CELLOS_LV2__ + device_ptr->menu_render = false; +#endif + } + else + { + gfx_ctx_set_blend(true); +#ifdef __CELLOS_LV2__ + device_ptr->menu_render = true; +#endif + } filebrowser_t * fb = &browser; @@ -989,8 +1035,19 @@ void menu_loop(void) } gfx_ctx_swap_buffers(); +#ifdef HAVE_SYSUTILS + cellSysutilCheckCallback(); +#endif + if(current_menu->enum_id == INGAME_MENU_RESIZE && (old_state & (1 << RETRO_DEVICE_ID_JOYPAD_Y)) || current_menu->enum_id == INGAME_MENU_SCREENSHOT) + { } + else + gfx_ctx_set_blend(false); }while(g_console.menu_enable); +#ifdef __CELLOS_LV2__ + device_ptr->menu_render = false; +#endif + if(g_console.ingame_menu_enable) menu_stack_decrement(); From 9976b81f18ee60f855ccfc4403de705ef23f36bc Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 3 Aug 2012 17:54:22 +0200 Subject: [PATCH 008/492] (PS3/Xbox 1) Menu changes --- gfx/context/ps3_ctx.c | 8 +++--- gfx/gfx_context.h | 3 +- ps3/frontend/menu.c | 67 ++++++++++++++++++++++++++----------------- ps3/frontend/menu.h | 7 +++++ xbox1/frontend/menu.c | 23 +++++++-------- 5 files changed, 62 insertions(+), 46 deletions(-) diff --git a/gfx/context/ps3_ctx.c b/gfx/context/ps3_ctx.c index 2c187b849d..41e341e7e7 100644 --- a/gfx/context/ps3_ctx.c +++ b/gfx/context/ps3_ctx.c @@ -334,11 +334,11 @@ const char *ps3_get_resolution_label(uint32_t resolution) switch (resolution) { case CELL_VIDEO_OUT_RESOLUTION_480: - return "720x480 (480p)"; + return "720x480"; case CELL_VIDEO_OUT_RESOLUTION_576: - return "720x576 (576p)"; + return "720x576"; case CELL_VIDEO_OUT_RESOLUTION_720: - return "1280x720 (720p)"; + return "1280x720"; case CELL_VIDEO_OUT_RESOLUTION_960x1080: return "960x1080"; case CELL_VIDEO_OUT_RESOLUTION_1280x1080: @@ -348,7 +348,7 @@ const char *ps3_get_resolution_label(uint32_t resolution) case CELL_VIDEO_OUT_RESOLUTION_1600x1080: return "1600x1080"; case CELL_VIDEO_OUT_RESOLUTION_1080: - return "1920x1080 (1080p)"; + return "1920x1080"; default: return "Unknown"; } diff --git a/gfx/gfx_context.h b/gfx/gfx_context.h index 31fa6424ac..732900363f 100644 --- a/gfx/gfx_context.h +++ b/gfx/gfx_context.h @@ -62,9 +62,8 @@ bool gfx_ctx_get_wm_info(SDL_SysWMinfo *info); #ifndef HAVE_GRIFFIN bool gfx_ctx_window_has_focus(void); - -void gfx_ctx_swap_buffers(void); #endif +void gfx_ctx_swap_buffers(void); void gfx_ctx_input_driver(const input_driver_t **input, void **input_data); diff --git a/ps3/frontend/menu.c b/ps3/frontend/menu.c index eba68f2239..e7225bc3e5 100644 --- a/ps3/frontend/menu.c +++ b/ps3/frontend/menu.c @@ -14,16 +14,17 @@ * If not, see . */ +#if defined(__CELLOS_LV2__) #include #include #include -#include #if(CELL_SDK_VERSION > 0x340000) #include #endif -#include "../ps3_input.h" +#endif + #include "../../console/fileio/file_browser.h" #include "../../console/rarch_console.h" @@ -31,18 +32,30 @@ #include "../../console/rarch_console_input.h" #include "../../console/rarch_console_config.h" #include "../../console/rarch_console_settings.h" + +#ifdef HAVE_RSOUND #include "../../console/rarch_console_rsound.h" +#endif + #include "../../console/rarch_console_video.h" #ifdef HAVE_ZLIB #include "../../console/rarch_console_rzlib.h" #endif +#if defined(HAVE_OPENGL) #include "../../gfx/gl_common.h" #include "../../gfx/gl_font.h" +#endif #include "../../gfx/gfx_context.h" + +#if defined(__CELLOS_LV2__) #include "../../gfx/context/ps3_ctx.h" +#endif + +#if defined(HAVE_CG) #include "../../gfx/shader_cg.h" +#endif #include "../../file.h" #include "../../general.h" @@ -62,7 +75,6 @@ filebrowser_t browser; filebrowser_t tmpBrowser; unsigned set_shader = 0; static unsigned currently_selected_controller_menu = 0; -static char strw_buffer[PATH_MAX]; char m_title[256]; static uint64_t old_state = 0; @@ -362,28 +374,28 @@ menu *menu_stack_get_current_ptr (void) static void menu_stack_refresh (item *items, menu *current_menu) { int page, i, j; - float increment; - float increment_step = 0.03f; + float y_position; + float increment_step = POSITION_Y_INCREMENT; float x_position = POSITION_X; page = 0; j = 0; - increment = 0.16f; + y_position = POSITION_Y_BEGIN; for(i = current_menu->first_setting; i < current_menu->max_settings; i++) { if(!(j < (NUM_ENTRY_PER_PAGE))) { j = 0; - increment = 0.16f; + y_position = POSITION_Y_BEGIN; page++; } items[i].text_xpos = x_position; - items[i].text_ypos = increment; + items[i].text_ypos = y_position; items[i].page = page; set_setting_label(current_menu, items, i); - increment += increment_step; + y_position += increment_step; j++; } } @@ -558,7 +570,7 @@ static void display_menubar(menu *current_menu) char current_path[256], rarch_version[128]; float x_position = POSITION_X; - float font_size = 0.91f; + float font_size = HARDCODE_FONT_SIZE; snprintf(rarch_version, sizeof(rarch_version), "v%s", PACKAGE_VERSION); @@ -706,9 +718,9 @@ static void select_file(item *items, menu *current_menu, uint64_t input) bool ret = true; float x_position = POSITION_X; - float comment_y_position = 0.83f; + float comment_y_position = COMMENT_Y_POSITION; float comment_two_y_position = 0.91f; - float font_size = 0.91f; + float font_size = HARDCODE_FONT_SIZE; switch(current_menu->enum_id) { @@ -814,9 +826,9 @@ static void select_directory(item *items, menu *current_menu, uint64_t input) DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; float x_position = POSITION_X; - float comment_y_position = 0.83f; + float comment_y_position = COMMENT_Y_POSITION; float comment_two_y_position = 0.91f; - float font_size = 0.91f; + float font_size = HARDCODE_FONT_SIZE; bool is_dir = filebrowser_get_current_path_isdir(&tmpBrowser); browser_update(&tmpBrowser, input, "empty"); @@ -1621,9 +1633,9 @@ static void select_setting(item *items, menu *current_menu, uint64_t input) float x_position = POSITION_X; float x_position_center = 0.5f; - float comment_y_position = 0.83f; + float comment_y_position = COMMENT_Y_POSITION; float comment_two_y_position = 0.91f; - float font_size = 0.91f; + float font_size = HARDCODE_FONT_SIZE; settings_action_t action = SETTINGS_ACTION_NOOP; @@ -1694,9 +1706,9 @@ static void select_rom(item *items, menu *current_menu, uint64_t input) DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; float x_position = POSITION_X; - float comment_y_position = 0.83f; - float font_size = 0.91f; + float comment_y_position = COMMENT_Y_POSITION; float comment_two_y_position = 0.91f; + float font_size = HARDCODE_FONT_SIZE; browser_update(&browser, input, rarch_console_get_rom_ext()); @@ -1743,11 +1755,11 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) float x_position = POSITION_X; float x_position_center = 0.5f; - float font_size = 0.91f; + float font_size = HARDCODE_FONT_SIZE; - float y_position = 0.16f; - float y_position_increment = 0.035f; - float comment_y_position = 0.83f; + float y_position = POSITION_Y_BEGIN; + float y_position_increment = POSITION_Y_INCREMENT; + float comment_y_position = COMMENT_Y_POSITION; g_console.aspect_ratio_index = ASPECT_RATIO_CUSTOM; gfx_ctx_set_aspect_ratio(NULL, g_console.aspect_ratio_index); @@ -1902,15 +1914,16 @@ static void ingame_menu_screenshot(item *items, menu *current_menu, uint64_t inp static void ingame_menu(item *items, menu *current_menu, uint64_t input) { char comment[256], overscan_msg[64]; + char strw_buffer[256]; static unsigned menuitem_colors[MENU_ITEM_LAST]; DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; float x_position = POSITION_X; - float y_position = 0.16f; - float comment_y_position = 0.83f; - float font_size = 0.91f; + float y_position = POSITION_Y_BEGIN; + float comment_y_position = COMMENT_Y_POSITION; + float font_size = HARDCODE_FONT_SIZE; - float y_position_increment = 0.035f; + float y_position_increment = POSITION_Y_INCREMENT; for(int i = 0; i < MENU_ITEM_LAST; i++) menuitem_colors[i] = GREEN; @@ -2318,7 +2331,7 @@ void menu_loop(void) float x_position = POSITION_X; float starting_y_position = POSITION_Y_START; - float y_position_increment = 0.035f; + float y_position_increment = POSITION_Y_INCREMENT; switch(current_menu->category_id) { diff --git a/ps3/frontend/menu.h b/ps3/frontend/menu.h index 7bade689f4..4cbd1236ac 100644 --- a/ps3/frontend/menu.h +++ b/ps3/frontend/menu.h @@ -21,6 +21,7 @@ #define DEVICE_CAST gl_t* #define input_ptr input_ps3 #define DEVICE_PTR device_ptr +#define HARDCODE_FONT_SIZE 0.91f #define FONT_SIZE (g_console.menu_font_size) #define render_msg_pre_func() gl_render_msg_pre(DEVICE_PTR) #define render_msg_place_func(xpos, ypos, scale, color, msg) gl_render_msg_place(xpos, ypos, scale, color, msg) @@ -28,6 +29,9 @@ #define POSITION_X 0.09f #define POSITION_Y_START 0.10f +#define POSITION_Y_BEGIN (POSITION_Y_START + POSITION_Y_INCREMENT) +#define POSITION_Y_INCREMENT 0.035f +#define COMMENT_Y_POSITION 0.83f #elif defined(_XBOX1) #define DEVICE_CAST xdk_d3d_video_t* #define input_ptr input_xinput @@ -39,6 +43,9 @@ #define POSITION_X m_menuMainRomListPos_x #define POSITION_Y_START m_menuMainRomListPos_y +#define POSITION_Y_BEGIN (POSITION_Y_START + POSITION_Y_INCREMENT) +#define POSITION_Y_INCREMENT 20 +#define COMMENT_Y_POSITION (ypos - POSITION_Y_INCREMENT) #endif typedef struct diff --git a/xbox1/frontend/menu.c b/xbox1/frontend/menu.c index e0077065dc..2ef04e7ded 100644 --- a/xbox1/frontend/menu.c +++ b/xbox1/frontend/menu.c @@ -47,10 +47,6 @@ d3d_surface_t m_menuMainBG; // Rom list coords int m_menuMainRomListPos_x; int m_menuMainRomListPos_y; - -// Backbuffer width, height -int width; -int height; #endif menu menuStack[10]; @@ -351,28 +347,28 @@ menu *menu_stack_get_current_ptr (void) static void menu_stack_refresh (item *items, menu *current_menu) { int page, i, j; - float increment; - float increment_step = 0.03f; + float y_position; + float increment_step = POSITION_Y_INCREMENT; float x_position = POSITION_X; page = 0; j = 0; - increment = 0.16f; + y_position = 0.16f; for(i = current_menu->first_setting; i < current_menu->max_settings; i++) { if(!(j < (NUM_ENTRY_PER_PAGE))) { j = 0; - increment = 0.16f; + y_position = 0.16f; page++; } items[i].text_xpos = x_position; - items[i].text_ypos = increment; + items[i].text_ypos = y_position; items[i].page = page; set_setting_label(current_menu, items, i); - increment += increment_step; + y_position += increment_step; j++; } } @@ -736,7 +732,7 @@ static void select_rom(item *items, menu *current_menu, uint64_t input) int menu_init(void) { - xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; + DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; // Set libretro filename and version to variable struct retro_system_info info; @@ -763,7 +759,8 @@ int menu_init(void) xbox_io_mount("F:", "Harddisk0\\Partition6"); xbox_io_mount("G:", "Harddisk0\\Partition7"); - width = d3d->d3dpp.BackBufferWidth; + // Backbuffer width + int width = device_ptr->d3dpp.BackBufferWidth; // Quick hack to properly center the romlist in 720p, // it might need more work though (font size and rom selector size -> needs more memory) @@ -991,7 +988,7 @@ void menu_loop(void) float x_position = POSITION_X; float starting_y_position = POSITION_Y_START; - float y_position_increment = 20; + float y_position_increment = POSITION_Y_INCREMENT; switch(current_menu->category_id) { From b06da6e25988fc7d5238aeef1f8cc2510cd981f9 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 3 Aug 2012 18:10:00 +0200 Subject: [PATCH 009/492] (Xbox 1) Build fix --- gfx/context/xdk_ctx.c | 5 +++++ xbox1/frontend/menu.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/gfx/context/xdk_ctx.c b/gfx/context/xdk_ctx.c index 55fc4e768a..ff65ba06a0 100644 --- a/gfx/context/xdk_ctx.c +++ b/gfx/context/xdk_ctx.c @@ -32,6 +32,11 @@ #define XBOX_PRESENTATIONINTERVAL D3DRS_PRESENTINTERVAL #endif +void gfx_ctx_set_blend(bool enable) +{ + (void)enable; +} + void gfx_ctx_set_swap_interval(unsigned interval, bool inited) { (void)inited; diff --git a/xbox1/frontend/menu.c b/xbox1/frontend/menu.c index 2ef04e7ded..6b24ff8831 100644 --- a/xbox1/frontend/menu.c +++ b/xbox1/frontend/menu.c @@ -683,7 +683,7 @@ static void browser_render(filebrowser_t *b, float current_x, float current_y, f #endif } -static void menu_romselect_iterate(filebrowser_t *filebrowser, menu_romselect_action_t action) +static void menu_romselect_iterate(filebrowser_t *filebrowser, item *items, menu_romselect_action_t action) { bool ret = true; @@ -723,7 +723,7 @@ static void select_rom(item *items, menu *current_menu, uint64_t input) } if (action != MENU_ROMSELECT_ACTION_NOOP) - menu_romselect_iterate(&browser, action); + menu_romselect_iterate(&browser, items, action); display_menubar(current_menu); From 8e71b6274887ed96c91570aa98347034344cf1ea Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 3 Aug 2012 18:27:38 +0200 Subject: [PATCH 010/492] (PS3/Xbox 1) Menu changes --- 360/frontend-xdk/menu.cpp | 12 +++--- console/griffin/griffin.c | 2 +- console/rarch_console.h | 1 + ps3/frontend/menu.c | 78 +++++++++++++++++++++++++++++++++------ ps3/frontend/menu.h | 5 ++- xbox1/xdk_d3d8.cpp | 2 + xbox1/xdk_d3d8.h | 2 + xdk/menu_shared.h | 2 +- 8 files changed, 83 insertions(+), 21 deletions(-) diff --git a/360/frontend-xdk/menu.cpp b/360/frontend-xdk/menu.cpp index 34feda88de..bfc022a7e0 100644 --- a/360/frontend-xdk/menu.cpp +++ b/360/frontend-xdk/menu.cpp @@ -808,7 +808,7 @@ HRESULT CRetroArchMain::OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled ) return 0; } -int menu_init (void) +void menu_init (void) { HRESULT hr; @@ -821,7 +821,7 @@ int menu_init (void) if (hr < 0) { RARCH_ERR("Failed initializing XUI application.\n"); - return 1; + return; } /* Register font */ @@ -829,21 +829,21 @@ int menu_init (void) if (hr < 0) { RARCH_ERR("Failed to register default typeface.\n"); - return 1; + return; } hr = app.LoadSkin( L"file://game:/media/rarch_scene_skin.xur"); if (hr < 0) { RARCH_ERR("Failed to load skin.\n"); - return 1; + return; } hr = XuiSceneCreate(hdmenus_allowed ? L"file://game:/media/hd/" : L"file://game:/media/sd/", L"rarch_main.xur", NULL, &app.hMainScene); if (hr < 0) { RARCH_ERR("Failed to create scene 'rarch_main.xur'.\n"); - return 1; + return; } hCur = app.hMainScene; @@ -852,8 +852,6 @@ int menu_init (void) browser = (filebrowser_t*)malloc(1 * sizeof(filebrowser_t)); tmp_browser = (filebrowser_t*)malloc(1 * sizeof(filebrowser_t)); filebrowser_new(browser, g_console.default_rom_startup_dir, rarch_console_get_rom_ext()); - - return 0; } void menu_free (void) diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index fa061d613c..4e3655f235 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -284,7 +284,7 @@ MENU #if defined(_XBOX360) #include "../../360/frontend-xdk/menu.cpp" #elif defined(_XBOX1) -#include "../../xbox1/frontend/menu.c" +#include "../../ps3/frontend/menu.c" #include "../../xbox1/frontend/RetroLaunch/IoSupport.cpp" #include "../../xbox1/frontend/RetroLaunch/Surface.cpp" #elif defined(GEKKO) diff --git a/console/rarch_console.h b/console/rarch_console.h index 8db82600b1..6291be438a 100644 --- a/console/rarch_console.h +++ b/console/rarch_console.h @@ -70,6 +70,7 @@ enum #ifdef HAVE_HEADSET SOUND_MODE_HEADSET, #endif + SOUND_MODE_LAST }; #define MAXIMUM_PATH 512 diff --git a/ps3/frontend/menu.c b/ps3/frontend/menu.c index e7225bc3e5..16592cd59d 100644 --- a/ps3/frontend/menu.c +++ b/ps3/frontend/menu.c @@ -67,6 +67,34 @@ #define INPUT_SCALE 2 #define MENU_ITEM_SELECTED(index) (menuitem_colors[index]) +#ifdef _XBOX1 +#include "../../xbox1/frontend/RetroLaunch/IoSupport.h" +#include "../../xbox1/frontend/RetroLaunch/Surface.h" +#include "../../gfx/fonts/xdk1_xfonts.h" + +#define NUM_ENTRY_PER_PAGE 17 + +#define ROM_PANEL_WIDTH 440 +#define ROM_PANEL_HEIGHT 20 + +#define MAIN_TITLE_X 305 +#define MAIN_TITLE_Y 30 +#define MAIN_TITLE_COLOR 0xFFFFFFFF + +#define MENU_MAIN_BG_X 0 +#define MENU_MAIN_BG_Y 0 + +int xpos, ypos; +// Rom selector panel with coords +d3d_surface_t m_menuMainRomSelectPanel; +// Background image with coords +d3d_surface_t m_menuMainBG; + +// Rom list coords +int m_menuMainRomListPos_x; +int m_menuMainRomListPos_y; +#endif + menu menuStack[10]; int menuStackindex = 0; static bool set_libretro_core_as_launch; @@ -667,7 +695,7 @@ static void browser_render(filebrowser_t * b, float current_x, float current_y, DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; unsigned file_count = b->current_dir.list->size; - int current_index, page_number, page_base, i; + unsigned int current_index, page_number, page_base, i; float currentX, currentY, ySpacing; current_index = b->current_dir.ptr; @@ -689,6 +717,7 @@ static void browser_render(filebrowser_t * b, float current_x, float current_y, render_msg_post_func(); } +#ifdef __CELLOS_LV2__ static void apply_scaling (unsigned init_mode) { DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; @@ -709,6 +738,7 @@ static void apply_scaling (unsigned init_mode) break; } } +#endif static void select_file(item *items, menu *current_menu, uint64_t input) { @@ -764,6 +794,7 @@ static void select_file(item *items, menu *current_menu, uint64_t input) switch(current_menu->enum_id) { +#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) case SHADER_CHOICE: rarch_load_shader(set_shader+1, path); switch(set_shader+1) @@ -780,9 +811,12 @@ static void select_file(item *items, menu *current_menu, uint64_t input) case PRESET_CHOICE: strlcpy(g_console.cgp_path, path, sizeof(g_console.cgp_path)); apply_scaling(FBO_DEINIT); +#ifdef HAVE_OPENGL gl_cg_reinit(path); +#endif apply_scaling(FBO_INIT); break; +#endif case INPUT_PRESET_CHOICE: strlcpy(g_console.input_cfg_path, path, sizeof(g_console.input_cfg_path)); config_read_keybinds(path); @@ -1017,13 +1051,13 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch if(gfx_ctx_check_resolution(CELL_VIDEO_OUT_RESOLUTION_576)) { //ps3graphics_set_pal60hz(Settings.PS3PALTemporalMode60Hz); - video_gl.restart(); + video_ptr.restart(); } } else { //ps3graphics_set_pal60hz(0); - video_gl.restart(); + video_ptr.restart(); } } break; @@ -1142,6 +1176,7 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch gfx_ctx_set_filtering(2, g_settings.video.second_pass_smooth); } break; +#ifdef HAVE_FBO case SETTING_SCALE_ENABLED: if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { @@ -1188,6 +1223,7 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch apply_scaling(FBO_INIT); } break; +#endif case SETTING_HW_OVERSCAN_AMOUNT: if(input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) { @@ -1221,7 +1257,7 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { rarch_settings_change(S_TRIPLE_BUFFERING); - video_gl.restart(); + video_ptr.restart(); } if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) { @@ -1229,7 +1265,7 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch rarch_settings_default(S_DEF_TRIPLE_BUFFERING); if(!old_buffer_input) - video_gl.restart(); + video_ptr.restart(); } break; case SETTING_ENABLE_SCREENSHOTS: @@ -1279,20 +1315,24 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch } if((input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { - if(g_console.sound_mode < SOUND_MODE_HEADSET) + if(g_console.sound_mode < (SOUND_MODE_LAST-1)) g_console.sound_mode++; } if((input & (1 << RETRO_DEVICE_ID_JOYPAD_UP)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN))) { +#ifdef HAVE_RSOUND if(g_console.sound_mode != SOUND_MODE_RSOUND) rarch_console_rsound_stop(); else rarch_console_rsound_start(g_settings.audio.device); +#endif } if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) { g_console.sound_mode = SOUND_MODE_NORMAL; +#ifdef HAVE_RSOUND rarch_console_rsound_stop(); +#endif } break; #ifdef HAVE_RSOUND @@ -1564,10 +1604,12 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch case SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_R3: set_keybind_digital(RETRO_DEVICE_ID_JOYPAD_R3, input); break; +#ifdef __CELLOS_LV2__ case SETTING_CONTROLS_SAVE_CUSTOM_CONTROLS: if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_START))) rarch_filename_input_and_save(INPUT_PRESET_FILE); break; +#endif case SETTING_CONTROLS_DEFAULT_ALL: if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_START))) { @@ -1905,8 +1947,10 @@ static void ingame_menu_screenshot(item *items, menu *current_menu, uint64_t inp { if(input & (1 << RETRO_DEVICE_ID_JOYPAD_A)) { - menu_stack_decrement(); - device_ptr->menu_render = true; + menu_stack_decrement(); +#ifdef __CELLOS_LV2__ + device_ptr->menu_render = true; +#endif } } } @@ -1974,26 +2018,28 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) if(input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) { rarch_settings_change(S_ROTATION_DECREMENT); - video_gl.set_rotation(NULL, g_console.screen_orientation); + video_ptr.set_rotation(NULL, g_console.screen_orientation); } if((input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { rarch_settings_change(S_ROTATION_INCREMENT); - video_gl.set_rotation(NULL, g_console.screen_orientation); + video_ptr.set_rotation(NULL, g_console.screen_orientation); } if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) { rarch_settings_default(S_DEF_ROTATION); - video_gl.set_rotation(NULL, g_console.screen_orientation); + video_ptr.set_rotation(NULL, g_console.screen_orientation); } snprintf(comment, sizeof(comment), "Press [%s] or [%s] to change the [Orientation] settings.\nPress [%s] to reset back to default values.",rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_LEFT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_RIGHT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_START)); break; +#ifdef HAVE_FBO case MENU_ITEM_SCALE_FACTOR: producesettingentry(current_menu, items, SETTING_SCALE_FACTOR, input); snprintf(comment, sizeof(comment), "Press [%s] or [%s] to change the [Scaling] settings.\nPress [%s] to reset back to default values.",rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_LEFT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_RIGHT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_START)); break; +#endif case MENU_ITEM_FRAME_ADVANCE: if((input & (1 << RETRO_DEVICE_ID_JOYPAD_B)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_R2)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_L2))) { @@ -2099,9 +2145,11 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) render_msg_place_func (x_position, (y_position+(y_position_increment*MENU_ITEM_ORIENTATION)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_ORIENTATION), strw_buffer); render_msg_post_func(); +#ifdef HAVE_FBO rarch_settings_create_menu_item_label(strw_buffer, S_LBL_SCALE_FACTOR, sizeof(strw_buffer)); render_msg_place_func (x_position, (y_position+(y_position_increment*MENU_ITEM_SCALE_FACTOR)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_SCALE_FACTOR), strw_buffer); render_msg_post_func(); +#endif render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_RESIZE_MODE)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_RESIZE_MODE), "Resize Mode"); @@ -2276,11 +2324,17 @@ void menu_loop(void) gfx_ctx_clear(); if(current_menu->enum_id == INGAME_MENU_RESIZE && (trig_state & RETRO_DEVICE_ID_JOYPAD_Y) || current_menu->enum_id == INGAME_MENU_SCREENSHOT) + { +#ifdef __CELLOS_LV2__ device_ptr->menu_render = false; +#endif + } else { gfx_ctx_set_blend(true); +#ifdef __CELLOS_LV2__ device_ptr->menu_render = true; +#endif } rarch_render_cached_frame(); @@ -2394,7 +2448,9 @@ void menu_loop(void) gfx_ctx_set_blend(false); }while(g_console.menu_enable); +#ifdef __CELLOS_LV2__ device_ptr->menu_render = false; +#endif if(g_console.ingame_menu_enable) menu_stack_decrement(); diff --git a/ps3/frontend/menu.h b/ps3/frontend/menu.h index 4cbd1236ac..969749a101 100644 --- a/ps3/frontend/menu.h +++ b/ps3/frontend/menu.h @@ -20,6 +20,7 @@ #if defined(__CELLOS_LV2__) #define DEVICE_CAST gl_t* #define input_ptr input_ps3 +#define video_ptr video_gl #define DEVICE_PTR device_ptr #define HARDCODE_FONT_SIZE 0.91f #define FONT_SIZE (g_console.menu_font_size) @@ -35,8 +36,10 @@ #elif defined(_XBOX1) #define DEVICE_CAST xdk_d3d_video_t* #define input_ptr input_xinput +#define video_ptr video_xdk_d3d #define DEVICE_PTR device_ptr -#define FONT_SIZE 0 +#define HARDCODE_FONT_SIZE 21 +#define FONT_SIZE 21 #define render_msg_pre_func() xfonts_render_msg_pre(DEVICE_PTR) #define render_msg_place_func(xpos, ypos, scale, color, msg) xfonts_render_msg_place(DEVICE_PTR, xpos, ypos, scale, msg) #define render_msg_post_func() xfonts_render_msg_post(DEVICE_PTR) diff --git a/xbox1/xdk_d3d8.cpp b/xbox1/xdk_d3d8.cpp index f33a8a089c..221a194de3 100644 --- a/xbox1/xdk_d3d8.cpp +++ b/xbox1/xdk_d3d8.cpp @@ -263,6 +263,8 @@ static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **inpu } } + d3d->win_width = d3d->d3dpp.BackBufferWidth; + d3d->win_height = d3d->d3dpp.BackBufferHeight; if(d3d->d3dpp.BackBufferWidth > 640 && ((float)d3d->d3dpp.BackBufferHeight / (float)d3d->d3dpp.BackBufferWidth != 0.75) || ((d3d->d3dpp.BackBufferWidth == 720) && (d3d->d3dpp.BackBufferHeight == 576))) // 16:9 diff --git a/xbox1/xdk_d3d8.h b/xbox1/xdk_d3d8.h index a6e867d9e1..26e790169f 100644 --- a/xbox1/xdk_d3d8.h +++ b/xbox1/xdk_d3d8.h @@ -62,6 +62,8 @@ typedef struct xdk_d3d_video unsigned frame_count; unsigned last_width; unsigned last_height; + unsigned win_width; + unsigned win_height; LPDIRECT3D d3d_device; LPDIRECT3DDEVICE d3d_render_device; LPDIRECT3DVERTEXBUFFER vertex_buf; diff --git a/xdk/menu_shared.h b/xdk/menu_shared.h index 9487fea619..44adfb1821 100644 --- a/xdk/menu_shared.h +++ b/xdk/menu_shared.h @@ -17,7 +17,7 @@ #ifndef _XDK_MENU_SHARED_H #define _XDK_MENU_SHARED_H -int menu_init (void); +void menu_init (void); void menu_free (void); void menu_loop (void); From bb338d07d73158801a3157fd55ecb8a178d6215b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 3 Aug 2012 18:54:59 +0200 Subject: [PATCH 011/492] (PS3/Xbox 1) Menu unification changes --- console/griffin/griffin.c | 3 +- ps3/frontend/menu-entries.h | 10 ++++++ ps3/frontend/menu.c | 63 ++++++++++++++++++++++++++++++++++++- ps3/frontend/menu.h | 10 ++++++ xbox1/frontend/menu.c | 14 ++++++--- 5 files changed, 94 insertions(+), 6 deletions(-) diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index 4e3655f235..f5a9cb9804 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -284,7 +284,8 @@ MENU #if defined(_XBOX360) #include "../../360/frontend-xdk/menu.cpp" #elif defined(_XBOX1) -#include "../../ps3/frontend/menu.c" +#include "../../xbox1/frontend/menu.c" +//#include "../../ps3/frontend/menu.c" #include "../../xbox1/frontend/RetroLaunch/IoSupport.cpp" #include "../../xbox1/frontend/RetroLaunch/Surface.cpp" #elif defined(GEKKO) diff --git a/ps3/frontend/menu-entries.h b/ps3/frontend/menu-entries.h index 728d5e42be..ce6578e3ad 100644 --- a/ps3/frontend/menu-entries.h +++ b/ps3/frontend/menu-entries.h @@ -16,6 +16,7 @@ item menu_items[MAX_NO_OF_CONTROLS_SETTINGS] = { +#ifdef __CELLOS_LV2__ { SETTING_CHANGE_RESOLUTION, /* enum ID of item */ "Resolution", /* item label */ @@ -26,6 +27,8 @@ item menu_items[MAX_NO_OF_CONTROLS_SETTINGS] = "INFO - Change the display resolution.", /* item comment */ WHITE, /* color of item comment */ }, +#endif +#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) { SETTING_SHADER_PRESETS, "Shader Preset (CGP)", @@ -56,6 +59,7 @@ item menu_items[MAX_NO_OF_CONTROLS_SETTINGS] = "INFO - Select a shader as [Shader #2]. NOTE: Some shaders might be\ntoo slow at 1080p. If you experience any slowdown, try another shader.", WHITE, }, +#endif { SETTING_FONT_SIZE, "Font Size", @@ -86,6 +90,7 @@ item menu_items[MAX_NO_OF_CONTROLS_SETTINGS] = "INFO - Hardware filtering is set to 'Bilinear filtering' for [Shader #1].", WHITE, }, +#ifdef HAVE_FBO { SETTING_HW_TEXTURE_FILTER_2, "Hardware Filtering shader #2", @@ -116,6 +121,7 @@ item menu_items[MAX_NO_OF_CONTROLS_SETTINGS] = "INFO - [Custom Scaling Factor] is set to '2x'.", WHITE, }, +#endif { SETTING_HW_OVERSCAN_AMOUNT, "Overscan", @@ -156,6 +162,7 @@ item menu_items[MAX_NO_OF_CONTROLS_SETTINGS] = "INFO - [Enable Screenshots] feature is set to 'OFF'.", WHITE, }, +#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) { SETTING_SAVE_SHADER_PRESET, "SAVE SETTINGS AS CGP PRESET ", @@ -176,6 +183,7 @@ item menu_items[MAX_NO_OF_CONTROLS_SETTINGS] = "INFO - Automatically load the currently selected [CG Preset] file on startup.", GREEN, }, +#endif { SETTING_DEFAULT_VIDEO_ALL, "DEFAULT", @@ -196,6 +204,7 @@ item menu_items[MAX_NO_OF_CONTROLS_SETTINGS] = "INFO - [Sound Output] is set to 'Normal' - normal audio output will be\nused.", WHITE, }, +#ifdef HAVE_RSOUND { SETTING_RSOUND_SERVER_IP_ADDRESS, "RSound Audio Server IP Address", @@ -206,6 +215,7 @@ item menu_items[MAX_NO_OF_CONTROLS_SETTINGS] = "INFO - Enter the IP Address of the [RSound Audio Server]. IP address\nmust be an IPv4 32-bits address, eg: '192.168.1.7'.", WHITE, }, +#endif { SETTING_ENABLE_CUSTOM_BGM, "Enable Custom BGM Feature", diff --git a/ps3/frontend/menu.c b/ps3/frontend/menu.c index 16592cd59d..7c8cfc0d18 100644 --- a/ps3/frontend/menu.c +++ b/ps3/frontend/menu.c @@ -190,6 +190,7 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current else snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Point filtering"); break; +#ifdef HAVE_FBO case SETTING_SCALE_ENABLED: set_setting_label_write_on_or_off(items, g_console.fbo_enabled, currentsetting); set_setting_label_color(items,g_console.fbo_enabled, currentsetting); @@ -199,6 +200,7 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "%fx (X) / %fx (Y)", g_settings.video.fbo_scale_x, g_settings.video.fbo_scale_y); snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - [Custom Scaling Factor] is set to: '%fx (X) / %fx (Y)'.", g_settings.video.fbo_scale_x, g_settings.video.fbo_scale_y); break; +#endif case SETTING_HW_OVERSCAN_AMOUNT: set_setting_label_color(items,g_console.overscan_amount == 0.0f, currentsetting); snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "%f", g_console.overscan_amount); @@ -215,7 +217,9 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current set_setting_label_write_on_or_off(items, g_console.screenshots_enable, currentsetting); set_setting_label_color(items,g_console.screenshots_enable, currentsetting); break; - case SETTING_APPLY_SHADER_PRESET_ON_STARTUP: +#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) + case SETTING_APPLY_SHADER_PRESET_ON_STARTUP: +#endif case SETTING_DEFAULT_VIDEO_ALL: break; case SETTING_SOUND_MODE: @@ -247,10 +251,12 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current break; } break; +#ifdef HAVE_RSOUND case SETTING_RSOUND_SERVER_IP_ADDRESS: set_setting_label_color(items,strcmp(g_settings.audio.device,"0.0.0.0") == 0, currentsetting); snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), g_settings.audio.device); break; +#endif case SETTING_DEFAULT_AUDIO_ALL: break; case SETTING_EMU_CURRENT_SAVE_STATE_SLOT: @@ -379,7 +385,9 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current case SETTING_EMU_AUDIO_DEFAULT_ALL: case SETTING_PATH_DEFAULT_ALL: case SETTING_EMU_DEFAULT_ALL: +#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) case SETTING_SAVE_SHADER_PRESET: +#endif set_setting_label_color(items, current_menu->selected == currentsetting, currentsetting); break; default: @@ -2183,6 +2191,8 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) void menu_init (void) { + DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; + //Set libretro filename and version to variable struct retro_system_info info; retro_get_system_info(&info); @@ -2191,13 +2201,62 @@ void menu_init (void) menu_stack_push(menu_items, FILE_BROWSER_MENU); filebrowser_set_root_and_ext(&browser, rarch_console_get_rom_ext(), default_paths.filebrowser_startup_dir); +#ifdef _XBOX1 + filebrowser_set_root(&tmpBrowser, "D:"); +#else filebrowser_set_root(&tmpBrowser, "/"); +#endif + +#ifdef _XBOX1 + // Set file cache size + XSetFileCacheSize(8 * 1024 * 1024); + + // Mount drives + xbox_io_mount("A:", "cdrom0"); + xbox_io_mount("E:", "Harddisk0\\Partition1"); + xbox_io_mount("Z:", "Harddisk0\\Partition2"); + xbox_io_mount("F:", "Harddisk0\\Partition6"); + xbox_io_mount("G:", "Harddisk0\\Partition7"); + + // Backbuffer width + int width = device_ptr->d3dpp.BackBufferWidth; + + // Quick hack to properly center the romlist in 720p, + // it might need more work though (font size and rom selector size -> needs more memory) + // Init rom list coords + // Load background image + if(width == 640) + { + d3d_surface_new(&m_menuMainBG, "D:\\Media\\menuMainBG.png"); + m_menuMainRomListPos_x = 100; + m_menuMainRomListPos_y = 100; + } + else if(width == 1280) + { + d3d_surface_new(&m_menuMainBG, "D:\\Media\\menuMainBG_720p.png"); + m_menuMainRomListPos_x = 400; + m_menuMainRomListPos_y = 150; + } + + // Load rom selector panel + d3d_surface_new(&m_menuMainRomSelectPanel, "D:\\Media\\menuMainRomSelectPanel.png"); + + //Display some text + //Center the text (hardcoded) + xpos = width == 640 ? 65 : 400; + ypos = width == 640 ? 430 : 670; +#endif } void menu_free (void) { filebrowser_free(&browser); filebrowser_free(&tmpBrowser); + +#ifdef _XBOX1 + d3d_surface_free(&m_menuMainBG); + d3d_surface_free(&m_menuMainRomSelectPanel); +#endif } void menu_loop(void) @@ -2337,7 +2396,9 @@ void menu_loop(void) #endif } +#ifdef __CELLOS_LV2__ rarch_render_cached_frame(); +#endif filebrowser_t * fb = &browser; diff --git a/ps3/frontend/menu.h b/ps3/frontend/menu.h index 969749a101..70f3122f0f 100644 --- a/ps3/frontend/menu.h +++ b/ps3/frontend/menu.h @@ -109,25 +109,35 @@ enum enum { +#ifdef __CELLOS_LV2__ SETTING_CHANGE_RESOLUTION, +#endif +#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) SETTING_SHADER_PRESETS, SETTING_SHADER, SETTING_SHADER_2, +#endif SETTING_FONT_SIZE, SETTING_KEEP_ASPECT_RATIO, SETTING_HW_TEXTURE_FILTER, SETTING_HW_TEXTURE_FILTER_2, +#ifdef HAVE_FBO SETTING_SCALE_ENABLED, SETTING_SCALE_FACTOR, +#endif SETTING_HW_OVERSCAN_AMOUNT, SETTING_THROTTLE_MODE, SETTING_TRIPLE_BUFFERING, SETTING_ENABLE_SCREENSHOTS, +#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) SETTING_SAVE_SHADER_PRESET, SETTING_APPLY_SHADER_PRESET_ON_STARTUP, +#endif SETTING_DEFAULT_VIDEO_ALL, SETTING_SOUND_MODE, +#ifdef HAVE_RSOUND SETTING_RSOUND_SERVER_IP_ADDRESS, +#endif SETTING_ENABLE_CUSTOM_BGM, SETTING_DEFAULT_AUDIO_ALL, SETTING_EMU_CURRENT_SAVE_STATE_SLOT, diff --git a/xbox1/frontend/menu.c b/xbox1/frontend/menu.c index 6b24ff8831..b7bbe1476c 100644 --- a/xbox1/frontend/menu.c +++ b/xbox1/frontend/menu.c @@ -95,12 +95,12 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), ps3_get_resolution_label(g_console.supported_resolutions[g_console.current_resolution_index])); break; #endif +#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) case SETTING_SHADER_PRESETS: set_setting_label_color(items,true, currentsetting); fill_pathname_base(fname, g_console.cgp_path, sizeof(fname)); snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), fname); break; -#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) case SETTING_SHADER: fill_pathname_base(fname, g_settings.video.cg_shader_path, sizeof(fname)); snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "%s", fname); @@ -135,6 +135,7 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current else snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Point filtering"); break; +#ifdef HAVE_FBO case SETTING_SCALE_ENABLED: set_setting_label_write_on_or_off(items, g_console.fbo_enabled, currentsetting); set_setting_label_color(items,g_console.fbo_enabled, currentsetting); @@ -144,6 +145,7 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "%fx (X) / %fx (Y)", g_settings.video.fbo_scale_x, g_settings.video.fbo_scale_y); snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - [Custom Scaling Factor] is set to: '%fx (X) / %fx (Y)'.", g_settings.video.fbo_scale_x, g_settings.video.fbo_scale_y); break; +#endif case SETTING_HW_OVERSCAN_AMOUNT: set_setting_label_color(items,g_console.overscan_amount == 0.0f, currentsetting); snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "%f", g_console.overscan_amount); @@ -160,7 +162,9 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current set_setting_label_write_on_or_off(items, g_console.screenshots_enable, currentsetting); set_setting_label_color(items,g_console.screenshots_enable, currentsetting); break; +#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) case SETTING_APPLY_SHADER_PRESET_ON_STARTUP: +#endif case SETTING_DEFAULT_VIDEO_ALL: break; case SETTING_SOUND_MODE: @@ -192,10 +196,12 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current break; } break; +#ifdef HAVE_RSOUND case SETTING_RSOUND_SERVER_IP_ADDRESS: set_setting_label_color(items,strcmp(g_settings.audio.device,"0.0.0.0") == 0, currentsetting); snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), g_settings.audio.device); break; +#endif case SETTING_DEFAULT_AUDIO_ALL: break; case SETTING_EMU_CURRENT_SAVE_STATE_SLOT: @@ -324,7 +330,9 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current case SETTING_EMU_AUDIO_DEFAULT_ALL: case SETTING_PATH_DEFAULT_ALL: case SETTING_EMU_DEFAULT_ALL: +#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) case SETTING_SAVE_SHADER_PRESET: +#endif set_setting_label_color(items, current_menu->selected == currentsetting, currentsetting); break; default: @@ -730,7 +738,7 @@ static void select_rom(item *items, menu *current_menu, uint64_t input) render_msg_place_func(xpos, ypos, 0, 0, m_title); } -int menu_init(void) +void menu_init(void) { DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; @@ -787,8 +795,6 @@ int menu_init(void) xpos = width == 640 ? 65 : 400; ypos = width == 640 ? 430 : 670; #endif - - return 0; } void menu_free(void) From a32fee16f43b24a2f5d4b289dfc292e085a54e79 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 3 Aug 2012 18:51:56 +0200 Subject: [PATCH 012/492] (PS3) Add _XBOX1 defines to menu.c --- ps3/frontend/menu.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/ps3/frontend/menu.c b/ps3/frontend/menu.c index 7c8cfc0d18..92d6e5d812 100644 --- a/ps3/frontend/menu.c +++ b/ps3/frontend/menu.c @@ -606,7 +606,11 @@ static void display_menubar(menu *current_menu) char current_path[256], rarch_version[128]; float x_position = POSITION_X; +#ifdef _XBOX1 + float font_size = m_menuMainRomListPos_y; +#else float font_size = HARDCODE_FONT_SIZE; +#endif snprintf(rarch_version, sizeof(rarch_version), "v%s", PACKAGE_VERSION); @@ -653,16 +657,26 @@ static void display_menubar(menu *current_menu) fb = &tmpBrowser; case FILE_BROWSER_MENU: snprintf(current_path, sizeof(current_path), "PATH: %s", filebrowser_get_current_dir(fb)); +#ifdef _XBOX1 + render_msg_place_func(x_position, current_y_position, 0, 0, current_path); +#else render_msg_place_func(x_position, 0.09f, FONT_SIZE, YELLOW, current_path); +#endif break; default: break; } +#ifdef _XBOX1 + //Render background image + d3d_surface_render(&m_menuMainBG, MENU_MAIN_BG_X, MENU_MAIN_BG_Y, + m_menuMainBG.m_imageInfo.Width, m_menuMainBG.m_imageInfo.Height); +#else render_msg_place_func(x_position, 0.05f, 1.4f, WHITE, current_menu->title); render_msg_place_func(0.3f, 0.06f, 0.82f, WHITE, m_title); render_msg_place_func(0.8f, 0.12f, 0.82f, WHITE, rarch_version); render_msg_post_func(); +#endif } static void browser_update(filebrowser_t * b, uint64_t input, const char *extensions) @@ -687,6 +701,7 @@ static void browser_update(filebrowser_t * b, uint64_t input, const char *extens else if (input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) { action = FILEBROWSER_ACTION_RESET; + //TODO - Dehardcode this filebrowser_set_root(b, "/"); strlcpy(b->extensions, extensions, sizeof(b->extensions)); } @@ -719,10 +734,22 @@ static void browser_render(filebrowser_t * b, float current_x, float current_y, char fname_tmp[256]; fill_pathname_base(fname_tmp, b->current_dir.list->elems[i].data, sizeof(fname_tmp)); currentY = currentY + ySpacing; + +#ifdef _XBOX1 + //check if this is the currently selected file + const char *current_pathname = filebrowser_get_current_path(b); + if(strcmp(current_pathname, b->current_dir.list->elems[i].data) == 0) + d3d_surface_render(&m_menuMainRomSelectPanel, currentX, currentY, ROM_PANEL_WIDTH, ROM_PANEL_HEIGHT); + + render_msg_place_func(currentX, currentY, 0, 0, fname_tmp); +#else render_msg_place_func(currentX, currentY, FONT_SIZE, i == current_index ? RED : b->current_dir.list->elems[i].attr.b ? GREEN : WHITE, fname_tmp); render_msg_post_func(); +#endif } +#ifndef _XBOX1 render_msg_post_func(); +#endif } #ifdef __CELLOS_LV2__ @@ -2503,6 +2530,10 @@ void menu_loop(void) #ifdef HAVE_SYSUTILS cellSysutilCheckCallback(); #endif +#ifdef _XBOX1 + device_ptr->frame_count++; +#endif + if(current_menu->enum_id == INGAME_MENU_RESIZE && (old_state & (1 << RETRO_DEVICE_ID_JOYPAD_Y)) || current_menu->enum_id == INGAME_MENU_SCREENSHOT) { } else From bc92cbc40aa3f5b56c3b94f4b516dfc601b7ae59 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 3 Aug 2012 19:36:11 +0200 Subject: [PATCH 013/492] (Xbox 1/PS3) more menu compatibility tweaks --- ps3/frontend/menu.c | 24 +++++++++++++++++++++--- xbox1/frontend/menu.c | 2 +- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/ps3/frontend/menu.c b/ps3/frontend/menu.c index 92d6e5d812..182d69b1c7 100644 --- a/ps3/frontend/menu.c +++ b/ps3/frontend/menu.c @@ -51,6 +51,8 @@ #if defined(__CELLOS_LV2__) #include "../../gfx/context/ps3_ctx.h" +#elif defined(_XBOX) +#include "../../gfx/context/xdk_ctx.h" #endif #if defined(HAVE_CG) @@ -607,6 +609,7 @@ static void display_menubar(menu *current_menu) float x_position = POSITION_X; #ifdef _XBOX1 + float current_y_position = m_menuMainRomListPos_y; float font_size = m_menuMainRomListPos_y; #else float font_size = HARDCODE_FONT_SIZE; @@ -2298,6 +2301,7 @@ void menu_loop(void) do { + RARCH_LOG("reaches here #0\n"); //first button input frame uint64_t input_state_first_frame = 0; uint64_t input_state = 0; @@ -2406,6 +2410,8 @@ void menu_loop(void) trig_state = input_state; //second input frame set as current frame } } + + RARCH_LOG("reaches here #1\n"); gfx_ctx_clear(); @@ -2471,6 +2477,8 @@ void menu_loop(void) break; } + RARCH_LOG("reaches here #1.1\n"); + float x_position = POSITION_X; float starting_y_position = POSITION_Y_START; float y_position_increment = POSITION_Y_INCREMENT; @@ -2487,6 +2495,8 @@ void menu_loop(void) } old_state = input_state_first_frame; + + RARCH_LOG("reaches here #1.2\n"); if(IS_TIMER_EXPIRED(device_ptr)) { @@ -2516,6 +2526,7 @@ void menu_loop(void) SET_TIMER_EXPIRATION(device_ptr, 30); } +#ifndef _XBOX1 const char * message = msg_queue_pull(g_extern.msg_queue); float message_y_position = 0.75f; float message_scale = 1.05f; @@ -2525,19 +2536,26 @@ void menu_loop(void) render_msg_place_func(g_settings.video.msg_pos_x, message_y_position, message_scale, WHITE, message); render_msg_post_func(); } +#endif + + RARCH_LOG("reaches here #1.3\n"); gfx_ctx_swap_buffers(); #ifdef HAVE_SYSUTILS cellSysutilCheckCallback(); #endif -#ifdef _XBOX1 - device_ptr->frame_count++; -#endif + RARCH_LOG("reaches here #1.4\n"); +#ifndef _XBOX1 if(current_menu->enum_id == INGAME_MENU_RESIZE && (old_state & (1 << RETRO_DEVICE_ID_JOYPAD_Y)) || current_menu->enum_id == INGAME_MENU_SCREENSHOT) { } else gfx_ctx_set_blend(false); +#endif + + RARCH_LOG("reaches here #1.5\n"); + + RARCH_LOG("reaches here #2\n"); }while(g_console.menu_enable); #ifdef __CELLOS_LV2__ diff --git a/xbox1/frontend/menu.c b/xbox1/frontend/menu.c index b7bbe1476c..090b11be0c 100644 --- a/xbox1/frontend/menu.c +++ b/xbox1/frontend/menu.c @@ -657,7 +657,7 @@ static void browser_render(filebrowser_t *b, float current_x, float current_y, f DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; unsigned file_count = b->current_dir.list->size; - unsigned current_index, page_number, page_base, i; + unsigned int current_index, page_number, page_base, i; float currentX, currentY, ySpacing; current_index = b->current_dir.ptr; From 6071c25905740d67743833e8119f59fa1999a1e4 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 3 Aug 2012 21:06:52 +0200 Subject: [PATCH 014/492] (Xbox 1/PS3) More changes --- ps3/frontend/menu.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ps3/frontend/menu.c b/ps3/frontend/menu.c index 182d69b1c7..2b650600f2 100644 --- a/ps3/frontend/menu.c +++ b/ps3/frontend/menu.c @@ -1818,12 +1818,16 @@ static void select_rom(item *items, menu *current_menu, uint64_t input) display_menubar(current_menu); +#ifdef __CELLOS_LV2__ snprintf(msg, sizeof(msg), "[%s] + [%s] - resume game", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_L3), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R3)); snprintf(msg2, sizeof(msg2), "[%s] - Settings", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_SELECT)); +#endif render_msg_place_func (x_position, comment_two_y_position, FONT_SIZE, YELLOW, msg); render_msg_place_func(x_position, comment_two_y_position + 0.04f, FONT_SIZE, YELLOW, msg2); +#ifdef __CELLOS_LV2__ render_msg_post_func(); +#endif } @@ -2222,6 +2226,7 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) void menu_init (void) { DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; + (void)device_ptr; //Set libretro filename and version to variable struct retro_system_info info; From 0314580bb5792a7006fcd08a262e71f54fc970b7 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 3 Aug 2012 21:25:49 +0200 Subject: [PATCH 015/492] (Xbox 1) Now reuses PS3 menu code --- console/griffin/griffin.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index f5a9cb9804..0f9bb41735 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -284,8 +284,8 @@ MENU #if defined(_XBOX360) #include "../../360/frontend-xdk/menu.cpp" #elif defined(_XBOX1) -#include "../../xbox1/frontend/menu.c" -//#include "../../ps3/frontend/menu.c" +//#include "../../xbox1/frontend/menu.c" +#include "../../ps3/frontend/menu.c" #include "../../xbox1/frontend/RetroLaunch/IoSupport.cpp" #include "../../xbox1/frontend/RetroLaunch/Surface.cpp" #elif defined(GEKKO) From 275fdb104b81e24f127bf604444f192640c15ba5 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 3 Aug 2012 21:22:43 +0200 Subject: [PATCH 016/492] (RMenu) Portable menu code - still WIP --- Makefile.ps3 | 2 +- ps3/frontend/menu.c => console/rmenu/rmenu.c | 34 +- ps3/frontend/menu.h => console/rmenu/rmenu.h | 6 +- .../rmenu/rmenu_entries.h | 2 +- ps3/frontend/main.c | 2 +- xbox1/frontend/menu.c | 1060 ----------------- xdk/frontend/main.c | 7 +- 7 files changed, 19 insertions(+), 1094 deletions(-) rename ps3/frontend/menu.c => console/rmenu/rmenu.c (99%) rename ps3/frontend/menu.h => console/rmenu/rmenu.h (99%) rename ps3/frontend/menu-entries.h => console/rmenu/rmenu_entries.h (99%) delete mode 100644 xbox1/frontend/menu.c diff --git a/Makefile.ps3 b/Makefile.ps3 index 6b941f24e7..33f8c37dd4 100644 --- a/Makefile.ps3 +++ b/Makefile.ps3 @@ -45,7 +45,7 @@ PYTHON2 = python2.exe GIT = git.exe endif -PPU_SRCS = ps3/frontend/main.c ps3/frontend/menu.c +PPU_SRCS = ps3/frontend/main.c console/rmenu/rmenu.c ifeq ($(HAVE_RGL), 1) DEFINES = -DHAVE_RGL diff --git a/ps3/frontend/menu.c b/console/rmenu/rmenu.c similarity index 99% rename from ps3/frontend/menu.c rename to console/rmenu/rmenu.c index 2b650600f2..f18087ad86 100644 --- a/ps3/frontend/menu.c +++ b/console/rmenu/rmenu.c @@ -62,8 +62,8 @@ #include "../../file.h" #include "../../general.h" -#include "menu.h" -#include "menu-entries.h" +#include "rmenu.h" +#include "rmenu_entries.h" #define NUM_ENTRY_PER_PAGE 17 #define INPUT_SCALE 2 @@ -2234,7 +2234,7 @@ void menu_init (void) const char *id = info.library_name ? info.library_name : "Unknown"; snprintf(m_title, sizeof(m_title), "Libretro core: %s %s", id, info.library_version); - menu_stack_push(menu_items, FILE_BROWSER_MENU); + menu_stack_push(rmenu_items, FILE_BROWSER_MENU); filebrowser_set_root_and_ext(&browser, rarch_console_get_rom_ext(), default_paths.filebrowser_startup_dir); #ifdef _XBOX1 filebrowser_set_root(&tmpBrowser, "D:"); @@ -2306,7 +2306,6 @@ void menu_loop(void) do { - RARCH_LOG("reaches here #0\n"); //first button input frame uint64_t input_state_first_frame = 0; uint64_t input_state = 0; @@ -2416,8 +2415,6 @@ void menu_loop(void) } } - RARCH_LOG("reaches here #1\n"); - gfx_ctx_clear(); if(current_menu->enum_id == INGAME_MENU_RESIZE && (trig_state & RETRO_DEVICE_ID_JOYPAD_Y) || current_menu->enum_id == INGAME_MENU_SCREENSHOT) @@ -2443,7 +2440,7 @@ void menu_loop(void) switch(current_menu->enum_id) { case FILE_BROWSER_MENU: - select_rom(menu_items, current_menu, trig_state); + select_rom(rmenu_items, current_menu, trig_state); fb = &browser; break; case GENERAL_VIDEO_MENU: @@ -2453,37 +2450,35 @@ void menu_loop(void) case EMU_AUDIO_MENU: case PATH_MENU: case CONTROLS_MENU: - select_setting(menu_items, current_menu, trig_state); + select_setting(rmenu_items, current_menu, trig_state); break; case SHADER_CHOICE: case PRESET_CHOICE: case BORDER_CHOICE: case LIBRETRO_CHOICE: case INPUT_PRESET_CHOICE: - select_file(menu_items, current_menu, trig_state); + select_file(rmenu_items, current_menu, trig_state); fb = &tmpBrowser; break; case PATH_SAVESTATES_DIR_CHOICE: case PATH_DEFAULT_ROM_DIR_CHOICE: case PATH_CHEATS_DIR_CHOICE: case PATH_SRAM_DIR_CHOICE: - select_directory(menu_items, current_menu, trig_state); + select_directory(rmenu_items, current_menu, trig_state); fb = &tmpBrowser; break; case INGAME_MENU: if(g_console.ingame_menu_enable) - ingame_menu(menu_items, current_menu, trig_state); + ingame_menu(rmenu_items, current_menu, trig_state); break; case INGAME_MENU_RESIZE: - ingame_menu_resize(menu_items, current_menu, trig_state); + ingame_menu_resize(rmenu_items, current_menu, trig_state); break; case INGAME_MENU_SCREENSHOT: - ingame_menu_screenshot(menu_items, current_menu, trig_state); + ingame_menu_screenshot(rmenu_items, current_menu, trig_state); break; } - RARCH_LOG("reaches here #1.1\n"); - float x_position = POSITION_X; float starting_y_position = POSITION_Y_START; float y_position_increment = POSITION_Y_INCREMENT; @@ -2501,8 +2496,6 @@ void menu_loop(void) old_state = input_state_first_frame; - RARCH_LOG("reaches here #1.2\n"); - if(IS_TIMER_EXPIRED(device_ptr)) { // if we want to force goto the emulation loop, skip this @@ -2543,13 +2536,10 @@ void menu_loop(void) } #endif - RARCH_LOG("reaches here #1.3\n"); - gfx_ctx_swap_buffers(); #ifdef HAVE_SYSUTILS cellSysutilCheckCallback(); #endif - RARCH_LOG("reaches here #1.4\n"); #ifndef _XBOX1 if(current_menu->enum_id == INGAME_MENU_RESIZE && (old_state & (1 << RETRO_DEVICE_ID_JOYPAD_Y)) || current_menu->enum_id == INGAME_MENU_SCREENSHOT) @@ -2557,10 +2547,6 @@ void menu_loop(void) else gfx_ctx_set_blend(false); #endif - - RARCH_LOG("reaches here #1.5\n"); - - RARCH_LOG("reaches here #2\n"); }while(g_console.menu_enable); #ifdef __CELLOS_LV2__ diff --git a/ps3/frontend/menu.h b/console/rmenu/rmenu.h similarity index 99% rename from ps3/frontend/menu.h rename to console/rmenu/rmenu.h index 70f3122f0f..2fd8286266 100644 --- a/ps3/frontend/menu.h +++ b/console/rmenu/rmenu.h @@ -14,8 +14,8 @@ * If not, see . */ -#ifndef MENU_H_ -#define MENU_H_ +#ifndef _RMENU_H_ +#define _RMENU_H_ #if defined(__CELLOS_LV2__) #define DEVICE_CAST gl_t* @@ -196,10 +196,8 @@ enum #define MAX_NO_OF_PATH_SETTINGS SETTING_PATH_DEFAULT_ALL+1 #define MAX_NO_OF_CONTROLS_SETTINGS SETTING_CONTROLS_DEFAULT_ALL+1 -#ifndef _XBOX void menu_init (void); void menu_loop (void); void menu_free (void); -#endif #endif /* MENU_H_ */ diff --git a/ps3/frontend/menu-entries.h b/console/rmenu/rmenu_entries.h similarity index 99% rename from ps3/frontend/menu-entries.h rename to console/rmenu/rmenu_entries.h index ce6578e3ad..300b1b991c 100644 --- a/ps3/frontend/menu-entries.h +++ b/console/rmenu/rmenu_entries.h @@ -14,7 +14,7 @@ * If not, see . */ -item menu_items[MAX_NO_OF_CONTROLS_SETTINGS] = +item rmenu_items[MAX_NO_OF_CONTROLS_SETTINGS] = { #ifdef __CELLOS_LV2__ { diff --git a/ps3/frontend/main.c b/ps3/frontend/main.c index 8793363074..2ff2a1e659 100644 --- a/ps3/frontend/main.c +++ b/ps3/frontend/main.c @@ -58,7 +58,7 @@ #include "../../general.h" #include "../../file.h" -#include "menu.h" +#include "../../console/rmenu/rmenu.h" #define EMULATOR_CONTENT_DIR "SSNE10000" diff --git a/xbox1/frontend/menu.c b/xbox1/frontend/menu.c deleted file mode 100644 index 090b11be0c..0000000000 --- a/xbox1/frontend/menu.c +++ /dev/null @@ -1,1060 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2012 - Hans-Kristian Arntzen - * Copyright (C) 2011-2012 - Daniel De Matteis - * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . - */ - -#include "RetroLaunch/IoSupport.h" -#include "RetroLaunch/Surface.h" - -#include "../../ps3/frontend/menu.h" -#include "../../ps3/frontend/menu-entries.h" -#include "../../console/fileio/file_browser.h" - -#include "../../console/rarch_console.h" - -#ifdef _XBOX1 -#include "../../gfx/fonts/xdk1_xfonts.h" - -#define NUM_ENTRY_PER_PAGE 17 - -#define ROM_PANEL_WIDTH 440 -#define ROM_PANEL_HEIGHT 20 - -#define MAIN_TITLE_X 305 -#define MAIN_TITLE_Y 30 -#define MAIN_TITLE_COLOR 0xFFFFFFFF - -#define MENU_MAIN_BG_X 0 -#define MENU_MAIN_BG_Y 0 - -int xpos, ypos; -// Rom selector panel with coords -d3d_surface_t m_menuMainRomSelectPanel; -// Background image with coords -d3d_surface_t m_menuMainBG; - -// Rom list coords -int m_menuMainRomListPos_x; -int m_menuMainRomListPos_y; -#endif - -menu menuStack[10]; -int menuStackindex = 0; - -filebrowser_t browser; -filebrowser_t tmpBrowser; -static unsigned currently_selected_controller_menu = 0; - -char m_title[128]; - -static uint64_t old_state = 0; - -typedef enum { - MENU_ROMSELECT_ACTION_OK, - MENU_ROMSELECT_ACTION_GOTO_SETTINGS, - MENU_ROMSELECT_ACTION_NOOP, -} menu_romselect_action_t; - -static void set_setting_label_write_on_or_off(item *items, bool cond, unsigned currentsetting) -{ - if(cond) - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "ON"); - else - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "OFF"); -} - -static void set_setting_label_color(item *items, bool cond, unsigned currentsetting) -{ - if(cond) - items[currentsetting].text_color = GREEN; - else - items[currentsetting].text_color = ORANGE; -} - -static void set_setting_label(menu * current_menu, item *items, unsigned currentsetting) -{ - char fname[PATH_MAX]; - (void)fname; - - switch(currentsetting) - { -#ifdef __CELLOS_LV2__ - case SETTING_CHANGE_RESOLUTION: - set_setting_label_color(items,g_console.initial_resolution_id == g_console.supported_resolutions[g_console.current_resolution_index], currentsetting); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), ps3_get_resolution_label(g_console.supported_resolutions[g_console.current_resolution_index])); - break; -#endif -#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) - case SETTING_SHADER_PRESETS: - set_setting_label_color(items,true, currentsetting); - fill_pathname_base(fname, g_console.cgp_path, sizeof(fname)); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), fname); - break; - case SETTING_SHADER: - fill_pathname_base(fname, g_settings.video.cg_shader_path, sizeof(fname)); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "%s", fname); - set_setting_label_color(items,strcmp(g_settings.video.cg_shader_path, default_paths.shader_file) == 0, currentsetting); - break; - case SETTING_SHADER_2: - fill_pathname_base(fname, g_settings.video.second_pass_shader, sizeof(fname)); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "%s", fname); - set_setting_label_color(items,strcmp(g_settings.video.second_pass_shader, default_paths.shader_file) == 0, - currentsetting); - break; -#endif - case SETTING_FONT_SIZE: - set_setting_label_color(items,g_console.menu_font_size == 1.0f, currentsetting); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "%f", g_console.menu_font_size); - break; - case SETTING_KEEP_ASPECT_RATIO: - set_setting_label_color(items,g_console.aspect_ratio_index == ASPECT_RATIO_4_3, currentsetting); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), aspectratio_lut[g_console.aspect_ratio_index].name); - break; - case SETTING_HW_TEXTURE_FILTER: - set_setting_label_color(items,g_settings.video.smooth, currentsetting); - if(g_settings.video.smooth) - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Linear interpolation"); - else - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Point filtering"); - break; - case SETTING_HW_TEXTURE_FILTER_2: - set_setting_label_color(items,g_settings.video.second_pass_smooth, currentsetting); - if(g_settings.video.second_pass_smooth) - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Linear interpolation"); - else - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Point filtering"); - break; -#ifdef HAVE_FBO - case SETTING_SCALE_ENABLED: - set_setting_label_write_on_or_off(items, g_console.fbo_enabled, currentsetting); - set_setting_label_color(items,g_console.fbo_enabled, currentsetting); - break; - case SETTING_SCALE_FACTOR: - set_setting_label_color(items,g_settings.video.fbo_scale_x == 2.0f, currentsetting); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "%fx (X) / %fx (Y)", g_settings.video.fbo_scale_x, g_settings.video.fbo_scale_y); - snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - [Custom Scaling Factor] is set to: '%fx (X) / %fx (Y)'.", g_settings.video.fbo_scale_x, g_settings.video.fbo_scale_y); - break; -#endif - case SETTING_HW_OVERSCAN_AMOUNT: - set_setting_label_color(items,g_console.overscan_amount == 0.0f, currentsetting); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "%f", g_console.overscan_amount); - break; - case SETTING_THROTTLE_MODE: - set_setting_label_write_on_or_off(items, g_console.throttle_enable, currentsetting); - set_setting_label_color(items,g_console.throttle_enable, currentsetting); - break; - case SETTING_TRIPLE_BUFFERING: - set_setting_label_write_on_or_off(items, g_console.triple_buffering_enable, currentsetting); - set_setting_label_color(items,g_console.triple_buffering_enable, currentsetting); - break; - case SETTING_ENABLE_SCREENSHOTS: - set_setting_label_write_on_or_off(items, g_console.screenshots_enable, currentsetting); - set_setting_label_color(items,g_console.screenshots_enable, currentsetting); - break; -#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) - case SETTING_APPLY_SHADER_PRESET_ON_STARTUP: -#endif - case SETTING_DEFAULT_VIDEO_ALL: - break; - case SETTING_SOUND_MODE: - switch(g_console.sound_mode) - { - case SOUND_MODE_NORMAL: - snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), - "INFO - [Sound Output] is set to 'Normal' - normal audio output will be\nused."); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Normal"); - items[currentsetting].text_color = GREEN; - break; -#ifdef HAVE_RSOUND - case SOUND_MODE_RSOUND: - snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), - "INFO - [Sound Output] is set to 'RSound' - the sound will be streamed over the\n network to the RSound audio server." ); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "RSound"); - items[currentsetting].text_color = ORANGE; - break; -#endif -#ifdef HAVE_HEADSET - case SOUND_MODE_HEADSET: - snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), - "INFO - [Sound Output] is set to 'USB/Bluetooth Headset' - sound will\n be output through the headset"); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "USB/Bluetooth Headset"); - items[currentsetting].text_color = ORANGE; - break; -#endif - default: - break; - } - break; -#ifdef HAVE_RSOUND - case SETTING_RSOUND_SERVER_IP_ADDRESS: - set_setting_label_color(items,strcmp(g_settings.audio.device,"0.0.0.0") == 0, currentsetting); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), g_settings.audio.device); - break; -#endif - case SETTING_DEFAULT_AUDIO_ALL: - break; - case SETTING_EMU_CURRENT_SAVE_STATE_SLOT: - set_setting_label_color(items,g_extern.state_slot == 0, currentsetting); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "%d", g_extern.state_slot); - break; - /* emu-specific */ - case SETTING_EMU_SHOW_INFO_MSG: - set_setting_label_write_on_or_off(items, g_console.info_msg_enable, currentsetting); - set_setting_label_color(items,g_console.info_msg_enable, currentsetting); - break; - case SETTING_EMU_REWIND_ENABLED: - set_setting_label_write_on_or_off(items, g_settings.rewind_enable, currentsetting); - if(g_settings.rewind_enable) - { - items[currentsetting].text_color = ORANGE; - snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - [Rewind] feature is set to 'ON'. You can rewind the game in real-time."); - } - else - { - items[currentsetting].text_color = GREEN; - snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - [Rewind] feature is set to 'OFF'."); - } - break; - case SETTING_ZIP_EXTRACT: - set_setting_label_color(items,g_console.zip_extract_mode == ZIP_EXTRACT_TO_CURRENT_DIR, currentsetting); - switch(g_console.zip_extract_mode) - { - case ZIP_EXTRACT_TO_CURRENT_DIR: - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Current dir"); - snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - [ZIP Extract Mode] is set to 'Current dir'.\nZIP files are extracted to the current directory."); - break; - case ZIP_EXTRACT_TO_CURRENT_DIR_AND_LOAD_FIRST_FILE: - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Current dir and load first file"); - snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - [ZIP Extract Mode] is set to 'Current dir and load first file'.\nZIP files are extracted to the current directory, and the first game is automatically loaded."); - break; - case ZIP_EXTRACT_TO_CACHE_DIR: - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Cache dir"); - snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - [ZIP Extract Mode] is set to 'Cache dir'.\nZIP files are extracted to the cache directory (dev_hdd1)."); - break; - } - break; - case SETTING_RARCH_DEFAULT_EMU: - fill_pathname_base(fname, g_settings.libretro, sizeof(fname)); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "%s", fname); - items[currentsetting].text_color = GREEN; - break; - case SETTING_EMU_AUDIO_MUTE: - set_setting_label_write_on_or_off(items, g_extern.audio_data.mute, currentsetting); - set_setting_label_color(items,!g_extern.audio_data.mute, currentsetting); - if(g_extern.audio_data.mute) - snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - [Audio Mute] feature is set to 'ON'. The game audio will be muted."); - else - snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - [Audio Mute] feature is set to 'OFF'."); - break; - case SETTING_ENABLE_CUSTOM_BGM: - set_setting_label_write_on_or_off(items, g_console.custom_bgm_enable, currentsetting); - set_setting_label_color(items,g_console.custom_bgm_enable, currentsetting); - break; - case SETTING_PATH_DEFAULT_ROM_DIRECTORY: - set_setting_label_color(items,!(strcmp(g_console.default_rom_startup_dir, "/")), currentsetting); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), g_console.default_rom_startup_dir); - break; - case SETTING_PATH_SAVESTATES_DIRECTORY: - set_setting_label_color(items,!(strcmp(g_console.default_savestate_dir, default_paths.port_dir)), currentsetting); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), g_console.default_savestate_dir); - break; - case SETTING_PATH_SRAM_DIRECTORY: - set_setting_label_color(items,!(strcmp(g_console.default_sram_dir, default_paths.port_dir)), currentsetting); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), g_console.default_sram_dir); - break; - case SETTING_PATH_CHEATS: - set_setting_label_color(items,!(strcmp(g_settings.cheat_database, default_paths.port_dir)), currentsetting); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), g_settings.cheat_database); - break; - case SETTING_PATH_SYSTEM: - set_setting_label_color(items,!(strcmp(g_settings.system_directory, default_paths.system_dir)), currentsetting); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), g_settings.system_directory); - break; - case SETTING_ENABLE_SRAM_PATH: - set_setting_label_write_on_or_off(items, g_console.default_sram_dir_enable, currentsetting); - set_setting_label_color(items,!g_console.default_sram_dir_enable, currentsetting); - break; - case SETTING_ENABLE_STATE_PATH: - set_setting_label_write_on_or_off(items, g_console.default_savestate_dir_enable, currentsetting); - set_setting_label_color(items,!g_console.default_savestate_dir_enable, currentsetting); - break; - case SETTING_CONTROLS_SCHEME: - set_setting_label_color(items,strcmp(g_console.input_cfg_path,"") == 0, currentsetting); - snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - Input scheme preset [%s] is selected.", g_console.input_cfg_path); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), g_console.input_cfg_path); - break; - case SETTING_CONTROLS_NUMBER: - set_setting_label_color(items,currently_selected_controller_menu == 0, currentsetting); - snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "Controller %d is currently selected.", currently_selected_controller_menu+1); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "%d", currently_selected_controller_menu+1); - break; - case SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_B: - case SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_Y: - case SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_SELECT: - case SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_START: - case SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_UP: - case SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_DOWN: - case SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_LEFT: - case SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_RIGHT: - case SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_A: - case SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_X: - case SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_L: - case SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_R: - case SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_L2: - case SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_R2: - case SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_L3: - case SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_R3: - { - set_setting_label_color(items,g_settings.input.binds[currently_selected_controller_menu][currentsetting-(FIRST_CONTROL_BIND)].joykey == rarch_default_keybind_lut[currentsetting-FIRST_CONTROL_BIND], currentsetting); - const char * value = rarch_input_find_platform_key_label(g_settings.input.binds[currently_selected_controller_menu][currentsetting-(FIRST_CONTROL_BIND)].joykey); - unsigned id = currentsetting - FIRST_CONTROL_BIND; - snprintf(items[currentsetting].text, sizeof(items[currentsetting].text), rarch_input_get_default_keybind_name(id)); - snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - [%s] on the PS3 controller is mapped to action:\n[%s].", items[currentsetting].text, value); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), value); - } - break; - case SETTING_CONTROLS_SAVE_CUSTOM_CONTROLS: - case SETTING_CONTROLS_DEFAULT_ALL: - case SETTING_EMU_VIDEO_DEFAULT_ALL: - case SETTING_EMU_AUDIO_DEFAULT_ALL: - case SETTING_PATH_DEFAULT_ALL: - case SETTING_EMU_DEFAULT_ALL: -#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) - case SETTING_SAVE_SHADER_PRESET: -#endif - set_setting_label_color(items, current_menu->selected == currentsetting, currentsetting); - break; - default: - break; - } -} - -static void menu_stack_decrement(void) -{ - if(menuStackindex > 0) - menuStackindex--; -} - -menu *menu_stack_get_current_ptr (void) -{ - menu *current_menu = &menuStack[menuStackindex]; - return current_menu; -} - -static void menu_stack_refresh (item *items, menu *current_menu) -{ - int page, i, j; - float y_position; - float increment_step = POSITION_Y_INCREMENT; - float x_position = POSITION_X; - - page = 0; - j = 0; - y_position = 0.16f; - - for(i = current_menu->first_setting; i < current_menu->max_settings; i++) - { - if(!(j < (NUM_ENTRY_PER_PAGE))) - { - j = 0; - y_position = 0.16f; - page++; - } - - items[i].text_xpos = x_position; - items[i].text_ypos = y_position; - items[i].page = page; - set_setting_label(current_menu, items, i); - y_position += increment_step; - j++; - } -} - -static void menu_stack_push(item *items, unsigned menu_id) -{ - static bool first_push_do_not_increment = true; - bool do_refresh = true; - - if(!first_push_do_not_increment) - menuStackindex++; - else - first_push_do_not_increment = false; - - menu *current_menu = menu_stack_get_current_ptr(); - - switch(menu_id) - { - case INGAME_MENU: - strlcpy(current_menu->title, "Ingame Menu", sizeof(current_menu->title)); - current_menu->enum_id = menu_id; - current_menu->selected = 0; - current_menu->page = 0; - current_menu->category_id = CATEGORY_INGAME_MENU; - break; - case INGAME_MENU_RESIZE: - strlcpy(current_menu->title, "Resize Menu", sizeof(current_menu->title)); - current_menu->enum_id = INGAME_MENU_RESIZE; - current_menu->selected = 0; - current_menu->page = 0; - current_menu->category_id = CATEGORY_INGAME_MENU; - break; - case INGAME_MENU_SCREENSHOT: - strlcpy(current_menu->title, "Ingame Menu", sizeof(current_menu->title)); - current_menu->enum_id = menu_id; - current_menu->selected = 0; - current_menu->page = 0; - current_menu->category_id = CATEGORY_INGAME_MENU; - break; - case FILE_BROWSER_MENU: - strlcpy(current_menu->title, "File Browser", sizeof(current_menu->title)); - current_menu->enum_id = menu_id; - current_menu->selected = 0; - current_menu->page = 0; - current_menu->category_id = CATEGORY_FILEBROWSER; - break; - case LIBRETRO_CHOICE: - strlcpy(current_menu->title, "Libretro cores", sizeof(current_menu->title)); - current_menu->enum_id = menu_id; - current_menu->selected = 0; - current_menu->page = 0; - current_menu->category_id = CATEGORY_FILEBROWSER; - break; - case PRESET_CHOICE: - strlcpy(current_menu->title, "Shader presets", sizeof(current_menu->title)); - current_menu->enum_id = menu_id; - current_menu->selected = 0; - current_menu->page = 0; - current_menu->category_id = CATEGORY_FILEBROWSER; - break; - case INPUT_PRESET_CHOICE: - strlcpy(current_menu->title, "Input presets", sizeof(current_menu->title)); - current_menu->enum_id = menu_id; - current_menu->selected = 0; - current_menu->page = 0; - current_menu->category_id = CATEGORY_FILEBROWSER; - break; - case SHADER_CHOICE: - strlcpy(current_menu->title, "Shaders", sizeof(current_menu->title)); - current_menu->enum_id = menu_id; - current_menu->selected = 0; - current_menu->page = 0; - current_menu->category_id = CATEGORY_FILEBROWSER; - break; - case BORDER_CHOICE: - strlcpy(current_menu->title, "Borders", sizeof(current_menu->title)); - current_menu->enum_id = menu_id; - current_menu->selected = 0; - current_menu->page = 0; - current_menu->category_id = CATEGORY_FILEBROWSER; - break; - case PATH_DEFAULT_ROM_DIR_CHOICE: - case PATH_SAVESTATES_DIR_CHOICE: - case PATH_SRAM_DIR_CHOICE: - case PATH_CHEATS_DIR_CHOICE: - case PATH_SYSTEM_DIR_CHOICE: - strlcpy(current_menu->title, "Path Selection", sizeof(current_menu->title)); - current_menu->enum_id = menu_id; - current_menu->selected = 0; - current_menu->page = 0; - current_menu->category_id = CATEGORY_FILEBROWSER; - break; - case GENERAL_VIDEO_MENU: - strlcpy(current_menu->title, "Video", sizeof(current_menu->title)); - current_menu->enum_id = GENERAL_VIDEO_MENU; - current_menu->selected = FIRST_VIDEO_SETTING; - current_menu->page = 0; - current_menu->first_setting = FIRST_VIDEO_SETTING; - current_menu->max_settings = MAX_NO_OF_VIDEO_SETTINGS; - current_menu->category_id = CATEGORY_SETTINGS; - break; - case GENERAL_AUDIO_MENU: - strlcpy(current_menu->title, "Audio", sizeof(current_menu->title)); - current_menu->enum_id = GENERAL_AUDIO_MENU; - current_menu->selected = FIRST_AUDIO_SETTING; - current_menu->page = 0; - current_menu->first_setting = FIRST_AUDIO_SETTING; - current_menu->max_settings = MAX_NO_OF_AUDIO_SETTINGS; - current_menu->category_id = CATEGORY_SETTINGS; - break; - case EMU_GENERAL_MENU: - strlcpy(current_menu->title, "Retro", sizeof(current_menu->title)); - current_menu->enum_id = EMU_GENERAL_MENU; - current_menu->selected = FIRST_EMU_SETTING; - current_menu->page = 0; - current_menu->first_setting = FIRST_EMU_SETTING; - current_menu->max_settings = MAX_NO_OF_EMU_SETTINGS; - current_menu->category_id = CATEGORY_SETTINGS; - break; - case EMU_VIDEO_MENU: - strlcpy(current_menu->title, "Retro Video", sizeof(current_menu->title)); - current_menu->enum_id = EMU_VIDEO_MENU; - current_menu->selected = FIRST_EMU_VIDEO_SETTING; - current_menu->page = 0; - current_menu->first_setting = FIRST_EMU_VIDEO_SETTING; - current_menu->max_settings = MAX_NO_OF_EMU_VIDEO_SETTINGS; - current_menu->category_id = CATEGORY_SETTINGS; - break; - case EMU_AUDIO_MENU: - strlcpy(current_menu->title, "Retro Audio", sizeof(current_menu->title)); - current_menu->enum_id = EMU_AUDIO_MENU; - current_menu->selected = FIRST_EMU_AUDIO_SETTING; - current_menu->page = 0; - current_menu->first_setting = FIRST_EMU_AUDIO_SETTING; - current_menu->max_settings = MAX_NO_OF_EMU_AUDIO_SETTINGS; - current_menu->category_id = CATEGORY_SETTINGS; - break; - case PATH_MENU: - strlcpy(current_menu->title, "Path", sizeof(current_menu->title)); - current_menu->enum_id = PATH_MENU; - current_menu->selected = FIRST_PATH_SETTING; - current_menu->page = 0; - current_menu->first_setting = FIRST_PATH_SETTING; - current_menu->max_settings = MAX_NO_OF_PATH_SETTINGS; - current_menu->category_id = CATEGORY_SETTINGS; - break; - case CONTROLS_MENU: - strlcpy(current_menu->title, "Controls", sizeof(current_menu->title)); - current_menu->enum_id = CONTROLS_MENU; - current_menu->selected = FIRST_CONTROLS_SETTING_PAGE_1; - current_menu->page = 0; - current_menu->first_setting = FIRST_CONTROLS_SETTING_PAGE_1; - current_menu->max_settings = MAX_NO_OF_CONTROLS_SETTINGS; - current_menu->category_id = CATEGORY_SETTINGS; - break; - default: - do_refresh = false; - break; - } - - if(do_refresh) - menu_stack_refresh(items, current_menu); -} - -static void display_menubar(menu *current_menu) -{ - DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; - filebrowser_t *fb = &browser; - char current_path[256], rarch_version[128]; - - float x_position = POSITION_X; - float current_y_position = POSITION_Y_START; -#ifdef _XBOX1 - float font_size = m_menuMainRomListPos_y; -#else - float font_size = 0.91f; -#endif - - snprintf(rarch_version, sizeof(rarch_version), "v%s", PACKAGE_VERSION); - - switch(current_menu->enum_id) - { - case GENERAL_VIDEO_MENU: - render_msg_place_func(x_position, 0.03f, font_size, WHITE, "NEXT ->"); - break; - case GENERAL_AUDIO_MENU: - case EMU_GENERAL_MENU: - case EMU_VIDEO_MENU: - case EMU_AUDIO_MENU: - case PATH_MENU: - render_msg_place_func(x_position, 0.03f, font_size, WHITE, "<- PREV | NEXT ->"); - break; - case CONTROLS_MENU: - case INGAME_MENU_RESIZE: - case SHADER_CHOICE: - case PRESET_CHOICE: - case BORDER_CHOICE: - case LIBRETRO_CHOICE: - case INPUT_PRESET_CHOICE: - case PATH_SAVESTATES_DIR_CHOICE: - case PATH_DEFAULT_ROM_DIR_CHOICE: - case PATH_CHEATS_DIR_CHOICE: - case PATH_SRAM_DIR_CHOICE: - render_msg_place_func(x_position, 0.03f, font_size, WHITE, "<- PREV"); - break; - default: - break; - } - - switch(current_menu->enum_id) - { - case SHADER_CHOICE: - case PRESET_CHOICE: - case BORDER_CHOICE: - case LIBRETRO_CHOICE: - case INPUT_PRESET_CHOICE: - case PATH_SAVESTATES_DIR_CHOICE: - case PATH_DEFAULT_ROM_DIR_CHOICE: - case PATH_CHEATS_DIR_CHOICE: - case PATH_SRAM_DIR_CHOICE: - fb = &tmpBrowser; - case FILE_BROWSER_MENU: - snprintf(current_path, sizeof(current_path), "PATH: %s", filebrowser_get_current_dir(fb)); -#ifdef _XBOX1 - render_msg_place_func(x_position, current_y_position, 0, 0, current_path); -#else - render_msg_place_func(x_position, 0.09f, FONT_SIZE, YELLOW, current_path); -#endif - break; - default: - break; - } - -#ifdef _XBOX1 - //Render background image - d3d_surface_render(&m_menuMainBG, MENU_MAIN_BG_X, MENU_MAIN_BG_Y, - m_menuMainBG.m_imageInfo.Width, m_menuMainBG.m_imageInfo.Height); -#else - render_msg_place_func(x_position, 0.05f, 1.4f, WHITE, current_menu->title); - render_msg_place_func(0.3f, 0.06f, 0.82f, WHITE, m_title); - render_msg_place_func(0.8f, 0.12f, 0.82f, WHITE, rarch_version); - render_msg_post_func(); -#endif -} - -static void browser_update(filebrowser_t * b, uint16_t input, const char *extensions) -{ - filebrowser_action_t action = FILEBROWSER_ACTION_NOOP; - - if (input & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)) - action = FILEBROWSER_ACTION_DOWN; - else if (input & (1 << RETRO_DEVICE_ID_JOYPAD_UP)) - action = FILEBROWSER_ACTION_UP; - else if (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) - action = FILEBROWSER_ACTION_RIGHT; - else if (input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) - action = FILEBROWSER_ACTION_LEFT; - else if (input & (1 << RETRO_DEVICE_ID_JOYPAD_R)) - action = FILEBROWSER_ACTION_SCROLL_DOWN; - else if (input & (1 << RETRO_DEVICE_ID_JOYPAD_L)) - action = FILEBROWSER_ACTION_SCROLL_UP; - else if (input & (1 << RETRO_DEVICE_ID_JOYPAD_A)) - action = FILEBROWSER_ACTION_CANCEL; - else if (input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) - { - action = FILEBROWSER_ACTION_RESET; - //TODO - Dehardcode this - filebrowser_set_root(b, "/"); - strlcpy(b->extensions, extensions, sizeof(b->extensions)); - } - - if(action != FILEBROWSER_ACTION_NOOP) - filebrowser_iterate(b, action); -} - -static void browser_render(filebrowser_t *b, float current_x, float current_y, float y_spacing) -{ - DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; - - unsigned file_count = b->current_dir.list->size; - unsigned int current_index, page_number, page_base, i; - float currentX, currentY, ySpacing; - - current_index = b->current_dir.ptr; - page_number = current_index / NUM_ENTRY_PER_PAGE; - page_base = page_number * NUM_ENTRY_PER_PAGE; - - currentX = current_x; - currentY = current_y; - ySpacing = y_spacing; - - for (i = page_base; i < file_count && i < page_base + NUM_ENTRY_PER_PAGE; ++i) - { - char fname_tmp[256]; - fill_pathname_base(fname_tmp, b->current_dir.list->elems[i].data, sizeof(fname_tmp)); - currentY = currentY + ySpacing; - -#ifdef _XBOX1 - //check if this is the currently selected file - const char *current_pathname = filebrowser_get_current_path(b); - if(strcmp(current_pathname, b->current_dir.list->elems[i].data) == 0) - d3d_surface_render(&m_menuMainRomSelectPanel, currentX, currentY, ROM_PANEL_WIDTH, ROM_PANEL_HEIGHT); - - render_msg_place_func(currentX, currentY, 0, 0, fname_tmp); -#else - render_msg_place_func(currentX, currentY, FONT_SIZE, i == current_index ? RED : b->current_dir.list->elems[i].attr.b ? GREEN : WHITE, fname_tmp); - render_msg_post_func(); -#endif - } -#ifndef _XBOX1 - render_msg_post_func(); -#endif -} - -static void menu_romselect_iterate(filebrowser_t *filebrowser, item *items, menu_romselect_action_t action) -{ - bool ret = true; - - switch(action) - { - case MENU_ROMSELECT_ACTION_OK: - if(filebrowser_get_current_path_isdir(filebrowser)) - ret = filebrowser_iterate(filebrowser, FILEBROWSER_ACTION_OK); - else - rarch_console_load_game_wrap(filebrowser_get_current_path(filebrowser), g_console.zip_extract_mode, S_DELAY_45); - break; - case MENU_ROMSELECT_ACTION_GOTO_SETTINGS: - menu_stack_push(items, GENERAL_VIDEO_MENU); - break; - default: - break; - } - - if(!ret) - rarch_settings_msg(S_MSG_DIR_LOADING_ERROR, S_DELAY_180); -} - -static void select_rom(item *items, menu *current_menu, uint64_t input) -{ - DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; - - browser_update(&browser, input, rarch_console_get_rom_ext()); - - menu_romselect_action_t action = MENU_ROMSELECT_ACTION_NOOP; - - if (input & (1 << RETRO_DEVICE_ID_JOYPAD_B)) - action = MENU_ROMSELECT_ACTION_OK; - else if (input & (1 << RETRO_DEVICE_ID_JOYPAD_R3)) - { - LD_LAUNCH_DASHBOARD LaunchData = { XLD_LAUNCH_DASHBOARD_MAIN_MENU }; - XLaunchNewImage( NULL, (LAUNCH_DATA*)&LaunchData ); - } - - if (action != MENU_ROMSELECT_ACTION_NOOP) - menu_romselect_iterate(&browser, items, action); - - display_menubar(current_menu); - - render_msg_place_func(xpos, ypos, 0, 0, m_title); -} - -void menu_init(void) -{ - DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; - - // Set libretro filename and version to variable - struct retro_system_info info; - retro_get_system_info(&info); - const char *id = info.library_name ? info.library_name : "Unknown"; - snprintf(m_title, sizeof(m_title), "Libretro core: %s %s", id, info.library_version); - - menu_stack_push(menu_items, FILE_BROWSER_MENU); - filebrowser_set_root_and_ext(&browser, rarch_console_get_rom_ext(), g_console.default_rom_startup_dir); -#ifdef _XBOX1 - filebrowser_set_root(&tmpBrowser, "D:"); -#else - filebrowser_set_root(&tmpBrowser, "/"); -#endif - -#ifdef _XBOX1 - // Set file cache size - XSetFileCacheSize(8 * 1024 * 1024); - - // Mount drives - xbox_io_mount("A:", "cdrom0"); - xbox_io_mount("E:", "Harddisk0\\Partition1"); - xbox_io_mount("Z:", "Harddisk0\\Partition2"); - xbox_io_mount("F:", "Harddisk0\\Partition6"); - xbox_io_mount("G:", "Harddisk0\\Partition7"); - - // Backbuffer width - int width = device_ptr->d3dpp.BackBufferWidth; - - // Quick hack to properly center the romlist in 720p, - // it might need more work though (font size and rom selector size -> needs more memory) - // Init rom list coords - // Load background image - if(width == 640) - { - d3d_surface_new(&m_menuMainBG, "D:\\Media\\menuMainBG.png"); - m_menuMainRomListPos_x = 100; - m_menuMainRomListPos_y = 100; - } - else if(width == 1280) - { - d3d_surface_new(&m_menuMainBG, "D:\\Media\\menuMainBG_720p.png"); - m_menuMainRomListPos_x = 400; - m_menuMainRomListPos_y = 150; - } - - // Load rom selector panel - d3d_surface_new(&m_menuMainRomSelectPanel, "D:\\Media\\menuMainRomSelectPanel.png"); - - //Display some text - //Center the text (hardcoded) - xpos = width == 640 ? 65 : 400; - ypos = width == 640 ? 430 : 670; -#endif -} - -void menu_free(void) -{ - filebrowser_free(&browser); - filebrowser_free(&tmpBrowser); - -#ifdef _XBOX1 - d3d_surface_free(&m_menuMainBG); - d3d_surface_free(&m_menuMainRomSelectPanel); -#endif -} - -void menu_loop(void) -{ - DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; - - g_console.menu_enable = true; - device_ptr->block_swap = true; - - if(g_console.ingame_menu_enable) - menu_stack_push(ingame_menu_settings, INGAME_MENU); - - do - { - //first button input frame - uint64_t input_state_first_frame = 0; - uint64_t input_state = 0; - static bool first_held = false; - menu *current_menu = menu_stack_get_current_ptr(); - - input_ptr.poll(NULL); - - static const struct retro_keybind *binds[MAX_PLAYERS] = { - g_settings.input.binds[0], - g_settings.input.binds[1], - g_settings.input.binds[2], - g_settings.input.binds[3], - g_settings.input.binds[4], - g_settings.input.binds[5], - g_settings.input.binds[6], - g_settings.input.binds[7], - }; - - static const struct retro_keybind _analog_binds[] = { - { 0, 0, (enum retro_key)0, (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_LEFT), 0 }, - { 0, 0, (enum retro_key)0, (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_RIGHT), 0 }, - { 0, 0, (enum retro_key)0, (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_UP), 0 }, - { 0, 0, (enum retro_key)0, (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_DOWN), 0 }, - { 0, 0, (enum retro_key)0, (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_LEFT), 0 }, - { 0, 0, (enum retro_key)0, (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_RIGHT), 0 }, - { 0, 0, (enum retro_key)0, (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_UP), 0 }, - { 0, 0, (enum retro_key)0, (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_DOWN), 0 }, - }; - - const struct retro_keybind *analog_binds[] = { - _analog_binds - }; - - for (unsigned i = 0; i < RARCH_FIRST_META_KEY; i++) - { - input_state |= input_ptr.input_state(NULL, binds, false, - RETRO_DEVICE_JOYPAD, 0, i) ? (1 << i) : 0; - } - - input_state |= input_ptr.input_state(NULL, analog_binds, false, - RETRO_DEVICE_JOYPAD, 0, 0) ? (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_LEFT) : 0; - input_state |= input_ptr.input_state(NULL, analog_binds, false, - RETRO_DEVICE_JOYPAD, 0, 1) ? (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_RIGHT) : 0; - input_state |= input_ptr.input_state(NULL, analog_binds, false, - RETRO_DEVICE_JOYPAD, 0, 2) ? (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_UP) : 0; - input_state |= input_ptr.input_state(NULL, analog_binds, false, - RETRO_DEVICE_JOYPAD, 0, 3) ? (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_DOWN) : 0; - - input_state |= input_ptr.input_state(NULL, analog_binds, false, - RETRO_DEVICE_JOYPAD, 0, 4) ? (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_LEFT) : 0; - input_state |= input_ptr.input_state(NULL, analog_binds, false, - RETRO_DEVICE_JOYPAD, 0, 5) ? (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_RIGHT) : 0; - input_state |= input_ptr.input_state(NULL, analog_binds, false, - RETRO_DEVICE_JOYPAD, 0, 6) ? (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_UP) : 0; - input_state |= input_ptr.input_state(NULL, analog_binds, false, - RETRO_DEVICE_JOYPAD, 0, 7) ? (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_DOWN) : 0; - - uint64_t trig_state = input_state & ~old_state; //set first button input frame as trigger - input_state_first_frame = input_state; //hold onto first button input frame - - //second button input frame - input_state = 0; - input_ptr.poll(NULL); - - - for (unsigned i = 0; i < RARCH_FIRST_META_KEY; i++) - { - input_state |= input_ptr.input_state(NULL, binds, false, - RETRO_DEVICE_JOYPAD, 0, i) ? (1 << i) : 0; - } - - input_state |= input_ptr.input_state(NULL, analog_binds, false, - RETRO_DEVICE_JOYPAD, 0, 0) ? (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_LEFT) : 0; - input_state |= input_ptr.input_state(NULL, analog_binds, false, - RETRO_DEVICE_JOYPAD, 0, 1) ? (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_RIGHT) : 0; - input_state |= input_ptr.input_state(NULL, analog_binds, false, - RETRO_DEVICE_JOYPAD, 0, 2) ? (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_UP) : 0; - input_state |= input_ptr.input_state(NULL, analog_binds, false, - RETRO_DEVICE_JOYPAD, 0, 3) ? (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_DOWN) : 0; - - input_state |= input_ptr.input_state(NULL, analog_binds, false, - RETRO_DEVICE_JOYPAD, 0, 4) ? (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_LEFT) : 0; - input_state |= input_ptr.input_state(NULL, analog_binds, false, - RETRO_DEVICE_JOYPAD, 0, 5) ? (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_RIGHT) : 0; - input_state |= input_ptr.input_state(NULL, analog_binds, false, - RETRO_DEVICE_JOYPAD, 0, 6) ? (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_UP) : 0; - input_state |= input_ptr.input_state(NULL, analog_binds, false, - RETRO_DEVICE_JOYPAD, 0, 7) ? (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_DOWN) : 0; - - bool analog_sticks_pressed = (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_LEFT)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_RIGHT)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_UP)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_DOWN)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_LEFT)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_RIGHT)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_UP)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_DOWN)); - bool shoulder_buttons_pressed = ((input_state & (1 << RETRO_DEVICE_ID_JOYPAD_L2)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_R2))) /*&& current_menu->category_id != CATEGORY_SETTINGS*/; - bool do_held = analog_sticks_pressed || shoulder_buttons_pressed; - - if(do_held) - { - if(!first_held) - { - first_held = true; - SET_TIMER_EXPIRATION(device_ptr, 7); - } - - if(IS_TIMER_EXPIRED(device_ptr)) - { - first_held = false; - trig_state = input_state; //second input frame set as current frame - } - } - - gfx_ctx_clear(); -#ifdef _XBOX1 - device_ptr->frame_count++; -#endif - - if(current_menu->enum_id == INGAME_MENU_RESIZE && (trig_state & RETRO_DEVICE_ID_JOYPAD_Y) || current_menu->enum_id == INGAME_MENU_SCREENSHOT) - { -#ifdef __CELLOS_LV2__ - device_ptr->menu_render = false; -#endif - } - else - { - gfx_ctx_set_blend(true); -#ifdef __CELLOS_LV2__ - device_ptr->menu_render = true; -#endif - } - - filebrowser_t * fb = &browser; - - switch(current_menu->enum_id) - { - case FILE_BROWSER_MENU: - select_rom(menu_items, current_menu, trig_state); - fb = &browser; - break; - case GENERAL_VIDEO_MENU: - case GENERAL_AUDIO_MENU: - case EMU_GENERAL_MENU: - case EMU_VIDEO_MENU: - case EMU_AUDIO_MENU: - case PATH_MENU: - case CONTROLS_MENU: - //select_setting(menu_items, current_menu, trig_state); - break; - case SHADER_CHOICE: - case PRESET_CHOICE: - case BORDER_CHOICE: - case LIBRETRO_CHOICE: - case INPUT_PRESET_CHOICE: - //select_file(menu_items, current_menu, trig_state); - fb = &tmpBrowser; - break; - case PATH_SAVESTATES_DIR_CHOICE: - case PATH_DEFAULT_ROM_DIR_CHOICE: - case PATH_CHEATS_DIR_CHOICE: - case PATH_SRAM_DIR_CHOICE: - //select_directory(menu_items, current_menu, trig_state); - fb = &tmpBrowser; - break; - case INGAME_MENU: - //if(g_console.ingame_menu_enable) - //ingame_menu(menu_items, current_menu, trig_state); - break; - case INGAME_MENU_RESIZE: - //ingame_menu_resize(menu_items, current_menu, trig_state); - break; - case INGAME_MENU_SCREENSHOT: - //ingame_menu_screenshot(menu_items, current_menu, trig_state); - break; - } - - float x_position = POSITION_X; - float starting_y_position = POSITION_Y_START; - float y_position_increment = POSITION_Y_INCREMENT; - - switch(current_menu->category_id) - { - case CATEGORY_FILEBROWSER: - browser_render(fb, x_position, starting_y_position, y_position_increment); - break; - case CATEGORY_SETTINGS: - case CATEGORY_INGAME_MENU: - default: - break; - } - - old_state = input_state_first_frame; - - if(IS_TIMER_EXPIRED(device_ptr)) - { - // if we want to force goto the emulation loop, skip this - if(g_console.mode_switch != MODE_EMULATION) - { - // for ingame menu, we need a different precondition because menu_enable - // can be set to false when going back from ingame menu to menu - if(g_console.ingame_menu_enable == true) - { - //we want to force exit when mode_switch is set to MODE_EXIT - if(g_console.mode_switch != MODE_EXIT) - g_console.mode_switch = (((old_state & (1 << RETRO_DEVICE_ID_JOYPAD_L3)) && (old_state & (1 << RETRO_DEVICE_ID_JOYPAD_R3)) && g_console.emulator_initialized)) ? MODE_EMULATION : MODE_MENU; - } - else - { - g_console.menu_enable = !(((old_state & (1 << RETRO_DEVICE_ID_JOYPAD_L3)) && (old_state & (1 << RETRO_DEVICE_ID_JOYPAD_R3)) && g_console.emulator_initialized)); - g_console.mode_switch = g_console.menu_enable ? MODE_MENU : MODE_EMULATION; - } - } - } - - // set a timer delay so that we don't instantly switch back to the menu when - // press and holding L3 + R3 in the emulation loop (lasts for 30 frame ticks) - if(g_console.mode_switch == MODE_EMULATION && !g_console.frame_advance_enable) - { - SET_TIMER_EXPIRATION(device_ptr, 30); - } - - gfx_ctx_swap_buffers(); -#ifdef HAVE_SYSUTILS - cellSysutilCheckCallback(); -#endif - if(current_menu->enum_id == INGAME_MENU_RESIZE && (old_state & (1 << RETRO_DEVICE_ID_JOYPAD_Y)) || current_menu->enum_id == INGAME_MENU_SCREENSHOT) - { } - else - gfx_ctx_set_blend(false); - }while(g_console.menu_enable); - -#ifdef __CELLOS_LV2__ - device_ptr->menu_render = false; -#endif - - if(g_console.ingame_menu_enable) - menu_stack_decrement(); - - device_ptr->block_swap = false; - - g_console.ingame_menu_enable = false; -} diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index 87c824148b..3b4d8bd779 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -20,11 +20,12 @@ #include #include -#include "../../xdk/menu_shared.h" - -#ifdef _XBOX360 +#if defined(_XBOX360) #include #include "../../360/frontend-xdk/menu.h" +#include "../../xdk/menu_shared.h" +#elif defined(_XBOX1) +#include "../../console/rmenu/rmenu.h" #endif #include From b40dc9e1a7a7bffedddc5cabb0614b81697a0061 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 3 Aug 2012 21:41:07 +0200 Subject: [PATCH 017/492] (RMenu) Some cleanups --- console/griffin/griffin.c | 3 +-- console/rmenu/rmenu.c | 11 +---------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index 0f9bb41735..85c45889ac 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -284,8 +284,7 @@ MENU #if defined(_XBOX360) #include "../../360/frontend-xdk/menu.cpp" #elif defined(_XBOX1) -//#include "../../xbox1/frontend/menu.c" -#include "../../ps3/frontend/menu.c" +#include "../rmenu/rmenu.c" #include "../../xbox1/frontend/RetroLaunch/IoSupport.cpp" #include "../../xbox1/frontend/RetroLaunch/Surface.cpp" #elif defined(GEKKO) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index f18087ad86..b4f1a2b39e 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -74,18 +74,9 @@ #include "../../xbox1/frontend/RetroLaunch/Surface.h" #include "../../gfx/fonts/xdk1_xfonts.h" -#define NUM_ENTRY_PER_PAGE 17 - #define ROM_PANEL_WIDTH 440 #define ROM_PANEL_HEIGHT 20 -#define MAIN_TITLE_X 305 -#define MAIN_TITLE_Y 30 -#define MAIN_TITLE_COLOR 0xFFFFFFFF - -#define MENU_MAIN_BG_X 0 -#define MENU_MAIN_BG_Y 0 - int xpos, ypos; // Rom selector panel with coords d3d_surface_t m_menuMainRomSelectPanel; @@ -672,7 +663,7 @@ static void display_menubar(menu *current_menu) #ifdef _XBOX1 //Render background image - d3d_surface_render(&m_menuMainBG, MENU_MAIN_BG_X, MENU_MAIN_BG_Y, + d3d_surface_render(&m_menuMainBG, 0, 0, m_menuMainBG.m_imageInfo.Width, m_menuMainBG.m_imageInfo.Height); #else render_msg_place_func(x_position, 0.05f, 1.4f, WHITE, current_menu->title); From ed0bda6869afb5694f481b4a3cba55e3fecd4150 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 4 Aug 2012 01:49:59 +0200 Subject: [PATCH 018/492] (xbox 1) Have most menus work on xbox 1 - font placement needs work --- console/rmenu/rmenu.c | 35 ++++++++++++++++++++++++++++++++++- xbox1/xdk_d3d8.cpp | 2 ++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index b4f1a2b39e..b1ba9c47dc 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -1726,8 +1726,9 @@ static void select_setting(item *items, menu *current_menu, uint64_t input) producesettingentry(current_menu, items, current_menu->selected, input); display_menubar(current_menu); +#ifdef __CELLOS_LV2__ render_msg_post_func(); - +#endif for(i = current_menu->first_setting; i < current_menu->max_settings; i++) { @@ -1735,7 +1736,9 @@ static void select_setting(item *items, menu *current_menu, uint64_t input) { render_msg_place_func(items[i].text_xpos, items[i].text_ypos, FONT_SIZE, current_menu->selected == items[i].enum_id ? YELLOW : items[i].item_color, items[i].text); render_msg_place_func(x_position_center, items[i].text_ypos, FONT_SIZE, items[i].text_color, items[i].setting_text); +#ifdef __CELLOS_LV2__ render_msg_post_func(); +#endif } } @@ -1745,7 +1748,9 @@ static void select_setting(item *items, menu *current_menu, uint64_t input) render_msg_place_func(x_position, comment_two_y_position, FONT_SIZE, YELLOW, msg); snprintf(msg, sizeof(msg), "[%s] - default | [%s]/[%s] - go back", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_START), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_L), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_A)); render_msg_place_func(x_position, comment_two_y_position + 0.04f, FONT_SIZE, YELLOW, msg); +#ifdef __CELLOS_LV2__ render_msg_post_func(); +#endif } static void menu_romselect_iterate(filebrowser_t *filebrowser, item *items, menu_romselect_action_t action) @@ -1913,7 +1918,9 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) render_msg_place_func (x_position, y_position+(y_position_increment*5), font_size, LIGHTBLUE, msg); render_msg_place_func (x_position_center, y_position+(y_position_increment*5), font_size, LIGHTBLUE, "- Decrease Viewport X"); +#ifdef __CELLOS_LV2__ render_msg_post_func(); +#endif snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_RIGHT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_RIGHT)); render_msg_place_func (x_position, y_position+(y_position_increment*6), font_size, LIGHTBLUE, msg); @@ -1923,7 +1930,9 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) render_msg_place_func (x_position, y_position+(y_position_increment*7), font_size, LIGHTBLUE, msg); render_msg_place_func (x_position_center, y_position+(y_position_increment*7), font_size, LIGHTBLUE, "- Increase Viewport Y"); +#ifdef __CELLOS_LV2__ render_msg_post_func(); +#endif snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_DOWN), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_DOWN)); render_msg_place_func (x_position, y_position+(y_position_increment*8), font_size, LIGHTBLUE, msg); @@ -1933,7 +1942,9 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) render_msg_place_func (x_position, y_position+(y_position_increment*9), font_size, LIGHTBLUE, msg); render_msg_place_func (x_position_center, y_position+(y_position_increment*9), font_size, LIGHTBLUE, "- Decrease Viewport Width"); +#ifdef __CELLOS_LV2__ render_msg_post_func(); +#endif snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_RIGHT)); render_msg_place_func (x_position, y_position+(y_position_increment*10), font_size, LIGHTBLUE, msg); @@ -1943,7 +1954,9 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) render_msg_place_func (x_position, y_position+(y_position_increment*11), font_size, LIGHTBLUE, msg); render_msg_place_func (x_position_center, y_position+(y_position_increment*11), font_size, LIGHTBLUE, "- Increase Viewport Height"); +#ifdef __CELLOS_LV2__ render_msg_post_func(); +#endif snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R2), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_DOWN)); render_msg_place_func (x_position, y_position+(y_position_increment*12), font_size, LIGHTBLUE, msg); @@ -1961,11 +1974,15 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) render_msg_place_func (x_position, y_position+(y_position_increment*15), font_size, LIGHTBLUE, msg); render_msg_place_func (x_position_center, y_position+(y_position_increment*15), font_size, LIGHTBLUE, "- Return to Ingame Menu"); +#ifdef __CELLOS_LV2__ render_msg_post_func(); +#endif snprintf(msg, sizeof(msg), "Allows you to resize the screen by moving around the two analog sticks.\nPress [%s] to reset to defaults, and [%s] to go back.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_X), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_A)); render_msg_place_func (x_position, comment_y_position, font_size, LIGHTBLUE, msg); +#ifdef __CELLOS_LV2__ render_msg_post_func(); +#endif } } @@ -2166,7 +2183,9 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) rarch_settings_create_menu_item_label(strw_buffer, S_LBL_SAVE_STATE_SLOT, sizeof(strw_buffer)); render_msg_place_func(x_position, y_position+(y_position_increment*MENU_ITEM_SAVE_STATE), font_size, MENU_ITEM_SELECTED(MENU_ITEM_SAVE_STATE), strw_buffer); +#ifdef __CELLOS_LV2__ render_msg_post_func(); +#endif rarch_settings_create_menu_item_label(strw_buffer, S_LBL_ASPECT_RATIO, sizeof(strw_buffer)); render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_KEEP_ASPECT_RATIO)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_KEEP_ASPECT_RATIO), strw_buffer); @@ -2176,7 +2195,9 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) rarch_settings_create_menu_item_label(strw_buffer, S_LBL_ROTATION, sizeof(strw_buffer)); render_msg_place_func (x_position, (y_position+(y_position_increment*MENU_ITEM_ORIENTATION)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_ORIENTATION), strw_buffer); +#ifdef __CELLOS_LV2__ render_msg_post_func(); +#endif #ifdef HAVE_FBO rarch_settings_create_menu_item_label(strw_buffer, S_LBL_SCALE_FACTOR, sizeof(strw_buffer)); @@ -2190,28 +2211,40 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_SCREENSHOT_MODE)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_SCREENSHOT_MODE), "Screenshot Mode"); +#ifdef __CELLOS_LV2__ render_msg_post_func(); +#endif render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_RESET)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_RESET), "Reset"); render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_RETURN_TO_GAME)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_RETURN_TO_GAME), "Return to Game"); +#ifdef __CELLOS_LV2__ render_msg_post_func(); +#endif render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_RETURN_TO_MENU)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_RETURN_TO_MENU), "Return to Menu"); +#ifdef __CELLOS_LV2__ render_msg_post_func(); +#endif render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_CHANGE_LIBRETRO)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_CHANGE_LIBRETRO), "Change libretro core"); +#ifdef __CELLOS_LV2__ render_msg_post_func(); +#endif #ifdef HAVE_MULTIMAN render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_RETURN_TO_MULTIMAN)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_RETURN_TO_MULTIMAN), "Return to multiMAN"); #endif render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_RETURN_TO_DASHBOARD)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_RETURN_TO_DASHBOARD), "Return to XMB"); +#ifdef __CELLOS_LV2__ render_msg_post_func(); +#endif render_msg_place_func(x_position, comment_y_position, font_size, LIGHTBLUE, comment); +#ifdef __CELLOS_LV2__ render_msg_post_func(); +#endif } void menu_init (void) diff --git a/xbox1/xdk_d3d8.cpp b/xbox1/xdk_d3d8.cpp index 221a194de3..bc24944732 100644 --- a/xbox1/xdk_d3d8.cpp +++ b/xbox1/xdk_d3d8.cpp @@ -165,11 +165,13 @@ static void xdk_d3d_set_rotation(void * data, unsigned orientation) break; } + /* D3DXMATRIX p_out; D3DXMatrixIdentity(&p_out); d3d->d3d_render_device->SetTransform(D3DTS_PROJECTION, &p_out); d3d->should_resize = TRUE; + */ } static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **input, void **input_data) From ab3b97cb408cb36b1618f833962d2cd61f730134 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sat, 4 Aug 2012 02:06:46 +0200 Subject: [PATCH 019/492] (PS3) Clean up RMenu - don't use 'post' font functions --- console/rmenu/rmenu.c | 68 -------------------------------------- console/rmenu/rmenu.h | 6 +--- gfx/fonts/ps3_libdbgfont.c | 5 ++- gfx/fonts/xdk1_xfonts.c | 4 ++- gfx/gl_font.h | 2 +- 5 files changed, 9 insertions(+), 76 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index b1ba9c47dc..0e60d9bd73 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -669,7 +669,6 @@ static void display_menubar(menu *current_menu) render_msg_place_func(x_position, 0.05f, 1.4f, WHITE, current_menu->title); render_msg_place_func(0.3f, 0.06f, 0.82f, WHITE, m_title); render_msg_place_func(0.8f, 0.12f, 0.82f, WHITE, rarch_version); - render_msg_post_func(); #endif } @@ -738,12 +737,8 @@ static void browser_render(filebrowser_t * b, float current_x, float current_y, render_msg_place_func(currentX, currentY, 0, 0, fname_tmp); #else render_msg_place_func(currentX, currentY, FONT_SIZE, i == current_index ? RED : b->current_dir.list->elems[i].attr.b ? GREEN : WHITE, fname_tmp); - render_msg_post_func(); #endif } -#ifndef _XBOX1 - render_msg_post_func(); -#endif } #ifdef __CELLOS_LV2__ @@ -879,7 +874,6 @@ static void select_file(item *items, menu *current_menu, uint64_t input) snprintf(comment_two, sizeof(comment_two), "[%s] - return to settings [%s] - Reset Startdir", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_X), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_START)); render_msg_place_func(x_position, comment_two_y_position, font_size, YELLOW, comment_two); render_msg_place_func(x_position, comment_y_position, font_size, LIGHTBLUE, comment); - render_msg_post_func(); } static void select_directory(item *items, menu *current_menu, uint64_t input) @@ -960,7 +954,6 @@ static void select_directory(item *items, menu *current_menu, uint64_t input) snprintf(msg, sizeof(msg), "INFO - Browse to a directory and assign it as the path by\npressing [%s].", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_Y)); render_msg_place_func(x_position, comment_y_position, font_size, LIGHTBLUE, msg); - render_msg_post_func(); } static void set_keybind_digital(uint64_t default_retro_joypad_id, uint64_t input) @@ -1726,9 +1719,6 @@ static void select_setting(item *items, menu *current_menu, uint64_t input) producesettingentry(current_menu, items, current_menu->selected, input); display_menubar(current_menu); -#ifdef __CELLOS_LV2__ - render_msg_post_func(); -#endif for(i = current_menu->first_setting; i < current_menu->max_settings; i++) { @@ -1736,9 +1726,6 @@ static void select_setting(item *items, menu *current_menu, uint64_t input) { render_msg_place_func(items[i].text_xpos, items[i].text_ypos, FONT_SIZE, current_menu->selected == items[i].enum_id ? YELLOW : items[i].item_color, items[i].text); render_msg_place_func(x_position_center, items[i].text_ypos, FONT_SIZE, items[i].text_color, items[i].setting_text); -#ifdef __CELLOS_LV2__ - render_msg_post_func(); -#endif } } @@ -1748,9 +1735,6 @@ static void select_setting(item *items, menu *current_menu, uint64_t input) render_msg_place_func(x_position, comment_two_y_position, FONT_SIZE, YELLOW, msg); snprintf(msg, sizeof(msg), "[%s] - default | [%s]/[%s] - go back", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_START), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_L), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_A)); render_msg_place_func(x_position, comment_two_y_position + 0.04f, FONT_SIZE, YELLOW, msg); -#ifdef __CELLOS_LV2__ - render_msg_post_func(); -#endif } static void menu_romselect_iterate(filebrowser_t *filebrowser, item *items, menu_romselect_action_t action) @@ -1821,9 +1805,6 @@ static void select_rom(item *items, menu *current_menu, uint64_t input) render_msg_place_func (x_position, comment_two_y_position, FONT_SIZE, YELLOW, msg); render_msg_place_func(x_position, comment_two_y_position + 0.04f, FONT_SIZE, YELLOW, msg2); -#ifdef __CELLOS_LV2__ - render_msg_post_func(); -#endif } @@ -1918,10 +1899,6 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) render_msg_place_func (x_position, y_position+(y_position_increment*5), font_size, LIGHTBLUE, msg); render_msg_place_func (x_position_center, y_position+(y_position_increment*5), font_size, LIGHTBLUE, "- Decrease Viewport X"); -#ifdef __CELLOS_LV2__ - render_msg_post_func(); -#endif - snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_RIGHT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_RIGHT)); render_msg_place_func (x_position, y_position+(y_position_increment*6), font_size, LIGHTBLUE, msg); render_msg_place_func (x_position_center, y_position+(y_position_increment*6), font_size, LIGHTBLUE, "- Increase Viewport X"); @@ -1930,10 +1907,6 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) render_msg_place_func (x_position, y_position+(y_position_increment*7), font_size, LIGHTBLUE, msg); render_msg_place_func (x_position_center, y_position+(y_position_increment*7), font_size, LIGHTBLUE, "- Increase Viewport Y"); -#ifdef __CELLOS_LV2__ - render_msg_post_func(); -#endif - snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_DOWN), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_DOWN)); render_msg_place_func (x_position, y_position+(y_position_increment*8), font_size, LIGHTBLUE, msg); render_msg_place_func (x_position_center, y_position+(y_position_increment*8), font_size, LIGHTBLUE, "- Decrease Viewport Y"); @@ -1942,10 +1915,6 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) render_msg_place_func (x_position, y_position+(y_position_increment*9), font_size, LIGHTBLUE, msg); render_msg_place_func (x_position_center, y_position+(y_position_increment*9), font_size, LIGHTBLUE, "- Decrease Viewport Width"); -#ifdef __CELLOS_LV2__ - render_msg_post_func(); -#endif - snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_RIGHT)); render_msg_place_func (x_position, y_position+(y_position_increment*10), font_size, LIGHTBLUE, msg); render_msg_place_func (x_position_center, y_position+(y_position_increment*10), font_size, LIGHTBLUE, "- Increase Viewport Width"); @@ -1954,9 +1923,6 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) render_msg_place_func (x_position, y_position+(y_position_increment*11), font_size, LIGHTBLUE, msg); render_msg_place_func (x_position_center, y_position+(y_position_increment*11), font_size, LIGHTBLUE, "- Increase Viewport Height"); -#ifdef __CELLOS_LV2__ - render_msg_post_func(); -#endif snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R2), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_DOWN)); render_msg_place_func (x_position, y_position+(y_position_increment*12), font_size, LIGHTBLUE, msg); @@ -1974,15 +1940,8 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) render_msg_place_func (x_position, y_position+(y_position_increment*15), font_size, LIGHTBLUE, msg); render_msg_place_func (x_position_center, y_position+(y_position_increment*15), font_size, LIGHTBLUE, "- Return to Ingame Menu"); -#ifdef __CELLOS_LV2__ - render_msg_post_func(); -#endif - snprintf(msg, sizeof(msg), "Allows you to resize the screen by moving around the two analog sticks.\nPress [%s] to reset to defaults, and [%s] to go back.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_X), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_A)); render_msg_place_func (x_position, comment_y_position, font_size, LIGHTBLUE, msg); -#ifdef __CELLOS_LV2__ - render_msg_post_func(); -#endif } } @@ -2183,9 +2142,6 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) rarch_settings_create_menu_item_label(strw_buffer, S_LBL_SAVE_STATE_SLOT, sizeof(strw_buffer)); render_msg_place_func(x_position, y_position+(y_position_increment*MENU_ITEM_SAVE_STATE), font_size, MENU_ITEM_SELECTED(MENU_ITEM_SAVE_STATE), strw_buffer); -#ifdef __CELLOS_LV2__ - render_msg_post_func(); -#endif rarch_settings_create_menu_item_label(strw_buffer, S_LBL_ASPECT_RATIO, sizeof(strw_buffer)); render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_KEEP_ASPECT_RATIO)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_KEEP_ASPECT_RATIO), strw_buffer); @@ -2195,14 +2151,10 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) rarch_settings_create_menu_item_label(strw_buffer, S_LBL_ROTATION, sizeof(strw_buffer)); render_msg_place_func (x_position, (y_position+(y_position_increment*MENU_ITEM_ORIENTATION)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_ORIENTATION), strw_buffer); -#ifdef __CELLOS_LV2__ - render_msg_post_func(); -#endif #ifdef HAVE_FBO rarch_settings_create_menu_item_label(strw_buffer, S_LBL_SCALE_FACTOR, sizeof(strw_buffer)); render_msg_place_func (x_position, (y_position+(y_position_increment*MENU_ITEM_SCALE_FACTOR)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_SCALE_FACTOR), strw_buffer); - render_msg_post_func(); #endif render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_RESIZE_MODE)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_RESIZE_MODE), "Resize Mode"); @@ -2211,40 +2163,21 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_SCREENSHOT_MODE)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_SCREENSHOT_MODE), "Screenshot Mode"); -#ifdef __CELLOS_LV2__ - render_msg_post_func(); -#endif - render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_RESET)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_RESET), "Reset"); render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_RETURN_TO_GAME)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_RETURN_TO_GAME), "Return to Game"); -#ifdef __CELLOS_LV2__ - render_msg_post_func(); -#endif render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_RETURN_TO_MENU)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_RETURN_TO_MENU), "Return to Menu"); -#ifdef __CELLOS_LV2__ - render_msg_post_func(); -#endif render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_CHANGE_LIBRETRO)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_CHANGE_LIBRETRO), "Change libretro core"); -#ifdef __CELLOS_LV2__ - render_msg_post_func(); -#endif #ifdef HAVE_MULTIMAN render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_RETURN_TO_MULTIMAN)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_RETURN_TO_MULTIMAN), "Return to multiMAN"); #endif render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_RETURN_TO_DASHBOARD)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_RETURN_TO_DASHBOARD), "Return to XMB"); -#ifdef __CELLOS_LV2__ - render_msg_post_func(); -#endif render_msg_place_func(x_position, comment_y_position, font_size, LIGHTBLUE, comment); -#ifdef __CELLOS_LV2__ - render_msg_post_func(); -#endif } void menu_init (void) @@ -2556,7 +2489,6 @@ void menu_loop(void) if (message && g_console.info_msg_enable) { render_msg_place_func(g_settings.video.msg_pos_x, message_y_position, message_scale, WHITE, message); - render_msg_post_func(); } #endif diff --git a/console/rmenu/rmenu.h b/console/rmenu/rmenu.h index 2fd8286266..0e8d58329f 100644 --- a/console/rmenu/rmenu.h +++ b/console/rmenu/rmenu.h @@ -24,9 +24,7 @@ #define DEVICE_PTR device_ptr #define HARDCODE_FONT_SIZE 0.91f #define FONT_SIZE (g_console.menu_font_size) -#define render_msg_pre_func() gl_render_msg_pre(DEVICE_PTR) -#define render_msg_place_func(xpos, ypos, scale, color, msg) gl_render_msg_place(xpos, ypos, scale, color, msg) -#define render_msg_post_func() gl_render_msg_post(DEVICE_PTR) +#define render_msg_place_func(xpos, ypos, scale, color, msg) gl_render_msg_place(DEVICE_PTR, xpos, ypos, scale, color, msg) #define POSITION_X 0.09f #define POSITION_Y_START 0.10f @@ -40,9 +38,7 @@ #define DEVICE_PTR device_ptr #define HARDCODE_FONT_SIZE 21 #define FONT_SIZE 21 -#define render_msg_pre_func() xfonts_render_msg_pre(DEVICE_PTR) #define render_msg_place_func(xpos, ypos, scale, color, msg) xfonts_render_msg_place(DEVICE_PTR, xpos, ypos, scale, msg) -#define render_msg_post_func() xfonts_render_msg_post(DEVICE_PTR) #define POSITION_X m_menuMainRomListPos_x #define POSITION_Y_START m_menuMainRomListPos_y diff --git a/gfx/fonts/ps3_libdbgfont.c b/gfx/fonts/ps3_libdbgfont.c index 16dd72375c..eb9d81a0a9 100644 --- a/gfx/fonts/ps3_libdbgfont.c +++ b/gfx/fonts/ps3_libdbgfont.c @@ -42,9 +42,12 @@ void gl_render_msg(gl_t *gl, const char *msg) cellDbgFontPrintf(g_settings.video.msg_pos_x, 0.75f, 1.05f, WHITE, msg); } -void gl_render_msg_place(float x, float y, float scale, uint32_t color, const char *msg) +void gl_render_msg_place(void *data, float x, float y, float scale, uint32_t color, const char *msg) { + gl_t *gl = (gl_t*)data; + cellDbgFontPrintf(x, y, scale, color, msg); + gl_render_msg_post(gl); } void gl_render_msg_post(gl_t *gl) diff --git a/gfx/fonts/xdk1_xfonts.c b/gfx/fonts/xdk1_xfonts.c index 264eb63961..d5cd337173 100644 --- a/gfx/fonts/xdk1_xfonts.c +++ b/gfx/fonts/xdk1_xfonts.c @@ -28,8 +28,10 @@ void xfonts_render_msg_pre(xdk_d3d_video_t *d3d) d3d->d3d_render_device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &d3d->pBackBuffer); } -void xfonts_render_msg_place(xdk_d3d_video_t *d3d, float x, float y, float scale, const char *msg) +void xfonts_render_msg_place(void *data, float x, float y, float scale, const char *msg) { + xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)data; + xfonts_render_msg_pre(d3d); wchar_t str[256]; diff --git a/gfx/gl_font.h b/gfx/gl_font.h index 45790d199f..25db371b67 100644 --- a/gfx/gl_font.h +++ b/gfx/gl_font.h @@ -24,7 +24,7 @@ void gl_render_msg(gl_t *gl, const char *msg); void gl_render_msg_post(gl_t *gl); #ifdef RARCH_CONSOLE -void gl_render_msg_place(float x, float y, float scale, uint32_t color, const char *msg); +void gl_render_msg_place(void *data, float x, float y, float scale, uint32_t color, const char *msg); #endif #endif From 17780cb5a82f3f219896484b6d33f336d4278ac4 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sat, 4 Aug 2012 02:28:38 +0200 Subject: [PATCH 020/492] (Rmenu/fonts) no longer use gl_render_msg_post --- gfx/fonts/freetype.c | 32 +++++++++++++------------------- gfx/fonts/ps3_libdbgfont.c | 13 +++++-------- gfx/fonts/xdk1_xfonts.c | 13 ++----------- gfx/fonts/xdk1_xfonts.h | 2 -- gfx/gl.c | 3 --- gfx/gl_font.h | 3 +-- xbox1/xdk_d3d8.cpp | 3 --- 7 files changed, 21 insertions(+), 48 deletions(-) diff --git a/gfx/fonts/freetype.c b/gfx/fonts/freetype.c index ac649782aa..6c9f1cdb0a 100644 --- a/gfx/fonts/freetype.c +++ b/gfx/fonts/freetype.c @@ -225,27 +225,10 @@ extern const GLfloat white_color[]; #endif -void gl_render_msg_post(gl_t *gl) -{ -#ifdef HAVE_FREETYPE - // Go back to old rendering path. - glTexCoordPointer(2, GL_FLOAT, 0, gl->tex_coords); - glVertexPointer(2, GL_FLOAT, 0, vertexes_flipped); - glColorPointer(4, GL_FLOAT, 0, white_color); - glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); - - glDisable(GL_BLEND); - - struct gl_ortho ortho = {0, 1, 0, 1, -1, 1}; - gl_set_projection(gl, &ortho, true); -#else - (void)gl; -#endif -} - -void gl_render_msg(gl_t *gl, const char *msg) +void gl_render_msg(void *data, const char *msg) { #ifdef HAVE_FREETYPE + gl_t *gl = (gl_t*)data; if (!gl->font) return; @@ -287,6 +270,17 @@ void gl_render_msg(gl_t *gl, const char *msg) glVertexPointer(2, GL_FLOAT, 0, font_vertex); glColorPointer(4, GL_FLOAT, 0, gl->font_color); glDrawArrays(GL_QUADS, 0, 4); + + // Post - Go back to old rendering path. + glTexCoordPointer(2, GL_FLOAT, 0, gl->tex_coords); + glVertexPointer(2, GL_FLOAT, 0, vertexes_flipped); + glColorPointer(4, GL_FLOAT, 0, white_color); + glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); + + glDisable(GL_BLEND); + + struct gl_ortho ortho = {0, 1, 0, 1, -1, 1}; + gl_set_projection(gl, &ortho, true); #else (void)gl; (void)msg; diff --git a/gfx/fonts/ps3_libdbgfont.c b/gfx/fonts/ps3_libdbgfont.c index eb9d81a0a9..17586eea87 100644 --- a/gfx/fonts/ps3_libdbgfont.c +++ b/gfx/fonts/ps3_libdbgfont.c @@ -36,21 +36,18 @@ void gl_deinit_font(gl_t *gl) cellDbgFontExit(); } -void gl_render_msg(gl_t *gl, const char *msg) +void gl_render_msg(void *data, const char *msg) { + (void)data; + cellDbgFontPrintf(g_settings.video.msg_pos_x, 0.75f, 1.06f, SILVER, msg); cellDbgFontPrintf(g_settings.video.msg_pos_x, 0.75f, 1.05f, WHITE, msg); } void gl_render_msg_place(void *data, float x, float y, float scale, uint32_t color, const char *msg) { - gl_t *gl = (gl_t*)data; + (void)data; cellDbgFontPrintf(x, y, scale, color, msg); - gl_render_msg_post(gl); -} - -void gl_render_msg_post(gl_t *gl) -{ - cellDbgFontDraw(); + cellDbgFontDraw(); //post } diff --git a/gfx/fonts/xdk1_xfonts.c b/gfx/fonts/xdk1_xfonts.c index d5cd337173..8d6793778f 100644 --- a/gfx/fonts/xdk1_xfonts.c +++ b/gfx/fonts/xdk1_xfonts.c @@ -22,17 +22,12 @@ void xfonts_deinit_font(void) { } -void xfonts_render_msg_pre(xdk_d3d_video_t *d3d) -{ - d3d->d3d_render_device->GetBackBuffer(-1, D3DBACKBUFFER_TYPE_MONO, &d3d->pFrontBuffer); - d3d->d3d_render_device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &d3d->pBackBuffer); -} - void xfonts_render_msg_place(void *data, float x, float y, float scale, const char *msg) { xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)data; - xfonts_render_msg_pre(d3d); + d3d->d3d_render_device->GetBackBuffer(-1, D3DBACKBUFFER_TYPE_MONO, &d3d->pFrontBuffer); + d3d->d3d_render_device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &d3d->pBackBuffer); wchar_t str[256]; convert_char_to_wchar(str, msg, sizeof(str)); @@ -40,10 +35,6 @@ void xfonts_render_msg_place(void *data, float x, float y, float scale, const ch d3d->debug_font->TextOut(d3d->pBackBuffer, str, (unsigned)-1, x, y); xfonts_render_msg_post(d3d); -} - -void xfonts_render_msg_post(xdk_d3d_video_t *d3d) -{ d3d->pFrontBuffer->Release(); d3d->pBackBuffer->Release(); } diff --git a/gfx/fonts/xdk1_xfonts.h b/gfx/fonts/xdk1_xfonts.h index fd804a986f..2d01dcbe1b 100644 --- a/gfx/fonts/xdk1_xfonts.h +++ b/gfx/fonts/xdk1_xfonts.h @@ -18,8 +18,6 @@ #define RARCH_XDK1_FONTS_H void xfonts_deinit_font(void); -void xfonts_render_msg_pre(xdk_d3d_video_t *d3d); void xfonts_render_msg_place(xdk_d3d_video_t *d3d, float x, float y, float scale, const char *msg); -void xfonts_render_msg_post(xdk_d3d_video_t *d3d); #endif diff --git a/gfx/gl.c b/gfx/gl.c index 93494a1e94..0c836d7bf5 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -931,10 +931,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei gl_next_texture_index(gl, &tex_info); if (msg) - { gl_render_msg(gl, msg); - gl_render_msg_post(gl); - } #ifndef RARCH_CONSOLE gfx_ctx_update_window_title(false); diff --git a/gfx/gl_font.h b/gfx/gl_font.h index 25db371b67..d83091072c 100644 --- a/gfx/gl_font.h +++ b/gfx/gl_font.h @@ -20,8 +20,7 @@ void gl_init_font(gl_t *gl, const char *font_path, unsigned font_size); void gl_deinit_font(gl_t *gl); -void gl_render_msg(gl_t *gl, const char *msg); -void gl_render_msg_post(gl_t *gl); +void gl_render_msg(void *data, const char *msg); #ifdef RARCH_CONSOLE void gl_render_msg_place(void *data, float x, float y, float scale, uint32_t color, const char *msg); diff --git a/xbox1/xdk_d3d8.cpp b/xbox1/xdk_d3d8.cpp index bc24944732..1212c0da33 100644 --- a/xbox1/xdk_d3d8.cpp +++ b/xbox1/xdk_d3d8.cpp @@ -452,7 +452,6 @@ static bool xdk_d3d_frame(void *data, const void *frame, { static MEMORYSTATUS stat; GlobalMemoryStatus(&stat); - xfonts_render_msg_pre(d3d); //Output memory usage @@ -471,8 +470,6 @@ static bool xdk_d3d_frame(void *data, const void *frame, } else if(buf_fps_last) xfonts_render_msg_place(d3d, font_x + 30, font_y + 70, 0 /* scale */, buf2); - - xfonts_render_msg_post(d3d); } } From 1cb896d0b65534dee1462c827184aac30155b7b4 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 4 Aug 2012 02:44:02 +0200 Subject: [PATCH 021/492] (Xbox 1) Rmenu build fix --- gfx/fonts/xdk1_xfonts.c | 1 - gfx/fonts/xdk1_xfonts.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/gfx/fonts/xdk1_xfonts.c b/gfx/fonts/xdk1_xfonts.c index 8d6793778f..3d65ede8ad 100644 --- a/gfx/fonts/xdk1_xfonts.c +++ b/gfx/fonts/xdk1_xfonts.c @@ -34,7 +34,6 @@ void xfonts_render_msg_place(void *data, float x, float y, float scale, const ch d3d->debug_font->TextOut(d3d->pFrontBuffer, str, (unsigned)-1, x, y); d3d->debug_font->TextOut(d3d->pBackBuffer, str, (unsigned)-1, x, y); - xfonts_render_msg_post(d3d); d3d->pFrontBuffer->Release(); d3d->pBackBuffer->Release(); } diff --git a/gfx/fonts/xdk1_xfonts.h b/gfx/fonts/xdk1_xfonts.h index 2d01dcbe1b..a90c5be0b0 100644 --- a/gfx/fonts/xdk1_xfonts.h +++ b/gfx/fonts/xdk1_xfonts.h @@ -18,6 +18,6 @@ #define RARCH_XDK1_FONTS_H void xfonts_deinit_font(void); -void xfonts_render_msg_place(xdk_d3d_video_t *d3d, float x, float y, float scale, const char *msg); +void xfonts_render_msg_place(void *data, float x, float y, float scale, const char *msg); #endif From d1ae6e41b6a5b6f008cd97a56fa20c8260c970aa Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 4 Aug 2012 03:11:49 +0200 Subject: [PATCH 022/492] (Rmenu / Xbox 1) Highlighter for selected item in settings/ingame menu --- console/rmenu/rmenu.c | 14 ++++++++++---- console/rmenu/rmenu.h | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index 0e60d9bd73..0e5d799ecc 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -176,6 +176,7 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current else snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Point filtering"); break; +#ifdef HAVE_FBO case SETTING_HW_TEXTURE_FILTER_2: set_setting_label_color(items,g_settings.video.second_pass_smooth, currentsetting); if(g_settings.video.second_pass_smooth) @@ -183,7 +184,6 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current else snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Point filtering"); break; -#ifdef HAVE_FBO case SETTING_SCALE_ENABLED: set_setting_label_write_on_or_off(items, g_console.fbo_enabled, currentsetting); set_setting_label_color(items,g_console.fbo_enabled, currentsetting); @@ -1186,6 +1186,7 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch gfx_ctx_set_filtering(1, g_settings.video.smooth); } break; +#ifdef HAVE_FBO case SETTING_HW_TEXTURE_FILTER_2: if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { @@ -1198,7 +1199,6 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch gfx_ctx_set_filtering(2, g_settings.video.second_pass_smooth); } break; -#ifdef HAVE_FBO case SETTING_SCALE_ENABLED: if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { @@ -1726,6 +1726,10 @@ static void select_setting(item *items, menu *current_menu, uint64_t input) { render_msg_place_func(items[i].text_xpos, items[i].text_ypos, FONT_SIZE, current_menu->selected == items[i].enum_id ? YELLOW : items[i].item_color, items[i].text); render_msg_place_func(x_position_center, items[i].text_ypos, FONT_SIZE, items[i].text_color, items[i].setting_text); +#ifdef _XBOX1 + if(current_menu->selected == items[i].enum_id) + d3d_surface_render(&m_menuMainRomSelectPanel, x_position, items[i].text_ypos, ROM_PANEL_WIDTH, ROM_PANEL_HEIGHT); +#endif } } @@ -2178,6 +2182,10 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_RETURN_TO_DASHBOARD)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_RETURN_TO_DASHBOARD), "Return to XMB"); render_msg_place_func(x_position, comment_y_position, font_size, LIGHTBLUE, comment); + +#ifdef _XBOX1 + d3d_surface_render(&m_menuMainRomSelectPanel, x_position, (y_position+(y_position_increment*g_console.ingame_menu_item)), ROM_PANEL_WIDTH, ROM_PANEL_HEIGHT); +#endif } void menu_init (void) @@ -2497,12 +2505,10 @@ void menu_loop(void) cellSysutilCheckCallback(); #endif -#ifndef _XBOX1 if(current_menu->enum_id == INGAME_MENU_RESIZE && (old_state & (1 << RETRO_DEVICE_ID_JOYPAD_Y)) || current_menu->enum_id == INGAME_MENU_SCREENSHOT) { } else gfx_ctx_set_blend(false); -#endif }while(g_console.menu_enable); #ifdef __CELLOS_LV2__ diff --git a/console/rmenu/rmenu.h b/console/rmenu/rmenu.h index 0e8d58329f..7031243d0f 100644 --- a/console/rmenu/rmenu.h +++ b/console/rmenu/rmenu.h @@ -116,8 +116,8 @@ enum SETTING_FONT_SIZE, SETTING_KEEP_ASPECT_RATIO, SETTING_HW_TEXTURE_FILTER, - SETTING_HW_TEXTURE_FILTER_2, #ifdef HAVE_FBO + SETTING_HW_TEXTURE_FILTER_2, SETTING_SCALE_ENABLED, SETTING_SCALE_FACTOR, #endif From 41ff7bb1fcd0d6ab5d214eb5717957bd2b92092d Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 4 Aug 2012 03:28:31 +0200 Subject: [PATCH 023/492] (RMenu) Trim down messages to fit on Xbox 1 screen (640x480 assumed) --- console/rmenu/rmenu.c | 44 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index 0e5d799ecc..c805234185 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -1901,36 +1901,36 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_LEFT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_LEFT)); render_msg_place_func (x_position, y_position+(y_position_increment*5), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*5), font_size, LIGHTBLUE, "- Decrease Viewport X"); + render_msg_place_func (x_position_center, y_position+(y_position_increment*5), font_size, LIGHTBLUE, "- Viewport X --"); snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_RIGHT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_RIGHT)); render_msg_place_func (x_position, y_position+(y_position_increment*6), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*6), font_size, LIGHTBLUE, "- Increase Viewport X"); + render_msg_place_func (x_position_center, y_position+(y_position_increment*6), font_size, LIGHTBLUE, "- Viewport X ++"); snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_UP), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_UP)); render_msg_place_func (x_position, y_position+(y_position_increment*7), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*7), font_size, LIGHTBLUE, "- Increase Viewport Y"); + render_msg_place_func (x_position_center, y_position+(y_position_increment*7), font_size, LIGHTBLUE, "- Viewport Y ++"); snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_DOWN), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_DOWN)); render_msg_place_func (x_position, y_position+(y_position_increment*8), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*8), font_size, LIGHTBLUE, "- Decrease Viewport Y"); + render_msg_place_func (x_position_center, y_position+(y_position_increment*8), font_size, LIGHTBLUE, "- Viewport Y --"); snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_L), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_LEFT)); render_msg_place_func (x_position, y_position+(y_position_increment*9), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*9), font_size, LIGHTBLUE, "- Decrease Viewport Width"); + render_msg_place_func (x_position_center, y_position+(y_position_increment*9), font_size, LIGHTBLUE, "- Viewport Width --"); snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_RIGHT)); render_msg_place_func (x_position, y_position+(y_position_increment*10), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*10), font_size, LIGHTBLUE, "- Increase Viewport Width"); + render_msg_place_func (x_position_center, y_position+(y_position_increment*10), font_size, LIGHTBLUE, "- Viewport Width ++"); snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_L2), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_UP)); render_msg_place_func (x_position, y_position+(y_position_increment*11), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*11), font_size, LIGHTBLUE, "- Increase Viewport Height"); + render_msg_place_func (x_position_center, y_position+(y_position_increment*11), font_size, LIGHTBLUE, "- Viewport Height ++"); snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R2), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_DOWN)); render_msg_place_func (x_position, y_position+(y_position_increment*12), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*12), font_size, LIGHTBLUE, "- Decrease Viewport Height"); + render_msg_place_func (x_position_center, y_position+(y_position_increment*12), font_size, LIGHTBLUE, "- Viewport Height --"); snprintf(msg, sizeof(msg), "[%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_X)); render_msg_place_func (x_position, y_position+(y_position_increment*13), font_size, LIGHTBLUE, msg); @@ -2003,7 +2003,7 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) if(input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) rarch_state_slot_increase(); - snprintf(comment, sizeof(comment), "Press [%s] or [%s] to change the current save state slot.\nPress [%s] to load the state from the current state slot.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_LEFT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_RIGHT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); + snprintf(comment, sizeof(comment), "Press [%s] / [%s] to change slots.\nPress [%s] to load the state from the current state slot.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_LEFT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_RIGHT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); break; case MENU_ITEM_SAVE_STATE: if(input & (1 << RETRO_DEVICE_ID_JOYPAD_B)) @@ -2017,15 +2017,15 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) if(input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) rarch_state_slot_increase(); - snprintf(comment, sizeof(comment), "Press [%s] or [%s] to change the current save state slot.\nPress [%s] to save the state to the current state slot.",rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_LEFT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_RIGHT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); + snprintf(comment, sizeof(comment), "Press [%s] / [%s] to change slots.\nPress [%s] to save the state to the current state slot.",rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_LEFT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_RIGHT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); break; case MENU_ITEM_KEEP_ASPECT_RATIO: producesettingentry(current_menu, items, SETTING_KEEP_ASPECT_RATIO, input); - snprintf(comment, sizeof(comment), "Press [%s] or [%s] to change the [Aspect Ratio].\nPress [%s] to reset back to default values.",rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_LEFT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_RIGHT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_START)); + snprintf(comment, sizeof(comment), "Press [%s] / [%s] to change the [Aspect Ratio].\nPress [%s] to reset back to default values.",rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_LEFT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_RIGHT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_START)); break; case MENU_ITEM_OVERSCAN_AMOUNT: producesettingentry(current_menu, items, SETTING_HW_OVERSCAN_AMOUNT, input); - snprintf(comment, sizeof(comment), "Press [%s] or [%s] to change the [Overscan] settings.\nPress [%s] to reset back to default values.",rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_LEFT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_RIGHT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_START)); + snprintf(comment, sizeof(comment), "Press [%s] / [%s] to change the [Overscan] settings.\nPress [%s] to reset back to default values.",rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_LEFT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_RIGHT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_START)); break; case MENU_ITEM_ORIENTATION: if(input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) @@ -2045,12 +2045,12 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) rarch_settings_default(S_DEF_ROTATION); video_ptr.set_rotation(NULL, g_console.screen_orientation); } - snprintf(comment, sizeof(comment), "Press [%s] or [%s] to change the [Orientation] settings.\nPress [%s] to reset back to default values.",rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_LEFT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_RIGHT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_START)); + snprintf(comment, sizeof(comment), "Press [%s] / [%s] to change the [Orientation] settings.\nPress [%s] to reset back to default values.",rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_LEFT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_RIGHT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_START)); break; #ifdef HAVE_FBO case MENU_ITEM_SCALE_FACTOR: producesettingentry(current_menu, items, SETTING_SCALE_FACTOR, input); - snprintf(comment, sizeof(comment), "Press [%s] or [%s] to change the [Scaling] settings.\nPress [%s] to reset back to default values.",rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_LEFT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_RIGHT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_START)); + snprintf(comment, sizeof(comment), "Press [%s] / [%s] to change the [Scaling] settings.\nPress [%s] to reset back to default values.",rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_LEFT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_RIGHT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_START)); break; #endif case MENU_ITEM_FRAME_ADVANCE: @@ -2059,23 +2059,23 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) rarch_settings_change(S_FRAME_ADVANCE); g_console.ingame_menu_item = MENU_ITEM_FRAME_ADVANCE; } - snprintf(comment, sizeof(comment), "Press [%s], [%s] or [%s] button to step one frame.\nPressing the button rapidly will advance the frame more slowly.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_L2), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R2)); + snprintf(comment, sizeof(comment), "Press [%s], [%s] or [%s] to step one frame.\nPressing the button rapidly will advance the frame more slowly.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_L2), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R2)); break; case MENU_ITEM_RESIZE_MODE: if(input & (1 << RETRO_DEVICE_ID_JOYPAD_B)) menu_stack_push(items, INGAME_MENU_RESIZE); - snprintf(comment, sizeof(comment), "Allows you to resize the screen by moving around the two analog sticks.\nPress [%s] to reset to defaults, and [%s] to go back.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_X), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_A)); + snprintf(comment, sizeof(comment), "Allows you to resize the screen.\nPress [%s] to reset to defaults, and [%s] to go back.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_X), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_A)); break; case MENU_ITEM_SCREENSHOT_MODE: if(input & (1 << RETRO_DEVICE_ID_JOYPAD_B)) menu_stack_push(items, INGAME_MENU_SCREENSHOT); - snprintf(comment, sizeof(comment), "Allows you to take a screenshot without any text clutter.\nPress [%s] to go back to the in-game menu.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_A)); + snprintf(comment, sizeof(comment), "Allows you to take a screenshot without any text.\nPress [%s] to go back to the in-game menu.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_A)); break; case MENU_ITEM_RETURN_TO_GAME: if(input & (1 << RETRO_DEVICE_ID_JOYPAD_B)) rarch_settings_change(S_RETURN_TO_GAME); - snprintf(comment, sizeof(comment), "Press [%s] to return back to the game.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); + snprintf(comment, sizeof(comment), "Press [%s] to return to the game.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); break; case MENU_ITEM_RESET: if(input & (1 << RETRO_DEVICE_ID_JOYPAD_B)) @@ -2090,7 +2090,7 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) { rarch_settings_change(S_RETURN_TO_MENU); } - snprintf(comment, sizeof(comment), "Press [%s] to return to the ROM Browser menu.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); + snprintf(comment, sizeof(comment), "Press [%s] to return to the ROM Browser.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); break; case MENU_ITEM_CHANGE_LIBRETRO: if(input & (1 << RETRO_DEVICE_ID_JOYPAD_B)) @@ -2099,7 +2099,7 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) filebrowser_set_root_and_ext(&tmpBrowser, EXT_EXECUTABLES, default_paths.core_dir); set_libretro_core_as_launch = true; } - snprintf(comment, sizeof(comment), "Press [%s] to choose a different emulator core.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); + snprintf(comment, sizeof(comment), "Press [%s] to choose another core.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); break; #ifdef HAVE_MULTIMAN case MENU_ITEM_RETURN_TO_MULTIMAN: @@ -2113,14 +2113,14 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) rarch_settings_change(S_RETURN_TO_DASHBOARD); } } - snprintf(comment, sizeof(comment), "Press [%s] to quit the emulator and return to multiMAN.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); + snprintf(comment, sizeof(comment), "Press [%s] to quit RetroArch and return to multiMAN.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); break; #endif case MENU_ITEM_RETURN_TO_DASHBOARD: if(input & (1 << RETRO_DEVICE_ID_JOYPAD_B)) rarch_settings_change(S_RETURN_TO_DASHBOARD); - snprintf(comment, sizeof(comment), "Press [%s] to quit the emulator and return to the XMB.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); + snprintf(comment, sizeof(comment), "Press [%s] to quit RetroArch.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); break; } From 09c33a5aa91d285dce0b9fda7d71d1e69ca5ac38 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 4 Aug 2012 03:31:54 +0200 Subject: [PATCH 024/492] (RMenu) More trimming of messages --- console/rmenu/rmenu_entries.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/console/rmenu/rmenu_entries.h b/console/rmenu/rmenu_entries.h index 300b1b991c..6686221020 100644 --- a/console/rmenu/rmenu_entries.h +++ b/console/rmenu/rmenu_entries.h @@ -82,23 +82,23 @@ item rmenu_items[MAX_NO_OF_CONTROLS_SETTINGS] = }, { SETTING_HW_TEXTURE_FILTER, - "Hardware Filtering shader #1", + "Hardware Filtering #1", "", 0.0f, 0.0f, YELLOW, - "INFO - Hardware filtering is set to 'Bilinear filtering' for [Shader #1].", + "INFO - Hardware filtering #1 is set to 'Bilinear filtering'.", WHITE, }, #ifdef HAVE_FBO { SETTING_HW_TEXTURE_FILTER_2, - "Hardware Filtering shader #2", + "Hardware Filtering #2", "", 0.0f, 0.0f, YELLOW, - "INFO - Hardware filtering is set to 'Bilinear filtering' for [Shader #2].", + "INFO - Hardware filtering #2 is set to 'Bilinear filtering'.", WHITE, }, { @@ -154,12 +154,12 @@ item rmenu_items[MAX_NO_OF_CONTROLS_SETTINGS] = }, { SETTING_ENABLE_SCREENSHOTS, - "Enable Screenshots Feature", + "Screenshots Feature", "", 0.0f, 0.0f, YELLOW, - "INFO - [Enable Screenshots] feature is set to 'OFF'.", + "INFO - [Screenshots] feature is set to 'OFF'.", WHITE, }, #if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) From 80a01479b1af0e62f66d860f79628f6854ba68d0 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sat, 4 Aug 2012 03:25:44 +0200 Subject: [PATCH 025/492] (RMenu) Add define HAVE_RMENU - add it to griffin.c --- Makefile.ps3 | 2 +- Makefile.ps3.retroarch | 2 +- console/griffin/griffin.c | 5 ++++- msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj | 10 +++++----- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Makefile.ps3 b/Makefile.ps3 index 33f8c37dd4..3450827ee0 100644 --- a/Makefile.ps3 +++ b/Makefile.ps3 @@ -45,7 +45,7 @@ PYTHON2 = python2.exe GIT = git.exe endif -PPU_SRCS = ps3/frontend/main.c console/rmenu/rmenu.c +PPU_SRCS = ps3/frontend/main.c ifeq ($(HAVE_RGL), 1) DEFINES = -DHAVE_RGL diff --git a/Makefile.ps3.retroarch b/Makefile.ps3.retroarch index 31ca1f83ee..183cfc874f 100644 --- a/Makefile.ps3.retroarch +++ b/Makefile.ps3.retroarch @@ -43,7 +43,7 @@ endif PPU_RANLIB = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ranlib.exe -DEFINES += -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_THREAD -DRARCH_CONSOLE -DHAVE_OPENGL -DHAVE_OPENGL_TEXREF -DHAVE_HEADSET -DHAVE_VID_CONTEXT -DHAVE_OPENGLES11 -DHAVE_CG -DHAVE_CG_MENU -DHAVE_FILEBROWSER -DHAVE_HDD_CACHE_PARTITION -DHAVE_FBO -DHAVE_RARCH_MAIN_WRAP -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_RGL -DHAVE_LIBRETRO_MANAGEMENT -DHAVE_RSOUND -DHAVE_ZLIB -D__CELLOS_LV2__ -DHAVE_CONFIGFILE=1 -DHAVE_NETPLAY=1 -DHAVE_SOCKET_LEGACY=1 -DHAVE_OSKUTIL -DHAVE_MOUSE -DHAVE_GRIFFIN=1 -DHAVE_MULTIMAN=1 -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -Dmain=rarch_main -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) +DEFINES += -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_THREAD -DRARCH_CONSOLE -DHAVE_RMENU -DHAVE_OPENGL -DHAVE_OPENGL_TEXREF -DHAVE_HEADSET -DHAVE_VID_CONTEXT -DHAVE_OPENGLES11 -DHAVE_CG -DHAVE_CG_MENU -DHAVE_FILEBROWSER -DHAVE_HDD_CACHE_PARTITION -DHAVE_FBO -DHAVE_RARCH_MAIN_WRAP -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_RGL -DHAVE_LIBRETRO_MANAGEMENT -DHAVE_RSOUND -DHAVE_ZLIB -D__CELLOS_LV2__ -DHAVE_CONFIGFILE=1 -DHAVE_NETPLAY=1 -DHAVE_SOCKET_LEGACY=1 -DHAVE_OSKUTIL -DHAVE_MOUSE -DHAVE_GRIFFIN=1 -DHAVE_MULTIMAN=1 -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -Dmain=rarch_main -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) ifeq ($(DEBUG), 1) PPU_OPTIMIZE_LV := -O0 -g diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index 85c45889ac..74587104f6 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -281,10 +281,13 @@ NETPLAY /*============================================================ MENU ============================================================ */ +#ifdef HAVE_RMENU +#include "../rmenu/rmenu.c" +#endif + #if defined(_XBOX360) #include "../../360/frontend-xdk/menu.cpp" #elif defined(_XBOX1) -#include "../rmenu/rmenu.c" #include "../../xbox1/frontend/RetroLaunch/IoSupport.cpp" #include "../../xbox1/frontend/RetroLaunch/Surface.cpp" #elif defined(GEKKO) diff --git a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj index 9134b8e136..8f8a6d3591 100644 --- a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj +++ b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj @@ -22,7 +22,7 @@ Optimization="3" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\msvc-stdint";"$(SolutionDir)\msvc-71"" - PreprocessorDefinitions="_DEBUG;_XBOX;_XBOX1;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.6\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" + PreprocessorDefinitions="_DEBUG;_XBOX;_XBOX1;HAVE_RMENU;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.6\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" MinimalRebuild="TRUE" BasicRuntimeChecks="0" RuntimeLibrary="1" @@ -72,7 +72,7 @@ OmitFramePointers="TRUE" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\msvc-stdint";"$(SolutionDir)\msvc-71"" - PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.6\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;PROFILE;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" + PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.6\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;PROFILE;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="TRUE" @@ -126,7 +126,7 @@ OmitFramePointers="TRUE" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\msvc-stdint";"$(SolutionDir)\msvc-71"" - PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.6\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;PROFILE;FASTCAP;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" + PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.6\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;PROFILE;FASTCAP;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="TRUE" @@ -187,7 +187,7 @@ EnableFiberSafeOptimizations="TRUE" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\msvc-stdint";"$(SolutionDir)\msvc-71"" - PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.6\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;HAVE_GRIFFIN;inline=_inline;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" + PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.6\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;HAVE_GRIFFIN;inline=_inline;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="TRUE" @@ -240,7 +240,7 @@ OmitFramePointers="TRUE" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\msvc-stdint";"$(SolutionDir)\msvc-71"" - PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.6\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;LTCG;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" + PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.6\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;LTCG;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="TRUE" From 770123eb743492385c0f4010b9a22b722391809d Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sat, 4 Aug 2012 03:32:25 +0200 Subject: [PATCH 026/492] (RGUI) Move RGUI and make define for it - two competing menus/GUIs now to choose from that are mostly platform agnostic --- Makefile.wii | 2 +- console/griffin/griffin.c | 8 +++++--- {wii/frontend => console/rgui}/list.c | 0 {wii/frontend => console/rgui}/list.h | 0 {wii/frontend => console/rgui}/rgui.c | 1 - {wii/frontend => console/rgui}/rgui.h | 0 wii/frontend/main.c | 3 ++- 7 files changed, 8 insertions(+), 6 deletions(-) rename {wii/frontend => console/rgui}/list.c (100%) rename {wii/frontend => console/rgui}/list.h (100%) rename {wii/frontend => console/rgui}/rgui.c (99%) rename {wii/frontend => console/rgui}/rgui.h (100%) diff --git a/Makefile.wii b/Makefile.wii index c9760a1694..4a0838a6d9 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -39,7 +39,7 @@ CFLAGS += -DHAVE_FILE_LOGGER CFLAGS += -Iconsole/logger endif -CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DRARCH_CONSOLE -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"0.9.6\" -Dmain=rarch_main -Wno-char-subscripts +CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_RGUI -DRARCH_CONSOLE -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"0.9.6\" -Dmain=rarch_main -Wno-char-subscripts ifeq ($(DEBUG), 1) CFLAGS += -O0 -g diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index 74587104f6..7a08a07405 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -285,12 +285,14 @@ MENU #include "../rmenu/rmenu.c" #endif +#ifdef HAVE_RGUI +#include "../rgui/rgui.c" +#include "../rgui/list.c" +#endif + #if defined(_XBOX360) #include "../../360/frontend-xdk/menu.cpp" #elif defined(_XBOX1) #include "../../xbox1/frontend/RetroLaunch/IoSupport.cpp" #include "../../xbox1/frontend/RetroLaunch/Surface.cpp" -#elif defined(GEKKO) -#include "../../wii/frontend/rgui.c" -#include "../../wii/frontend/list.c" #endif diff --git a/wii/frontend/list.c b/console/rgui/list.c similarity index 100% rename from wii/frontend/list.c rename to console/rgui/list.c diff --git a/wii/frontend/list.h b/console/rgui/list.h similarity index 100% rename from wii/frontend/list.h rename to console/rgui/list.h diff --git a/wii/frontend/rgui.c b/console/rgui/rgui.c similarity index 99% rename from wii/frontend/rgui.c rename to console/rgui/rgui.c index 32e6691231..3dc8c363ef 100644 --- a/wii/frontend/rgui.c +++ b/console/rgui/rgui.c @@ -732,4 +732,3 @@ const char *rgui_iterate(rgui_handle_t *rgui, rgui_action_t action) return found ? rgui->path_buf : NULL; } - diff --git a/wii/frontend/rgui.h b/console/rgui/rgui.h similarity index 100% rename from wii/frontend/rgui.h rename to console/rgui/rgui.h diff --git a/wii/frontend/main.c b/wii/frontend/main.c index 18739fd007..8a5c281ecf 100644 --- a/wii/frontend/main.c +++ b/wii/frontend/main.c @@ -17,11 +17,12 @@ #undef main #include -#include "rgui.h" #include "../../driver.h" #include "../../general.h" #include "../../libretro.h" +#include "../../console/rgui/rgui.h" + #include "../../console/rarch_console_input.h" #include "../../console/rarch_console_main_wrap.h" From 7ca0637418582265f96a5c34954212448b3f3e06 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sat, 4 Aug 2012 03:50:10 +0200 Subject: [PATCH 027/492] (Xbox 1) Cleanups to IoSupport.cpp / Surface.cpp --- console/rmenu/rmenu.h | 1 + xbox1/frontend/RetroLaunch/IoSupport.cpp | 133 ++++++++++++----------- xbox1/frontend/RetroLaunch/Surface.cpp | 114 +++++++++---------- 3 files changed, 125 insertions(+), 123 deletions(-) diff --git a/console/rmenu/rmenu.h b/console/rmenu/rmenu.h index 7031243d0f..bae7508434 100644 --- a/console/rmenu/rmenu.h +++ b/console/rmenu/rmenu.h @@ -31,6 +31,7 @@ #define POSITION_Y_BEGIN (POSITION_Y_START + POSITION_Y_INCREMENT) #define POSITION_Y_INCREMENT 0.035f #define COMMENT_Y_POSITION 0.83f + #elif defined(_XBOX1) #define DEVICE_CAST xdk_d3d_video_t* #define input_ptr input_xinput diff --git a/xbox1/frontend/RetroLaunch/IoSupport.cpp b/xbox1/frontend/RetroLaunch/IoSupport.cpp index cb0d3065f6..5652d68e81 100644 --- a/xbox1/frontend/RetroLaunch/IoSupport.cpp +++ b/xbox1/frontend/RetroLaunch/IoSupport.cpp @@ -24,106 +24,107 @@ HRESULT xbox_io_mount(char *szDrive, char *szDevice) { - char szSourceDevice[48]; - char szDestinationDrive[16]; + char szSourceDevice[48]; + char szDestinationDrive[16]; - snprintf(szSourceDevice, sizeof(szSourceDevice), "\\Device\\%s", szDevice); - snprintf(szDestinationDrive, sizeof(szDestinationDrive), "\\??\\%s", szDrive); + snprintf(szSourceDevice, sizeof(szSourceDevice), "\\Device\\%s", szDevice); + snprintf(szDestinationDrive, sizeof(szDestinationDrive), "\\??\\%s", szDrive); - STRING DeviceName = - { - strlen(szSourceDevice), - strlen(szSourceDevice) + 1, - szSourceDevice - }; + STRING DeviceName = + { + strlen(szSourceDevice), + strlen(szSourceDevice) + 1, + szSourceDevice + }; - STRING LinkName = - { - strlen(szDestinationDrive), - strlen(szDestinationDrive) + 1, - szDestinationDrive - }; + STRING LinkName = + { + strlen(szDestinationDrive), + strlen(szDestinationDrive) + 1, + szDestinationDrive + }; - IoCreateSymbolicLink(&LinkName, &DeviceName); + IoCreateSymbolicLink(&LinkName, &DeviceName); - return S_OK; + return S_OK; } HRESULT xbox_io_unmount(char *szDrive) { - char szDestinationDrive[16]; - snprintf(szDestinationDrive, sizeof(szDestinationDrive), "\\??\\%s", szDrive); + char szDestinationDrive[16]; + snprintf(szDestinationDrive, sizeof(szDestinationDrive), "\\??\\%s", szDrive); - STRING LinkName = - { - strlen(szDestinationDrive), - strlen(szDestinationDrive) + 1, - szDestinationDrive - }; + STRING LinkName = + { + strlen(szDestinationDrive), + strlen(szDestinationDrive) + 1, + szDestinationDrive + }; - IoDeleteSymbolicLink(&LinkName); + IoDeleteSymbolicLink(&LinkName); - return S_OK; + return S_OK; } HRESULT xbox_io_remount(char *szDrive, char *szDevice) { - char szSourceDevice[48]; - snprintf(szSourceDevice, sizeof(szSourceDevice), "\\Device\\%s", szDevice); + char szSourceDevice[48]; + snprintf(szSourceDevice, sizeof(szSourceDevice), "\\Device\\%s", szDevice); - xbox_io_unmount(szDrive); + xbox_io_unmount(szDrive); - ANSI_STRING filename; - OBJECT_ATTRIBUTES attributes; - IO_STATUS_BLOCK status; - HANDLE hDevice; - NTSTATUS error; - DWORD dummy; + ANSI_STRING filename; + OBJECT_ATTRIBUTES attributes; + IO_STATUS_BLOCK status; + HANDLE hDevice; + NTSTATUS error; + DWORD dummy; - RtlInitAnsiString(&filename, szSourceDevice); - InitializeObjectAttributes(&attributes, &filename, OBJ_CASE_INSENSITIVE, NULL); + RtlInitAnsiString(&filename, szSourceDevice); + InitializeObjectAttributes(&attributes, &filename, OBJ_CASE_INSENSITIVE, NULL); - if (!NT_SUCCESS(error = NtCreateFile(&hDevice, GENERIC_READ | + if (!NT_SUCCESS(error = NtCreateFile(&hDevice, GENERIC_READ | SYNCHRONIZE | FILE_READ_ATTRIBUTES, &attributes, &status, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT))) - { - return E_FAIL; - } + { + return E_FAIL; + } - if (!DeviceIoControl(hDevice, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dummy, NULL)) - { - CloseHandle(hDevice); - return E_FAIL; - } + if (!DeviceIoControl(hDevice, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dummy, NULL)) + { + CloseHandle(hDevice); + return E_FAIL; + } - CloseHandle(hDevice); - xbox_io_mount(szDrive, szDevice); + CloseHandle(hDevice); + xbox_io_mount(szDrive, szDevice); - return S_OK; + return S_OK; } HRESULT xbox_io_remap(char *szMapping) { - char szMap[32]; - strlcpy(szMap, szMapping, sizeof(szMap)); + char szMap[32]; + strlcpy(szMap, szMapping, sizeof(szMap)); - char *pComma = strstr(szMap, ","); - if (pComma) - { - *pComma = 0; + char *pComma = strstr(szMap, ","); - // map device to drive letter - xbox_io_unmount(szMap); - xbox_io_mount(szMap, &pComma[1]); - return S_OK; - } + if (pComma) + { + *pComma = 0; - return E_FAIL; + // map device to drive letter + xbox_io_unmount(szMap); + xbox_io_mount(szMap, &pComma[1]); + return S_OK; + } + + return E_FAIL; } HRESULT xbox_io_shutdown(void) { - HalInitiateShutdown(); - return S_OK; -} \ No newline at end of file + HalInitiateShutdown(); + return S_OK; +} diff --git a/xbox1/frontend/RetroLaunch/Surface.cpp b/xbox1/frontend/RetroLaunch/Surface.cpp index 639b7cc3f7..e80b561f08 100644 --- a/xbox1/frontend/RetroLaunch/Surface.cpp +++ b/xbox1/frontend/RetroLaunch/Surface.cpp @@ -22,10 +22,10 @@ bool d3d_surface_new(d3d_surface_t *surface, const char *filename) { xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; - surface->m_pTexture = NULL; - surface->m_pVertexBuffer = NULL; + surface->m_pTexture = NULL; + surface->m_pVertexBuffer = NULL; - HRESULT ret = D3DXCreateTextureFromFileExA(d3d->d3d_render_device, // d3d device + HRESULT ret = D3DXCreateTextureFromFileExA(d3d->d3d_render_device, // d3d device filename, // filename D3DX_DEFAULT, // width D3DX_DEFAULT, // height @@ -40,93 +40,93 @@ bool d3d_surface_new(d3d_surface_t *surface, const char *filename) NULL, // pallete &surface->m_pTexture); // texture - if (FAILED(ret)) - { - RARCH_ERR("Error occurred during D3DXCreateTextureFromFileExA().\n"); - return false; - } + if(FAILED(ret)) + { + RARCH_ERR("Error occurred during D3DXCreateTextureFromFileExA().\n"); + return false; + } - // create a vertex buffer for the quad that will display the texture + // create a vertex buffer for the quad that will display the texture ret = d3d->d3d_render_device->CreateVertexBuffer(4 * sizeof(DrawVerticeFormats), D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &surface->m_pVertexBuffer); - if (FAILED(ret)) - { - RARCH_ERR("Error occurred during CreateVertexBuffer().\n"); - surface->m_pTexture->Release(); - return false; - } + if (FAILED(ret)) + { + RARCH_ERR("Error occurred during CreateVertexBuffer().\n"); + surface->m_pTexture->Release(); + return false; + } - return true; + return true; } void d3d_surface_free(d3d_surface_t *surface) { - // free the vertex buffer - if (surface->m_pVertexBuffer) - { - surface->m_pVertexBuffer->Release(); - surface->m_pVertexBuffer = NULL; - } + // free the vertex buffer + if (surface->m_pVertexBuffer) + { + surface->m_pVertexBuffer->Release(); + surface->m_pVertexBuffer = NULL; + } - // free the texture - if (surface->m_pTexture) - { - surface->m_pTexture->Release(); - surface->m_pTexture = NULL; - } + // free the texture + if (surface->m_pTexture) + { + surface->m_pTexture->Release(); + surface->m_pTexture = NULL; + } } bool d3d_surface_render(d3d_surface_t *surface, int x, int y, int32_t w, int32_t h) { xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; - if (surface->m_pTexture == NULL || surface->m_pVertexBuffer == NULL) - return false; + if (surface->m_pTexture == NULL || surface->m_pVertexBuffer == NULL) + return false; - float fX = static_cast(x); - float fY = static_cast(y); + float fX = static_cast(x); + float fY = static_cast(y); // create the new vertices DrawVerticeFormats newVerts[] = - { - // x, y, z, color, u ,v + { + // x, y, z, color, u ,v {fX, fY, 0.0f, 0, 0, 0}, {fX + w, fY, 0.0f, 0, 1, 0}, {fX + w, fY + h, 0.0f, 0, 1, 1}, {fX, fY + h, 0.0f, 0, 0, 1} - }; + }; - // load the existing vertices + // load the existing vertices DrawVerticeFormats *pCurVerts; - HRESULT ret = surface->m_pVertexBuffer->Lock(0, 0, (unsigned char**)&pCurVerts, 0); + HRESULT ret = surface->m_pVertexBuffer->Lock(0, 0, (unsigned char**)&pCurVerts, 0); - if (FAILED(ret)) - { - RARCH_ERR("Error occurred during m_pVertexBuffer->Lock().\n"); - return false; - } + if (FAILED(ret)) + { + RARCH_ERR("Error occurred during m_pVertexBuffer->Lock().\n"); + return false; + } - // copy the new verts over the old verts - memcpy(pCurVerts, newVerts, 4 * sizeof(DrawVerticeFormats)); + // copy the new verts over the old verts + memcpy(pCurVerts, newVerts, 4 * sizeof(DrawVerticeFormats)); - surface->m_pVertexBuffer->Unlock(); + surface->m_pVertexBuffer->Unlock(); d3d->d3d_render_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - d3d->d3d_render_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - d3d->d3d_render_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + d3d->d3d_render_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + d3d->d3d_render_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - // also blend the texture with the set alpha value - d3d->d3d_render_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - d3d->d3d_render_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); - d3d->d3d_render_device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); + // also blend the texture with the set alpha value + d3d->d3d_render_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + d3d->d3d_render_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); + d3d->d3d_render_device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); - // draw the quad - d3d->d3d_render_device->SetTexture(0, surface->m_pTexture); - d3d->d3d_render_device->SetStreamSource(0, surface->m_pVertexBuffer, sizeof(DrawVerticeFormats)); - d3d->d3d_render_device->SetVertexShader(D3DFVF_CUSTOMVERTEX); - d3d->d3d_render_device->DrawPrimitive(D3DPT_QUADLIST, 0, 1); + // draw the quad + d3d->d3d_render_device->SetTexture(0, surface->m_pTexture); + d3d->d3d_render_device->SetStreamSource(0, surface->m_pVertexBuffer, sizeof(DrawVerticeFormats)); + d3d->d3d_render_device->SetVertexShader(D3DFVF_CUSTOMVERTEX); + d3d->d3d_render_device->DrawPrimitive(D3DPT_QUADLIST, 0, 1); - return true; + return true; } From 8ac6a7968ed41758b059d2cb391ce0a7c084db4d Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 4 Aug 2012 05:10:49 +0200 Subject: [PATCH 028/492] (RMenu) message queue works now on Xbox 1 too --- console/rarch_console_settings.c | 6 +++--- console/rmenu/rmenu.c | 34 +++++++++++++++----------------- console/rmenu/rmenu.h | 12 +++++++++++ console/rmenu/rmenu_entries.h | 10 +++++----- xbox1/xdk_d3d8.cpp | 3 +++ 5 files changed, 39 insertions(+), 26 deletions(-) diff --git a/console/rarch_console_settings.c b/console/rarch_console_settings.c index 47dc563de7..de0fab99e8 100644 --- a/console/rarch_console_settings.c +++ b/console/rarch_console_settings.c @@ -257,13 +257,13 @@ void rarch_settings_msg(unsigned setting, unsigned delay) snprintf(str, sizeof(str), "INFO - Resize the screen by moving around the two analog sticks.\nPress [RetroPad X] to reset to default values, and [RetroPad A] to go back.\nTo select the resized screen mode, set Aspect Ratio to: 'Custom'."); break; case S_MSG_RESTART_RARCH: - snprintf(str, sizeof(str), "INFO - You need to restart RetroArch for this change to take effect."); + snprintf(str, sizeof(str), "INFO - You need to restart RetroArch."); break; case S_MSG_SELECT_LIBRETRO_CORE: - snprintf(str, sizeof(str), "INFO - Select a Libretro core from the menu by pressing [RetroPad B]."); + snprintf(str, sizeof(str), "INFO - Select a Libretro core from the menu."); break; case S_MSG_SELECT_SHADER: - snprintf(str, sizeof(str), "INFO - Select a shader from the menu by pressing [RetroPad A]."); + snprintf(str, sizeof(str), "INFO - Select a shader from the menu."); break; case S_MSG_SHADER_LOADING_SUCCEEDED: snprintf(str, sizeof(str), "INFO - Shader successfully loaded."); diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index c805234185..61cc6fb046 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -65,7 +65,6 @@ #include "rmenu.h" #include "rmenu_entries.h" -#define NUM_ENTRY_PER_PAGE 17 #define INPUT_SCALE 2 #define MENU_ITEM_SELECTED(index) (menuitem_colors[index]) @@ -74,7 +73,7 @@ #include "../../xbox1/frontend/RetroLaunch/Surface.h" #include "../../gfx/fonts/xdk1_xfonts.h" -#define ROM_PANEL_WIDTH 440 +#define ROM_PANEL_WIDTH 510 #define ROM_PANEL_HEIGHT 20 int xpos, ypos; @@ -172,17 +171,17 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current case SETTING_HW_TEXTURE_FILTER: set_setting_label_color(items,g_settings.video.smooth, currentsetting); if(g_settings.video.smooth) - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Linear interpolation"); + snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Bilinear"); else - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Point filtering"); + snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Point"); break; #ifdef HAVE_FBO case SETTING_HW_TEXTURE_FILTER_2: set_setting_label_color(items,g_settings.video.second_pass_smooth, currentsetting); if(g_settings.video.second_pass_smooth) - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Linear interpolation"); + snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Bilinear"); else - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Point filtering"); + snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Point"); break; case SETTING_SCALE_ENABLED: set_setting_label_write_on_or_off(items, g_console.fbo_enabled, currentsetting); @@ -220,14 +219,14 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current { case SOUND_MODE_NORMAL: snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), - "INFO - [Sound Output] is set to 'Normal' - normal audio output will be\nused."); + "INFO - [Sound Output] is set to 'Normal'."); snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "Normal"); items[currentsetting].text_color = GREEN; break; #ifdef HAVE_RSOUND case SOUND_MODE_RSOUND: snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), - "INFO - [Sound Output] is set to 'RSound' - the sound will be streamed over the\n network to the RSound audio server." ); + "INFO - [Sound Output] is set to 'RSound'." ); snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "RSound"); items[currentsetting].text_color = ORANGE; break; @@ -235,7 +234,7 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current #ifdef HAVE_HEADSET case SOUND_MODE_HEADSET: snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), - "INFO - [Sound Output] is set to 'USB/Bluetooth Headset' - sound will\n be output through the headset"); + "INFO - [Sound Output] is set to 'USB/Bluetooth Headset'."); snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "USB/Bluetooth Headset"); items[currentsetting].text_color = ORANGE; break; @@ -266,7 +265,7 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current if(g_settings.rewind_enable) { items[currentsetting].text_color = ORANGE; - snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - [Rewind] feature is set to 'ON'. You can rewind the game in real-time."); + snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - [Rewind] feature is set to 'ON'."); } else { @@ -368,7 +367,7 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current const char * value = rarch_input_find_platform_key_label(g_settings.input.binds[currently_selected_controller_menu][currentsetting-(FIRST_CONTROL_BIND)].joykey); unsigned id = currentsetting - FIRST_CONTROL_BIND; snprintf(items[currentsetting].text, sizeof(items[currentsetting].text), rarch_input_get_default_keybind_name(id)); - snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - [%s] on the PS3 controller is mapped to action:\n[%s].", items[currentsetting].text, value); + snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - [%s] is mapped to action:\n[%s].", items[currentsetting].text, value); snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), value); } break; @@ -1696,7 +1695,7 @@ static void select_setting(item *items, menu *current_menu, uint64_t input) DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; float x_position = POSITION_X; - float x_position_center = 0.5f; + float x_position_center = POSITION_X_CENTER; float comment_y_position = COMMENT_Y_POSITION; float comment_two_y_position = 0.91f; float font_size = HARDCODE_FONT_SIZE; @@ -1819,7 +1818,7 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; float x_position = POSITION_X; - float x_position_center = 0.5f; + float x_position_center = POSITION_X_CENTER; float font_size = HARDCODE_FONT_SIZE; float y_position = POSITION_Y_BEGIN; @@ -2489,16 +2488,15 @@ void menu_loop(void) SET_TIMER_EXPIRATION(device_ptr, 30); } -#ifndef _XBOX1 const char * message = msg_queue_pull(g_extern.msg_queue); - float message_y_position = 0.75f; - float message_scale = 1.05f; + float msg_queue_x_position = MSG_QUEUE_X_POSITION; + float msg_queue_y_position = MSG_QUEUE_Y_POSITION; + float msg_queue_font_size= MSG_QUEUE_FONT_SIZE; if (message && g_console.info_msg_enable) { - render_msg_place_func(g_settings.video.msg_pos_x, message_y_position, message_scale, WHITE, message); + render_msg_place_func(msg_queue_x_position, msg_queue_y_position, msg_queue_font_size, WHITE, message); } -#endif gfx_ctx_swap_buffers(); #ifdef HAVE_SYSUTILS diff --git a/console/rmenu/rmenu.h b/console/rmenu/rmenu.h index 7031243d0f..ff99b31f72 100644 --- a/console/rmenu/rmenu.h +++ b/console/rmenu/rmenu.h @@ -26,11 +26,17 @@ #define FONT_SIZE (g_console.menu_font_size) #define render_msg_place_func(xpos, ypos, scale, color, msg) gl_render_msg_place(DEVICE_PTR, xpos, ypos, scale, color, msg) +#define NUM_ENTRY_PER_PAGE 17 #define POSITION_X 0.09f +#define POSITION_X_CENTER 0.5f #define POSITION_Y_START 0.10f #define POSITION_Y_BEGIN (POSITION_Y_START + POSITION_Y_INCREMENT) #define POSITION_Y_INCREMENT 0.035f #define COMMENT_Y_POSITION 0.83f + +#define MSG_QUEUE_X_POSITION g_settings.video.msg_pos_x +#define MSG_QUEUE_Y_POSITION 0.75f +#define MSG_QUEUE_FONT_SIZE 1.05f #elif defined(_XBOX1) #define DEVICE_CAST xdk_d3d_video_t* #define input_ptr input_xinput @@ -40,11 +46,17 @@ #define FONT_SIZE 21 #define render_msg_place_func(xpos, ypos, scale, color, msg) xfonts_render_msg_place(DEVICE_PTR, xpos, ypos, scale, msg) +#define NUM_ENTRY_PER_PAGE 12 #define POSITION_X m_menuMainRomListPos_x +#define POSITION_X_CENTER (m_menuMainRomListPos_x + 350) #define POSITION_Y_START m_menuMainRomListPos_y #define POSITION_Y_BEGIN (POSITION_Y_START + POSITION_Y_INCREMENT) #define POSITION_Y_INCREMENT 20 #define COMMENT_Y_POSITION (ypos - POSITION_Y_INCREMENT) + +#define MSG_QUEUE_X_POSITION POSITION_X +#define MSG_QUEUE_Y_POSITION (ypos - (POSITION_Y_INCREMENT * 2)) +#define MSG_QUEUE_FONT_SIZE HARDCODE_FONT_SIZE #endif typedef struct diff --git a/console/rmenu/rmenu_entries.h b/console/rmenu/rmenu_entries.h index 6686221020..24bf9efb5e 100644 --- a/console/rmenu/rmenu_entries.h +++ b/console/rmenu/rmenu_entries.h @@ -67,7 +67,7 @@ item rmenu_items[MAX_NO_OF_CONTROLS_SETTINGS] = 0.0f, 0.0f, YELLOW, - "INFO - Increase or decrease the font size in the menu.", + "INFO - Increase or decrease the font size.", WHITE, }, { @@ -77,7 +77,7 @@ item rmenu_items[MAX_NO_OF_CONTROLS_SETTINGS] = 0.0f, 0.0f, YELLOW, - "INFO - [Aspect Ratio] is set to 'Scaled (4:3)' - screen will have black\nborders left/right on widescreen TVs/monitors.", + "INFO - [Aspect Ratio] is set to 'Scaled (4:3)'.", WHITE, }, { @@ -87,7 +87,7 @@ item rmenu_items[MAX_NO_OF_CONTROLS_SETTINGS] = 0.0f, 0.0f, YELLOW, - "INFO - Hardware filtering #1 is set to 'Bilinear filtering'.", + "INFO - Hardware filtering #1 is set to 'Bilinear'.", WHITE, }, #ifdef HAVE_FBO @@ -98,7 +98,7 @@ item rmenu_items[MAX_NO_OF_CONTROLS_SETTINGS] = 0.0f, 0.0f, YELLOW, - "INFO - Hardware filtering #2 is set to 'Bilinear filtering'.", + "INFO - Hardware filtering #2 is set to 'Bilinear'.", WHITE, }, { @@ -604,7 +604,7 @@ item rmenu_items[MAX_NO_OF_CONTROLS_SETTINGS] = 0.0f, 0.0f, YELLOW, - "INFO - Set all [Controls settings] back to their 'DEFAULT' values.", + "INFO - Set all [Controls] back to their 'DEFAULT' values.", GREEN, } }; diff --git a/xbox1/xdk_d3d8.cpp b/xbox1/xdk_d3d8.cpp index 1212c0da33..0b66cf5e5a 100644 --- a/xbox1/xdk_d3d8.cpp +++ b/xbox1/xdk_d3d8.cpp @@ -473,6 +473,9 @@ static bool xdk_d3d_frame(void *data, const void *frame, } } + if (msg) + xfonts_render_msg_place(d3d, 100, 390, 0, msg); //TODO: dehardcode x/y here for HD (720p) mode + if(!d3d->block_swap) gfx_ctx_swap_buffers(); From 15e9860ab97bd51a2659f7b5d35ee99403ec97bb Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 4 Aug 2012 05:26:46 +0200 Subject: [PATCH 029/492] (Xbox 1/RMenu) Fixes for some of the 'set directory' settings --- console/rmenu/rmenu.c | 38 +++++++++++++++++++++++++++++++++----- xdk/frontend/main.c | 1 + 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index 61cc6fb046..da093ab2f0 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -694,7 +694,11 @@ static void browser_update(filebrowser_t * b, uint64_t input, const char *extens { action = FILEBROWSER_ACTION_RESET; //TODO - Dehardcode this +#ifdef _XBOX1 + filebrowser_set_root(b, "D:"); +#else filebrowser_set_root(b, "/"); +#endif strlcpy(b->extensions, extensions, sizeof(b->extensions)); } @@ -780,27 +784,27 @@ static void select_file(item *items, menu *current_menu, uint64_t input) case SHADER_CHOICE: strlcpy(extensions, EXT_SHADERS, sizeof(extensions)); strlcpy(object, "Shader", sizeof(object)); - snprintf(comment, sizeof(comment), "INFO - Select a shader from the menu by pressing [%s].", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); + snprintf(comment, sizeof(comment), "INFO - Select a shader by pressing [%s].", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); break; case PRESET_CHOICE: strlcpy(extensions, EXT_CGP_PRESETS, sizeof(extensions)); strlcpy(object, "Shader preset", sizeof(object)); - snprintf(comment, sizeof(comment), "INFO - Select a shader preset from the menu by pressing [%s].", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); + snprintf(comment, sizeof(comment), "INFO - Select a shader preset by pressing [%s].", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); break; case INPUT_PRESET_CHOICE: strlcpy(extensions, EXT_INPUT_PRESETS, sizeof(extensions)); strlcpy(object, "Input preset", sizeof(object)); - snprintf(comment, sizeof(comment), "INFO - Select an input preset from the menu by pressing [%s].", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); + snprintf(comment, sizeof(comment), "INFO - Select an input preset by pressing [%s].", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); break; case BORDER_CHOICE: strlcpy(extensions, EXT_IMAGES, sizeof(extensions)); strlcpy(object, "Border image file", sizeof(object)); - snprintf(comment, sizeof(comment), "INFO - Select a border image file from the menu by pressing [%s].", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); + snprintf(comment, sizeof(comment), "INFO - Select a border image file by pressing [%s].", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); break; case LIBRETRO_CHOICE: strlcpy(extensions, EXT_EXECUTABLES, sizeof(extensions)); strlcpy(object, "Libretro core", sizeof(object)); - snprintf(comment, sizeof(comment), "INFO - Select a Libretro core from the menu by pressing [%s].", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); + snprintf(comment, sizeof(comment), "INFO - Select a Libretro core by pressing [%s].", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); break; } @@ -1468,17 +1472,29 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { menu_stack_push(items, PATH_DEFAULT_ROM_DIR_CHOICE); +#ifdef _XBOX1 + filebrowser_set_root_and_ext(&tmpBrowser, "empty", "D:"); +#else filebrowser_set_root_and_ext(&tmpBrowser, "empty", "/"); +#endif } if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) +#ifdef _XBOX1 + strlcpy(g_console.default_rom_startup_dir, "D:", sizeof(g_console.default_rom_startup_dir)); +#else strlcpy(g_console.default_rom_startup_dir, "/", sizeof(g_console.default_rom_startup_dir)); +#endif break; case SETTING_PATH_SAVESTATES_DIRECTORY: if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { menu_stack_push(items, PATH_SAVESTATES_DIR_CHOICE); +#ifdef _XBOX1 + filebrowser_set_root_and_ext(&tmpBrowser, "empty", "D:"); +#else filebrowser_set_root_and_ext(&tmpBrowser, "empty", "/"); +#endif } if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) @@ -1489,7 +1505,11 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { menu_stack_push(items, PATH_SRAM_DIR_CHOICE); +#ifdef _XBOX1 + filebrowser_set_root_and_ext(&tmpBrowser, "empty", "D:"); +#else filebrowser_set_root_and_ext(&tmpBrowser, "empty", "/"); +#endif } if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) @@ -1499,7 +1519,11 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { menu_stack_push(items, PATH_CHEATS_DIR_CHOICE); +#ifdef _XBOX1 + filebrowser_set_root_and_ext(&tmpBrowser, "empty", "D:"); +#else filebrowser_set_root_and_ext(&tmpBrowser, "empty", "/"); +#endif } if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) @@ -1509,7 +1533,11 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { menu_stack_push(items, PATH_SYSTEM_DIR_CHOICE); +#ifdef _XBOX1 + filebrowser_set_root_and_ext(&tmpBrowser, "empty", "D:"); +#else filebrowser_set_root_and_ext(&tmpBrowser, "empty", "/"); +#endif } if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index 3b4d8bd779..68d3a73714 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -106,6 +106,7 @@ static void get_environment_settings (void) #if defined(_XBOX1) /* FIXME: Hardcoded */ + strlcpy(default_paths.core_dir, "D:\\", sizeof(default_paths.core_dir)); strlcpy(default_paths.config_file, "D:\\retroarch.cfg", sizeof(default_paths.config_file)); strlcpy(default_paths.system_dir, "D:\\system\\", sizeof(default_paths.system_dir)); strlcpy(default_paths.filesystem_root_dir, "D:\\", sizeof(default_paths.filesystem_root_dir)); From 98385f8ccfc8f149ed5d7614987932be79e73971 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 4 Aug 2012 05:37:02 +0200 Subject: [PATCH 030/492] (RMenu) Cosmetic tweaks -label adjustments --- console/rmenu/rmenu.c | 2 +- console/rmenu/rmenu_entries.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index da093ab2f0..f339106995 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -2206,7 +2206,7 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_RETURN_TO_MULTIMAN)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_RETURN_TO_MULTIMAN), "Return to multiMAN"); #endif - render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_RETURN_TO_DASHBOARD)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_RETURN_TO_DASHBOARD), "Return to XMB"); + render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_RETURN_TO_DASHBOARD)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_RETURN_TO_DASHBOARD), "Return to Dashboard"); render_msg_place_func(x_position, comment_y_position, font_size, LIGHTBLUE, comment); diff --git a/console/rmenu/rmenu_entries.h b/console/rmenu/rmenu_entries.h index 24bf9efb5e..80f4332aca 100644 --- a/console/rmenu/rmenu_entries.h +++ b/console/rmenu/rmenu_entries.h @@ -207,7 +207,7 @@ item rmenu_items[MAX_NO_OF_CONTROLS_SETTINGS] = #ifdef HAVE_RSOUND { SETTING_RSOUND_SERVER_IP_ADDRESS, - "RSound Audio Server IP Address", + "RSound Server IP Address", "", 0.0f, 0.0f, @@ -218,12 +218,12 @@ item rmenu_items[MAX_NO_OF_CONTROLS_SETTINGS] = #endif { SETTING_ENABLE_CUSTOM_BGM, - "Enable Custom BGM Feature", + "Custom BGM Feature", "", 0.0f, 0.0f, YELLOW, - "INFO - [Enable Custom BGM] feature is set to 'ON'.", + "INFO - [Custom BGM] feature is set to 'ON'.", WHITE, }, { @@ -757,7 +757,7 @@ item ingame_menu_settings[MENU_ITEM_LAST] = #endif { MENU_ITEM_RETURN_TO_DASHBOARD, - "Return to XMB", + "Return to Dashboard", "", 0.0f, 0.0f, From 529e5d7d180fcd615cd3cf06bb0228655ad490c5 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 4 Aug 2012 05:59:30 +0200 Subject: [PATCH 031/492] (Xbox 1) Add D3D8 alpha blending --- console/rmenu/rmenu.c | 2 -- gfx/context/xdk_ctx.c | 9 ++++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index f339106995..2f6bd3d51c 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -2423,9 +2423,7 @@ void menu_loop(void) #endif } -#ifdef __CELLOS_LV2__ rarch_render_cached_frame(); -#endif filebrowser_t * fb = &browser; diff --git a/gfx/context/xdk_ctx.c b/gfx/context/xdk_ctx.c index ff65ba06a0..8b69a01594 100644 --- a/gfx/context/xdk_ctx.c +++ b/gfx/context/xdk_ctx.c @@ -34,7 +34,14 @@ void gfx_ctx_set_blend(bool enable) { - (void)enable; + xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; + + if(enable) + { + d3d->d3d_render_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); + d3d->d3d_render_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + } + d3d->d3d_render_device->SetRenderState(D3DRS_ALPHABLENDENABLE, enable); } void gfx_ctx_set_swap_interval(unsigned interval, bool inited) From a1eecbfcc5ff16188cbb8a53da6feefe0f19137d Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 4 Aug 2012 07:24:15 +0200 Subject: [PATCH 032/492] (Xbox 1) Ifdef out PATH_CHEATS if HAVE_XML is not defined --- console/rmenu/rmenu.c | 18 ++++++++++++++++++ console/rmenu/rmenu.h | 4 ++++ console/rmenu/rmenu_entries.h | 2 ++ 3 files changed, 24 insertions(+) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index 2f6bd3d51c..1d9cf65cdf 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -320,10 +320,12 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current set_setting_label_color(items,!(strcmp(g_console.default_sram_dir, default_paths.port_dir)), currentsetting); snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), g_console.default_sram_dir); break; +#ifdef HAVE_XML case SETTING_PATH_CHEATS: set_setting_label_color(items,!(strcmp(g_settings.cheat_database, default_paths.port_dir)), currentsetting); snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), g_settings.cheat_database); break; +#endif case SETTING_PATH_SYSTEM: set_setting_label_color(items,!(strcmp(g_settings.system_directory, default_paths.system_dir)), currentsetting); snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), g_settings.system_directory); @@ -508,7 +510,9 @@ static void menu_stack_push(item *items, unsigned menu_id) case PATH_DEFAULT_ROM_DIR_CHOICE: case PATH_SAVESTATES_DIR_CHOICE: case PATH_SRAM_DIR_CHOICE: +#ifdef HAVE_XML case PATH_CHEATS_DIR_CHOICE: +#endif case PATH_SYSTEM_DIR_CHOICE: strlcpy(current_menu->title, "Path Selection", sizeof(current_menu->title)); current_menu->enum_id = menu_id; @@ -628,7 +632,9 @@ static void display_menubar(menu *current_menu) case INPUT_PRESET_CHOICE: case PATH_SAVESTATES_DIR_CHOICE: case PATH_DEFAULT_ROM_DIR_CHOICE: +#ifdef HAVE_XML case PATH_CHEATS_DIR_CHOICE: +#endif case PATH_SRAM_DIR_CHOICE: render_msg_place_func(x_position, 0.03f, font_size, WHITE, "<- PREV"); break; @@ -645,7 +651,9 @@ static void display_menubar(menu *current_menu) case INPUT_PRESET_CHOICE: case PATH_SAVESTATES_DIR_CHOICE: case PATH_DEFAULT_ROM_DIR_CHOICE: +#ifdef HAVE_XML case PATH_CHEATS_DIR_CHOICE: +#endif case PATH_SRAM_DIR_CHOICE: fb = &tmpBrowser; case FILE_BROWSER_MENU: @@ -910,9 +918,11 @@ static void select_directory(item *items, menu *current_menu, uint64_t input) case PATH_DEFAULT_ROM_DIR_CHOICE: strlcpy(g_console.default_rom_startup_dir, path, sizeof(g_console.default_rom_startup_dir)); break; +#ifdef HAVE_XML case PATH_CHEATS_DIR_CHOICE: strlcpy(g_settings.cheat_database, path, sizeof(g_settings.cheat_database)); break; +#endif } menu_stack_decrement(); } @@ -931,9 +941,11 @@ static void select_directory(item *items, menu *current_menu, uint64_t input) case PATH_DEFAULT_ROM_DIR_CHOICE: strlcpy(g_console.default_rom_startup_dir, path, sizeof(g_console.default_rom_startup_dir)); break; +#ifdef HAVE_XML case PATH_CHEATS_DIR_CHOICE: strlcpy(g_settings.cheat_database, path, sizeof(g_settings.cheat_database)); break; +#endif } menu_stack_decrement(); @@ -1515,6 +1527,7 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) strlcpy(g_console.default_sram_dir, default_paths.sram_dir, sizeof(g_console.default_sram_dir)); break; +#ifdef HAVE_XML case SETTING_PATH_CHEATS: if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { @@ -1529,6 +1542,7 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) strlcpy(g_settings.cheat_database, default_paths.port_dir, sizeof(g_settings.cheat_database)); break; +#endif case SETTING_PATH_SYSTEM: if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { @@ -1572,7 +1586,9 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch { strlcpy(g_console.default_rom_startup_dir, "/", sizeof(g_console.default_rom_startup_dir)); strlcpy(g_console.default_savestate_dir, default_paths.port_dir, sizeof(g_console.default_savestate_dir)); +#ifdef HAVE_XML strlcpy(g_settings.cheat_database, default_paths.port_dir, sizeof(g_settings.cheat_database)); +#endif strlcpy(g_console.default_sram_dir, "", sizeof(g_console.default_sram_dir)); menu_stack_refresh(items, current_menu); @@ -2452,7 +2468,9 @@ void menu_loop(void) break; case PATH_SAVESTATES_DIR_CHOICE: case PATH_DEFAULT_ROM_DIR_CHOICE: +#ifdef HAVE_XML case PATH_CHEATS_DIR_CHOICE: +#endif case PATH_SRAM_DIR_CHOICE: select_directory(rmenu_items, current_menu, trig_state); fb = &tmpBrowser; diff --git a/console/rmenu/rmenu.h b/console/rmenu/rmenu.h index ff99b31f72..073e1b0e62 100644 --- a/console/rmenu/rmenu.h +++ b/console/rmenu/rmenu.h @@ -106,7 +106,9 @@ enum LIBRETRO_CHOICE, PATH_SAVESTATES_DIR_CHOICE, PATH_DEFAULT_ROM_DIR_CHOICE, +#ifdef HAVE_XML PATH_CHEATS_DIR_CHOICE, +#endif PATH_SRAM_DIR_CHOICE, PATH_SYSTEM_DIR_CHOICE, INPUT_PRESET_CHOICE, @@ -160,7 +162,9 @@ enum SETTING_PATH_DEFAULT_ROM_DIRECTORY, SETTING_PATH_SAVESTATES_DIRECTORY, SETTING_PATH_SRAM_DIRECTORY, +#ifdef HAVE_XML SETTING_PATH_CHEATS, +#endif SETTING_PATH_SYSTEM, SETTING_ENABLE_SRAM_PATH, SETTING_ENABLE_STATE_PATH, diff --git a/console/rmenu/rmenu_entries.h b/console/rmenu/rmenu_entries.h index 80f4332aca..2c881a7a8f 100644 --- a/console/rmenu/rmenu_entries.h +++ b/console/rmenu/rmenu_entries.h @@ -356,6 +356,7 @@ item rmenu_items[MAX_NO_OF_CONTROLS_SETTINGS] = "INFO - Set the default SRAM (SaveRAM) directory path. All the\nbattery backup saves will be stored in this directory.", WHITE, }, +#ifdef HAVE_XML { SETTING_PATH_CHEATS, "Cheatfile Directory", @@ -366,6 +367,7 @@ item rmenu_items[MAX_NO_OF_CONTROLS_SETTINGS] = "INFO - Set the default [Cheatfile directory] path. All CHT (cheat) files\nwill be stored here.", WHITE, }, +#endif { SETTING_PATH_SYSTEM, "System Directory", From 50ce3fc6c9b363236e021fd7efa23e939904520e Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 4 Aug 2012 07:26:50 +0200 Subject: [PATCH 033/492] More ifdeffing out of cheat settings if HAVE_XML is not defined --- console/rarch_console_config.c | 2 ++ console/rarch_console_settings.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/console/rarch_console_config.c b/console/rarch_console_config.c index 4b62aa272b..1c303ac7c5 100644 --- a/console/rarch_console_config.c +++ b/console/rarch_console_config.c @@ -47,7 +47,9 @@ void rarch_config_load(const char * conf_name, const char * libretro_dir_path, c #endif CONFIG_GET_STRING(system_directory, "system_directory"); +#ifdef HAVE_XML CONFIG_GET_STRING(cheat_database, "cheat_database"); +#endif CONFIG_GET_BOOL(rewind_enable, "rewind_enable"); CONFIG_GET_STRING(video.cg_shader_path, "video_cg_shader"); #ifdef HAVE_FBO diff --git a/console/rarch_console_settings.c b/console/rarch_console_settings.c index de0fab99e8..d49e28b0e3 100644 --- a/console/rarch_console_settings.c +++ b/console/rarch_console_settings.c @@ -316,7 +316,9 @@ void rarch_settings_set_default (const input_driver_t *input) { // g_settings g_settings.rewind_enable = false; +#ifdef HAVE_XML strlcpy(g_settings.cheat_database, default_paths.port_dir, sizeof(g_settings.cheat_database)); +#endif #if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) strlcpy(g_settings.video.cg_shader_path, default_paths.shader_file, sizeof(g_settings.video.cg_shader_path)); From fe299c19a7d61fdb26cb387ef485bb626d84c023 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 4 Aug 2012 16:53:34 +0200 Subject: [PATCH 034/492] (RMenu) Dehardcode some font paths --- console/rmenu/rmenu.c | 34 +++++++++++++++++----------------- console/rmenu/rmenu.h | 8 ++++++++ 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index 1d9cf65cdf..001d157f33 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -608,20 +608,22 @@ static void display_menubar(menu *current_menu) #else float font_size = HARDCODE_FONT_SIZE; #endif + float current_path_y_position = CURRENT_PATH_Y_POSITION; + float msg_prev_next_y_position = MSG_PREV_NEXT_Y_POSITION; snprintf(rarch_version, sizeof(rarch_version), "v%s", PACKAGE_VERSION); switch(current_menu->enum_id) { case GENERAL_VIDEO_MENU: - render_msg_place_func(x_position, 0.03f, font_size, WHITE, "NEXT ->"); + render_msg_place_func(x_position, msg_prev_next_y_position, font_size, WHITE, "NEXT ->"); break; case GENERAL_AUDIO_MENU: case EMU_GENERAL_MENU: case EMU_VIDEO_MENU: case EMU_AUDIO_MENU: case PATH_MENU: - render_msg_place_func(x_position, 0.03f, font_size, WHITE, "<- PREV | NEXT ->"); + render_msg_place_func(x_position, msg_prev_next_y_position, font_size, WHITE, "<- PREV | NEXT ->"); break; case CONTROLS_MENU: case INGAME_MENU_RESIZE: @@ -636,7 +638,7 @@ static void display_menubar(menu *current_menu) case PATH_CHEATS_DIR_CHOICE: #endif case PATH_SRAM_DIR_CHOICE: - render_msg_place_func(x_position, 0.03f, font_size, WHITE, "<- PREV"); + render_msg_place_func(x_position, msg_prev_next_y_position, font_size, WHITE, "<- PREV"); break; default: break; @@ -658,11 +660,7 @@ static void display_menubar(menu *current_menu) fb = &tmpBrowser; case FILE_BROWSER_MENU: snprintf(current_path, sizeof(current_path), "PATH: %s", filebrowser_get_current_dir(fb)); -#ifdef _XBOX1 - render_msg_place_func(x_position, current_y_position, 0, 0, current_path); -#else - render_msg_place_func(x_position, 0.09f, FONT_SIZE, YELLOW, current_path); -#endif + render_msg_place_func(x_position, current_path_y_position, FONT_SIZE, YELLOW, current_path); break; default: break; @@ -784,7 +782,7 @@ static void select_file(item *items, menu *current_menu, uint64_t input) float x_position = POSITION_X; float comment_y_position = COMMENT_Y_POSITION; - float comment_two_y_position = 0.91f; + float comment_two_y_position = COMMENT_TWO_Y_POSITION; float font_size = HARDCODE_FONT_SIZE; switch(current_menu->enum_id) @@ -895,7 +893,8 @@ static void select_directory(item *items, menu *current_menu, uint64_t input) float x_position = POSITION_X; float comment_y_position = COMMENT_Y_POSITION; - float comment_two_y_position = 0.91f; + float y_position_increment = POSITION_Y_INCREMENT; + float comment_two_y_position = COMMENT_TWO_Y_POSITION; float font_size = HARDCODE_FONT_SIZE; bool is_dir = filebrowser_get_current_path_isdir(&tmpBrowser); @@ -965,7 +964,7 @@ static void select_directory(item *items, menu *current_menu, uint64_t input) render_msg_place_func(x_position, comment_two_y_position, font_size, YELLOW, msg); snprintf(msg, sizeof(msg), "[%s] - Reset to startdir", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_START)); - render_msg_place_func(x_position, comment_two_y_position + 0.04f, FONT_SIZE, YELLOW, msg); + render_msg_place_func(x_position, comment_two_y_position + (y_position_increment * 1), FONT_SIZE, YELLOW, msg); snprintf(msg, sizeof(msg), "INFO - Browse to a directory and assign it as the path by\npressing [%s].", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_Y)); render_msg_place_func(x_position, comment_y_position, font_size, LIGHTBLUE, msg); @@ -1741,7 +1740,7 @@ static void select_setting(item *items, menu *current_menu, uint64_t input) float x_position = POSITION_X; float x_position_center = POSITION_X_CENTER; float comment_y_position = COMMENT_Y_POSITION; - float comment_two_y_position = 0.91f; + float comment_two_y_position = COMMENT_TWO_Y_POSITION; float font_size = HARDCODE_FONT_SIZE; settings_action_t action = SETTINGS_ACTION_NOOP; @@ -1778,7 +1777,7 @@ static void select_setting(item *items, menu *current_menu, uint64_t input) render_msg_place_func(x_position, comment_y_position, font_size, LIGHTBLUE, items[current_menu->selected].comment); - snprintf(msg, sizeof(msg), "[%s] + [%s] - resume game | [%s] -go forward", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_L3), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R3), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R)); + snprintf(msg, sizeof(msg), "[%s] + [%s] - resume game | [%s] - go forward", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_L3), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R3), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R)); render_msg_place_func(x_position, comment_two_y_position, FONT_SIZE, YELLOW, msg); snprintf(msg, sizeof(msg), "[%s] - default | [%s]/[%s] - go back", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_START), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_L), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_A)); render_msg_place_func(x_position, comment_two_y_position + 0.04f, FONT_SIZE, YELLOW, msg); @@ -1814,7 +1813,8 @@ static void select_rom(item *items, menu *current_menu, uint64_t input) float x_position = POSITION_X; float comment_y_position = COMMENT_Y_POSITION; - float comment_two_y_position = 0.91f; + float y_position_increment = POSITION_Y_INCREMENT; + float comment_two_y_position = COMMENT_TWO_Y_POSITION; float font_size = HARDCODE_FONT_SIZE; browser_update(&browser, input, rarch_console_get_rom_ext()); @@ -1851,7 +1851,7 @@ static void select_rom(item *items, menu *current_menu, uint64_t input) #endif render_msg_place_func (x_position, comment_two_y_position, FONT_SIZE, YELLOW, msg); - render_msg_place_func(x_position, comment_two_y_position + 0.04f, FONT_SIZE, YELLOW, msg2); + render_msg_place_func(x_position, comment_two_y_position + (y_position_increment * 1), FONT_SIZE, YELLOW, msg2); } @@ -1932,8 +1932,8 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) snprintf(viewport_x, sizeof(viewport_x), "Viewport X: #%d", g_console.viewports.custom_vp.x); snprintf(viewport_y, sizeof(viewport_y), "Viewport Y: #%d", g_console.viewports.custom_vp.y); - snprintf(viewport_w, sizeof(viewport_w), "Viewport Width: #%d", g_console.viewports.custom_vp.width); - snprintf(viewport_h, sizeof(viewport_h), "Viewport Height: #%d", g_console.viewports.custom_vp.height); + snprintf(viewport_w, sizeof(viewport_w), "Viewport W: #%d", g_console.viewports.custom_vp.width); + snprintf(viewport_h, sizeof(viewport_h), "Viewport Ht: #%d", g_console.viewports.custom_vp.height); render_msg_place_func(x_position, y_position, font_size, GREEN, viewport_x); render_msg_place_func(x_position, y_position+(y_position_increment*1), font_size, GREEN, viewport_y); diff --git a/console/rmenu/rmenu.h b/console/rmenu/rmenu.h index 073e1b0e62..427b609a81 100644 --- a/console/rmenu/rmenu.h +++ b/console/rmenu/rmenu.h @@ -32,11 +32,15 @@ #define POSITION_Y_START 0.10f #define POSITION_Y_BEGIN (POSITION_Y_START + POSITION_Y_INCREMENT) #define POSITION_Y_INCREMENT 0.035f +#define COMMENT_TWO_Y_POSITION 0.91f #define COMMENT_Y_POSITION 0.83f #define MSG_QUEUE_X_POSITION g_settings.video.msg_pos_x #define MSG_QUEUE_Y_POSITION 0.75f #define MSG_QUEUE_FONT_SIZE 1.05f + +#define MSG_PREV_NEXT_Y_POSITION 0.03f +#define CURRENT_PATH_Y_POSITION 0.09f #elif defined(_XBOX1) #define DEVICE_CAST xdk_d3d_video_t* #define input_ptr input_xinput @@ -53,10 +57,14 @@ #define POSITION_Y_BEGIN (POSITION_Y_START + POSITION_Y_INCREMENT) #define POSITION_Y_INCREMENT 20 #define COMMENT_Y_POSITION (ypos - POSITION_Y_INCREMENT) +#define COMMENT_TWO_Y_POSITION (ypos + ((POSITION_Y_INCREMENT/2) *1)) #define MSG_QUEUE_X_POSITION POSITION_X #define MSG_QUEUE_Y_POSITION (ypos - (POSITION_Y_INCREMENT * 2)) #define MSG_QUEUE_FONT_SIZE HARDCODE_FONT_SIZE + +#define MSG_PREV_NEXT_Y_POSITION 24 +#define CURRENT_PATH_Y_POSITION (m_menuMainRomListPos_y) #endif typedef struct From d1d587b988e6ebea6e2a10399bf9dcfa66c756d2 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 4 Aug 2012 17:21:49 +0200 Subject: [PATCH 035/492] (RMenu) Changes --- console/rmenu/rmenu.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index 001d157f33..4be095a30b 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -1739,6 +1739,7 @@ static void select_setting(item *items, menu *current_menu, uint64_t input) float x_position = POSITION_X; float x_position_center = POSITION_X_CENTER; + float y_position_increment = POSITION_Y_INCREMENT; float comment_y_position = COMMENT_Y_POSITION; float comment_two_y_position = COMMENT_TWO_Y_POSITION; float font_size = HARDCODE_FONT_SIZE; @@ -1780,7 +1781,7 @@ static void select_setting(item *items, menu *current_menu, uint64_t input) snprintf(msg, sizeof(msg), "[%s] + [%s] - resume game | [%s] - go forward", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_L3), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R3), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R)); render_msg_place_func(x_position, comment_two_y_position, FONT_SIZE, YELLOW, msg); snprintf(msg, sizeof(msg), "[%s] - default | [%s]/[%s] - go back", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_START), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_L), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_A)); - render_msg_place_func(x_position, comment_two_y_position + 0.04f, FONT_SIZE, YELLOW, msg); + render_msg_place_func(x_position, comment_two_y_position + (y_position_increment * 1), FONT_SIZE, YELLOW, msg); } static void menu_romselect_iterate(filebrowser_t *filebrowser, item *items, menu_romselect_action_t action) @@ -1845,10 +1846,8 @@ static void select_rom(item *items, menu *current_menu, uint64_t input) display_menubar(current_menu); -#ifdef __CELLOS_LV2__ snprintf(msg, sizeof(msg), "[%s] + [%s] - resume game", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_L3), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R3)); snprintf(msg2, sizeof(msg2), "[%s] - Settings", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_SELECT)); -#endif render_msg_place_func (x_position, comment_two_y_position, FONT_SIZE, YELLOW, msg); render_msg_place_func(x_position, comment_two_y_position + (y_position_increment * 1), FONT_SIZE, YELLOW, msg2); From 6826301b75de6060458731c485f6abf85cf238dc Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sat, 4 Aug 2012 17:30:31 +0200 Subject: [PATCH 036/492] (PS3) Debug fonts show again + menu label tweaks --- console/rmenu/rmenu.c | 16 ++++++++-------- gfx/fonts/ps3_libdbgfont.c | 1 + 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index 4be095a30b..07b0a8b8ad 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -960,7 +960,7 @@ static void select_directory(item *items, menu *current_menu, uint64_t input) display_menubar(current_menu); - snprintf(msg, sizeof(msg), "[%s] - Enter dir | [%s] - Return to settings", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_X)); + snprintf(msg, sizeof(msg), "[%s] - Enter dir | [%s] - Go back", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_X)); render_msg_place_func(x_position, comment_two_y_position, font_size, YELLOW, msg); snprintf(msg, sizeof(msg), "[%s] - Reset to startdir", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_START)); @@ -1932,7 +1932,7 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) snprintf(viewport_x, sizeof(viewport_x), "Viewport X: #%d", g_console.viewports.custom_vp.x); snprintf(viewport_y, sizeof(viewport_y), "Viewport Y: #%d", g_console.viewports.custom_vp.y); snprintf(viewport_w, sizeof(viewport_w), "Viewport W: #%d", g_console.viewports.custom_vp.width); - snprintf(viewport_h, sizeof(viewport_h), "Viewport Ht: #%d", g_console.viewports.custom_vp.height); + snprintf(viewport_h, sizeof(viewport_h), "Viewport H: #%d", g_console.viewports.custom_vp.height); render_msg_place_func(x_position, y_position, font_size, GREEN, viewport_x); render_msg_place_func(x_position, y_position+(y_position_increment*1), font_size, GREEN, viewport_y); @@ -1959,20 +1959,20 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_L), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_LEFT)); render_msg_place_func (x_position, y_position+(y_position_increment*9), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*9), font_size, LIGHTBLUE, "- Viewport Width --"); + render_msg_place_func (x_position_center, y_position+(y_position_increment*9), font_size, LIGHTBLUE, "- Viewport W --"); snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_RIGHT)); render_msg_place_func (x_position, y_position+(y_position_increment*10), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*10), font_size, LIGHTBLUE, "- Viewport Width ++"); + render_msg_place_func (x_position_center, y_position+(y_position_increment*10), font_size, LIGHTBLUE, "- Viewport W ++"); snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_L2), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_UP)); render_msg_place_func (x_position, y_position+(y_position_increment*11), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*11), font_size, LIGHTBLUE, "- Viewport Height ++"); + render_msg_place_func (x_position_center, y_position+(y_position_increment*11), font_size, LIGHTBLUE, "- Viewport H ++"); snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R2), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_DOWN)); render_msg_place_func (x_position, y_position+(y_position_increment*12), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*12), font_size, LIGHTBLUE, "- Viewport Height --"); + render_msg_place_func (x_position_center, y_position+(y_position_increment*12), font_size, LIGHTBLUE, "- Viewport H --"); snprintf(msg, sizeof(msg), "[%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_X)); render_msg_place_func (x_position, y_position+(y_position_increment*13), font_size, LIGHTBLUE, msg); @@ -1980,11 +1980,11 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) snprintf(msg, sizeof(msg), "[%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_Y)); render_msg_place_func (x_position, y_position+(y_position_increment*14), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*14), font_size, LIGHTBLUE, "- Show Game Screen"); + render_msg_place_func (x_position_center, y_position+(y_position_increment*14), font_size, LIGHTBLUE, "- Show Game"); snprintf(msg, sizeof(msg), "[%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_A)); render_msg_place_func (x_position, y_position+(y_position_increment*15), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*15), font_size, LIGHTBLUE, "- Return to Ingame Menu"); + render_msg_place_func (x_position_center, y_position+(y_position_increment*15), font_size, LIGHTBLUE, "- Go back"); snprintf(msg, sizeof(msg), "Allows you to resize the screen by moving around the two analog sticks.\nPress [%s] to reset to defaults, and [%s] to go back.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_X), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_A)); render_msg_place_func (x_position, comment_y_position, font_size, LIGHTBLUE, msg); diff --git a/gfx/fonts/ps3_libdbgfont.c b/gfx/fonts/ps3_libdbgfont.c index 17586eea87..0b43958c13 100644 --- a/gfx/fonts/ps3_libdbgfont.c +++ b/gfx/fonts/ps3_libdbgfont.c @@ -42,6 +42,7 @@ void gl_render_msg(void *data, const char *msg) cellDbgFontPrintf(g_settings.video.msg_pos_x, 0.75f, 1.06f, SILVER, msg); cellDbgFontPrintf(g_settings.video.msg_pos_x, 0.75f, 1.05f, WHITE, msg); + cellDbgFontDraw(); //post } void gl_render_msg_place(void *data, float x, float y, float scale, uint32_t color, const char *msg) From 104ff161695a018d5d1dfa19b14f787f72df24cf Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 4 Aug 2012 20:57:59 +0200 Subject: [PATCH 037/492] (RMenu) New backgrounds --- console/rmenu/rmenu.c | 8 ++++---- console/rmenu/rmenu.h | 6 +++--- .../USRDIR/cores/borders/Menu/main-menu.png | Bin 180904 -> 45307 bytes xbox1/Media/menuMainBG.png | Bin 6415 -> 16746 bytes xbox1/Media/menuMainBG_720p.png | Bin 20341 -> 31787 bytes 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index 07b0a8b8ad..fac47d5142 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -2270,14 +2270,14 @@ void menu_init (void) if(width == 640) { d3d_surface_new(&m_menuMainBG, "D:\\Media\\menuMainBG.png"); - m_menuMainRomListPos_x = 100; - m_menuMainRomListPos_y = 100; + m_menuMainRomListPos_x = 60; + m_menuMainRomListPos_y = 80; } else if(width == 1280) { d3d_surface_new(&m_menuMainBG, "D:\\Media\\menuMainBG_720p.png"); - m_menuMainRomListPos_x = 400; - m_menuMainRomListPos_y = 150; + m_menuMainRomListPos_x = 360; + m_menuMainRomListPos_y = 130; } // Load rom selector panel diff --git a/console/rmenu/rmenu.h b/console/rmenu/rmenu.h index 427b609a81..7f4e5d7770 100644 --- a/console/rmenu/rmenu.h +++ b/console/rmenu/rmenu.h @@ -56,11 +56,11 @@ #define POSITION_Y_START m_menuMainRomListPos_y #define POSITION_Y_BEGIN (POSITION_Y_START + POSITION_Y_INCREMENT) #define POSITION_Y_INCREMENT 20 -#define COMMENT_Y_POSITION (ypos - POSITION_Y_INCREMENT) -#define COMMENT_TWO_Y_POSITION (ypos + ((POSITION_Y_INCREMENT/2) *1)) +#define COMMENT_Y_POSITION (ypos - ((POSITION_Y_INCREMENT/2) * 3)) +#define COMMENT_TWO_Y_POSITION (ypos - ((POSITION_Y_INCREMENT/2) * 1)) #define MSG_QUEUE_X_POSITION POSITION_X -#define MSG_QUEUE_Y_POSITION (ypos - (POSITION_Y_INCREMENT * 2)) +#define MSG_QUEUE_Y_POSITION (ypos - ((POSITION_Y_INCREMENT/2) * 7)) #define MSG_QUEUE_FONT_SIZE HARDCODE_FONT_SIZE #define MSG_PREV_NEXT_Y_POSITION 24 diff --git a/ps3/pkg/USRDIR/cores/borders/Menu/main-menu.png b/ps3/pkg/USRDIR/cores/borders/Menu/main-menu.png index 3056a1b781cc093c3e49a988dd41574f6b097cfb..eb8c60cb37dcced5aab76186e04b56e05a2ae6d2 100644 GIT binary patch literal 45307 zcmce;WmuK#8Z|n>00S&aQY=bQB&EebK|qvF1p%cSBrTA}K#^8dKvF=u3__(;x=TPB zr2C9_?dzQF+TZzgejN8&*IJvUbH4L=?ilwNhwmM>{n>f3emD-?|;*q75rB;?$|K{=$AM^cNzwBRTrDQ*NkbT?N>tX$! z)5{wsEWGdU{B)hYP`~yGMO1s9-FV)h;^SLgwI|7MQ=F-Pdw(ZcSA0mul{qFKcR4Px zvE170G3R178L&wVIp_DyMwHAAjlYV2Uy!NKzq9G%kof$?awqkf%CPA9I`^p58=*Tt ziPuI68jCH9v`$A380HnV#aL=94vL8VjES!suMsVud;f|jD2;!w? z%BDELLTNU-K5TjW%;FCFl9+L4(T1sww(Sn(vp*gQ&DF0B1(>B|dS-8OiRtJlAJ1hK zD+sQ67NdEGu|i_ZDL`6(nq^TpBYtJAUUOnq*Jhl2(N$J`C90v*QMjv^W3{@8*0Vs^ zv&(A2Cg$suQ^Sb;Y}XWvM0Q=CN5L|GcJyRR=a63A9cEb*m*@>0LDHj1{2AWTgWKYEtTN7-14wOXE4zDl+$s)2m5oc@dOPw8Slis3-X?_}0il&=c-Ns>?Wj~8Tgu(($T z1+@jujkWA1#f^@Jy%Ue`thpER2dDAZI+&~WSjglKW zg74hO*?E`jxbnWvePVqNF1WUJ?Ag#3U05PLc3|gVmRRuM#ffKTYdV`hNc4ryr;ax5 zX=~PWy5ux-Yy0gDu2mBK_cEgEpGDJ=oaUxBWsnOzTsBW(Yn_(-(LrXdL=_=w=jLQz zAg#_uVH&W}rQP8yQ^6ni!HbB&C&opK zE$Zml=$5_-^Hqr#!r28JB~3GNUG%QK=`-aeZDLD%&si-=Bnz)geyly?s92mmpk^6^!)FK@<|AN_io$2e&SPOAj7;aE2l=<^RGvlrTafW zks_JGe?L%Bbjah1Piqo`!9zNdimbxR^E#jYem571sk&Al4m%+)T8SwQ#fG@dl;Aek ziza1b(vm&Xfs6gW+6CTSd@6A%)͏>`K{FJI&F!}xT4&VBE6=e;L=A$o% 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 literal 6415 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 diff --git a/xbox1/Media/menuMainBG_720p.png b/xbox1/Media/menuMainBG_720p.png index 2bd9482cc13556020cdbdeff58ea4eb8e4f4ebe5..6991ec60aa9cb5ba3a933c796c4183e953758e22 100644 GIT binary patch literal 31787 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

q! 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 literal 20341 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 From 755f73cee9842874ead9e10910e906776b07d7ac Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sat, 4 Aug 2012 21:43:46 +0200 Subject: [PATCH 038/492] (RMenu) Graphical tweaks --- console/rmenu/rmenu.c | 10 +++++----- console/rmenu/rmenu.h | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index fac47d5142..c22ea40f07 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -466,28 +466,28 @@ static void menu_stack_push(item *items, unsigned menu_id) current_menu->category_id = CATEGORY_INGAME_MENU; break; case FILE_BROWSER_MENU: - strlcpy(current_menu->title, "File Browser", sizeof(current_menu->title)); + strlcpy(current_menu->title, "Filebrowser", sizeof(current_menu->title)); current_menu->enum_id = menu_id; current_menu->selected = 0; current_menu->page = 0; current_menu->category_id = CATEGORY_FILEBROWSER; break; case LIBRETRO_CHOICE: - strlcpy(current_menu->title, "Libretro cores", sizeof(current_menu->title)); + strlcpy(current_menu->title, "Libretro", sizeof(current_menu->title)); current_menu->enum_id = menu_id; current_menu->selected = 0; current_menu->page = 0; current_menu->category_id = CATEGORY_FILEBROWSER; break; case PRESET_CHOICE: - strlcpy(current_menu->title, "Shader presets", sizeof(current_menu->title)); + strlcpy(current_menu->title, "Shader", sizeof(current_menu->title)); current_menu->enum_id = menu_id; current_menu->selected = 0; current_menu->page = 0; current_menu->category_id = CATEGORY_FILEBROWSER; break; case INPUT_PRESET_CHOICE: - strlcpy(current_menu->title, "Input presets", sizeof(current_menu->title)); + strlcpy(current_menu->title, "Input", sizeof(current_menu->title)); current_menu->enum_id = menu_id; current_menu->selected = 0; current_menu->page = 0; @@ -514,7 +514,7 @@ static void menu_stack_push(item *items, unsigned menu_id) case PATH_CHEATS_DIR_CHOICE: #endif case PATH_SYSTEM_DIR_CHOICE: - strlcpy(current_menu->title, "Path Selection", sizeof(current_menu->title)); + strlcpy(current_menu->title, "Path", sizeof(current_menu->title)); current_menu->enum_id = menu_id; current_menu->selected = 0; current_menu->page = 0; diff --git a/console/rmenu/rmenu.h b/console/rmenu/rmenu.h index 7f4e5d7770..651936ef5e 100644 --- a/console/rmenu/rmenu.h +++ b/console/rmenu/rmenu.h @@ -26,14 +26,14 @@ #define FONT_SIZE (g_console.menu_font_size) #define render_msg_place_func(xpos, ypos, scale, color, msg) gl_render_msg_place(DEVICE_PTR, xpos, ypos, scale, color, msg) -#define NUM_ENTRY_PER_PAGE 17 +#define NUM_ENTRY_PER_PAGE 16 #define POSITION_X 0.09f #define POSITION_X_CENTER 0.5f -#define POSITION_Y_START 0.10f +#define POSITION_Y_START 0.13f #define POSITION_Y_BEGIN (POSITION_Y_START + POSITION_Y_INCREMENT) #define POSITION_Y_INCREMENT 0.035f #define COMMENT_TWO_Y_POSITION 0.91f -#define COMMENT_Y_POSITION 0.83f +#define COMMENT_Y_POSITION 0.82f #define MSG_QUEUE_X_POSITION g_settings.video.msg_pos_x #define MSG_QUEUE_Y_POSITION 0.75f From c531908d214f15bb3abf2bd607b011355c0e1546 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 4 Aug 2012 22:55:37 +0200 Subject: [PATCH 039/492] (Xbox 1/RMenu) Aesthetic tweaks + original GIMP image --- console/rmenu/images/main-menu.xcf | Bin 0 -> 783026 bytes console/rmenu/rmenu.c | 1 + console/rmenu/rmenu.h | 4 ++-- xbox1/Media/menuMainBG.png | Bin 16746 -> 16213 bytes xbox1/xdk_d3d8.cpp | 2 +- 5 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 console/rmenu/images/main-menu.xcf diff --git a/console/rmenu/images/main-menu.xcf b/console/rmenu/images/main-menu.xcf new file mode 100644 index 0000000000000000000000000000000000000000..f9c18f4b70aa831ec3168edea25caf84b8d34b1b GIT binary patch literal 783026 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 am^onPfSChk4*aZgpp|j=6Yz1q;rMTJJa^0h literal 0 HcmV?d00001 diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index c22ea40f07..7e06909a31 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -2538,6 +2538,7 @@ void menu_loop(void) if (message && g_console.info_msg_enable) { + RARCH_LOG("x: %f, y: %f\n", msg_queue_x_position, msg_queue_y_position); render_msg_place_func(msg_queue_x_position, msg_queue_y_position, msg_queue_font_size, WHITE, message); } diff --git a/console/rmenu/rmenu.h b/console/rmenu/rmenu.h index 651936ef5e..161de862c5 100644 --- a/console/rmenu/rmenu.h +++ b/console/rmenu/rmenu.h @@ -60,11 +60,11 @@ #define COMMENT_TWO_Y_POSITION (ypos - ((POSITION_Y_INCREMENT/2) * 1)) #define MSG_QUEUE_X_POSITION POSITION_X -#define MSG_QUEUE_Y_POSITION (ypos - ((POSITION_Y_INCREMENT/2) * 7)) +#define MSG_QUEUE_Y_POSITION (ypos - ((POSITION_Y_INCREMENT/2) * 7) + 5) #define MSG_QUEUE_FONT_SIZE HARDCODE_FONT_SIZE #define MSG_PREV_NEXT_Y_POSITION 24 -#define CURRENT_PATH_Y_POSITION (m_menuMainRomListPos_y) +#define CURRENT_PATH_Y_POSITION (m_menuMainRomListPos_y - ((POSITION_Y_INCREMENT/2))) #endif typedef struct diff --git a/xbox1/Media/menuMainBG.png b/xbox1/Media/menuMainBG.png index e81ea10789ddeb103830ae1f1feb3cb3f7434707..f62a2c39692a7d6076723d06fde6fdb7280ee8c1 100644 GIT binary patch literal 16213 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 HzWl!cbdb}o literal 16746 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 diff --git a/xbox1/xdk_d3d8.cpp b/xbox1/xdk_d3d8.cpp index 0b66cf5e5a..d37f5db9ae 100644 --- a/xbox1/xdk_d3d8.cpp +++ b/xbox1/xdk_d3d8.cpp @@ -474,7 +474,7 @@ static bool xdk_d3d_frame(void *data, const void *frame, } if (msg) - xfonts_render_msg_place(d3d, 100, 390, 0, msg); //TODO: dehardcode x/y here for HD (720p) mode + xfonts_render_msg_place(d3d, 60, 365, 0, msg); //TODO: dehardcode x/y here for HD (720p) mode if(!d3d->block_swap) gfx_ctx_swap_buffers(); From 3c85d9f386b3915c772ef65e0462cd9aec74504e Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sun, 5 Aug 2012 03:00:38 +0200 Subject: [PATCH 040/492] (PS3 / RMenu) Graphic changes --- console/rmenu/rmenu.c | 65 +++++++++--------- console/rmenu/rmenu.h | 15 ++-- gfx/fonts/ps3_libdbgfont.c | 4 +- .../USRDIR/cores/borders/Menu/main-menu.png | Bin 45307 -> 44258 bytes 4 files changed, 44 insertions(+), 40 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index 7e06909a31..d3a0cd22ae 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -609,6 +609,7 @@ static void display_menubar(menu *current_menu) float font_size = HARDCODE_FONT_SIZE; #endif float current_path_y_position = CURRENT_PATH_Y_POSITION; + float current_path_font_size = CURRENT_PATH_FONT_SIZE; float msg_prev_next_y_position = MSG_PREV_NEXT_Y_POSITION; snprintf(rarch_version, sizeof(rarch_version), "v%s", PACKAGE_VERSION); @@ -660,7 +661,7 @@ static void display_menubar(menu *current_menu) fb = &tmpBrowser; case FILE_BROWSER_MENU: snprintf(current_path, sizeof(current_path), "PATH: %s", filebrowser_get_current_dir(fb)); - render_msg_place_func(x_position, current_path_y_position, FONT_SIZE, YELLOW, current_path); + render_msg_place_func(x_position, current_path_y_position, current_path_font_size, WHITE, current_path); break; default: break; @@ -673,7 +674,7 @@ static void display_menubar(menu *current_menu) #else render_msg_place_func(x_position, 0.05f, 1.4f, WHITE, current_menu->title); render_msg_place_func(0.3f, 0.06f, 0.82f, WHITE, m_title); - render_msg_place_func(0.8f, 0.12f, 0.82f, WHITE, rarch_version); + render_msg_place_func(0.80f, 0.015f, 0.82f, WHITE, rarch_version); #endif } @@ -882,7 +883,7 @@ static void select_file(item *items, menu *current_menu, uint64_t input) snprintf(comment_two, sizeof(comment_two), "[%s] - return to settings [%s] - Reset Startdir", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_X), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_START)); render_msg_place_func(x_position, comment_two_y_position, font_size, YELLOW, comment_two); - render_msg_place_func(x_position, comment_y_position, font_size, LIGHTBLUE, comment); + render_msg_place_func(x_position, comment_y_position, font_size, WHITE, comment); } static void select_directory(item *items, menu *current_menu, uint64_t input) @@ -967,7 +968,7 @@ static void select_directory(item *items, menu *current_menu, uint64_t input) render_msg_place_func(x_position, comment_two_y_position + (y_position_increment * 1), FONT_SIZE, YELLOW, msg); snprintf(msg, sizeof(msg), "INFO - Browse to a directory and assign it as the path by\npressing [%s].", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_Y)); - render_msg_place_func(x_position, comment_y_position, font_size, LIGHTBLUE, msg); + render_msg_place_func(x_position, comment_y_position, font_size, WHITE, msg); } static void set_keybind_digital(uint64_t default_retro_joypad_id, uint64_t input) @@ -1776,7 +1777,7 @@ static void select_setting(item *items, menu *current_menu, uint64_t input) } } - render_msg_place_func(x_position, comment_y_position, font_size, LIGHTBLUE, items[current_menu->selected].comment); + render_msg_place_func(x_position, comment_y_position, font_size, WHITE, items[current_menu->selected].comment); snprintf(msg, sizeof(msg), "[%s] + [%s] - resume game | [%s] - go forward", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_L3), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R3), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R)); render_msg_place_func(x_position, comment_two_y_position, FONT_SIZE, YELLOW, msg); @@ -1842,7 +1843,7 @@ static void select_rom(item *items, menu *current_menu, uint64_t input) else snprintf(msg, sizeof(msg), "INFO - Press [%s] to load the game.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_B)); - render_msg_place_func(x_position, comment_y_position, font_size, LIGHTBLUE, msg); + render_msg_place_func(x_position, comment_y_position, font_size, WHITE, msg); display_menubar(current_menu); @@ -1939,55 +1940,55 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) render_msg_place_func(x_position, y_position+(y_position_increment*2), font_size, GREEN, viewport_w); render_msg_place_func(x_position, y_position+(y_position_increment*3), font_size, GREEN, viewport_h); - render_msg_place_func(x_position, y_position+(y_position_increment*4), font_size, LIGHTBLUE, "CONTROLS:"); + render_msg_place_func(x_position, y_position+(y_position_increment*4), font_size, WHITE, "CONTROLS:"); snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_LEFT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_LEFT)); - render_msg_place_func (x_position, y_position+(y_position_increment*5), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*5), font_size, LIGHTBLUE, "- Viewport X --"); + render_msg_place_func (x_position, y_position+(y_position_increment*5), font_size, WHITE, msg); + render_msg_place_func (x_position_center, y_position+(y_position_increment*5), font_size, WHITE, "- Viewport X --"); snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_RIGHT), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_RIGHT)); - render_msg_place_func (x_position, y_position+(y_position_increment*6), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*6), font_size, LIGHTBLUE, "- Viewport X ++"); + render_msg_place_func (x_position, y_position+(y_position_increment*6), font_size, WHITE, msg); + render_msg_place_func (x_position_center, y_position+(y_position_increment*6), font_size, WHITE, "- Viewport X ++"); snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_UP), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_UP)); - render_msg_place_func (x_position, y_position+(y_position_increment*7), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*7), font_size, LIGHTBLUE, "- Viewport Y ++"); + render_msg_place_func (x_position, y_position+(y_position_increment*7), font_size, WHITE, msg); + render_msg_place_func (x_position_center, y_position+(y_position_increment*7), font_size, WHITE, "- Viewport Y ++"); snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_DOWN), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_DOWN)); - render_msg_place_func (x_position, y_position+(y_position_increment*8), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*8), font_size, LIGHTBLUE, "- Viewport Y --"); + render_msg_place_func (x_position, y_position+(y_position_increment*8), font_size, WHITE, msg); + render_msg_place_func (x_position_center, y_position+(y_position_increment*8), font_size, WHITE, "- Viewport Y --"); snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_L), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_LEFT)); - render_msg_place_func (x_position, y_position+(y_position_increment*9), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*9), font_size, LIGHTBLUE, "- Viewport W --"); + render_msg_place_func (x_position, y_position+(y_position_increment*9), font_size, WHITE, msg); + render_msg_place_func (x_position_center, y_position+(y_position_increment*9), font_size, WHITE, "- Viewport W --"); snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_RIGHT)); - render_msg_place_func (x_position, y_position+(y_position_increment*10), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*10), font_size, LIGHTBLUE, "- Viewport W ++"); + render_msg_place_func (x_position, y_position+(y_position_increment*10), font_size, WHITE, msg); + render_msg_place_func (x_position_center, y_position+(y_position_increment*10), font_size, WHITE, "- Viewport W ++"); snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_L2), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_UP)); - render_msg_place_func (x_position, y_position+(y_position_increment*11), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*11), font_size, LIGHTBLUE, "- Viewport H ++"); + render_msg_place_func (x_position, y_position+(y_position_increment*11), font_size, WHITE, msg); + render_msg_place_func (x_position_center, y_position+(y_position_increment*11), font_size, WHITE, "- Viewport H ++"); snprintf(msg, sizeof(msg), "[%s] or [%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_R2), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_DOWN)); - render_msg_place_func (x_position, y_position+(y_position_increment*12), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*12), font_size, LIGHTBLUE, "- Viewport H --"); + render_msg_place_func (x_position, y_position+(y_position_increment*12), font_size, WHITE, msg); + render_msg_place_func (x_position_center, y_position+(y_position_increment*12), font_size, WHITE, "- Viewport H --"); snprintf(msg, sizeof(msg), "[%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_X)); - render_msg_place_func (x_position, y_position+(y_position_increment*13), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*13), font_size, LIGHTBLUE, "- Reset To Defaults"); + render_msg_place_func (x_position, y_position+(y_position_increment*13), font_size, WHITE, msg); + render_msg_place_func (x_position_center, y_position+(y_position_increment*13), font_size, WHITE, "- Reset To Defaults"); snprintf(msg, sizeof(msg), "[%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_Y)); - render_msg_place_func (x_position, y_position+(y_position_increment*14), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*14), font_size, LIGHTBLUE, "- Show Game"); + render_msg_place_func (x_position, y_position+(y_position_increment*14), font_size, WHITE, msg); + render_msg_place_func (x_position_center, y_position+(y_position_increment*14), font_size, WHITE, "- Show Game"); snprintf(msg, sizeof(msg), "[%s]", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_A)); - render_msg_place_func (x_position, y_position+(y_position_increment*15), font_size, LIGHTBLUE, msg); - render_msg_place_func (x_position_center, y_position+(y_position_increment*15), font_size, LIGHTBLUE, "- Go back"); + render_msg_place_func (x_position, y_position+(y_position_increment*15), font_size, WHITE, msg); + render_msg_place_func (x_position_center, y_position+(y_position_increment*15), font_size, WHITE, "- Go back"); - snprintf(msg, sizeof(msg), "Allows you to resize the screen by moving around the two analog sticks.\nPress [%s] to reset to defaults, and [%s] to go back.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_X), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_A)); - render_msg_place_func (x_position, comment_y_position, font_size, LIGHTBLUE, msg); + snprintf(msg, sizeof(msg), "Allows you to resize the screen.\nPress [%s] to reset to defaults, and [%s] to go back.", rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_X), rarch_input_find_platform_key_label(1 << RETRO_DEVICE_ID_JOYPAD_A)); + render_msg_place_func (x_position, comment_y_position, font_size, WHITE, msg); } } @@ -2223,7 +2224,7 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) render_msg_place_func(x_position, (y_position+(y_position_increment*MENU_ITEM_RETURN_TO_DASHBOARD)), font_size, MENU_ITEM_SELECTED(MENU_ITEM_RETURN_TO_DASHBOARD), "Return to Dashboard"); - render_msg_place_func(x_position, comment_y_position, font_size, LIGHTBLUE, comment); + render_msg_place_func(x_position, comment_y_position, font_size, WHITE, comment); #ifdef _XBOX1 d3d_surface_render(&m_menuMainRomSelectPanel, x_position, (y_position+(y_position_increment*g_console.ingame_menu_item)), ROM_PANEL_WIDTH, ROM_PANEL_HEIGHT); diff --git a/console/rmenu/rmenu.h b/console/rmenu/rmenu.h index 161de862c5..8cda02b960 100644 --- a/console/rmenu/rmenu.h +++ b/console/rmenu/rmenu.h @@ -26,21 +26,22 @@ #define FONT_SIZE (g_console.menu_font_size) #define render_msg_place_func(xpos, ypos, scale, color, msg) gl_render_msg_place(DEVICE_PTR, xpos, ypos, scale, color, msg) -#define NUM_ENTRY_PER_PAGE 16 +#define NUM_ENTRY_PER_PAGE 15 #define POSITION_X 0.09f #define POSITION_X_CENTER 0.5f -#define POSITION_Y_START 0.13f -#define POSITION_Y_BEGIN (POSITION_Y_START + POSITION_Y_INCREMENT) +#define POSITION_Y_START 0.17f #define POSITION_Y_INCREMENT 0.035f +#define POSITION_Y_BEGIN (POSITION_Y_START + POSITION_Y_INCREMENT) #define COMMENT_TWO_Y_POSITION 0.91f #define COMMENT_Y_POSITION 0.82f #define MSG_QUEUE_X_POSITION g_settings.video.msg_pos_x -#define MSG_QUEUE_Y_POSITION 0.75f -#define MSG_QUEUE_FONT_SIZE 1.05f +#define MSG_QUEUE_Y_POSITION 0.76f +#define MSG_QUEUE_FONT_SIZE 1.03f #define MSG_PREV_NEXT_Y_POSITION 0.03f -#define CURRENT_PATH_Y_POSITION 0.09f +#define CURRENT_PATH_Y_POSITION 0.15f +#define CURRENT_PATH_FONT_SIZE FONT_SIZE #elif defined(_XBOX1) #define DEVICE_CAST xdk_d3d_video_t* #define input_ptr input_xinput @@ -64,7 +65,9 @@ #define MSG_QUEUE_FONT_SIZE HARDCODE_FONT_SIZE #define MSG_PREV_NEXT_Y_POSITION 24 + #define CURRENT_PATH_Y_POSITION (m_menuMainRomListPos_y - ((POSITION_Y_INCREMENT/2))) +#define CURRENT_PATH_FONT_SIZE 21 #endif typedef struct diff --git a/gfx/fonts/ps3_libdbgfont.c b/gfx/fonts/ps3_libdbgfont.c index 0b43958c13..db98edabbb 100644 --- a/gfx/fonts/ps3_libdbgfont.c +++ b/gfx/fonts/ps3_libdbgfont.c @@ -40,8 +40,8 @@ void gl_render_msg(void *data, const char *msg) { (void)data; - cellDbgFontPrintf(g_settings.video.msg_pos_x, 0.75f, 1.06f, SILVER, msg); - cellDbgFontPrintf(g_settings.video.msg_pos_x, 0.75f, 1.05f, WHITE, msg); + cellDbgFontPrintf(g_settings.video.msg_pos_x, 0.76f, 1.04f, SILVER, msg); + cellDbgFontPrintf(g_settings.video.msg_pos_x, 0.76f, 1.03f, WHITE, msg); cellDbgFontDraw(); //post } diff --git a/ps3/pkg/USRDIR/cores/borders/Menu/main-menu.png b/ps3/pkg/USRDIR/cores/borders/Menu/main-menu.png index eb8c60cb37dcced5aab76186e04b56e05a2ae6d2..3da7b3c26ee589b0cbe70c849409d1a3c089cab1 100644 GIT binary patch literal 44258 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 Qg}y@Vgobk3F{7LR14}F>b^rhX literal 45307 zcmce;WmuK#8Z|n>00S&aQY=bQB&EebK|qvF1p%cSBrTA}K#^8dKvF=u3__(;x=TPB zr2C9_?dzQF+TZzgejN8&*IJvUbH4L=?ilwNhwmM>{n>f3emD-?|;*q75rB;?$|K{=$AM^cNzwBRTrDQ*NkbT?N>tX$! z)5{wsEWGdU{B)hYP`~yGMO1s9-FV)h;^SLgwI|7MQ=F-Pdw(ZcSA0mul{qFKcR4Px zvE170G3R178L&wVIp_DyMwHAAjlYV2Uy!NKzq9G%kof$?awqkf%CPA9I`^p58=*Tt ziPuI68jCH9v`$A380HnV#aL=94vL8VjES!suMsVud;f|jD2;!w? z%BDELLTNU-K5TjW%;FCFl9+L4(T1sww(Sn(vp*gQ&DF0B1(>B|dS-8OiRtJlAJ1hK zD+sQ67NdEGu|i_ZDL`6(nq^TpBYtJAUUOnq*Jhl2(N$J`C90v*QMjv^W3{@8*0Vs^ zv&(A2Cg$suQ^Sb;Y}XWvM0Q=CN5L|GcJyRR=a63A9cEb*m*@>0LDHj1{2AWTgWKYEtTN7-14wOXE4zDl+$s)2m5oc@dOPw8Slis3-X?_}0il&=c-Ns>?Wj~8Tgu(($T z1+@jujkWA1#f^@Jy%Ue`thpER2dDAZI+&~WSjglKW zg74hO*?E`jxbnWvePVqNF1WUJ?Ag#3U05PLc3|gVmRRuM#ffKTYdV`hNc4ryr;ax5 zX=~PWy5ux-Yy0gDu2mBK_cEgEpGDJ=oaUxBWsnOzTsBW(Yn_(-(LrXdL=_=w=jLQz zAg#_uVH&W}rQP8yQ^6ni!HbB&C&opK zE$Zml=$5_-^Hqr#!r28JB~3GNUG%QK=`-aeZDLD%&si-=Bnz)geyly?s92mmpk^6^!)FK@<|AN_io$2e&SPOAj7;aE2l=<^RGvlrTafW zks_JGe?L%Bbjah1Piqo`!9zNdimbxR^E#jYem571sk&Al4m%+)T8SwQ#fG@dl;Aek ziza1b(vm&Xfs6gW+6CTSd@6A%)͏>`K{FJI&F!}xT4&VBE6=e;L=A$o% zH__|75D*gbGfU0eylK;>6w6HGYQ|)Zbn?p3W3tA^al~EMXL62`|2N!XYo5f!q~Z7U zhP2Vr(7edaWuTLvZ?L=>?#<@8vP)1<(85w(Tif4Zr19F!?;llreSBOP{*_n``wfSG zT}jtCGP&qxUC`0dsuxkc`K)rQgANrHmH0=RRr zjNBH5y4R^Aq@Xlqi!3c89GuuA%72BqXhXQ5*^H$7QsfC`Dr)L;=g*(d$ySx~ot&J! zviSqz;>V94&6y@jp^EFH(~G3;>v#6KNwU$LedJhBq{}`xG*_*3s#v5&sJg8ovZC)! z)5zKL=Y3XgN*GHn7^b z-w59vTya1^VNZUle`)ENN72!|m#+psy3^8vtJa;>0X^Ul!cB{G2{Ra;!8;!T!FgG{f z6)wz1A*Flz1Se;Lwh7aX9XV}OTyJ*DNGsD&vVX6y-{@bq|K8oZE9GVBh81U~nMkig zaMG7lRij7U8wRI8_DxZ$s#cE-#aHayy?cL(+K8r@_rJm?YI8wHPDWcr5L#p3HP~l#K=~*XlYU&4{lMBuLV>zuwqY&0U;w>J@YG(dtrkm3Z zS*QcvguH7pH+6K(*8egz<$OtBKNyKbLrdH9<zriEVrW7gdt$cT3K3|&)i@SN_#*N#R{U^#v z0t!zY3v{=#zpfh!!4q_Ntnh})Bc^nlyi!NrX&l*)cRq9W?8hGKecaqzm84b$_8&Mf zyX(NY-=|KU8n7!_TQckS<%r&?mqsr`nXAKFhysE%v;FhyYl`B>OL}^|?Up$%Q)Tp@ zjWa(Qq+gvLs9vb`T)X$^fUN1)uU}2ZmInTnQLS&4VkGxVN$LCg``<%KD2ExRYgqsK zvTL*@Q}!4)_hSVGg#o+!J8vkF@~pZfRn*k{dOknkk)iA`&Lk7jd*q1UI%Jzi?s6nO zJ$?U)6F<#gRrH;*v`qceViFT&Yih#2QAS2aOXZQbmzVF%jQyiWkJy>1A1GT;avj1y z5k(J*-IpDU4pi)abH?8O{qvJ{aU$skjg(tGT`neT=TH+d@~6MjX0rQK$B_NE`}a5Q zWnt;)k(R9!C@m}VCCX}~WkHTboA(9^>U{?eoIZHy(AVVTBYf^lGyIYdF3XvB6|>B@ z+wJ)D=@Ux-{Sy|g?;Dp&-7ZqHH>PMmSeza-?8tZcIWqgr$A@w+8{4r1`}d1VO#XCW zLDtI1y$xWK(#u<08qqd0^v}+rOBI%?dH$RMp~xiM<;Jg;rk7Iq=Nr#L&jYsW7cT}x zb6s1{ zxyMV(#U)=LTf%MOUGCCwl2?bN)Xfrd>6}6tVd$U@P z*w4=w?U`N-`TqTq&D!FiKd!~_%R_dL3aj>=))PhZvDw*b+nI#6S8wRnEpX%t)pZP8 zWDc$Ln(uVoA?7&x;n&wEO09!PyWXXdG+}*NWtu{KOcBS?=cEsRL!1QR%Bm`wx;TX^ z!OSQ3H>T=t%V`UY;Z{J&d=wcOFp^fH*HY|WfJcalpfxGC{~DiRR7qEeRLaF?4?%t6 z4v#w}=ZjNQQBnCV|Ln*Q9&T>(-RHM69GAZM{P?M-m$!yi8mXzJ>J>2_D_J?ANc%l8 z(GMRLbtEkK?74G(mB&hSvf9RaE7&~G+`4trURRjMFG`W)&!0c_XmwMwP5L9Ms;cqs zNAgo&Aq>k@TF!}Fzklb}ty^CzD?b|sOL*^)T#&vsT`in$+Q1za8JRpk(WNgMRYN`d z%0{tOJKgO4+eLxm4^yT!(tMUeHzWg7esFLY&IG59^maIP(M}XjQ_qce@YMbMIfEGP z=&`o{Ca9vW&VeHS7|pWXvCYE6qTYeUFZTWO&it&m0ZO!+gK^QX&INvoJ?mfUf2=rx zS2tgU8bG18s!G5r`S*q4;o(af8VPH2IVH4td3i^jtoA2^uvm2<|rSGx$ zM$}%Dz%td9F^gHLdV(`K2A(*gSy z%*+42_}?@rJ!K(WSL)e37EZOhP8201CYq)P#&YJO=uFjLQQ~3}wyfX5D$YsPJ=yd5 z#Ia*LLiIgPK0B(tIjw0M`cIa2M1+*5WHE|XX?b~X{M$=>H@@!^M>c-**>&LE^{>0D zM`ojcq@&>Z`tIRK9BE3UKUTc3Urt{BTDr!In~cXu`NZXLB_s2VA3FL=B`?!#B9hu;E;FX*D@P0s zisu#Lw^A0H$c{#aKeE6A!galUAmOO_Mwb`}h z39DUe(ML!P4lF%AJGz{6B`uh6Di>K~sx$a8&-Y=T3fjtD7SlMafC!9Z2mz_R?bkb}L}%s@b~>Bw>s?cd{6 z>=iWi8>Xh8?rz$qMdf*??`0j%%B0<8B!z*`;QnP5mDd-z(mhsP+^e4ReT!L};g|v* zeOX-0DilGLpK91u?5>e(&AxTpw(3>%+TQMu_XgHOLqfVUYb8IwzVPHKI!WA1^ghmS z-@Z-el&qp%n%}T%yY|`p+RxV)e9&=1c8ABYA3nU9Uf+#R$fET%o4E6(wfBdU&MPRW z(jC>Z|2audLgx8fm8{YMzysy;i$2RvJRLY|MMeE!L$LTC%5%Z2fwHW(&Mcygoz>He zmbCwUsp!B{kLr7QS5!ALnY|;w-84c=vQFf#uWMQNeHzU%5;JhE$v2o{({o5bnVGZFDe`)nnq0`9Yh{t!i2B+C7skL4S`)Ke&G9Q-@YIq`q~PmzUQTpBpcj zFvY1G{Qmy(6Xh)x)iQ@BU5;}>%v`L_-DH3Q(e^P}Sy=#{WGCsk4h6A@8K>5|o_PEA zt@CVy`mViuxp;VZjHUZ zKVsG5Ukhg2<>_dYcu0^w00NRUax7VTdwajTrQ9%#oE>S}aq{HJfskw&O1HTdla$T+ zez8|;qa`@p$Nv1WC7?lIU?8XhX?uHtrMWTx@87?xeeU79688cLl{;M{R@PhQ|1>V{ z@bLIoUQuyQY@)n`-=yY@oZMF8^rnz$vQgrrHg~vDU2E*RRh+io8ir9ceDS z#gDOL7bBw|fDE7!4l=#WQHBy{+5;?h_VVS&&LC7(00H<6%Oj`iTM8V5&E`K3H?`h2UH#=cUfypk5 z_jQA*1z&@efqXK1#D-Hgs@s$nEvxd6CGyd(WOnVPU?J zk<0^*oiu2ep`jiy572@s2+w(Ba$s*)3GBf#Xf1O8bBtPxF{gk!!J567U z^JU7;yXUDO1>()zJT7DSAN+PTj#dGSvxl$F}{xA3TyIw`rLfv^UJ^h1EpJZC1 zXAk-N`x~K)UQ|@H(q4d+%=69bPS+oWH*OUgL;I-DGqCW>8rk zxd=18Q;7frETZ>u@z+{1jCRU&XH@cjrV?(y{q+gQ0U@ErW63pNzI@=X6~6~q>;|MK zhk1+{UCbkY)j7Z7T0l&8Be|mpvqxQbwy<-9KuTG7Tw-GQND>`A{VPx$fTefJ3_cR6 z1=LCnw7eI`x}wLy&Q6AAd)T-p(wCM;jT2KC1Lo12v$dT?t__-*#$5cyRX6yu(wj!g z(2J)+OI9{b57t`EE`p7~2=a)Xot<*a7UCb6?tYFr`nR@f5sb_$+2Bw8wp;q#R+hWg z%YmDGV^&8^a{HfY6L4Xgc`t1$+QGtz{<>d;W&Q;>RMg>_p}MTsuU}hkxl{S=TPcR# z)x@XUwr-s)=vqxZyI|%F4E`u0!XI(?eDDaO7jKG|V40pOGT9|q7|bH(eN;R9YUQ(| z&basQC7zz`)}N_zQOoeBMufAyc0T7fq1NH0k9MEaEVIn1BQ@qMd~5OV$?}wH!{9bQe>&C8zpZ4`=PjvR!gJ( zd%sEh^IYjyKawBO$=#W0Qd`dA)P4umpv1HrReHzz#QLh#%CLILC!puF^3u{TAt51- z6nCmmAHmp#G5%&|%Xh6!aX;cPhHN42-MbePU$_NdcAWzY=JCi}&%Q!b6i_td^NfD6 z(oGJf82=l~P0YwLY6m|9p4{=;M&COSVO1V^((X7QM#LtSZ3K>3Z6_++%2co?im_MMJk8lta&mqb<>l*u*biWm0m3yG zig@2Pc1e|1GG+&Q(x;JGgvZOoL^&EdI=|KBc^>@my8{cG+ay_IvgSR4H!NA{Kh|R} zTD?_Ww}}tbLm_5IVt&>rbWV3EqgB6Ao;M_CnbVeRELd~p+O?NmG|f{}Qzs4`I-9S< zJK9m8e$(8%bhsgj@8-{gfVa|ezH6(?pDlAf_uKl$#l<;>nohLk>>w};-4Tu3%M&GR z>bee3PZnjQj$ESI+H!_E z0V*D~{;8--c&Brt7MUGBoH?la0qFy$5DJ=~Cc@vBQv8*J+nlwHitlLg{(ECRv$kdEWH6`E%0uIzUe zXT9&`^_FzTthT88?zR~`>bHRrVWyW>AS%Scw*73i^V&&#Ga`I@kFsuQ#^k1WEKN;OS}>r zK$}g=4%9>?y?*oN>&w#*qU|NF#?(?M)YWTS714hD_|c=n2^^pJpDza%CO_|3jot$; zPBxe|CI0p6-z;0Y?)3HK)(xGJk-7UUEbOgS^Se_m;0}9dU8a7@AA5<`p(HU&0|-Cj zM4gsD%q@;+Sm>DWh@Tm0QW_W-7}nL)Y;DcsCvX4#`^HI&R)M1;BF*i_Ak19wxS;!0 zV`@!;9u3s#=Rp4mqZjfr9XhDG%>Dr_ZQb7aewEkD8W z9z1xa)jXTJ52K<|f>|ZBtgNg(xG_;<*gSFg@Hu%!#b@X;mmqXG&42=ldC*=^27*)bSTH2>J69sN-{Gtu1`aTwFom21=T|@P@%{3M*?nsCPtDkRaNF$G2r&z zfz_TJ%jptIb9m)$)|mWp!w&J=drZWCca@YBqS(KOcy!;}TduFjPgL<=N_$oc=q-$e za)w1Ub=U4IfB~05#Vyo3)@~^rFe|6@ptAqdk5{tFpdyBcO>vXmn0Po=6W_i)<=`Ng zn3z~Kn8mSTq1fc$EY8ZWBkD542~N&?&*!%T6>ZNztd6$lU6JZ=jO0~S-L+@Wfn%6d zEk51f65e51fjM-lbdS0cd_bd!!erfo?1s@&gY*Se2c}xVwRLmtC-tUT zvHB$*g!a%15=DRn>1_v2UlNtPUR;uW;E1pbmPue&xmbQRA(U~c%b?(2OM8#TVJ4Hz4dDs6w<}0 z&+pzH7oV=;2k)R!A`TC8l=JshUCf1RCnsC(IG{qEW`Q&eMa@suJxJ!(h+79g>r->tOv*7QO3+Xk6z;l@+sj7akvyuNRvryaM{XD(xsp zs}Bk3sXh zYm{5JUM4+nW7LOyGYkPNgkX$jXJ;kG-9)1lb*w*bS_1zs$i5K*Mqtea!usP%(7f(2;fuT@T${fTtVKoCMdtMH~cnJ!x#@RZHvKH z3y^l>?VL`RZJ=;ty9C-u$6aP_tn|{Cd;km!0crL_vmqY36~zu#6^K;BQ_l661rBj> zeYJ`}1K!Ri$!ud|tN)>ab4FC%v_EZO7 z>9nmpS{xY}Nv*Kz{`)(-vYuWl&N+cKSe8ZDGE(1DBSr1kuV4E(IAoDRS?TFNCMw4q zlORh}RaGg5J$g}Kv-QSblDXsY#vE0e{?|_n0ANzo9&cfXqS(N*bV`}#%(-*fOA`Mf zh3gv|vzOc2*aSi*ZVQR`9rx4-2X&apnAQ{1kxUC_8N{P9I_WU_#{Kc@?qk4rJ63&w^oCm^85W)U$uf&H} z#BpvNN8v35B}S-YA*gppp=Mtx2fO$34{QosUKt3ovwyUTz`YgDHfmp@Im_wy)8HbE z2FUO;va%HKEs(nW{8#i`$Ff=Yo~8>}fqG1)~&XFS&cGUpv69p%fH_XF{) zUareBYf6MoAzkyRRlqvP!yKg1o4k(OWE*}7HtF;suUIUt@Bj=_9)&IdCo;-3I(F59 z9uqvElc7b6VbI^we~>;h?j{tIdF|=^oPYUY>J>Q@^IS44!j*zeH%gea(R{Rk(cvih z9+(2!>V!ME#Kg4IQd8-GQ7;eF#sovw*bgB$KlQY#DrDn60`1jAi9Ll9*kPLW4RGMV zp+j%VR0?D$H*VT=4XJC9+O~~^>nKA7x)&wp#Ep2KupxVAqiBbF46Qr_SeLc}s;dIZ zQk5ZW5aodNL~|#YN#Ee$rhvq`@Nh;4LrWQS4?V3pzZ`S->XZ1v2K{wa;2Qp_k>5 zjIZP3mQqf&tFAWhvHo}FiK;%lbm7@=aw7~~7#4trhiToB4$vre z0oWiDLcr{C8kPqrA6AS^K$ndzEL?eAJGSLiC1~_4oJ<~M7eM1y@wCfwgwT&11LBK) z`*sUd5A=eEk}(sn`(8-AoX6C392!)}vu6-68w}~0sJ3pE!OR#P5^^vU4HxE|urAc9 zFV)qXNW?jymf-Z>jJM^aF^JkHbQKRE=?}?2d+z=)IyzMeJn2ZP;RyaKGh7hk_M-i0 z+moK_^PV1kKa4Yb=Gv?%Nak(XW3SEHqu&C@u0jws=R2pkvbA(sSr*uCJFB<`8>Rp~ zH8t=4%20@*KMFknc?b#_;wz~H+nwCp3V~z?_C6>f z9k=e5c3=F{pRqVoU7a+o6d$Y@Ut9Zcr<~$x?NbEUV0D{31uV!z08^q8z}=DHx$v3o zo$LI#p3TZ-xn%tkR?qe2u1AnbF()gsNV?_bqrDJx=*+?#kKbJ&88aL(82qBHTP$Gg zGCaF$D3y8WUgW)_yQ`CpbmUrdhWXs?hS&UhwyFPIy!p>^_@Y&<-KKQ3sHAQ+j43r zme@|(9t7g6A}xTDBcR4V@%?s0l(=3DsiX=kUP7zQl1}j|zV>;u5ejPT`}gmgymH8H z#TfoQVQ#7cX>0=l&=4Zwm#<$xo~75lZ-O@usRiZtiRgH52YP`tvR{0m`<_U{Qao%71W@JkSaC);8;&-o=ZDz3`T2d zo~xA;Ht1-l?rr`E7OgH4Jcbd51&@YMVAT^zNfts(yoHl85&{D6WtrR1O=e-pD9Xs# zjrJ3Fi`r`^z;o_sM&%_)=-fO!Vuuo%1gK&>*YdiaKfWx}G+Re~UyNTm$k+GL;^N}c z((Fh&)EK%6RiTLLL50s? zVzqTb&y~E-@f5YSlU1q^{M)!n{-tl~{YffYGiGWE%c5B|Vo>!U>jBucf%k`~mJmg^ z-Vif1FtDy*aq9NtNuAuLNFa<9?VMf|O;i5l8**izY$+yEP=N<3D< zJl)@k_PmKij94&d5MClZFd@D1ThGBZ(w6LZl#AW3(>Xtnt+lbNh>QqBFg_N`Iw+tOR1lRacb(=Ty-wot47z$ZnI{!J8jXwFrR zjg5`HN}fx5Ko_(X|7mVa`Q4MPII~ZL^6-k~IP`PH`^Wnc8a+>HoDs0txO(AeheJRXeNvFf42f ziIagkLTY28;qdB zU52_0K5E~6X)P^AT)^35%4K`I4wyckD4Pvuw6wy}0om{0?y#IMSp39rI-XHUEh$TWi4&X&h~96#y#~P3 z;lUN9r5{YQJ`GO41V4%)LMPIBkFRoIL}cWVCyyVC8g0LBY%KR`htlXCt~Z*CNr|TZ zk^-z^nhp@Z|K&FCNRGdsGAQ%AP3NBvz_%&r!8y=UC^I^J*)Yl3_Lll;xw{uZ%~4j| z?s2E@%HjC70wyNHVR0r{cTxn@B*BrK^{4YiQ?7AqH_l||=idXMaXW5PvGYkzPD+9nHY&7=X}I@O9`!_yxmO`SlV#=?-Hi433iCrgp`7_?p!qL< zf5*jt4A!K{ZFTo|f`5uSL2Ea?8odyHZlR^k3+~lDNzM`TJ4gU*gbByW)KmsM|K37D zdOA99yj>BFvB;FQ1-{dp7f0IUvU2ev$GLC62|;!W#rI`tr7(zCUk#?Zt*Uw!q*Fgi zf3=;JN+6@zNMl38mIt4AP1=dVLZnN1XRIxUheNG~(P9XMilk|M0^O=Q?5C}*t-O`< zh*C{mvjDO_lLH@4MbrC!k>8?~(;)Iu6vh zU)b7h%uKflxl-A`J1i{B!|V`~nRGmO*3|ISe5%+3tDf10oBmqDP!=|W@?%#k@u19~ zKEf<{I6ny41W_aJ3b(B;FFnEG5I%PBzQ=i%K=p$VXw+i~Vt`16pG~@s0_cE#fiqxm zC3nVI9ITfBk64jj+TKZSzx`zEvk&nqfJ7)-a&mIPY2HEp{!efy%{f+VU@^#;)0_om zCYF|#)RJOq475kU%V3-Vk+;;|L ze!TA0aB@I)nTZ^;L)gGW+ExD!X@=)Rs-7I0&d(sv6cdEx3J@~=T!M86K2SjMXWu${ z;1;lXlW*VfkJ3(aj$^?*DD1Q5M@<*L`_{pi&7&dS1iG=n(0Hab{GV`xQW*-oC!o zpJL#?aOjzy;SXHPv#wqAau?e8fwU7{90GAkMZi!%t=G-(ZM}{KgqZN?`STmmh9nWU zh2!7>lht@=&Q3+FX;PBG7vAkmYHww%s9$Uz`D=~DzUC&<4|M`#tnj@mh$pci$w}Sz zqP0V>OOlhfV+Pt)9q(+3Nbsg&3Rt_zCzuh-X{>6!Lt{Bh7wZeVP(Zp%>NJ@?rlpPy z+Ao?yk%jqf5BmB*9)L1%1>q49VLsZpVBvA^;`#HG6VHYY|62t1rTt)Xu4$IF&J!4) zFp4j(%TSuP=k7v4L+QbM7AdI?Eb$E{&WU*qNTqWVT{}pC@*&ktWdAe~JJIgU3s9#{ z@;d0sf~-HLMk4gA$?lK)d3Y+Vj{XAmjVCayY5mu^^9REqv|YB%ur?(15ixyxg%h8XGmWU)q^B3%hsd#94R1Bm21yS~p~D zCU-Zr`<|Go;baj^vq9VuGs)n%==cA4_~gLDGYDHUzYaP6X${7b-8fyKi>JufhnK_6 zIGNb3(Tw>vR}CsR^(t}wO?!P8pn^$(LCBl|zy!4VP9`RQQ1`fs0G9fISWXlRX>;=< z_#?=LjZotKdGjfO<4jaGxy6y$Ubx_k%AvxW_iJ}a#b9lWm7>+CwFq8>M`>=UxvdzH(bk4?`!uEh%C`9Tp6edB zT8u)!Vpvm4hA5qw7z@q`Jg~~$8&W=pV%lO?K^a+Kk|q+oE`MI&2Mm%j?!BA~rB!767MIwxWk=WZ#=o%*|&#JUoIWJAeMX%x6$ad5t+fWH&x5uq8PO zGR>Dxy6w?&@b-8t^iUXq?cIOuSnVi1X`w=D?GEY&ISFX{I0 z+Nk%Q_!YVBHlR@{oN^7frU$m5!LB{JYyi%bczQAtI>0HEj*UTS)7lyuH!L~se*kMk zSYH5eIQ7!hLC?U54|4cv7{3Ymg4L$qN@ScQV)tV3GHGN+8DT zF&ru6fvi|%EjenxR5FgMO`E zhqLw_D>zg0eZ+VYZWRNb7NKFdzP3sPxh=dy^Iwh^rKj(LrPBZ#YXb`#ZzDWGi<3n3 z$lOu`&}#xgRwWP~9c-Jm_J*%k>aX1eCq^QHe4T}b;sObNvryR3SOS;~0!Eg-nJhnm zqY406^GB^cP8v7R+3?r0=I`w+AX83{q|BXDOQMCt1%vnSt}!k|I0ZHHyLOujmT$D` zI@dP4m*=@a!6q!xcFUlshX;S&Is&O1n-t3W5J?_IMUBl%faHc5VJCLmgljE8Rahnm zGT~%kk$Q16d~ZTUS=qH;UmiWYOsLcnLJwL|Lr)leqj|~ccWVrB7G}r}Jj~cIQltx; z4k4vNI=j(N45%n?uS1My*T4!9`XbRvK}`d@GpZH=A#(EYJi!W)M^ht+`&}@*frjRm zj0u)Hn9uMp$2I?J&aDuef3RF(nipUVrhq)t!Rn1}1S_hpO+m*nB!GS3YhbYdb;v+{^M|Ro53O>0HWL&q3io|xfg2AsSGSQ+egL#73AaiM2;b`_ zCWe^v;Cj`_GJV=ww{#uO-fs{$Lm*SuYrC;{MnMu`rY5}DR>g5vaBOVfvgIQZV|!YYSuuQw zxr+l4KhVC8XlGyKi))BW{rE4!s^%f4N(eGoVY;NP?OMLf|0y&zkyGeyfi%#aETsCp zI7^cpF>JNr><#e9!=Qp5K6-SAuny`#J%RVoWA(<&2r_;uqHAR{Xb*w;r%#@|;y83@ zHgUHl*gUv~;lL)0Y>6S4F*EmqZl)(>M-|msn3wIpAi#;v1qY~whZXY31)oFQW*zO^ zc6PWSHZE>6GQn7C{ZD8~Dfp>(j$>L==uw=AJBiqge8S2`OUnhl%KM}c9B@~z?2%mP z-e6aN6`r?=rfCcm=qJFJpTS=qk)eb(ZUC;5SYkMC8FXC6x{vXP14~-rpREMzIqe+; z_Hl?Kb;vwjgFrn9++&VotzNJfg>`L%9Sw&b41-Pk zdxSZ82BqJ&JKoO|`p=EulD{lppjUU1e|F%peCyb=rQ`fXJ%ZJ5Z1ZmMJ>6-Sm-jmE zg^}g?gYqA~?63UruEwooa9*~0#as2+-e+~wi_VjmOp3cEP7d1DI2r#EjH&fSfYDP> zF~09~Jph)dWT8>ps=p$TiC%x{XDFjb*j2dDrrsQL=R##GdM;vPkZMvJeY3CsRn7y0 zbOz6*x)@t9ZXQ3uWeeUNMAFlMe3U)2;?6Z$o~h&H7$5Co3Tk10zT;T<%tV)zBMjbx zod;%z)7Dj!)XGq*>j*Oj>a*zn{Vub^PlFivVl~#~X#>ZKm&b>&%tUOv1yiuOz3ZXh z_Gi&8((TXJDYRorR@c#V9c(K6gsFSw%8~TqqAefr4JahiyQgq1MM%Pz*OQo)>wjSM5=7m7_mS8VI$XTmF;Sjg!5Yz6Ur*RFnaHgHA(l`< zXry?Zg}v~OB4h9C7=vC-ISU32TzHI4V++FbX)~79RE}xBX_666iy@fXb#F8zs>Y4? zK*h8lX*@a{>Xgdnzho5MRGh7rscx*Ip#Ef}liK5zVnq4^_zjTBWmp;&Zs!pU ztt7TX>M$P~vrS|LTa4wZuBRi6v19Ltin6~L(q>w^z$|aU=x&ZkYnhi<;uXWTT@I{x zHC57dY+5Hx+XuI5FKwgJHUw7v`pIjX9YnDkpPlQ2%LoyiaJ@3J z7NEqu8HpGQe>!r_U4O$fUR_2a<9cPKmXz@j**$hB@k4wS%vYK<-gm$X9}9YE2t@s3 zEB6uYsb<6AvzYxqH$8(%r~;Y^J+|#^QOFLj_aE~-`D7xG#h0}GpDR$fj@5&aGl4Cc zCh;6m_Lqw@GHmaWiNw^(!gX5}d6M6P*)!)2jtb`a^P$J|S;4n;cDvtsa?lr_yuy!` z=O>ILNx2dRdZpp~3{BD1&*N@_!4@~JdcF(BUrPcRPQmtW891m8u@H68?ImoMVcV6N z7-N?B5>r!ypk|i-v-$_MtG7Q?U$1Ym$YoXzD`Q_|(4wUr-Jsm)6=JTigB$WHGmia7 zl6so=nB#Cgmu2BpITW^=#2RZJIz$9I&H zeB8lkygm*GK^cI$fLW8w>MbibDk$G&m=}m!;d2~qCN_$gp1B42Bw(ab5*>Q|31D(9 zy^qiS_xE0G%ss}5o`8M-Vx-IPTQeQkn3Z1~efTXwnKhz3x4Q38{E3gWmAf|PDpzN3 z>;2DBlfr9}@KM^i*4Nws^qJf)zP#iE57=*rG(X|CyY4z>hWX?PSj6W*{+mNjE7l3% zzsG_NYr%|}t!tZlXHcjT?rZ;Tf z?xSs)cj#OI!!Ba99mk2*HZ?X{KC!{RqFg89X~lE3$@9>?%~V<@0nyIAzQmd-lcW&N z#sDmXaq2w*1w%}QW-BM8i$GbI9|#uTeLyxS03hdP;6fWNZzh1hrup>()71R(;rWrK zW7UJxgqT`^W|LDcdGNwNza9TaxHZcxl(2{{!p}GqQeC?J>OY5hgB&Xx7x0LWw3jdyLu@&#xV2L3qwK^c$1O{6 zQx{fue_wQy43qNoSi*)!aW1yijAJ^~0egtl#MyBpy|cz(ynvzv+Z_I&W(tN$y1RVE;M;D^)?S`@jYBD#ndr`+``|QJ12{7rFn$xnCMAh_ zl-5i%pxk*Ipgm@r(p^My@OhVdLCF~6+z=*#omM}v9X!m_xB9crFXPyALXH zJTh>?xT4Faq-)0#*hb!L4B#HHb5y_yIHvLb#t+8K;5vaopzbofCj-bYN20t7<5VA` z3m-i7gl_}GKdF`d6Pm#^@VlICgQ|KN(Dr_XI&@*>BXousAJ~>x@cGNR;v;t>&o1E5 ziaU(=VRL+>tQPy&i-<1awLYn}16#eQl&T=a1feRQT@4sqdh;BM^8G}Iv&BiNF99_O zkEGW>c!S-(!*Mu#A|rtnJp;p151b3|!ACkqv|AJyj>r1zOHGUL7H5A);#GBdzBj6T z1}oKFV&}pT8Z`n?y%cA_x@%pEJO+ORicv7}9Swar01HbPIldxTi_Y@f5uoA|@a1DT zz77+P%08m4Zigo;@KA!7!!Qk6gX<_#d2h{I{vU$B%k5AKLj*Kk%-2|U@#0{LU3X< ziBMpY^(PP()&;-hBB36K>bboAg^eC1;uFe%F5)i`Sk5-s{2#Do?u9QNkd0T2>QygU zQoR@@DhNj@3n-*?+x~B8A%IdS(TqRM+}y7txy?qOWLcGvUP%G_NjkmZDWLW4<#bFfJEYi{tcn zkRao^a98&tnEicj_yq0pjOljVW2Q@y7_mG1uY7b=TF3 zrg;->`8t7N6R|FAhWyhs;H4?9@z}v4DnNW8K$&{+pQq1J5dUB$PgDv;yP6l|8t+=a z{@NStKr(`WzfOG70-w>h5bx<9&XItqg+vSM!hPK%>-w*@UPqvbgET`fGne7lCoC{5Su4{X~)59@Smp@j*+V z_1uAQGXprW_@m}Zh9O42;u`9SF?GK>%XkHF z&;$+qv_C&niydjg)qd%>#d8po?*-7-j}bGruWFU*1c=TCEN$=;%QM$8GPJ#JMBEd( zP!%r7lZx-d5m{U4V;Xk~KX}1@qEo^$e<GdI2V1$z%W20YkwS7=heV%v%Vx-FVssFF`zB4MS zC0g@<1jT?TAPR^9MI;N7X+Q);1r)p>f`ViuNzTw_k)#;NNs>sCAQ>71G>T-&p_QDG zoMCnW-uGs`dB0|6t(mp#KT7vGr|MMg+O@;Czk=9IWj+;n$ZiW2I;jOng8*DJ61}#7 zRc9fp8r26g$86a~AtWB~w|j^OUCmkGwGi0{YE*R9K zyNNHr8@TrVkUOYw8sGa`AoQrz?Bxi^E?Q2$#Rwqv<{Ecdb_kg^JYWod7=$e+09FE@ z7*rQ-1g%;pg>(k$4dCf7a{ zcrXsodi=h>E<1MhN?#$UI0@Li2`?2lz09#~ZD~4$>CDI#^INEKh_`Hs;E4lz+6~RA*wEV;nwf3_=XGFRFb=a;_yw_pb@@R~43wnv04}di z6e>z$aJeG8K7yqKA(l7blka5Hg5~!;RD=(ZQU{Ut@PqY(EV5DvOFza6Z*6+>=5YY& zP`dd#3+fSWwe+yIK(4lFejJ1(cEQc#g~uhE4FLH=yCX(4Z}#)dI6% z4FwjZuzRrq?#O(r_OWBftO2HcE|B*|7fh$O#!csA1Te~a1S1zNMT1=!npL#e5&#)c zYbbcK{4F{xHxA@I&3D4h-<1h!gnohuhBvHEe?W@#!?YiO-O&^^0XR*1V3yLB5ct~u>vpsv(4FH@Iury17S_ycagunJr)q;eZph<>FZ1k%GTeVR{ z%L!1J6Q9{u`4Op9S=$AFvA!VW>^eS~FW~Xu)CG8XDe#lTBJ%^yUmhs@7|2JVITZ!3 zp)q$1B0Pj#K;y>%f)|;CJxC0REVh@@-@MU#K}-VgXAtNlZa6|QMIiDxzk=eTLnb_` zih?xW+h)(T73OSBLPuHCtpN5~@Ig%=BK>(D0H3_+oEPn_#+o9MdALRomaH3w?_UWU z&W=gHPWFYhFOOW+@KGjcJRC3`LLli&>Ha+QG*?d0XAiD|>O;!i<wbP+88Gyh^=`m~=fkFqVuxMOO>c0J9}$0ycPny)(<3F?1;Gzr>E&Ovd0^rSqy4)w z-x7I2EYM6efVb8IQV=p>M21@-AeA_Va#biF75VD-VG+1Ve3D~EWo;3~L4f~omK?@%G7Er{7#Xd1ZK!u{gB zVCsR$6NFJcx`FXpqoN>eWIFa z6a&mBRbwH&=8sbE5O0yVfpvoEXair7Vl|V&-v#QXPse3a3fvE?O-4wc(us*gw*{fOufB*{SiRezt>; z-xK6*yFeB1K9|`Mpwv5n+}AMA)rAQ#WKT;b;I6a58nbS*$SH;A?e&Ch%Le>i^RezS zV+&9VoDp_)iuSNZ6$807_W-)X7;H__lX16x39yx|l11iIq;|2195*AB!9Jx2bAxEr zh+vTIgRqEY?oFs>yDT{v`+^2cQq*}o;F=fSY}n_&}5% z1RxN&K2N06>1ZAVR=YuT{Nddn?SBZG16leIpgjq6Uj?}i+!iD7AYW-9wrvcW$>I7cfV}!wFB0AXGj@3g&cC>{*>4{yYa09N#U zWB{X`XacNBBKU-vW%iIbsz8RII50gSm)h~|+)XfU5x>s_Sd9u`?VpL>jl!g7zqnLu z7D1G<6gZBWce^0ng&qzrz5*;Av=`i>@__3}zXI><+y0ED>$ z%pbC_YoTq3U;6<4BH#(U;WZF{K@6nchgn=&VXxT00u)+8AR77eJ1v z`VbHRSFQ}*0YU>kM%4;tV9o0$tQE8W5mXm|1Z{`XU>C{7ftWlfWg>#vH+=u%+2u7& zL#QG#LW9XS;#1)V8v%r5QVYQ8zkn*p3_yngJ=4=i~%+FeFQ)g=z)uprQP*Hr;iiOggq{6IYI4;)8l!B~octPcPZ>Cie`Um#H^q5>Kk zA{Z$6R|Z;954QSY9~GDsG}9drAoJGBtgcK1R~GgfdT6EHrMmJFiWs{?m`8XX57Olr z?r*`}3aw-{146(Kxf+maJ&wZnR4Tu~xP4LW)+eYX%NIyj2+z0AbR-m{rt$&_Ur`ki!dzLkD$dp0uE_l6u?D#d<;~@&R>q_ zcDSHv1phF8rUKV=F@PO3ZB8dEFDIvB8|YkU_eQrkY7f0MctTI0+bQWIjv?_V@#~4o z&sN)~OSTcb6$Vi24U~UNgl;~m+#aRHjL$KU2%QZ3Fdo;+(q{5>6jU=T0V>*qg;mo8 z6cq>mL=VjF;UY)N0CvDSG9nv{7rgdFo#PIpM0%Qs0Q&a>=g!_C1AI8J`|3cIB>4K@ zQmZzDkOG9%e78)uc0=Y5<~J5BnH&1S9YRV-Z9v^3^Y(qbm!6jDeV!d!1H%Fl5e%ZJ zRuu*~pws4#a{bYTg_3CB`2-lJfEmi4LP|#?tBH`YeF1)+h4p2N!VXxHu-U4l!_DjC z1^aamK-+EyZCkW%11Af4(`Ug7tpmdht;>3#F^mHlQaXABSa}0}5I>jA?d=Sh(^Xrk zlUwoVvB^W2fP9k25<^o&?e(<<2w|SkBsE1HlyZrMiB@7BuaNejI|8BBdI+zl+4=(7 zybN_|Cy(__LM24Ql0_lbV4r$-aaa)Sd)OyXsgz>(N@puX1*ZLwj6f*R${K~9AvLQv zSQocb$7(nSsS6|wLtC6+UqCR7CJ!AB#XaCCST;A6EnOo>t^s4Ew;7-PjT7`J`}ef8 zOW9TWC;JigrPr0x1%2~7KcuV})v-u(TO>7^4UtyOhOCm6CJt!1-VC+T$)0}vDy3z$ z(dTnjHc2bLlBdWr$Id*bH`g-Bx}9o!B>@U#~r05%1PM+euV% z9;tfoFY#$Eh})yOHDa8^I@@MQxnNzVvVJ8Va=xUbSEs)OAtS{0pI>> zw_Xs<;2CKC9j%Ceh8=~IeGGrvqOf+NY(N!&TA)jiSN zJfF<>K)83_eDw4c!sw#wGI$_%FUaqpc?XF+2RoKtdh>hFO0n*o#8p3M{qCY@GeiBR zTPtFnVZ+AmX@vA8U6H2K@6)@rT?>b+r&^mnEmmFZCZ@t}mgN_Pg}Kz&;zJ%}p=oJ$6;} zk2`o4(uztdqQ4$wfeNI|RJNq0v?Nrzk7XZx9B#;#W2Y0^ z#bQ~RE?k4ec7N6yw$j>eVO}w6;LgT8-v3%#Ma#ygZ7EM_VL85ro-8-hBV zw)lC&*D20y=H5+hVNFm01s>a*ScCq`xBoT)jux~^m%i`|is&LSZY-@Ra;CbY-C{M9 z`X^7v8jn=9k~52vHMdfcw2~OEa>k`{CPZRn?j$LdY<(QC4B0^De$~~2R3Qq_Z_gWlmaC|*Snqdzo>;yFngg8QH!eILsL3s@n=!pTU%>Z_RXMjud`o1m- zQ7x!c1<`R^G};ERdqJ+_i;BnO3xr>mrNHo&8~v{_2OW9bQjwyne+pQ*qt+w5UjvR& z?ZGhN=j$POnat~8Ie$Tp9q_giTB=!bZcZrta79f`{}6O>@1LmxJ3(bR$8#yi3jm@s zM$&WOaQJYg<{kmUh@I>h=C)&9i18MEkUNcVf+VW>>=bTgP=yF(K5XE>2tI)qpxYeu zAAp9R@`5VIj*)&OAYe?gLQqryT|@R~9wFAg4`ADE$^D>(njs3;1z{hAM`t>VVb^Fk z+e^L1t=t~46~gc%gtb-c%F|6}fo$|H48wdR6Ig@1<%?6cq+#dsLEgh zXyhHR;_MBZY(<%onEhxuxSe)Qu z^oE4ZK`^UPeEI~VH*&=QO5Gs5pBOG168}8j6hH%r;2mr+sNF^xoyJB5P~A_OQ@b0$ zE=3_p7yz+bl|KOi)0#{K-!b_Y362cdaR_Vk-OLqX&*;SD&=A7s+0G3a!7v$xjY)94f> zm6rcbTK-B1hW)iO*QMaU(Iy!P{-ju+{F`3%~>A!}^hP?g% z;lh3SME^Uxt)npi=J;xNL+=b5pK+>A+w5RM~vF6lHto4nH8?T0A|0 zcA7h|LQGUN2#ylbkruSIvoi=lnNAFI;@VnL_`&k?IAOI-dbtnEct67#SO$Ln{`~+v zwsmq61z;?kv~UXeVS$Me3Q#2A%UoIlH8u5;zPqDy`tR(G(fc_XYd6ujK=fSfIOn+l zr%dsAtgI%h8`}b=E)NP=%x=vU$nM*?cJ=DklI4Mw)$z5y7+TMXU(3_RQ0hR)mr%iJ zR~ES%TP>UQg@%R(@1NMX0WYmd&M$qzb3V{>b>Kd&2M&5O^*h{kszN8cvf86KOu}(> zE_X@pmt#&F;33=u_wC!4c{8ma67y3)9g~-zA2K{VEG8}<0<>^qQc~f-B;Gdau#1)! zjtu(_MMWd`HahlOeK&sL%6tK7Z7c==%cYVY%VS~T;gvRdVbV)qC)|Gbb4<-Ac(d&w zBf~PM4aJ(OZC818c3UG&g0FIu5)PA)?K{ycDiAhVZd9qf+Gde6qU^tiT z=f=A~sF7WnV?<)7BCD|+F0<-FWnC;bipBAPAn23BaMH3838o#6hP*jp?bl%=w>xE-^tWHnr@i_q`xWZQ-F_jwgqY^ zafbppUmy&ozS1Z&xT2zBWt)H%X?YmESL^{O z(C$AzJx%Bz8BVJPxfn@XQyC*gewJ{A1JjJM+eWpQHC*Qo@@V{XeCu+Xy;U#k-WdFo zdnQiw{y+J#?@tY!ixd(pwCU+w~@!nt$$zz&AW89!X-dDk!$+crrH$5_SEe~|JItmt)#EN^r0 z?H_XTybfF~JAeZWUgM26Zxhk)_J`~Q9!G_<@A`j?6<$M&KXVOVF>fzzbg2h`8G#H&wBFJ7D|l>3&+=mFcnencMt^%aK^4HHoX3T+VMLl@Ky?7O<5 z`>0-X;Rn4Oijt!k==eo0xLvY$_T$E_ zC2DYMu1N8M)k#!TnXH}n#^Zz4m+6NjP|A|1S{Bf8afgsBS&*Oeoa<_; z4G=>Rp$HCyM&;yk@z39s>D8-p&sEW}6lDlX1~en~Ku?mhjb-E3?=Q&tEgWa_bFQM| z+H1wjrUH_ZS3TWoyPh*Uy*S1rY_p6qn}<%PJ#?!9UAD^RG;tf4&-KHu6@%m~yL1yLK@s|+(IR-Z8??WWud z@SUfitDCH*!VERJZ{X;wrOh3G%>g3JZ%W!lz8#L>vIYX1ZJUO-9iE(jDtmU+SRLw3 z_Ht?9q%OokU%zIk7X4lVx-|C2;;9TM;gQe-{Mfzq!U7Cqjm0k2N4VAqp6oB|mr5VU zEh#VhlDr<0fGL%yb0(si2=&hUfmMU>r+@oSVD;|_xZa*`h-D^8gAE;EoJtyV*84Tr zFTLhmsNZo6;l{RZAm1^&U~>MQ&QqFcX@xz8}+{8nYzNHCP*T0(rj+fT?7D$s4y1O8wo3LZ=)d%MR$Nc=;ND%pNylcl`!qwGDJ{?9tWIuVSD!CFYXFV?ftO^0D%Zp6}KSVzO zJPNn(qNNO|Gh7rVS%RBPpVQbSHT{g~;6YgUAeg*9TXvl!LUCJH8>yI=H-F#_oJ!|$ z`0~d4)Ns(_scVLnrQ>Yi^PBOpcHf9^S_r%6s z1A;UqTl((zhu;8BNF|Ws^KtamT1AH<98JV7#L)xUm{}N*|Dfv8ZJPr(eVFnm*<>&m zZ{kP}sTg>D%;h=#oPNEzHk+l2&PSO5ngvNzWy`dGKi!{Z)S#KJinVUrS4btrKDke; zxtp3bW9c0Uo$hV@k#gUcx#Bq~**_zYfN9?`4qIsb_LU$g5***o_~`heoI1`0(YR6eo*iZtQS z<|_Vp0^9e!Ww=vS3`)ch&TnGm{MF=f||q?3G}3t!Xi1~Z&y@AiuJ zynT3uH=#LQ|J-_ME~>vo@3VDtM(D%H??g(B-*W_c>3Mc7+wIC#KTVb;oU3RCw>O~b zOHuuGsRM_x|(HL@ASrCg9fm1J(V+#xy7Heco4AbNQY0 zDzHYBnkIy!LxLV}N)Ptp1lIrE)2VdZD}q$_hY4d29GAMJyGflbi7-(%-&U{U4+XoI zqSpI>;W_E?wmo5UsVU0|8Y^w0lg$ZA`9nF^Q_75SQ^D7AEW`giR!|kI^77_&_Uvs) zDB_RE({Zlr1_lIg#0{02+eNdvsxYHCtX<#J{oB`98Y_X)-Wm}$b}uVT>(*)h3TINR zd=V?|pVq}VvALSis>QTdYYvS%U+B(Bn|-qdqC|_rarbd=pol#G=gLPg)#c7?VwsbU z#)Kn`e8KG$4YyC@fE3_AuLP5)G3TzKsW&SH9lRNE7QSZ%~V9dw)v~4qFvQ2UBe-N~|xAogzHYuwjIC zTqZ-mm(towHCLM0Xxv2CJ~olK`K2Y&8m<$pEh5m=a9!Kzq>NUqF}G8t z)Tf%8`Ynw^v*~L~MAGuG6dx*})Puup>ZafT_KT>`V|nKWHWUbcc7nOY;-x&}(FWh6 z!+fqYSG2NMhA)DpMB*$Zp<4Kxvl)S$s~dU{v*>56u~4nd*2wYi$b*B7(~|r=d%1M> z_u4quSw!ZTx9sT;vsHE*yr{E>d!tuTN9ple@O%|@Hl_tN`_JV?bCynnaLy!dZ~;g{ zzxaxDG683eB_jDF-!vBNe6(b8qC$LstcosnTNoG5#1V0;^WzCTtEimZdMGjBu1P_n+9o8?&k-?oL9jW>>)N+wz-Kc5hg(RzF<1T!v_4a||Bk!aN z%_;_Hvu`>#JY2IhFz9&zlxm{j@~kiT<_~5XZe4pLpFsJxLFuL;5H+k#){eg}95VWL zl`vXxJJb=?3UaVG_dG`)LN)jwrD!7s4p|>WIrnEIrXO(O``;(cF5S>NXVpGQ8yL3I z1x94V9pKoLzrYDjSJBpGsM-7i{1>tFn=d#0k_&JA%&@`y+)OH~gc+gJx!YGH;!d3+ zhkWAn)grfL5~4Umq;l!j-3m}^vHo%S#!ynvlp=-8H=L%{;$7&;?_LGoqp&+*j4Pj9 zRX7VE_oG$PYs-koiNSMIe6;US{-)4W_m%!sP>ws>pcTaGQ<}9G^W< zv|u0RFqHU|uyL!**p6j}5>0jQ=R-xF2NF9(CS%w-96kXieji9+wQYen0c?zQ5(Xk} zHXTtj7;d)u?BbRiSgMi4yEfuj`)Z{b&T|>Iau#4T01N2s2=8kA%Qv9PfQ7KssjaQ^ zxYkCCcx~o#Eg9qIrRQffjwTfU`WfRf)#fR-`ch5V3#cs{y$N)5oN;heqgt4C+5Ug~ zsl$}Zg->en8`4>Bco)MvU*3=oG$_{qWdG6-if0*-kHm5zVmDDig37+8M(xqh)Y>W6l%hoK; z(CQwIldt-uOsi(v#~#NktJm{MOzCsRiREOH4w?<;A7Q4oeUX+VqS}_@j;j#LklJhe zu4s6))~xT^IjzPP-%-nj@vo!ez2i5(#L0M8GZ4hqB9h!gR<+vZ3ts5A_K2moxQ%}a zYAi^1!L>b4XzDQwb~spFImcwq&lcJ$Tu|V=JU)y4I9!*q`Z^+18mlXEx)mWvUWHJom7BZTS97PJU`u|I}y8V&T(k zAumIkiAH*L?HRrnb7~cp;tHp;R0^6JE=+u2tq>`$v@JCmW2!2)$Ryz6gery;tO6%` zja^BWIM@Xwo5XC*XFV#_JVjPR76_h8oiTaD(DsP^HU+H1mPQ3yI@!S%CT=Z4EBETZ zB!93MUdAb9X;>W$<=v&mcCr4FOg*mg{;0+9VuESfV4F+zYIRMgpu2!+Dv^4OvBuq# zDI(r&jN`b4)I){X+O8ZYDUDiMn^MqQ5u zyK@%Xmjn)xrc51iF`+J4yZ6MceDCx5_Jy5(`uDs9LWhSs2fISOy90#Qt|?VDv~2$x z-rN+NS`xuK8_tU{6Edpo+TzvgBJQ4PtD{x*zL*`-`#I0|LcE}(RLvn*ScrM*G(=y< zqJD8|i~h$kz6`q~erRk5_~q_Pif3i7iZ4baMRit8^)I+3M!hneyNUB(!kGq_5BW+B zR!L+^QrYGD3oraC>mhHL_fELEQ*t%VU;S~Mf{yf{_nG>Ux=Zqvj~u0`BP)eZl~t<` zgqsEz^;dWL5)$t(NT+Yh%yzSmu1z}4EEXS_F$-qnv{9oLo!u8?Gez=wNH-{HE{D zg*B5YQT?97JquMLDV-rXubRF$2>WJf9nE@kE7sMz)uo9v-n;?(03-(bT-)#C~ZJS?k;`^*e=1TIXJSP-O$o8b+;JD8pz@5UiOSMr_>tVt5G#i>81L##fXDIw!>nqOZnpz^R3bP z?#4Uv{0hHQt?u0u z>ih^Q^h@ZBd7l0@ILV;jk$JGpLjvbL=-DdbyJl7AT$-gNGF+zAF?xEskLVw#7FltR z;Lb2fHEI8@B~)l`NqGDtb*GuG)QuC%Rrd0BTxk|Pw}%$Y1>JvG8#RYzn;WWe4VIs1 zXwO)g==jDca)os44Le1T*#JNP;ZUkjou+0kiK)FqQ`@cx z`^RNimI@9l&}Y8ZZ(j5>%oH)ORXN9K_uf8!HT=V@V?CF-%l7>v4=j15GkDGAw8~nN zXPgtwUT7xt^(DJjd@rbM6;C|ShVMGBa2mh7s|K_Cr}6i1iOK*?;mU{i>r>Ke9fQ}* z+KM?Xd#`YnG$woQbEptMhSxv;cnwch zb)H&x{;`AU^u^4$;?6}`^Jd|j0s#!{HFa?!&#NYz7XzYW+_}t_w&xe0;h)Gq1doFFTvEP+2XWv6PBYu}HqC@2e?>@!V0)`92C;X|+(hHA^vdA^MYQ zU8_4I+2LmlM|>HnSLA-mu5M)<*pK(~)s{EMlkZSTJo;HHu{!3S%u!J5EcCSm&X?>5 zFx}K9n?u`7(|#>S?oj#OX?{W2STnonR6Wl>S)F0M=1P}y$7Cfwwaw1flwd&ywH{ap zQ{za|PjcN82?V8+SVCC4PHw}LaX%^O!893GKK{Tgp3431$4Vz>+R-tMS?gzWoL}wf zc3&RQJj2nEqU0*x#ATe^5&uM}BI%+ywWtHr%dKXS2Xhqay7})py6&CcgMHsYx$Ax( zMR_&;_NCXj8!E5a&)wDJ#Pp9S6uc3WQK4`q)knmRGm39H&G++;P2IPh-aju35)RWP z-#ve`(meU(rE(+M>#+V5D{d8%xxcLszm!H<^75WthQ7^q0|x%{Qf=k(S8U6Q_)TAN z;lH-j+|oTGywlv(grCY1e_rqCT1}Y4H@{x1HJ>XoIy*`eX^BZf1HP|GqOmOI_5p#j zJYu3R_-fSSET?x;$_=b#jaNQgUd)jUl-^M_e?;H#`F9w1dFh8oX58CM?eHI&1YT6i zJbra=@{pD0vlrLpYL^~z;aMNtHAs*SQCrfVm(@RPiuv4%BKA4x`<&;GmLAwmkjJ6%Ogr+;|${5y4<_zYvpXpb=c3do%qTs zWFl>(7C^g5_$71ZkSzWa?Tyg`1*+76!WW-BDcZuHzioR~*b7b-&d6y+#S3J5Jv6%0 zUY6r8NZ0O$_2fkyy=(CJK6Ndo$aB@?(pwJWp)}rSi?a=7J0@;DW4_v|+OzzewD1P= z;XPUAzIXd`{cN{qZ1|Rtk6+&i-w-}j%PCW>NKO@CU##_VvY1b?toddhxqIEt0H*zZ zHs{HhSYHZ9ZoSJ=_TadU3BPr%a1l*vNsI{gjF2w0^LKIRZ}CiT)7=Lu@9xTqt)?k) zk(|_h7NUN!{_FFj`?W4HP@21ICNmh2*QG|0U7Fm2edgJr$5EG7tJ9igy`?$$LdFBh z4+=xQ3i*yfyGmpdau3Snyx{jLE2%On3;o2F(q|>eeuKH|*@KeYrm}17bVmHdC+z*l z9vzx)N{zc~b~pCuKwS1!Kl<~E(*rpa&u-&u9~GOYv8xz*XP-R~y+F3(hci=K<$;G6 zcq+ZNC@)dfpBOw`##MgN=$n>Lj0x%B$P@WHfpa#`U~E&HZVv0qw!b(UiPAvsFc*5@UA z4)D|Ci`i3UB6sadaYZOkRl>uHvo)u!ts;m&ou1WwRL=9e(qiDp&ScI4{+JZPZch{bTa?VoVtS{-ZMk zG0pK2mJW4p;>T^6ohg`@T30_A96Dnxm{#AYu8x%jZNr;l{NhpjsgLJOZ^7U6DN@k6 z!~Nj(nK3&x#ggcPmNY*6(T5$U1YWC}$ZxCji+XZ{_e}KurwqNZ9lg{80vP6A$xtHt z@?0jSyGO?8o+L{N_EZwXb}e(p2Si}uRTniD$aKXiFtz=<6f!tW#xW}gGcTsV!d@O# z1K+e{f3l!yic)nhW!6Ec|Cc$qbj+1(&;C(LEdI?p7f-abX=@S0+!q&Z0RG54qi3^{3@Zi(nt7I69&S6U=}kS5JQQ_jTNz-zKcJ4%8m zdjiSdPwc_&gslgP=pT^t*T{ZbkDjsiA7#QWnO~~uBfoRJ0kxH1#jy_yIv|s9uLDL3 z!%qpqmtkz==q?POc>^o=y|fj+y8Z@hXTX_I;=87-PY)PD*P7;=Zyd$bM?QxOMLXkk zPI#a&#APQOh1o0k3a$v8?>wY?h#V7F0-}NVUlK+guSe*j_HDu9O)$JLdL7K@dF%3e z&L}(<8`;ALcflv>5Ir6}3qCYwHi$j&ob8fy*dnCn;LFSXpFMcM)|nQe)Wxtx^*!tF z8FUt1O7mrAJ1qITYBP_s}v{gQ2_82Y>G}7U3r$ zw%MjTsKt#RP)AH@rCrOiw3TV`pIKR^(Dy)d!;d}N@{|M9eMdb&r8B$*d#bW=i|*xl z)m<2U1UbJbFLaRR<3AQ9*zdz$!8BOVM&IFn8QBw<<9(~+M|e|5XZXzFKLK-Dls6CL1sO)taoCngoyf z_|_gqt|xL2gL@T23H*jWlmaYtF`r6CRC8eo+tThhBR%jBi8%^q<#n^20hfa;%;oi(;Y{ zr~UqTQxG#xL1$Lu;Wcac+>U^SjbYzqkt{TScGtOE_&bFIeqT_<9w}dRUitZn`eaT2 zeed1qGK~M>`ZF->KG89W?8J%9F^s>=Mu}gI{WCTEveKS(@7OnP!LZVwG`j0|uL~^< zwF@^I5WH+pV@3@mCa|9-`|*}nhT#`X{L+R{;#Yr3)PT}3npq Date: Sun, 5 Aug 2012 03:22:44 +0200 Subject: [PATCH 041/492] (PS3/RMenu) Small changes to menu background --- console/rmenu/images/main-menu.xcf | Bin 783026 -> 794236 bytes .../USRDIR/cores/borders/Menu/main-menu.png | Bin 44258 -> 44198 bytes xbox1/Media/menuMainBG_720p.png | Bin 31787 -> 30950 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/console/rmenu/images/main-menu.xcf b/console/rmenu/images/main-menu.xcf index f9c18f4b70aa831ec3168edea25caf84b8d34b1b..13b6d5c1f45a5394707942c27bf05089d8adab6d 100644 GIT binary patch delta 21099 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 delta 17536 zcmY-04}4rzoha}#X*+G^x|qphBkiuxi5M;Wgih2*QJ|COMuUo-tmZ>mg-+0{Wmo7# z%~C#ZNhiA1qCzKXpjDs~HCkk$6E#qFmv*umDZ4@^YNS=5lhv%P{OLqD&$0;b%j(;G zPM-URwG%%-Z|6m^uaqx-b8OAmLO8HBB&OdU62JO`5S{h? z5Vc(xqW8QxL?8c~5KX=%y!aK>4u9@rulvU4hWGsEk0G|x_a2sp(C|^acrQ6V{L<|W z_l0o!r6HvEh47yDh4A6&5I#K~!rq^TFfkdzx4saM);H3`vWt_p;tmSuy8vb9s2S-DAP+t$)--G)7 z(fdOtgVu*d@eIZsnJH-BObBG;^huAOP5gJzfCN#X} z`Y_b+r|%C9xvz(YZHuAdwzr0czi$o=v$utYXZ|ECiD$!-v+f8>UVnO6^7fr!$z{)l zC4aS?SMVC%#M{D>tx;HV)62t>JxyWBw=NG$4qXwJ%*}-*zg-iSp7FY{wBy{cwCA3% z^qRr2^t1mbEWP_b!qV>_2upwYPeWnZinoPjuX#8uduvZv*4G=B-SCRAZ1g8#+1+P_ zW#9X9SoV|Ggk>jx8RD^PL;MfdvYx-%em5C5Pt2M+^;~{=_ zXNb3*2=O&XL;QdG`MmxRZ@)go-#8KC=YK22-~5#j&kWf~_n{Ea+Udsj5Z`oJi2sF7 zKFmiBhWK@dL;QvMpmt3!Nf z$6CR9Hn52;Y-1;T*vCN*bBvQAeq*4C)vRSb8`#7awy~2v?BgJZImXEl|8$^<)nO?9 z>9vCOY+w^x*v3xwu#bZr<`^eK{4;?jRVVv6l60 zU=v%|#!mLIkAocM7$-yA6(YW~iPfxSJsa4>7PhgIJ?!HkhdIW{5HALrCF)5BoUCVUBS!#76^7tY$6i*}x{Yu#KJUVIK!M%rQ=e_$`5eI0vvkdq<)#WT?EiyvYq_i-%5zqEq2T*fxO&S8EN;Mea-}{5G{KG#E%Rlu;VfomVVfo)b7?%IwU&8XI&Il`(d?~D0^}ev;ynhHQ zG6%zo>>Xjn`@bAkd}v8naqTC$g|CGbANxjFal<`f#f`Ux6{F9E72})3ipi(KibEU2 zipNe5D~1;Gp>b)6a%gPY5gJqCH$ER4-;oQAn>L5Wzvd>s%Khpd{#$iSIra!Y%)H%aZnw-}>uM-umkp4J=_P%ZRg_75Coy>&A7@4}EXh@7FBb z{%g&W_}=S6Vxfw@7moAqmRzxy)Jr_#_#VlSB}bkDMM{*ZP^CsaBo4<&k|Iqe3?&X{ z1v&B*C{m(Kg(@}bAyJKyBt@DGS#snlP^3he3RP;8AX;Hc?uLMQKmvQBz_blO%B_C z9DN&|El^S*V|7k2FewrjjnhaTTLF2!kt9W$3|VsIDNv+DnF>{E@?Wcm z#9WLdDbi%fk|R%nA|=XHs8XXI68{<_Ns2TXvgF89ph$@_6{^(a|6l7N@v|67Ql!a{ zB}bkDMM{*ZP^CsaBz_(vNs2TXvgF89ph$@_6{^(a|L66Pn2(VpMVbs*a^xvcq(qqt zRch2j;@@H;{knhaTT#(qzbzBTs=M zCCXH&%KtBGf_g|i86!!GG#Rqw$Wx$5i82+c)ToEVQ!$dHNRuH;jywg5lqgf7D*sQ_ zsE5SUF_NT6lOaovJOzrBC{v+Ije1Bt6C+8AG#Rqw$Wx$5i82+2s)`!*kT@A5Ns2TX zvgF89ph$@_6{^&zheSO_k`!q&WXX}IK#>wsZkG!-^L{Jw@Ff@$&e*So&rTml&MgqMm;2+kC7xrnhaTT9DN&|El^XRBC1NB=ktRcy9C->9DKS)5RH#y;9-=5lk`!q&WXX}IK#>w< zDpaXa57EnFBuSAbLzWzQ3KS{H|I5mP3RP;{E)I;=#F_NT6 zlOaovJOzrBC{v+Ije3Y$VkAkCCPS7Sc?uNezojH7Q=v+YdWc>TBT0%h8M5TaQ=mwR zG8L-SsE6o`7)es3$&e*So&rVrKchsM3RP;w9DN&|El^XRB{c(&WDbi%fk|R$+ z{{OfrC{d`2VUu`ih*tldXFhh- z=J`+CN?uL+CH10|Wk%{Bsq%A9g{W2iR$aHgk#63PZd?DBUD$7Hg&%R8-x|-aN`~lF zI(XGO-i2d*)yLR@^~|fve3v6U6{53saCVvuS=2u}Pk|yO%2cRQqaLDH$4HVQO@{2B zD01W}P^3he3RP;<{r30X^sXq~aLdi_icY`xz`LVp$xz$#|NW*c{n+o`yw|ja=+9p8 zz%1ewyo&Q)QZG7hEJWu`FvSdWEQDxn1I@J3PA5I|F~Be*j4|QOTRSC~VUC61@Mxx$ zb~@>yj{$}mVT=i;m|>2E5VbeZOe^hl(nB8u3^T$Q6D|hrQ_L{OLWo}9Kr^kh(@76~ z3^2?HV@xo`409}m=nV}t(@Hy?^w7ru!;CP-(1c=&8Rl3B(Hk3Rrj>R&>7kDSh8bau z38t7~j)f3)G|)^d?R3&Z9|H_C!kCLe$An;t8Rl3B(VH4*rj>R&>7kDSh8bau38t7~ zj)f4N-#|01w9`oseGD+n2xIbp{)AwP8Rl3B(YgkjX{DV`dgx<-VMZ8Zf+=R0Vx!m|})G7D9Ak1I@J3PA5I|F~Be*j4{C!Gt99NqKg`6rj>R&>7kDS zh8dCni^c>KOfkb83n99=fo581r;{G~7+{zY#+YD=8Rl3B(fS6OX{DV`dgx<-VMgSC z{g_~aDQ1{sAw-!5nrWq-PI~BLfMG@$V}dDWm}4PCoeeb8N;{qO(8mD7jL3iI7!yn} z!yF4C`dD;38t7~j)f5Y zX#>r)(oQEm^fACNBaAV@6f?}R5TdRInrWqjOSpmowzFIQyY3cf*fq-uo)6L6G^4Dmn;^SQke9^xL)LI1Sw6^CK1+#jbBM>Nhv*&4Sjp?iu#3IyN4<9(;W(#4 z^v*_BvPS;jxsGl&vYD;yU>AGY&moR*oKqosS0gJ~!#cXz$mS4TdM);Q>CN21JsjW> zp5Pf?2+_M=&d^zk^SGFIb0ya@#Le8nJsjW>p5Pf?2+@X@a~9`uG4JL|u4Rauxr2K+ zz#}}tGrSO@?91gpdzRolF6P}_$+Zk|Gk0(g2Y7@hc!n23)bn!A;yfBO;h>=A7E7E9lMV1_S z3KS_(rb3k(^$=YdGmNiH3R0xWkR?Z+0!2!csZgaxJw%&gBuSAbLzWzQ3KS_(rb3k( z^$_LU(~5FQQl!a{B}bkDMM{*ZP^CsaM13)myc)x~&pXza!%5n=1LtU;c75OF2v3FR zDs8TEj$Y*yxN68rdQ}#0@l{*-EG3+zR~-t`2kiU<8S;4j1Jw|H&<;MBCP$G9$2k?E z{zg_}=l$#GW+R)~$_{q1m;Huu{~^HTF*07FlHnN$m>|hsr+0P-4aGX;i z`cNY)S;IQI*~n(LvV&dhWxxD?=#bzD$2k?E&5f*N4eRJ;Bb(XE4tBAZ{T$*5$2k?E zs~cI#8rIRxMmDpR9qeK+`{n=YLmc5ar$Y3XjjUu1>*!`9o7u_^cCnZJ9O4MaITfP6 zYGfsASVuP-+00gUu#3G6?N=P)2*)`Uq7OH+k~OTOn~iK{D?8Z5UiNc{BOK>ch^}d5 zC2LqmHyhc^R(7z9z4Cv}e!(G*aGX;iy0(#(tYID9Y-BTA*}*RMvY$g7;W(#4w55@i ztYID9Y-BTA*}*RM%Kw)Af}5ZPIKpvGh3KP=tYi)A z=w>6E*~$)fF|=2)pF(gI)4JxL2^BLmc5ar$Y4CjjUu1>*!`9o7u_^cCnZJ9O4MaITfPo8d=F2*3r#I zHnSBMy6Z~eFQe;R>8?A3<;ZpQ5N%zChFf1phWDb;*1y5kZtGXs&-bbE?;*OrkyqlX zc>SNEqw7CRfiJL^f4q0?9DN&|El^S*Pa*QM?(l5^L%Np+e zhfhZro;~!5H~xQj9)9;(+2|AR_c2}{;hlULXK*%aUs5mnOfE#9$y1<6i82+c)ToE( zvoVsSNRuH;j=WR*vjsts5@jk>sZkHnO)-+BNRuH;jywg5lqgf7N{xDmZjO;8MVbs* za^#)bHy0>UqD+M
VS86!!GG#Rqw$Wx$5i82+c)ToE37$ZrFG#Rqw7|JUO6e&@r zLX{fz5RJr0k|IrpEIINNC{m(Kg(@}bA^Kd5Bq`El$dWU>KbIF2C{m(Kg(@}bA^Lob zBq`El$dV&Zfg&Z!RH#y;9-=SANRlE=hAcVx|3Y3+ph$@_6{^&zhiEiLk`!q&WXX}I zK#>wU{Ek=?QX)8G#Os}JM4}ec?uLMQKmwb8ubwE ziIF5lnhaTTml%eanPxsONrjr{LDBSd@8=Q6J2R_^0beiNcQ&)|G6<2r8TJ|5*aA@bSS z=o{yA8P{AKsJK4iN4sw`d zoD9)Kpo!J2Wj!0%#1^)(lRfO?Acr}|$q;>WC@7j(&05y8flX{-8#~#_XHaZNYsV;iyXOQiTGR`E^%rehni2f-~3vG1JMKApfvYk=JnPi$- z=2;BUcjC0r#!!c%i(dK}WILmbGs!fw%(EDx@5X7NjSjl#rJq5zGs-xVOf$IFn2>%RGxAdMHi{ZSwz6 z2VL~i&mh|wWt>T-nPr~E5dCwU7TV~bi(dK}WILmbGs!fw%(EDxe~Ht=P@AHIE_&%_ zknM~z&Lq>!GS6a&z8|NBHah5{mwpD>&M4zdGR-XWEQaXeI4$!3aGRimE_&%_knM~z z&Lq>!GS6a&9*NUJ8y$4fOFx5bXOwX!nP!%G7DIG6PK*2>ZWDCSMKApfvYk=JnPi$- z=2;9;HBJj{bkIdF{S305QO22Mnpx&q4AD%S7WtoPqk}Gb>1UAbj55w7)66o@Vu*ea zr-e2;=%SZ?2HDOi<4iIgq96MH!xz8LGSARrh<+5Og*H0qqL+RK+0H2AOft)Z>A^K^8RsLB1={a1$CAa+ZWc0Qn^XFrq zz>?%Kliy?J&c}YpFL*9Qk2m3O>&MUMoowQxe2On&zJ2^VJj#8!w2{%pWyR+g>Ug4e#p=GwHbRUr*k%M z;H|ue5Aabw@!~?DeEPk&y%7EH(}tqCo)DIA`~9yYY{L zUUb56I$`?>**YXsWP8cmG)IV`MV~lercQe5x_hU4jm}1(Ac;X=*#_&2Z%TXR@ z4#Vxl37%$wMV{sP5dE@&I0;UpnHE-YCatt_4(HNN2N!S=oeXs;F5yyo=;d;*ppSm8 z<{AbVeTo@^jag41ZGg;ktMD{Y*^xwO;41zbd@6YgIv!I z46~gZxrq@*+0E^YG0vUb%>9EYFANsRrUC zIE`jnSjCyN(#AQQOFJE0z(ovoD!RCYOX;DP%ejI+`nj5G7+{d=xq)G}b0aq~!YI4B zoiWC_le?KO!E*AGs7%Ld7L@sIlg8(`crJRh&sHZJfiow9~-_@_+IoK_^{Y!lm@k z%jH}_AN^d-H4HGw_1wTP+qsdO7-5v%+|C%|+{xWcFv>-P&DV2WuT;$dc(RZRMRd}|C0t4my|~D^0F1T9D3!;zWILv(h$Bp diff --git a/ps3/pkg/USRDIR/cores/borders/Menu/main-menu.png b/ps3/pkg/USRDIR/cores/borders/Menu/main-menu.png index 3da7b3c26ee589b0cbe70c849409d1a3c089cab1..6bb60e6aa87d91c33c4defebf2cd19a0bb44e6c5 100644 GIT binary patch delta 7943 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 Ve0?o$9;i$)Yh2e>&Ax{8{~v60CgA`8 delta 8007 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 diff --git a/xbox1/Media/menuMainBG_720p.png b/xbox1/Media/menuMainBG_720p.png index 6991ec60aa9cb5ba3a933c796c4183e953758e22..916da176f01e327bfda1a2cafe4951d9423f4de4 100644 GIT binary patch literal 30950 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 R$n*dJ002ovPDHLkV1mvXJSzYI literal 31787 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

q! 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 From 8cfeeeb2b6c03b37710a234fedd28f0570d0276f Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Aug 2012 03:45:56 +0200 Subject: [PATCH 042/492] (Xbox 1) Updated Xbox 1 BG --- xbox1/Media/menuMainBG.png | Bin 16213 -> 16119 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/xbox1/Media/menuMainBG.png b/xbox1/Media/menuMainBG.png index f62a2c39692a7d6076723d06fde6fdb7280ee8c1..2e2a4fe8d5841ea32382e7e993b0ef637ac4def6 100644 GIT binary patch literal 16119 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 literal 16213 zcmeIZbySq^yDvN@28f6Vf`AetNT;+)N=i#hNrQBQh!RpFC5_T8HFPK{EzJl+h=4TG zFx0%)^WE<`XP>=(d#|bebitRzEpf${*}xap%fR&BH?LuXak`fFlu6C0D& z%hw)q-k!PX&susa_LYt7&%<*Jm#^7Boql{j-O7RG(<{X<>?8Nj6>^8#3 zKDW2{iYkMHDFXYZU9!}FE*y9^en@lMAF)UyW;ZV^Yt@y;A13?qSFpAhmJIAWl@;f) z1mOAn8usw6{ohTxCoOA|2jvTAnMUL2V!7Opm4@lZT%G!}-{oQ5v5!8wBrUGQb)cgy zsAcYE49rpn_SrUt@HPE9>cWrw!qBY*eds*rE4sBAQjy?(Q0pEsI~BpCv{NG)krGlt z&4m47iGOc_l{3|Ur)^MH^R4|L3f&N`cSZR?;hB#_cDJLMnHl3Cg__Ibkm1Yk#viCT zG&|`8x?iGH66$s?^rGuLSLL&xZxb@?@zI59_3v})xabI$ifKXteG7sGhOyTd_mxJq z3b(^6422SIYhVW~+ZL8~Vk|h7&Bg^s4BEZfsax}$Z)^@Yu!dhN9#EN(JitDm5*hXW za%M$RoOE?B&c;H4;okQPTJ5Jra!zn+R?Gi+#r5sPV?8CYtCkYda`{u)kvlq>yUD4y zgpcY6%0t~dFDv6x2JP#YXoMW6GgaX?Ya9`pd=8xP>O77(rWHzbrkj5HJMd&MGy||bD zR2V)oW#F2KvcsZVj#Dh&%HKxarfgJQZyaEaonPljjV5KX<=bHzxHIxWXDe-mhoZ{G zPk&BFI5e{1+pba(k23SNIRdS+%u*2SeVDk-U;V)(aX&CK5V^v>#d z9jTnHd72Me<;j!W!&_xVMT&n%D?9D%?Q_abAg?1;NEI2m_x#rj+}?C#Xt1n-L2994 zlY!4hJCj&v+3!RxS6B4R++5P+{&3aTrR_JCiH!Gjn~=R|`S>Hg?2uOjYO0P)OBd$d2sb!C)sAX_n1n88DY zhLNtnukV(kqT;*g=#296@(kY}=#}QVmjSV6+Wmur4D9jpc;Sz4;X z+WGF|N4j+m{9vBi?{#-)O-;=&F3IunIUOAx>JAR29X&ndEu3HHHXqsA7Tpl_RHwc7 z{C?fIT}pIxbpHx=csQGdg(aqQ_FaS5u2l@;SZuGEDkiq8eLQYz~S!dk!?(S~KU(F|c_SU9yKRg}GRmuPO z@gWfvzXHF_&tCd2j|KzV#O$sVVN6>`hiaTzNat+7ebW(od}L(A#8*&I@O!twq)qar zGyP*@tX@0IQCfyR8da5*BlI#6Vd^xMRzoa20s;b;mkC?mMl&gQ)VeG=!&Non{v?IV z-lAt>k{K>BA21jrqbtLLb@0_3rR%7Ctdjc+dIZ z!o`ak4<7iRCTRcj=UHA!NqmM(acJY-W7)vL8jVQ=1CFrx^( zA?~YZ|MSy>OE>O44W|*+iI0m*#IF(KZ&FiJBfCvRL{w&r)%$ zTGH_Fs7Vy@D9g{yeGGSNj75)mZ+7p03}r8?82nhI=t)%lW_(1Lbkuca-d6w)@SgZ>+*Ywz*|TU=s9)sAvZdI z=Hj*az`(OZP+)!s*vXl^oYZ&WR04@oQc{lV-^j5Z9v+(V^721%mtbQoi^7>w-M?5^ zSiDsh!%4=dImBF5_3;@UEIk{I-kh zqUBI(>(i|Tzix6m{ZY^^HGaL{ZSQL$vOTD_^ZQ$9i;sBG_ek233l}cbHayYPyscy1 zry~!Iyb&q(n#Xzmv8BCze5pyR>w$sm_ps|_-Z;nYgk`ty?!x5IDAyxiQkutR(v8>ZUz?xh~P z<8D+yBbp8l4qq}HS|g}=U=P`ymVcJ|W2D0q1hg^4;)jnnHaE@SQ}U~;pHx;Zx2sy7Y%)BW#2=;Y*>6?j zj}Nk{tAASA+Qw#Q-}c#>R}pobku`y;FZ09ul8^{`Y-CE-aY{$prnMTL6f zdboXC46|C8u6=`szUzotom|a|4HdgHYbc-AJt+eZ0i)xpO>%s(`{sh}%H^!WL+R?VynT<}4_{|@}%J~Ha zv#{LiyOVxR)^Ib!Bj#z;JNw;gIZAmd8PW*?lip4@oe^X`-p4d`OyZB-@(Kz_N&1dm zwu9Dwk(lGH{ZIF7zePx4@w9lNl;j~M-I62e)jm_Z@fl< zW;rBB&#jqw&t)#)IOWk~vt&%HUkMzPA1CrP(MMny7d0uHf30ed!9cO5y;$ z+nbKCO?gHHpLT`TdwJ%f9>&0{XmNi2t@zP`@tgNggB~4eyYO-yya*{Jp4H^&V zMaoQCFKuUW__PDfI#=~k;>%A73k%PFBR5nBsQ32}2aL0t?TBS3iAqksakN_ZS0^PU zMTqzQSw9Vm2vr17mZ1QD()t~imOksItc3S-0aWVL(9&nLZ`h6-Ei(({^4hUEaK1To z%zcSkNZruyXj=@gRdU=csL@sd$2b~c15^{u_{ zW|FG9dZt#fo@JWT4?%R3NRGW~AHpB3`nBq4`$@aQIltqaQlA4?xIg9gYKQ5W(pDNZ zjGj|?LR#A2(78Y7iYiUb%|k)L{QP+*-oP_YLto#v2{`x}Xc8`f;&nqqODy{8wQGw7 z#kC#7I-N=Ojh0!dAtNJ`vu67&z<+OH`RKui%uGq3 za2?Xy3Xhxihf2CY2)SVN-P*MpH^@A;hqS^0z(u|Hp0Bvp#fra&%GZOo1IYiq?U@Di zIA-VeRoEk7>9#xX04E{yojbjq@f=mR6%#XkkCqIR&YU^37$ko9!F#*FFqYiVyU)VX zvUGD}BeS7ly!v>5i3qR)&}{=qQw<7ctIVwPqd|{3MW8~8&`@z<;b2L_PGYI&w$(Il zE-k(v6NFrhD)+N43Q^;)=R{50F7vr8s;}Vl z`L|At!vcG5&G&f%^z2xdG(0naD*N8a(ZmY+EgGTKMW}c_gy%zp-5U%xg(qpG-GW#fm9H8b8GG-rG|_wE450@l*pj$^s%Zk$19YK;fvv9kI7?&VWWPvl|ym ziH|prjf-29?F=yk$+`bdp1l-wpuGXGj@4*|rQ>X@Rz909nu3%`sUn_D_gUBtK~)4( z5S~!i)Lev5Y$NwnlVgD0+V7X=s06qm!+jTMG&)>$Yl?K$8BhXM&%b<%Decw9G zRb0OzX97|Jp+Uqu#F%Nb<1t&%nOAI&h+5u~-PL>oV6(r2wHK(e8KL7b{}DrO;Qj#T zEhY$VWIcfPu$fa)ZMaC62@HG%t1h}Lk;goOntjl#!Jxgflc%I^RfrF0o%!zFXatct zm6+^coj|ATtYBL&QF^Q1M_khsD5L(~-ltc|$&>2b{%U@n0%>Z*ZStKES5BO|;aykLy1>*0TM}6hk;b3JQym*cE6OGq0S9^PVR05B=oW6bv zvipmRi}&aCDlDRs0mYGbL{ybR62Icm&=8|fyd{_sgIedjZ4Uef2go6_{jCMZjhRQF zkh#n{uEMu5Xd~mqY=audEHXV>C5cUtA%$*}K3d|NT|BA=2JD-2Jz4~pZah~vqV?VT zfZ)Sn4`s5Lk7qi~vmeRKN-guCAXm_6{sW};xlF#xnwe$g=jEw@^w*sJ9v+Qwzp~%H zns)W`4}5N`W5L9@RiLTFL`qNxVNieVJw3!R<{&J&ZAW>z6nPfXXm40hoH&ijlu}d- zAA^hOSaBs-CEW4)9l~V#BUunpVmKgTRwkw7V4;%pq_^8zh{ag}OW)#gY4|8zyBaCU zTIpD{-8c)f-XLgT`QN@Pi;s_A@;TTUDJm+G2BrTbjuDZt^}7>Z8*44Zp+*#rN81>A zS6A0x(y=SpDw!KcZ?rTtVtrRCF%`kNVEI(!+S{V&H7qUj>OqtO3|!Mj+a!oO&-cFS z&u*QLf+o-<7TtPly}dYu$X$oJ@%-{~HDggiubxy7J}@;Q7KFLeBb180NU@PR{Syq;oD$t55=0Z@GUQjmqfZE{{ zTo3u}Cs<(*hqEog_Ny8i{&k-X0;)|)N&=Y#+6id{7G`D@IyzX;WIgZoZ(JqU*W5+m z4vqZQJ`+f*sYT}(6~)3bEks0IQjvQEEs+c|$l=sEh&y_N4x8$yh!vqCxWorWM=9O2 z4J9NbO7wcg!S}5AjRp72ML&wZy-;5-(mCr`Q!%Uxs0wheV>myaowpww0>4-xjt2Ab zCNxw^(iGa3+pHrdv#CeK=TuOG)11nSy{;!@RlBm&9os^`cyLMH&0Dnxt;I8#6 zEDsYX_UTb4QT^AKlh1zK*>M#Fn%3L2x3YSdot^#a)Ps7E(i%oaA8rUbO4b|Lml#TD z8W(AS61bf>g;J%vd-ra}YQ@%Ma#S#=*GllL84V5k2qZ`Z687bsdQuX0duVt# z9|DKbHP40(P=<1Lc6Ps1gmTgd-oJAM2McwYpOq!0qod<_^q_rZW#v0`{LFx|cxzy zb=zlx*~APE-XVzslm!@)83bO5rYW|zwpN>Njf{uo2Lm)95p-##(zep=ufcSjt{oTR zR6#<(9_Pq}QQQg-4+nc_x?W7$bPsV^5f zV)FA@3NkalnkQz%`%P4P9zv_<6&CW^gUimUjBBOwQb!JbX@!Oz+<_z)fB`+ZB31~03Tn7s@$KRw2}x~@zk=8KkQGD?2yP?EG_w- z!$VpKd}zVh5a3y4?YR`yK%hDUdx$yweigAD>%7*}N-gO4^$Bp$(vl&*mJ7NYfiF{t z5V#=#0`0g~K}el)%q+x4w*f&JrPJIGmvIPxzW08RnBB%0#viQKDI+O~OgLqh_~Dww zNRwZaH%L4(P*zsf*3ojj03u};eRL9%GZ~R$??A`QCnqOY6z14s5pNC+idg^62;o&u zj+&V(rM9}O4Z8+{kPQ_V7Y{?iun!iw54^-NkeIfC*9xDbT;duTC+g;`5LlX*7unxJ zUic=sjVaB$ea^7t~|lONKh)l!EJ@w z<;G%aoKGN`=}HryM3$k{_}c{}Cc2Yl+8M`I2B94@$PB2I@_r3vm{OEE&dQm9++4&? z9-{$?$Vs9QS-{?O=y+Ys+x;nyfS6{G)@Lh9A%R5W{dDg9%--9LQehp+RhYwlG+7b{3WmpTAy{YS6A$pwhqd z^oWqUPB3(ml3&YMEdi*&cxl?zt?&a=??YQu7$0# zJy%W74-z~0wcnrcN7YX`c)kB5T zS0|e$t3iMeLBl{Y5-kqS5b=$c*N@cX+82ik%s@)e^>6d-0@=+Fi0}D}94wb}1Lhw< zU{Wb13H^;YoTk0sp^M+C>|=i$^Ss%F|)9| zgN^JQt+bvc_S*{xqvVt0(61e2VP#dYp0}{IMS@&_pIG?%$2{V<4e^Y?1IP_&t|>Rf z#>C9StuG?E?;?Ox6akI<{o!JLYn$;}4aC~ijIX}$EN7Jm#z7*fp=3x2kjx2b6cE`< zt|=z@Ll}%aB%h{cX6=C8EXeNh^6@Qv3nj;bNS^1f6)^vC2(HKD#ZUUc?j>7OF$BKa-IO0$V!4EnqvE2@WO zZG10jB4r>OMRYxECmXmpw9UvzD0P?enwk*}u*BEM$%PyF?J&jqj;+*gZIIn%LZpsB znIL?=DX4DE3iB1*sb^&vL0?cM|LDC48c`Nl97j->9a{?nW)N*?R!`zU?G-nGVLAej z6JkWM(JMjRjz|U*c=tb01nL#Pu)V$Mge{!*wF|cqsO*Osf%x%yq#2}(o{(v|))tR! z0i_|X5b3Bsoz9O^p{7tskgF8+K;_dIuEc>CYma8a8t#1|M^p#?_H zvI+Bn1&lwq~T+16CqlX$NMi<)(#b3ktiBu3X>H&_m=Lo7 zAltJ&;q_M=#Qdk0*Wxh404D?bpDNJkG>whEo}Nvs6ScmzbpbLVLc|er!0?~+#-cZJGDRbLTh)kFG9TkjL*{9jr+71O8 zS>S`8!kmdx&@nR+%$N>9Bye~Pgts-2M*b7aT;!k zw0?z3sUms0Iy#v^`F}^sWt5ZesW`=RAmX$YN^x*-@bobaw`p*)&(6sHd|!quH4x$N%j z;bzZ2nJ$&x_fni2Ud%sVHRs->LOPG>)#1pA%Xqbs?^-6%_Y^M}o;>yWCZ`v@A(nWeGO8UlELLF#%!zw}L<@g&6(UV|vIl^%?XCp2$d>vXAR zkq%=M{^)O3S(z%0=lrdjh3urTs!3lgVQLdh`5;Gvxe<~8T^IGNfU&1G?C=Gj<*v84 zBp3t)s#>+a9XC0_6cC&qFyjiuT-HPR8XLgDn$qEvjKpGl>4o}r!|ni9p56kWm!9}Q z{Jxj!z455Qc|p}2{+h%6CrssqCwolj5wg@83?3(J4J3m_ow*lpYutvTH2 zoE_3Kj78GFjY;pQ;9C-b$mkW$BCvJM&CZ6%Vzv`ND?@UGKpqm5_CTaHj7;bd{UYeO zm5Zd2zU!fex!`Yjwi5gx)JDb&UK8~m!zPiU+2kAstZritK{g|0-)LWD)z<19(zgd1 z$wIZw{Q2W*?IoAjyyUZP@lhcQyogX;!{t9=tXp(rzcBRr6;%74nU?h3;;A0@j=T#U z8ER?PV9cK-=V@wf<1Sk-dS~S4q25pOF z7Hp&nyalrcK8Vn8RZT~VF{;Sm%L9M3>jSn#XjBAr_YhF39!P448CO8f=mZ+ILFAtg zrga$!xbI{g5BC$KRea2fdsoCM0tZ*sw{ydOI{N3YC!SzMxcNV6b7!s3>fS}BZzcrJAEWO2K~rY zWs7|l6BC1s1Wc#CyhdO>+fq(fH_2wQQ6CW>ZC-yHm|)t?ZQ0Lo0F7BCQNk6LGg(+r zpa!zh1uT9iB$(Tk7=xuvcM->#Hj?f2R@x*T>q=0s0KlwJ6Dr%=+xzvKKgtn#1LImG zx#a{AWEMs(tXXeR0@He|)1R(Vg#kj{K(JrPs)a-GHe1-(s3UF&v@4Qi!Tlb<45%DQ zw3o;0FhJ1pFu(Fz|NSk_h@uRV1cVG~Y_M_2qX1TM16`MU4x;uAayDg6Yb`oMOYzUv z5sAzQ2M#uIF|rsZ{Lb>o^mb%*Jrp<{T?Z#&YzOI~+k}UVby35yOnd#>mx~a1smh&+ zBYgxowBlHUBp(Nz`mj=WH4E2#z_kU6&+rKdfM3&)V+Jz;4$vm82V*jU*c%WYkIc<; zt}N6}!3JJ#KWMm*DVTh{! z@kB2tVS7hMnU7c+veFg99dH~1yK=3l5*PskOo`;(;IkqjIYH1hBSXTnXchv9vPrNq z&6_uLb#-UKHNxET-m)iU;H`4=o?-Yx0|zn7MAB$LqV_n>44EfXm}xuiUwSSKlNafT z8+k`d@hK^6*_NYpbfE5ryve%G-K2jJhT=ZihWxl;pyI2to!<=B31!AiY1EXj*v9uEGc+2tJ!3dhophSSP=hy7PWaM@w z8oW%UD=hKeseF9Ak`h6=-K;!|$Q?!q7GhM5wKdZZj~yujN!**O@FymYA1~SqA8)*o zt=bRK5NqK)iN`Gs|8q#hKdo#N=j|`VLnxsXsop`0-;=2;EbOA>Ha$oG!t^QXe!etn zt|yHHmQ7tc(1v(5Ow{D>M8n3Yb%_H{u(+(+85mqVnk#vBQ|wjKDgbo`N%`lO|2SqC z=1;<~Z{9R2%BVUo?-Aq>LvT7E?=oUZV^4g_&i)Rn!i9JL>T2SbCj)1csTN#v(jv{Z zl`yx)MCcmgiX9oaeLkjzm{SSsD;4%gd2(o8x5dUm5-go}9vPUZ%C*DcnU&|%4lH&L zohVV$4IXzUW@VCs#Lo#6v9(V$Q>^?cakqb^FvAlPSm|6(UQF}FCyvDGA5VOXbE2;P z{EO4g6NE439}=EL!LhfKDAWrG0^u;-P529jGH+F0rtS3%;7|M_)bjH3sv`f5WBX;1 z7P93jGVq-z(mgKrjfZ4i3tLpJGk23ZM&{!Zl_e!Uvb0s_8H?}5dm}D#L-neBf1j^> zc_b=mDZijorOqzCCt#gX8B5{vF&amWRj*7j^(7XJJ+S0%ja65UU)+{6zaD`7fOmU# z)TBi?eW1SO)4p@JwBsk0nc|$+!eL?bu9sJ$X^vBocKPiO3ESVdLU{8h?&#JV z@x)Sz_YtIJd+KgUPb+9NC?xnOV@V%+WOF-gnl4` zWljj9$no?N^m*>Y0*7{XqSnf;bivb8QJ5 z=v;w)weL{ml7qUB&z6!5k-esI0#)ijbn}IO6sqPsF|v5Df<3d_o;bmKsH2o?B(bsI z1e#I5?x4_>9(iZrAyv7rOO?D$+vibzJ@KNcHdzQ5a|z}`!6c$zy09T6^OP~LvHvgX=zoFpe|~}gv1I;v=FM+c%08PDn`jn^__pK!6+@+~6x6YY^NZ=6k~6@WF(d+#@fqy1ls} z+gmwv88KH{=4+RG;dHLZ;U@eFT+L53wF3=gL&tDBl^Kk}kv2zhh!1=Xwk>lN1RsY$9Y-SkT!RarU1Vipl*m4k!e%(=wA(Xj7^NFANKyq5O4N= z(4=#j^&ggE=W8vB=)2@48AgSq{KTU+zIn2Zi3|u&rY^m2JIr9CPv!qJ1OHRu!XHxK zhLonsqlRDH-}Y^O=@(H`GbDF$kflA?e{EfNNsMvbw`<)o<_cL>tW{BMRmQmi86AVQ zrSV-7>hL)HNxe8ckGUA-@sp{{!oEd5y^+JTaQlgaUoJ6%tc(kpIH^&~nZ^DUN zv8yL^b+o-=bvP=kkT7R%!G^|MNJyqLSbJh^^Wv^=p;@4=LB-0FDJ9bi!zk~^BdoFv z(X`4O$=rcb#|^d_A;G?2jfhWwM|3LgCG*eRjFY|jcirv%Ws2iWde!%vw1qD(y`uYA z7g1{@ekJdi&gDli*}ES$@>wx=is--E4Q)5}lQ{ZmnNLqTM~Tti9hA95XY}P|!1kN* zsgwkJi=P+A&A+^UKz)U=wntoUjfmN6jr(Cdc`<9$F?CU)(nO>ttBY(Ha|)t?x@pC(-r0(&#U^-O|7d5jb5lm0wAp&49an7=S7$Hc3h$7_{ye1TXvLX7 zBruLqMb7k?!D+?_?&^Vyt2W5|-_}Cr>WxbhlNX7|rm`IlaRaS4@qxp~3%}p{S!6k< z;SP&d#PYyOAYxp@a;riD8sLR-5SH_(ng+WpC)+(a?fN6^DFY@u(F zb3-rZ!+@kv=OTYmZgF!)t!wb}&U@uiJ%!4dDvi&L?)3XlqHVbdGw#M)u<0vmZ=drx z?m57EWx8xBlj<;uE_F7gK1kaQVvzWHub~+2ldUkdIDlUH%)&{a6;_7MD|rSl#2JIQ45Tj0TG?Wq4tz@)YU#jMlr@udol!zf~%jyOV5`Yv=GN zO$?pO*}3Gw+Iy>WB{63svNzcI42EX&qJe9V$s0evb1U(Oox4pmo;K%>3m1p;T#3n! zJpzABiWdzZKc?O{*fYr+@RM1ppl_fl7MXfzQSHI7;j1<2^~_`Hq)hd;Adlbq7-4te z*EG{F1JrkWwh6H;4CnT9c6*w1uPf08)cLJ$Iaa>1H5Bc<#=M-ST~&-rOO0P#JXKes zyoEc!Iu!1Qp{XTyPeH^zL|bw~Bzk#(%bpBBpXmO!7M)lG2Fi6wstV}Q1h3h5W|XVN|*fC2X9wT(V0st&_}B8h_n-> z7+Sm!KB~0Nu8130DyE~B(TEI?Sv&t=-b(5~h;PF2o8Jw>m8a9iAvBXObLTJ04P6Vi z{`2{R*k$$u?1=5Yl}1)^mAungLVVzDyp-jh`H!w-MJfk%jgN)|KYfD5yk8Ld3_Yr$ zt~Ez;hz^2ObBy*nK*J3b;+a3OVkDb=cWtODGX6zl zi=P(r^rMm$(HC<9>YdcU<887}!{)^X#CggoWw?SZ>QAbirq{XVzHN%qU2a`xo}Fvf zD;DCU{QhEMM(=>Lw+HnlP@LMnU_~%o$?7OYxzOcsiet~dh>!T?v!M9^H4Y(sm?*uH zhCuEWv5VQ$-PIH^AAK~5VnhROQ~E^=A7vH>g&#HG}aC~<8h=*j7$cNJ?W@KyBMDhk}sn?wqdzCS5kASp>pTZ3T z&EAAzc>lqpB`(e@$IH@Lev=)!H@Kdso+{$D;bCy?voE2+^N0i!uIY2O^xQN)tkB6G z>n7##5Y)?_KDz6w;I!5EYDsz5$a>*GRBkuahe=0*nj+Hwd=70mYH@3)q+NtSC+oTD z5XWxWiQb_cqtg$~bkbcsIWMNbe_vekp5lG)R>!cD^eMdc^QWW%^Cv=MX45*SVo72r z>?yS-Q%~j4H81Q{nQ;_;iVm_Q4nxg1RX;HQWk;s9r1_u;ofvqTGHYRHvPJoJk-wb% zW-!mYZ%wALk|8bPi!b_W{i6g>feIBsZ}*;5EH+U3U1Q*=+qhY_Pdg?48H`K6yt6`0`3o#}UoS7dx*!)W>B zq-TcW;!je^B#kZe_5y~B$;<1?+d8_0$AZGKGi9o-gP3;qC%ciZsd-XE4L>V)H~fd% z=C6J5oHl={gzr)r)lGG+KO#N4rekh=afw6tl^h=J(wJ3CtC2i5N$OVDXI@shT29pI zE+;qotV?OW>$HkrH7i+wPspkQ3r~UYLd#3J##n-U>=gTe&%PL?_v8Lh+xxpd0e#Gc zXoE4mgzG4cJ(aWy=j+EzDYqTi$`@OFveS|$i8g42Ce)Ox!~=CfO(v`zi2 zmY6@*vASvd^Lfw3#Cj!T&2^2i#Q-0c?QI%spMmFr%bbk2Co6Ytmw35ZV)tk_GPY6G z{nh<`$0JBzk3e<*bf@F^bc_xo|+u%xKi6#GZ!lag}u$ zy_41B$_;;xi%sFBm5HjIgb1B|ChyR1yXxc|W0WelzL&hp-Z$z@ zpi1|`k&_MlXzQ|CZSd@C7(5+4Dy2I1Se>KtVeDt8P`9B0E*4Ay!P(e+QK!dgLZrcG zyM%V9?n{Tsa7y{zHaV11wR)Z!l(oc}*{|~W~y=%*vw{`XR&)CK{-pj-PYf@gJpZDhx3w2j zdh4x!chs7|Q`geZ?%ryHjH=c2*$eykOrEYX`e=PHO_z+cc-8!QSiJ1p`KM0_=nl8_ z^|<%ZXXu?G+4IRIC~b{CCClIIq1&tOa)2BPz3HR1Aej8jQ3~Wy4 zX$o$B(V}=WAgtV+&r*r+1mt|i&!xZhHl2U@KeI*Wh$XMzpUG5Es(x)|rnEOvS5ETm zS9jl{v=nE1>UJZOAc{B5Ap7agjZ^+7$Wad_!@?FWU4KSXJ$K&cdWq`21K$D3k;q=+ z(c333KdPXMaJ)X6vFj03)D|7E%PWy1P@1Pu!W($EPZ@c_^~=xp=Y#XI=6Fg@e5I}C z#!W?^nyDw0b-^;AKH_96ZI}VuyM`!F?0euX}=-xN}((^`eXD#hc5rY2nVP zy6cr!QN3iZh+k}7-Woump5DAjZNXjJdU?z29ON;w=I01WQP%@bLdr>q81i(#-%I7M zYCJV*tLSe^xH&3rD&$Vwt2)K`IMV)XYfT%S)|+9S8p*FzxPV%6^u)qR7SHX8(X}H_ z7mM42Ds4~$>9I9)?Pt1qeLu?7|tKL<7Hh2_;Phn z_isBp)>d6R{ruewFRH9HJ@SnB*|VsW8~b>!6rzcoWAWrt4R_BR87;7%s7F#tlEn|7 HzWl!cbdb}o From fe62cf91a9750b60e9925d7c58de6ede85fe2ea0 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Aug 2012 04:30:02 +0200 Subject: [PATCH 043/492] (Xbox 1) Fixes crashes when attempting to go to 'Libretro/paths' dir selection screens - had to do with wrong path setting --- console/rmenu/rmenu.c | 1 + xdk/frontend/main.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index d3a0cd22ae..e367e71775 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -720,6 +720,7 @@ static void browser_render(filebrowser_t * b, float current_x, float current_y, { DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; + RARCH_LOG("pointer b: %p\n", b); unsigned file_count = b->current_dir.list->size; unsigned int current_index, page_number, page_base, i; float currentX, currentY, ySpacing; diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index 68d3a73714..8972ec43a9 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -106,10 +106,10 @@ static void get_environment_settings (void) #if defined(_XBOX1) /* FIXME: Hardcoded */ - strlcpy(default_paths.core_dir, "D:\\", sizeof(default_paths.core_dir)); + strlcpy(default_paths.core_dir, "D:", sizeof(default_paths.core_dir)); strlcpy(default_paths.config_file, "D:\\retroarch.cfg", sizeof(default_paths.config_file)); strlcpy(default_paths.system_dir, "D:\\system\\", sizeof(default_paths.system_dir)); - strlcpy(default_paths.filesystem_root_dir, "D:\\", sizeof(default_paths.filesystem_root_dir)); + strlcpy(default_paths.filesystem_root_dir, "D:", sizeof(default_paths.filesystem_root_dir)); strlcpy(default_paths.executable_extension, ".xbe", sizeof(default_paths.executable_extension)); strlcpy(default_paths.filebrowser_startup_dir, "D:", sizeof(default_paths.filebrowser_startup_dir)); #elif defined(_XBOX360) From bbe055518501f8157d576080399cf5b6ae054099 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Aug 2012 04:36:04 +0200 Subject: [PATCH 044/492] (Xbox) Take out debug log --- console/rmenu/rmenu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index e367e71775..d3a0cd22ae 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -720,7 +720,6 @@ static void browser_render(filebrowser_t * b, float current_x, float current_y, { DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; - RARCH_LOG("pointer b: %p\n", b); unsigned file_count = b->current_dir.list->size; unsigned int current_index, page_number, page_base, i; float currentX, currentY, ySpacing; From 2affce8829d695f23ff396a011d61f96bf5a1a92 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Aug 2012 04:43:21 +0200 Subject: [PATCH 045/492] (RMenu) Take out _XBOX1-specific defines - make it more generic --- console/rmenu/rmenu.c | 49 +++++++------------------------------------ xdk/frontend/main.c | 3 +-- 2 files changed, 9 insertions(+), 43 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index d3a0cd22ae..6e744b8738 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -700,12 +700,7 @@ static void browser_update(filebrowser_t * b, uint64_t input, const char *extens else if (input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) { action = FILEBROWSER_ACTION_RESET; - //TODO - Dehardcode this -#ifdef _XBOX1 - filebrowser_set_root(b, "D:"); -#else - filebrowser_set_root(b, "/"); -#endif + filebrowser_set_root(b, default_paths.filesystem_root_dir); strlcpy(b->extensions, extensions, sizeof(b->extensions)); } @@ -1484,29 +1479,17 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { menu_stack_push(items, PATH_DEFAULT_ROM_DIR_CHOICE); -#ifdef _XBOX1 - filebrowser_set_root_and_ext(&tmpBrowser, "empty", "D:"); -#else - filebrowser_set_root_and_ext(&tmpBrowser, "empty", "/"); -#endif + filebrowser_set_root_and_ext(&tmpBrowser, "empty", default_paths.filesystem_root_dir); } if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) -#ifdef _XBOX1 - strlcpy(g_console.default_rom_startup_dir, "D:", sizeof(g_console.default_rom_startup_dir)); -#else - strlcpy(g_console.default_rom_startup_dir, "/", sizeof(g_console.default_rom_startup_dir)); -#endif + strlcpy(g_console.default_rom_startup_dir, default_paths.filesystem_root_dir, sizeof(g_console.default_rom_startup_dir)); break; case SETTING_PATH_SAVESTATES_DIRECTORY: if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { menu_stack_push(items, PATH_SAVESTATES_DIR_CHOICE); -#ifdef _XBOX1 - filebrowser_set_root_and_ext(&tmpBrowser, "empty", "D:"); -#else - filebrowser_set_root_and_ext(&tmpBrowser, "empty", "/"); -#endif + filebrowser_set_root_and_ext(&tmpBrowser, "empty", default_paths.filesystem_root_dir); } if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) @@ -1517,11 +1500,7 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { menu_stack_push(items, PATH_SRAM_DIR_CHOICE); -#ifdef _XBOX1 - filebrowser_set_root_and_ext(&tmpBrowser, "empty", "D:"); -#else - filebrowser_set_root_and_ext(&tmpBrowser, "empty", "/"); -#endif + filebrowser_set_root_and_ext(&tmpBrowser, "empty", default_paths.filesystem_root_dir); } if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) @@ -1532,11 +1511,7 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { menu_stack_push(items, PATH_CHEATS_DIR_CHOICE); -#ifdef _XBOX1 - filebrowser_set_root_and_ext(&tmpBrowser, "empty", "D:"); -#else - filebrowser_set_root_and_ext(&tmpBrowser, "empty", "/"); -#endif + filebrowser_set_root_and_ext(&tmpBrowser, "empty", default_paths.filesystem_root_dir); } if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) @@ -1547,11 +1522,7 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { menu_stack_push(items, PATH_SYSTEM_DIR_CHOICE); -#ifdef _XBOX1 - filebrowser_set_root_and_ext(&tmpBrowser, "empty", "D:"); -#else - filebrowser_set_root_and_ext(&tmpBrowser, "empty", "/"); -#endif + filebrowser_set_root_and_ext(&tmpBrowser, "empty", default_paths.filesystem_root_dir); } if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) @@ -2244,11 +2215,7 @@ void menu_init (void) menu_stack_push(rmenu_items, FILE_BROWSER_MENU); filebrowser_set_root_and_ext(&browser, rarch_console_get_rom_ext(), default_paths.filebrowser_startup_dir); -#ifdef _XBOX1 - filebrowser_set_root(&tmpBrowser, "D:"); -#else - filebrowser_set_root(&tmpBrowser, "/"); -#endif + filebrowser_set_root(&tmpBrowser, default_paths.filesystem_root_dir); #ifdef _XBOX1 // Set file cache size diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index 8972ec43a9..296654f924 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -105,10 +105,9 @@ static void get_environment_settings (void) #endif #if defined(_XBOX1) - /* FIXME: Hardcoded */ strlcpy(default_paths.core_dir, "D:", sizeof(default_paths.core_dir)); strlcpy(default_paths.config_file, "D:\\retroarch.cfg", sizeof(default_paths.config_file)); - strlcpy(default_paths.system_dir, "D:\\system\\", sizeof(default_paths.system_dir)); + strlcpy(default_paths.system_dir, "D:\\system", sizeof(default_paths.system_dir)); strlcpy(default_paths.filesystem_root_dir, "D:", sizeof(default_paths.filesystem_root_dir)); strlcpy(default_paths.executable_extension, ".xbe", sizeof(default_paths.executable_extension)); strlcpy(default_paths.filebrowser_startup_dir, "D:", sizeof(default_paths.filebrowser_startup_dir)); From 51507235b45263f6fed9d192f013f9d224ee7a7e Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Aug 2012 04:56:27 +0200 Subject: [PATCH 046/492] (RMenu) Change dir passed to 'System dir selection' to default_paths.system_dir --- console/rmenu/rmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index 6e744b8738..f6e752f2c6 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -1522,7 +1522,7 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) { menu_stack_push(items, PATH_SYSTEM_DIR_CHOICE); - filebrowser_set_root_and_ext(&tmpBrowser, "empty", default_paths.filesystem_root_dir); + filebrowser_set_root_and_ext(&tmpBrowser, "empty", default_paths.system_dir); } if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) From 6b02f6d21db27924fc0da376f78866869fab60dc Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Aug 2012 05:20:12 +0200 Subject: [PATCH 047/492] (Xbox 1) Have to mess around to get libretro management working properly again --- xdk/frontend/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index 296654f924..2bc5790649 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -133,7 +133,12 @@ int main(int argc, char *argv[]) input_xinput.init(); +#ifdef _XBOX1 + char path_prefix[256]; + snprintf(path_prefix, sizeof(path_prefix), "D:\\"); +#else const char *path_prefix = default_paths.filesystem_root_dir; +#endif const char *extension = default_paths.executable_extension; const input_driver_t *input = &input_xinput; bool find_libretro_file = rarch_configure_libretro(input, path_prefix, extension); From 848ef3c1e43051ff0925cde8eba54fc1719c1394 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Aug 2012 07:51:43 +0200 Subject: [PATCH 048/492] (Libretro mgmt) use rarch_configure_libretro_core for Xbox 1 port --- console/rarch_console_libretro_mgmt.c | 4 +++- console/rarch_console_libretro_mgmt.h | 2 ++ xdk/frontend/main.c | 7 ++++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/console/rarch_console_libretro_mgmt.c b/console/rarch_console_libretro_mgmt.c index 6dd04328fc..684a7c8b63 100644 --- a/console/rarch_console_libretro_mgmt.c +++ b/console/rarch_console_libretro_mgmt.c @@ -18,6 +18,8 @@ #include "../boolean.h" #include "../file.h" +#include "rarch_console_libretro_mgmt.h" + // if a CORE executable exists (full_path), this means we have just installed // a new libretro port and therefore we need to change it to a more // sane name. @@ -100,7 +102,7 @@ static bool rarch_manage_libretro_install(char *libretro_core_installed, size_t return ret; } -static bool rarch_configure_libretro_core(const char *full_path, const char *tmp_path, +bool rarch_configure_libretro_core(const char *full_path, const char *tmp_path, const char *libretro_path, const char *config_path, const char *extension) { bool libretro_core_was_installed = false; diff --git a/console/rarch_console_libretro_mgmt.h b/console/rarch_console_libretro_mgmt.h index de8d5170aa..e7f258ed1b 100644 --- a/console/rarch_console_libretro_mgmt.h +++ b/console/rarch_console_libretro_mgmt.h @@ -30,6 +30,8 @@ enum void rarch_manage_libretro_set_first_file(char *first_file, size_t size_of_first_file, const char *libretro_path, const char * exe_ext); #ifndef IS_SALAMANDER +bool rarch_configure_libretro_core(const char *full_path, const char *tmp_path, + const char *libretro_path, const char *config_path, const char *extension); bool rarch_configure_libretro(const input_driver_t *input, const char *path_prefix, const char * extension); bool rarch_manage_libretro_extension_supported(const char *filename); #endif diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index 2bc5790649..85085af5d7 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -141,7 +141,12 @@ int main(int argc, char *argv[]) #endif const char *extension = default_paths.executable_extension; const input_driver_t *input = &input_xinput; - bool find_libretro_file = rarch_configure_libretro(input, path_prefix, extension); + + char full_path[1024]; + snprintf(full_path, sizeof(full_path), "%sCORE%s", path_prefix, extension); + + bool find_libretro_file = rarch_configure_libretro_core(full_path, path_prefix, path_prefix, + default_paths.config_file, extension); rarch_settings_set_default(input); rarch_config_load(default_paths.config_file, path_prefix, extension, find_libretro_file); From d521edd86ac18424e770a56763622a56b115367e Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sun, 5 Aug 2012 07:43:37 +0200 Subject: [PATCH 049/492] (libretro mgmt) Get rid of rarch_configure_libretro function --- console/rarch_console_libretro_mgmt.c | 11 ----------- console/rarch_console_libretro_mgmt.h | 1 - ps3/frontend/main.c | 6 +++++- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/console/rarch_console_libretro_mgmt.c b/console/rarch_console_libretro_mgmt.c index 684a7c8b63..0fd5416737 100644 --- a/console/rarch_console_libretro_mgmt.c +++ b/console/rarch_console_libretro_mgmt.c @@ -128,17 +128,6 @@ bool rarch_configure_libretro_core(const char *full_path, const char *tmp_path, return find_libretro_file; } -bool rarch_configure_libretro(const input_driver_t *input, const char *path_prefix, const char * extension) -{ - char full_path[1024]; - snprintf(full_path, sizeof(full_path), "%sCORE%s", path_prefix, extension); - - bool find_libretro_file = rarch_configure_libretro_core(full_path, path_prefix, path_prefix, - default_paths.config_file, extension); - - return find_libretro_file; -} - bool rarch_manage_libretro_extension_supported(const char *filename) { bool ext_supported = false; diff --git a/console/rarch_console_libretro_mgmt.h b/console/rarch_console_libretro_mgmt.h index e7f258ed1b..cd11b181ab 100644 --- a/console/rarch_console_libretro_mgmt.h +++ b/console/rarch_console_libretro_mgmt.h @@ -32,7 +32,6 @@ void rarch_manage_libretro_set_first_file(char *first_file, size_t size_of_first #ifndef IS_SALAMANDER bool rarch_configure_libretro_core(const char *full_path, const char *tmp_path, const char *libretro_path, const char *config_path, const char *extension); -bool rarch_configure_libretro(const input_driver_t *input, const char *path_prefix, const char * extension); bool rarch_manage_libretro_extension_supported(const char *filename); #endif diff --git a/ps3/frontend/main.c b/ps3/frontend/main.c index 2ff2a1e659..157f17393d 100644 --- a/ps3/frontend/main.c +++ b/ps3/frontend/main.c @@ -259,7 +259,11 @@ int main(int argc, char *argv[]) const char *extension = default_paths.executable_extension; const input_driver_t *input = &input_ps3; - bool find_libretro_file = rarch_configure_libretro(input, path_prefix, extension); + char full_path[1024]; + snprintf(full_path, sizeof(full_path), "%sCORE%s", path_prefix, extension); + + bool find_libretro_file = rarch_configure_libretro_core(full_path, path_prefix, path_prefix, + default_paths.config_file, extension); rarch_settings_set_default(input); rarch_config_load(default_paths.config_file, path_prefix, extension, find_libretro_file); From 6f8f063b90253b8aa44c1148335e43849517a7ff Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 5 Aug 2012 13:01:33 +0200 Subject: [PATCH 050/492] Simplify win32 read_stdin(). Still untested. --- command.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/command.c b/command.c index 3e6fda43f1..91b5288b0b 100644 --- a/command.c +++ b/command.c @@ -248,25 +248,16 @@ static size_t read_stdin(char *buf, size_t size) // Check first if we're a pipe // (not console). DWORD avail = 0; - BOOL ret = PeekNamedPipe(hnd, NULL, 0, NULL, &avail, NULL); - if (!ret) // If not a pipe, check if we're running in a console. + // If not a pipe, check if we're running in a console. + if (!PeekNamedPipe(hnd, NULL, 0, NULL, &avail, NULL)) { - DWORD mode = 0; + DWORD mode; if (!GetConsoleMode(hnd, &mode)) return 0; - INPUT_RECORD rec = {0}; - DWORD has_read = 0; - - do - { - has_read = 0; - PeekConsoleInput(hnd, &rec, 1, &has_read); - } while (has_read && rec.EventType != KEY_EVENT); - - if (rec.EventType == KEY_EVENT) - avail = size; + if (!GetNumberOfConsoleInputEvents(hnd, &avail)) + return 0; } if (!avail) From ac579f2d6a14d1d9b554b4fd8a8adaf148566926 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sun, 5 Aug 2012 15:32:20 +0200 Subject: [PATCH 051/492] (RMenu) Move image files to console/rmenu/images --- Makefile.ps3 | 12 +++++++----- .../rmenu/images/main-menu_1080p.png | Bin ps3/pkg/USRDIR/cores/borders/Menu/.empty | 0 3 files changed, 7 insertions(+), 5 deletions(-) rename ps3/pkg/USRDIR/cores/borders/Menu/main-menu.png => console/rmenu/images/main-menu_1080p.png (100%) create mode 100644 ps3/pkg/USRDIR/cores/borders/Menu/.empty diff --git a/Makefile.ps3 b/Makefile.ps3 index 3450827ee0..82eb6fc8eb 100644 --- a/Makefile.ps3 +++ b/Makefile.ps3 @@ -119,6 +119,8 @@ create-npdrm-salamander: create-salamander: $(MAKE_SELF) $(SALAMANDER_TARGET) $(EBOOT_PATH) $(CONTENT_ID_FULL) +copy-media-files: + @cp console/rmenu/images/main-menu_1080p.png ps3/pkg/USRDIR/cores/borders/Menu/main-menu.png create-shaders: ifeq ($(DOWNLOAD_SHADERS),1) @@ -126,21 +128,21 @@ ifeq ($(DOWNLOAD_SHADERS),1) $(GIT) clone git://github.com/libretro/common-shaders.git ps3/pkg/USRDIR/cores/shaders endif -pkg: $(PPU_TARGET) create-shaders create-npdrm-salamander create-npdrm-core +pkg: $(PPU_TARGET) copy-media-files create-shaders create-npdrm-salamander create-npdrm-core $(MAKE_PACKAGE_NPDRM) ps3/pkg/package.conf ps3/pkg -pkg-signed: $(PPU_TARGET) create-shaders create-salamander create-core +pkg-signed: $(PPU_TARGET) copy-media-files create-shaders create-salamander create-core $(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) ps3/pkg/ retroarch-ps3-cfw-$(RARCH_VERSION).pkg -pkg-signed-standalone: $(PPU_TARGET) create-shaders create-core +pkg-signed-standalone: $(PPU_TARGET) copy-media-files create-shaders create-core $(MAKE_SELF) $(PPU_TARGET) $(EBOOT_PATH) $(CONTENT_ID) $(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) ps3/pkg/ retroarch-ps3-cfw-$(RARCH_VERSION).pkg -pkg-signed-cfw: $(PPU_TARGET) create-shaders create-salamander create-core +pkg-signed-cfw: $(PPU_TARGET) copy-media-files create-shaders create-salamander create-core $(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) ps3/pkg/ retroarch-ps3-cfw-$(RARCH_VERSION)-kmeaw.pkg $(PKG_FINALIZE) retroarch-ps3-cfw-$(RARCH_VERSION)-kmeaw.pkg -pkg-signed-cfw-standalone: $(PPU_TARGET) create-shaders create-core +pkg-signed-cfw-standalone: $(PPU_TARGET) copy-media-files create-shaders create-core $(MAKE_SELF) $(PPU_TARGET) $(EBOOT_PATH) $(CONTENT_ID) $(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) ps3/pkg/ retroarch-ps3-cfw-$(RARCH_VERSION).pkg $(PKG_FINALIZE) retroarch-ps3-cfw-$(RARCH_VERSION)-kmeaw.pkg diff --git a/ps3/pkg/USRDIR/cores/borders/Menu/main-menu.png b/console/rmenu/images/main-menu_1080p.png similarity index 100% rename from ps3/pkg/USRDIR/cores/borders/Menu/main-menu.png rename to console/rmenu/images/main-menu_1080p.png diff --git a/ps3/pkg/USRDIR/cores/borders/Menu/.empty b/ps3/pkg/USRDIR/cores/borders/Menu/.empty new file mode 100644 index 0000000000..e69de29bb2 From 8e1dfde5cb90a3453053712828db8cb520b86db8 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Aug 2012 16:35:01 +0200 Subject: [PATCH 052/492] (Xbox 1) Rename PNG files --- console/rmenu/rmenu.c | 4 ++-- xbox1/Media/{menuMainBG.png => main-menu_480p.png} | Bin .../{menuMainBG_720p.png => main-menu_720p.png} | Bin 3 files changed, 2 insertions(+), 2 deletions(-) rename xbox1/Media/{menuMainBG.png => main-menu_480p.png} (100%) rename xbox1/Media/{menuMainBG_720p.png => main-menu_720p.png} (100%) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index f6e752f2c6..f12ab4d5a5 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -2237,13 +2237,13 @@ void menu_init (void) // Load background image if(width == 640) { - d3d_surface_new(&m_menuMainBG, "D:\\Media\\menuMainBG.png"); + d3d_surface_new(&m_menuMainBG, "D:\\Media\\main-menu_480p.png"); m_menuMainRomListPos_x = 60; m_menuMainRomListPos_y = 80; } else if(width == 1280) { - d3d_surface_new(&m_menuMainBG, "D:\\Media\\menuMainBG_720p.png"); + d3d_surface_new(&m_menuMainBG, "D:\\Media\\main-menu_720p.png"); m_menuMainRomListPos_x = 360; m_menuMainRomListPos_y = 130; } diff --git a/xbox1/Media/menuMainBG.png b/xbox1/Media/main-menu_480p.png similarity index 100% rename from xbox1/Media/menuMainBG.png rename to xbox1/Media/main-menu_480p.png diff --git a/xbox1/Media/menuMainBG_720p.png b/xbox1/Media/main-menu_720p.png similarity index 100% rename from xbox1/Media/menuMainBG_720p.png rename to xbox1/Media/main-menu_720p.png From 1448761e7316ff364661ccec909c443e7def6ec9 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Aug 2012 17:18:19 +0200 Subject: [PATCH 053/492] (Xbox 1) Refactor surface code to implementation of texture_image --- console/griffin/griffin.c | 3 +- console/rmenu/rmenu.c | 46 ++++++++++----- gfx/image.h | 16 +++++ xbox1/frontend/RetroLaunch/Surface.h | 33 ----------- .../RetroLaunch/Surface.cpp => image.c} | 59 +++++++++++-------- 5 files changed, 83 insertions(+), 74 deletions(-) delete mode 100644 xbox1/frontend/RetroLaunch/Surface.h rename xbox1/{frontend/RetroLaunch/Surface.cpp => image.c} (75%) diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index 7a08a07405..dda6547f5c 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -112,6 +112,8 @@ VIDEO IMAGE #if defined(__CELLOS_LV2__) #include "../../ps3/image.c" +#elif defined(_XBOX1) +#include "../../xbox1/image.c" #endif /*============================================================ @@ -294,5 +296,4 @@ MENU #include "../../360/frontend-xdk/menu.cpp" #elif defined(_XBOX1) #include "../../xbox1/frontend/RetroLaunch/IoSupport.cpp" -#include "../../xbox1/frontend/RetroLaunch/Surface.cpp" #endif diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index f12ab4d5a5..f75f961423 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -33,6 +33,8 @@ #include "../../console/rarch_console_config.h" #include "../../console/rarch_console_settings.h" +#include "../../gfx/image.h" + #ifdef HAVE_RSOUND #include "../../console/rarch_console_rsound.h" #endif @@ -70,17 +72,14 @@ #ifdef _XBOX1 #include "../../xbox1/frontend/RetroLaunch/IoSupport.h" -#include "../../xbox1/frontend/RetroLaunch/Surface.h" #include "../../gfx/fonts/xdk1_xfonts.h" #define ROM_PANEL_WIDTH 510 #define ROM_PANEL_HEIGHT 20 int xpos, ypos; -// Rom selector panel with coords -d3d_surface_t m_menuMainRomSelectPanel; -// Background image with coords -d3d_surface_t m_menuMainBG; +texture_image m_menuMainRomSelectPanel; +texture_image m_menuMainBG; // Rom list coords int m_menuMainRomListPos_x; @@ -669,8 +668,9 @@ static void display_menubar(menu *current_menu) #ifdef _XBOX1 //Render background image - d3d_surface_render(&m_menuMainBG, 0, 0, - m_menuMainBG.m_imageInfo.Width, m_menuMainBG.m_imageInfo.Height); + m_menuMainBG.x = 0; + m_menuMainBG.y = 0; + texture_image_render(&m_menuMainBG); #else render_msg_place_func(x_position, 0.05f, 1.4f, WHITE, current_menu->title); render_msg_place_func(0.3f, 0.06f, 0.82f, WHITE, m_title); @@ -737,7 +737,13 @@ static void browser_render(filebrowser_t * b, float current_x, float current_y, //check if this is the currently selected file const char *current_pathname = filebrowser_get_current_path(b); if(strcmp(current_pathname, b->current_dir.list->elems[i].data) == 0) - d3d_surface_render(&m_menuMainRomSelectPanel, currentX, currentY, ROM_PANEL_WIDTH, ROM_PANEL_HEIGHT); + { + m_menuMainRomSelectPanel.x = currentX; + m_menuMainRomSelectPanel.y = currentY; + m_menuMainRomSelectPanel.width = ROM_PANEL_WIDTH; + m_menuMainRomSelectPanel.height = ROM_PANEL_HEIGHT; + texture_image_render(&m_menuMainRomSelectPanel); + } render_msg_place_func(currentX, currentY, 0, 0, fname_tmp); #else @@ -1743,7 +1749,13 @@ static void select_setting(item *items, menu *current_menu, uint64_t input) render_msg_place_func(x_position_center, items[i].text_ypos, FONT_SIZE, items[i].text_color, items[i].setting_text); #ifdef _XBOX1 if(current_menu->selected == items[i].enum_id) - d3d_surface_render(&m_menuMainRomSelectPanel, x_position, items[i].text_ypos, ROM_PANEL_WIDTH, ROM_PANEL_HEIGHT); + { + m_menuMainRomSelectPanel.x = x_position; + m_menuMainRomSelectPanel.y = items[i].text_ypos; + m_menuMainRomSelectPanel.width = ROM_PANEL_WIDTH; + m_menuMainRomSelectPanel.height = ROM_PANEL_HEIGHT; + texture_image_render(&m_menuMainRomSelectPanel); + } #endif } } @@ -2198,7 +2210,11 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) render_msg_place_func(x_position, comment_y_position, font_size, WHITE, comment); #ifdef _XBOX1 - d3d_surface_render(&m_menuMainRomSelectPanel, x_position, (y_position+(y_position_increment*g_console.ingame_menu_item)), ROM_PANEL_WIDTH, ROM_PANEL_HEIGHT); + m_menuMainRomSelectPanel.x = x_position; + m_menuMainRomSelectPanel.y = (y_position+(y_position_increment*g_console.ingame_menu_item)); + m_menuMainRomSelectPanel.width = ROM_PANEL_WIDTH; + m_menuMainRomSelectPanel.height = ROM_PANEL_HEIGHT; + texture_image_render(&m_menuMainRomSelectPanel); #endif } @@ -2237,19 +2253,19 @@ void menu_init (void) // Load background image if(width == 640) { - d3d_surface_new(&m_menuMainBG, "D:\\Media\\main-menu_480p.png"); + texture_image_load("D:\\Media\\main-menu_480p.png", &m_menuMainBG); m_menuMainRomListPos_x = 60; m_menuMainRomListPos_y = 80; } else if(width == 1280) { - d3d_surface_new(&m_menuMainBG, "D:\\Media\\main-menu_720p.png"); + texture_image_load("D:\\Media\\main-menu_720p.png", &m_menuMainBG); m_menuMainRomListPos_x = 360; m_menuMainRomListPos_y = 130; } // Load rom selector panel - d3d_surface_new(&m_menuMainRomSelectPanel, "D:\\Media\\menuMainRomSelectPanel.png"); + texture_image_load("D:\\Media\\menuMainRomSelectPanel.png", &m_menuMainRomSelectPanel); //Display some text //Center the text (hardcoded) @@ -2264,8 +2280,8 @@ void menu_free (void) filebrowser_free(&tmpBrowser); #ifdef _XBOX1 - d3d_surface_free(&m_menuMainBG); - d3d_surface_free(&m_menuMainRomSelectPanel); + texture_image_free(&m_menuMainBG); + texture_image_free(&m_menuMainRomSelectPanel); #endif } diff --git a/gfx/image.h b/gfx/image.h index 1b4660833d..6c9775cf35 100644 --- a/gfx/image.h +++ b/gfx/image.h @@ -19,13 +19,29 @@ #include #include "../boolean.h" +#ifdef _XBOX1 +#include "../xdk/xdk_defines.h" +#endif + struct texture_image { unsigned width; unsigned height; +#ifdef _XBOX1 + unsigned x; + unsigned y; + LPDIRECT3DTEXTURE pixels; + LPDIRECT3DVERTEXBUFFER vertex_buf; +#else uint32_t *pixels; +#endif }; +#ifdef _XBOX1 +void texture_image_free(struct texture_image *out_img); +bool texture_image_render(struct texture_image *out_img); +#endif + bool texture_image_load(const char *path, struct texture_image* img); #endif diff --git a/xbox1/frontend/RetroLaunch/Surface.h b/xbox1/frontend/RetroLaunch/Surface.h deleted file mode 100644 index 51466e7f78..0000000000 --- a/xbox1/frontend/RetroLaunch/Surface.h +++ /dev/null @@ -1,33 +0,0 @@ -/* RetroArch - A frontend for libretro. -* Copyright (C) 2010-2012 - Hans-Kristian Arntzen -* Copyright (C) 2011-2012 - Daniel De Matteis -* -* RetroArch is free software: you can redistribute it and/or modify it under the terms -* of the GNU General Public License as published by the Free Software Found- -* ation, either version 3 of the License, or (at your option) any later version. -* -* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with RetroArch. -* If not, see . -*/ - -#ifndef _D3D_SURFACE_H_ -#define _D3D_SURFACE_H_ - -#include "../../../xdk/xdk_defines.h" - -typedef struct -{ - LPDIRECT3DTEXTURE m_pTexture; - LPDIRECT3DVERTEXBUFFER m_pVertexBuffer; - D3DXIMAGE_INFO m_imageInfo; -} d3d_surface_t; - -bool d3d_surface_new(d3d_surface_t *surface, const char *filename); -void d3d_surface_free(d3d_surface_t *surface); -bool d3d_surface_render(d3d_surface_t *surface, int x, int y, int32_t w, int32_t h); - -#endif \ No newline at end of file diff --git a/xbox1/frontend/RetroLaunch/Surface.cpp b/xbox1/image.c similarity index 75% rename from xbox1/frontend/RetroLaunch/Surface.cpp rename to xbox1/image.c index e80b561f08..26b2978037 100644 --- a/xbox1/frontend/RetroLaunch/Surface.cpp +++ b/xbox1/image.c @@ -14,19 +14,20 @@ * If not, see . */ -#include "Surface.h" +#include "../gfx/image.h" +#include "xdk_d3d8.h" -#include "../../xdk_d3d8.h" - -bool d3d_surface_new(d3d_surface_t *surface, const char *filename) +bool texture_image_load(const char *path, struct texture_image *out_img) { xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; + + D3DXIMAGE_INFO m_imageInfo; - surface->m_pTexture = NULL; - surface->m_pVertexBuffer = NULL; + out_img->pixels = NULL; + out_img->vertex_buf = NULL; HRESULT ret = D3DXCreateTextureFromFileExA(d3d->d3d_render_device, // d3d device - filename, // filename + path, // filename D3DX_DEFAULT, // width D3DX_DEFAULT, // height D3DX_DEFAULT, // mipmaps @@ -36,9 +37,9 @@ bool d3d_surface_new(d3d_surface_t *surface, const char *filename) D3DX_DEFAULT, // texture filter D3DX_DEFAULT, // mipmapping 0, // colorkey - &surface->m_imageInfo, // image info - NULL, // pallete - &surface->m_pTexture); // texture + &m_imageInfo, // image info + NULL, // palette + &out_img->pixels); // texture if(FAILED(ret)) { @@ -48,42 +49,50 @@ bool d3d_surface_new(d3d_surface_t *surface, const char *filename) // create a vertex buffer for the quad that will display the texture ret = d3d->d3d_render_device->CreateVertexBuffer(4 * sizeof(DrawVerticeFormats), - D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &surface->m_pVertexBuffer); + D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &out_img->vertex_buf); if (FAILED(ret)) { RARCH_ERR("Error occurred during CreateVertexBuffer().\n"); - surface->m_pTexture->Release(); + out_img->pixels->Release(); return false; } + + out_img->width = m_imageInfo.Width; + out_img->height = m_imageInfo.Height; return true; } -void d3d_surface_free(d3d_surface_t *surface) +void texture_image_free(struct texture_image *out_img) { // free the vertex buffer - if (surface->m_pVertexBuffer) + if (out_img->vertex_buf) { - surface->m_pVertexBuffer->Release(); - surface->m_pVertexBuffer = NULL; + out_img->vertex_buf->Release(); + out_img->vertex_buf = NULL; } // free the texture - if (surface->m_pTexture) + if (out_img->pixels) { - surface->m_pTexture->Release(); - surface->m_pTexture = NULL; + out_img->pixels->Release(); + out_img->pixels = NULL; } } -bool d3d_surface_render(d3d_surface_t *surface, int x, int y, int32_t w, int32_t h) +bool texture_image_render(struct texture_image *out_img) { xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; - if (surface->m_pTexture == NULL || surface->m_pVertexBuffer == NULL) + if (out_img->pixels == NULL || out_img->vertex_buf == NULL) return false; + int x = out_img->x; + int y = out_img->y; + int w = out_img->width; + int h = out_img->height; + float fX = static_cast(x); float fY = static_cast(y); @@ -100,7 +109,7 @@ bool d3d_surface_render(d3d_surface_t *surface, int x, int y, int32_t w, int32_t // load the existing vertices DrawVerticeFormats *pCurVerts; - HRESULT ret = surface->m_pVertexBuffer->Lock(0, 0, (unsigned char**)&pCurVerts, 0); + HRESULT ret = out_img->vertex_buf->Lock(0, 0, (unsigned char**)&pCurVerts, 0); if (FAILED(ret)) { @@ -111,7 +120,7 @@ bool d3d_surface_render(d3d_surface_t *surface, int x, int y, int32_t w, int32_t // copy the new verts over the old verts memcpy(pCurVerts, newVerts, 4 * sizeof(DrawVerticeFormats)); - surface->m_pVertexBuffer->Unlock(); + out_img->vertex_buf->Unlock(); d3d->d3d_render_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); d3d->d3d_render_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); @@ -123,8 +132,8 @@ bool d3d_surface_render(d3d_surface_t *surface, int x, int y, int32_t w, int32_t d3d->d3d_render_device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); // draw the quad - d3d->d3d_render_device->SetTexture(0, surface->m_pTexture); - d3d->d3d_render_device->SetStreamSource(0, surface->m_pVertexBuffer, sizeof(DrawVerticeFormats)); + d3d->d3d_render_device->SetTexture(0, out_img->pixels); + d3d->d3d_render_device->SetStreamSource(0, out_img->vertex_buf, sizeof(DrawVerticeFormats)); d3d->d3d_render_device->SetVertexShader(D3DFVF_CUSTOMVERTEX); d3d->d3d_render_device->DrawPrimitive(D3DPT_QUADLIST, 0, 1); From 0625286a224b24778629c63e33185b88bd27264a Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Aug 2012 17:38:21 +0200 Subject: [PATCH 054/492] (Xbox 1) Only show debug messages if g_console.fps_info_enable is set to true --- xbox1/xdk_d3d8.cpp | 5 ----- xbox1/xdk_d3d8.h | 7 ------- 2 files changed, 12 deletions(-) diff --git a/xbox1/xdk_d3d8.cpp b/xbox1/xdk_d3d8.cpp index d37f5db9ae..a1429967c5 100644 --- a/xbox1/xdk_d3d8.cpp +++ b/xbox1/xdk_d3d8.cpp @@ -357,11 +357,6 @@ static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **inpu font_x = 0; font_y = 0; - // TODO: place this somewhere else outside of xdk_d3d8.cpp -#ifdef SHOW_DEBUG_INFO - g_console.fps_info_enable = true; -#endif - return d3d; } diff --git a/xbox1/xdk_d3d8.h b/xbox1/xdk_d3d8.h index 26e790169f..d7a55ad915 100644 --- a/xbox1/xdk_d3d8.h +++ b/xbox1/xdk_d3d8.h @@ -18,17 +18,10 @@ #define _XDK_VIDEO_H #include - -#ifdef _XBOX1 -#define XFONT_TRUETYPE // use true type fonts -#endif - #include #include "../xdk/xdk_defines.h" -#define SHOW_DEBUG_INFO - #define DFONT_MAX 4096 #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_TEX1) From 0ec872c917defff0f10edbe1fb1221ea5bd16b0a Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Aug 2012 17:53:01 +0200 Subject: [PATCH 055/492] (RMenu) PATH_SYSTEM_DIR_CHOICE works now --- console/rmenu/rmenu.c | 11 ++++++++++- xbox1/xdk_d3d8.h | 1 - 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index f75f961423..bda2572f81 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -638,6 +638,7 @@ static void display_menubar(menu *current_menu) case PATH_CHEATS_DIR_CHOICE: #endif case PATH_SRAM_DIR_CHOICE: + case PATH_SYSTEM_DIR_CHOICE: render_msg_place_func(x_position, msg_prev_next_y_position, font_size, WHITE, "<- PREV"); break; default: @@ -657,6 +658,7 @@ static void display_menubar(menu *current_menu) case PATH_CHEATS_DIR_CHOICE: #endif case PATH_SRAM_DIR_CHOICE: + case PATH_SYSTEM_DIR_CHOICE: fb = &tmpBrowser; case FILE_BROWSER_MENU: snprintf(current_path, sizeof(current_path), "PATH: %s", filebrowser_get_current_dir(fb)); @@ -924,6 +926,9 @@ static void select_directory(item *items, menu *current_menu, uint64_t input) strlcpy(g_settings.cheat_database, path, sizeof(g_settings.cheat_database)); break; #endif + case PATH_SYSTEM_DIR_CHOICE: + strlcpy(g_settings.system_directory, path, sizeof(g_settings.system_directory)); + break; } menu_stack_decrement(); } @@ -947,6 +952,9 @@ static void select_directory(item *items, menu *current_menu, uint64_t input) strlcpy(g_settings.cheat_database, path, sizeof(g_settings.cheat_database)); break; #endif + case PATH_SYSTEM_DIR_CHOICE: + strlcpy(g_settings.system_directory, path, sizeof(g_settings.system_directory)); + break; } menu_stack_decrement(); @@ -2454,7 +2462,8 @@ void menu_loop(void) #ifdef HAVE_XML case PATH_CHEATS_DIR_CHOICE: #endif - case PATH_SRAM_DIR_CHOICE: + case PATH_SRAM_DIR_CHOICE: + case PATH_SYSTEM_DIR_CHOICE: select_directory(rmenu_items, current_menu, trig_state); fb = &tmpBrowser; break; diff --git a/xbox1/xdk_d3d8.h b/xbox1/xdk_d3d8.h index d7a55ad915..0c23da9794 100644 --- a/xbox1/xdk_d3d8.h +++ b/xbox1/xdk_d3d8.h @@ -22,7 +22,6 @@ #include "../xdk/xdk_defines.h" -#define DFONT_MAX 4096 #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_TEX1) #define MIN_SCALING_FACTOR (1.0f) From 9e6c9e5f7b76703249a1e3c321160580033943c5 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Aug 2012 18:42:54 +0200 Subject: [PATCH 056/492] (Xbox 1) Option for debug info messages --- console/rmenu/rmenu.c | 10 ++++++++++ console/rmenu/rmenu.h | 1 + console/rmenu/rmenu_entries.h | 10 ++++++++++ general.h | 2 +- xbox1/xdk_d3d8.cpp | 2 +- 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index bda2572f81..b8af014e50 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -255,6 +255,10 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "%d", g_extern.state_slot); break; /* emu-specific */ + case SETTING_EMU_SHOW_DEBUG_INFO_MSG: + set_setting_label_write_on_or_off(items, g_console.fps_info_msg_enable, currentsetting); + set_setting_label_color(items,g_console.fps_info_msg_enable, currentsetting); + break; case SETTING_EMU_SHOW_INFO_MSG: set_setting_label_write_on_or_off(items, g_console.info_msg_enable, currentsetting); set_setting_label_color(items,g_console.info_msg_enable, currentsetting); @@ -1415,6 +1419,12 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) rarch_settings_default(S_DEF_SAVE_STATE); break; + case SETTING_EMU_SHOW_DEBUG_INFO_MSG: + if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) + g_console.fps_info_msg_enable = !g_console.fps_info_msg_enable; + if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) + g_console.fps_info_msg_enable = false; + break; case SETTING_EMU_SHOW_INFO_MSG: if((input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) g_console.info_msg_enable = !g_console.info_msg_enable; diff --git a/console/rmenu/rmenu.h b/console/rmenu/rmenu.h index 8cda02b960..9ed18c6ed3 100644 --- a/console/rmenu/rmenu.h +++ b/console/rmenu/rmenu.h @@ -162,6 +162,7 @@ enum SETTING_ENABLE_CUSTOM_BGM, SETTING_DEFAULT_AUDIO_ALL, SETTING_EMU_CURRENT_SAVE_STATE_SLOT, + SETTING_EMU_SHOW_DEBUG_INFO_MSG, SETTING_EMU_SHOW_INFO_MSG, SETTING_ZIP_EXTRACT, SETTING_RARCH_DEFAULT_EMU, diff --git a/console/rmenu/rmenu_entries.h b/console/rmenu/rmenu_entries.h index 2c881a7a8f..d60700b283 100644 --- a/console/rmenu/rmenu_entries.h +++ b/console/rmenu/rmenu_entries.h @@ -245,6 +245,16 @@ item rmenu_items[MAX_NO_OF_CONTROLS_SETTINGS] = YELLOW, "INFO - Set the current savestate slot (can also be configured ingame).", WHITE, + }, + { + SETTING_EMU_SHOW_DEBUG_INFO_MSG, + "Debug Info messages", + "", + 0.0f, + 0.0f, + YELLOW, + "INFO - Show onscreen debug messages.", + WHITE, }, { SETTING_EMU_SHOW_INFO_MSG, diff --git a/general.h b/general.h index ec7c118a36..288a806585 100644 --- a/general.h +++ b/general.h @@ -207,7 +207,7 @@ struct console_settings bool default_sram_dir_enable; bool default_savestate_dir_enable; bool fbo_enabled; - bool fps_info_enable; + bool fps_info_msg_enable; bool frame_advance_enable; #ifdef _XBOX bool menus_hd_enable; diff --git a/xbox1/xdk_d3d8.cpp b/xbox1/xdk_d3d8.cpp index a1429967c5..462b266153 100644 --- a/xbox1/xdk_d3d8.cpp +++ b/xbox1/xdk_d3d8.cpp @@ -368,7 +368,7 @@ static bool xdk_d3d_frame(void *data, const void *frame, xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)data; bool menu_enabled = g_console.menu_enable; - bool fps_enable = g_console.fps_info_enable; + bool fps_enable = g_console.fps_info_msg_enable; if (d3d->last_width != width || d3d->last_height != height) //240*160 { From a66291c3090bd1abad0ea73f088a6ae6a1b52a74 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Aug 2012 19:09:51 +0200 Subject: [PATCH 057/492] (Xbox 1) Create RetroArch Salamander XBE file - default.xbe --- conf/config_file.c | 2 -- msvc/RetroArch-Xbox1.sln | 16 +++++++++++++++- msvc/msvc-71/logger_override.h | 2 ++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/conf/config_file.c b/conf/config_file.c index af58eb4d6c..0edf06e309 100644 --- a/conf/config_file.c +++ b/conf/config_file.c @@ -30,8 +30,6 @@ #define WIN32_LEAN_AND_MEAN #include #elif defined(_XBOX) -#define NOD3D -#define NONET #include #endif diff --git a/msvc/RetroArch-Xbox1.sln b/msvc/RetroArch-Xbox1.sln index 6c13d1eb60..cbabddb331 100644 --- a/msvc/RetroArch-Xbox1.sln +++ b/msvc/RetroArch-Xbox1.sln @@ -1,5 +1,9 @@ Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RetroArch-Xbox1", "RetroArch-Xbox1/RetroArch-Xbox1.vcproj", "{0E616FC4-0954-4FE3-935C-B7383B18D325}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RetroArch", "RetroArch-Xbox1\RetroArch-Xbox1.vcproj", "{0E616FC4-0954-4FE3-935C-B7383B18D325}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RetroArch-Salamander", "RetroArch-Salamander\RetroArch-Salamander.vcproj", "{EA17F7A7-7E66-4E32-9BA3-DEC11E4BBA8E}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject @@ -22,6 +26,16 @@ Global {0E616FC4-0954-4FE3-935C-B7383B18D325}.Release.Build.0 = Release|Xbox {0E616FC4-0954-4FE3-935C-B7383B18D325}.Release_LTCG.ActiveCfg = Release_LTCG|Xbox {0E616FC4-0954-4FE3-935C-B7383B18D325}.Release_LTCG.Build.0 = Release_LTCG|Xbox + {EA17F7A7-7E66-4E32-9BA3-DEC11E4BBA8E}.Debug.ActiveCfg = Debug|Xbox + {EA17F7A7-7E66-4E32-9BA3-DEC11E4BBA8E}.Debug.Build.0 = Debug|Xbox + {EA17F7A7-7E66-4E32-9BA3-DEC11E4BBA8E}.Profile.ActiveCfg = Profile|Xbox + {EA17F7A7-7E66-4E32-9BA3-DEC11E4BBA8E}.Profile.Build.0 = Profile|Xbox + {EA17F7A7-7E66-4E32-9BA3-DEC11E4BBA8E}.Profile_FastCap.ActiveCfg = Profile_FastCap|Xbox + {EA17F7A7-7E66-4E32-9BA3-DEC11E4BBA8E}.Profile_FastCap.Build.0 = Profile_FastCap|Xbox + {EA17F7A7-7E66-4E32-9BA3-DEC11E4BBA8E}.Release.ActiveCfg = Release|Xbox + {EA17F7A7-7E66-4E32-9BA3-DEC11E4BBA8E}.Release.Build.0 = Release|Xbox + {EA17F7A7-7E66-4E32-9BA3-DEC11E4BBA8E}.Release_LTCG.ActiveCfg = Release_LTCG|Xbox + {EA17F7A7-7E66-4E32-9BA3-DEC11E4BBA8E}.Release_LTCG.Build.0 = Release_LTCG|Xbox EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection diff --git a/msvc/msvc-71/logger_override.h b/msvc/msvc-71/logger_override.h index a9999b8978..de4495c3d5 100644 --- a/msvc/msvc-71/logger_override.h +++ b/msvc/msvc-71/logger_override.h @@ -19,6 +19,8 @@ #include +#include "../msvc_compat.h" + static inline void RARCH_LOG(const char *msg, ...) { char msg_new[1024], buffer[1024]; From 62d01cbca7c8f451a9f64069cb7c07d7f0ab2196 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sun, 5 Aug 2012 21:52:54 +0200 Subject: [PATCH 058/492] (Libretro mgmt) Clean up rarch_configure_libretro --- console/rarch_console_libretro_mgmt.c | 88 +++++++++++++-------------- 1 file changed, 41 insertions(+), 47 deletions(-) diff --git a/console/rarch_console_libretro_mgmt.c b/console/rarch_console_libretro_mgmt.c index 0fd5416737..10df6013ee 100644 --- a/console/rarch_console_libretro_mgmt.c +++ b/console/rarch_console_libretro_mgmt.c @@ -59,53 +59,10 @@ static void rarch_console_name_from_id(char *name, size_t size) } } -static bool rarch_manage_libretro_install(char *libretro_core_installed, size_t sizeof_libretro_core, const char *full_path, const char *path, const char *exe_ext) -{ - int ret; - char tmp_path2[1024], tmp_pathnewfile[1024]; - - rarch_console_name_from_id(tmp_path2, sizeof(tmp_path2)); - strlcat(tmp_path2, exe_ext, sizeof(tmp_path2)); - snprintf(tmp_pathnewfile, sizeof(tmp_pathnewfile), "%s%s", path, tmp_path2); - - if (path_file_exists(tmp_pathnewfile)) - { - // if libretro core already exists, this means we are - // upgrading the libretro core - so delete pre-existing - // file first. - - RARCH_LOG("Upgrading emulator core...\n"); - ret = remove(tmp_pathnewfile); - - if (ret == 0) - RARCH_LOG("Succeeded in removing pre-existing libretro core: [%s].\n", tmp_pathnewfile); - else - RARCH_ERR("Failed to remove pre-existing libretro core: [%s].\n", tmp_pathnewfile); - } - - //now attempt the renaming. - ret = rename(full_path, tmp_pathnewfile); - - if (ret == 0) - { - RARCH_LOG("libretro core [%s] renamed to: [%s].\n", full_path, tmp_pathnewfile); - strlcpy(libretro_core_installed, tmp_pathnewfile, sizeof_libretro_core); - ret = 1; - } - else - { - RARCH_ERR("Failed to rename CORE executable.\n"); - RARCH_WARN("CORE executable was not found, or some other errors occurred. Will attempt to load libretro core path from config file.\n"); - ret = 0; - } - - return ret; -} - bool rarch_configure_libretro_core(const char *full_path, const char *tmp_path, const char *libretro_path, const char *config_path, const char *extension) { - bool libretro_core_was_installed = false; + bool ret = false; bool find_libretro_file = false; char libretro_core_installed[1024]; @@ -113,14 +70,51 @@ bool rarch_configure_libretro_core(const char *full_path, const char *tmp_path, //install and rename libretro core first if 'CORE' executable exists if (path_file_exists(full_path)) - libretro_core_was_installed = rarch_manage_libretro_install( - libretro_core_installed, sizeof(libretro_core_installed), full_path, tmp_path, extension); + { + size_t sizeof_libretro_core = sizeof(libretro_core_installed); + char tmp_path2[1024], tmp_pathnewfile[1024]; + + rarch_console_name_from_id(tmp_path2, sizeof(tmp_path2)); + strlcat(tmp_path2, extension, sizeof(tmp_path2)); + snprintf(tmp_pathnewfile, sizeof(tmp_pathnewfile), "%s%s", tmp_path, tmp_path2); + + if (path_file_exists(tmp_pathnewfile)) + { + // if libretro core already exists, this means we are + // upgrading the libretro core - so delete pre-existing + // file first. + + RARCH_LOG("Upgrading emulator core...\n"); + ret = remove(tmp_pathnewfile); + + if (ret == 0) + RARCH_LOG("Succeeded in removing pre-existing libretro core: [%s].\n", tmp_pathnewfile); + else + RARCH_ERR("Failed to remove pre-existing libretro core: [%s].\n", tmp_pathnewfile); + } + + //now attempt the renaming. + ret = rename(full_path, tmp_pathnewfile); + + if (ret == 0) + { + RARCH_LOG("libretro core [%s] renamed to: [%s].\n", full_path, tmp_pathnewfile); + strlcpy(libretro_core_installed, tmp_pathnewfile, sizeof_libretro_core); + ret = 1; + } + else + { + RARCH_ERR("Failed to rename CORE executable.\n"); + RARCH_WARN("CORE executable was not found, or some other errors occurred. Will attempt to load libretro core path from config file.\n"); + ret = 0; + } + } g_extern.verbose = false; //if we have just installed a libretro core, set libretro path in settings to newly installed libretro core - if(libretro_core_was_installed) + if(ret) strlcpy(g_settings.libretro, libretro_core_installed, sizeof(g_settings.libretro)); else find_libretro_file = true; From 07a2803515e542f3414437cb6d42f692b525f41f Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sun, 5 Aug 2012 21:55:53 +0200 Subject: [PATCH 059/492] (Libretro mgmt) Move comments to header --- console/rarch_console_libretro_mgmt.c | 10 ---------- console/rarch_console_libretro_mgmt.h | 8 ++++++++ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/console/rarch_console_libretro_mgmt.c b/console/rarch_console_libretro_mgmt.c index 10df6013ee..253f6459ff 100644 --- a/console/rarch_console_libretro_mgmt.c +++ b/console/rarch_console_libretro_mgmt.c @@ -20,14 +20,8 @@ #include "rarch_console_libretro_mgmt.h" -// if a CORE executable exists (full_path), this means we have just installed -// a new libretro port and therefore we need to change it to a more -// sane name. - #ifndef IS_SALAMANDER -// Transforms a library id to a name suitable as a pathname. - static void rarch_console_name_from_id(char *name, size_t size) { if (size == 0) @@ -138,14 +132,10 @@ bool rarch_manage_libretro_extension_supported(const char *filename) return ext_supported; } - #endif void rarch_manage_libretro_set_first_file(char *first_file, size_t size_of_first_file, const char *libretro_path, const char * exe_ext) { - //We need to set libretro to the first entry in the cores - //directory so that it will be saved to the config file - struct string_list *dir_list = dir_list_new(libretro_path, exe_ext, false); const char * first_exe; diff --git a/console/rarch_console_libretro_mgmt.h b/console/rarch_console_libretro_mgmt.h index cd11b181ab..6a452a23fa 100644 --- a/console/rarch_console_libretro_mgmt.h +++ b/console/rarch_console_libretro_mgmt.h @@ -27,11 +27,19 @@ enum #endif }; +//We need to set libretro to the first entry in the cores +//directory so that it will be saved to the config file void rarch_manage_libretro_set_first_file(char *first_file, size_t size_of_first_file, const char *libretro_path, const char * exe_ext); #ifndef IS_SALAMANDER + +// if a CORE executable exists (full_path), this means we have just installed +// a new libretro port and therefore we need to change it to a more +// sane name. bool rarch_configure_libretro_core(const char *full_path, const char *tmp_path, const char *libretro_path, const char *config_path, const char *extension); + +// Transforms a library id to a name suitable as a pathname. bool rarch_manage_libretro_extension_supported(const char *filename); #endif From aecd2be8607c015c4d3add5c479455f52cc9e298 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 6 Aug 2012 00:01:10 +0200 Subject: [PATCH 060/492] (Wii) Add RARCH_EXEC for Wii port - should load values from config file now and save them (WIP) --- Makefile.wii | 2 +- console/exec/dol.c | 72 ++++++++++++++++++++++++++++++++++++ console/exec/dol.h | 33 +++++++++++++++++ console/griffin/griffin.c | 4 ++ console/rarch_console_exec.c | 26 +++++++++++++ wii/frontend/main.c | 17 ++++++++- 6 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 console/exec/dol.c create mode 100644 console/exec/dol.h diff --git a/Makefile.wii b/Makefile.wii index 4a0838a6d9..8193c53ba0 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -39,7 +39,7 @@ CFLAGS += -DHAVE_FILE_LOGGER CFLAGS += -Iconsole/logger endif -CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_RGUI -DRARCH_CONSOLE -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"0.9.6\" -Dmain=rarch_main -Wno-char-subscripts +CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_RGUI -DRARCH_CONSOLE -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"0.9.6\" -Dmain=rarch_main -Wno-char-subscripts ifeq ($(DEBUG), 1) CFLAGS += -O0 -g diff --git a/console/exec/dol.c b/console/exec/dol.c new file mode 100644 index 0000000000..280bade59f --- /dev/null +++ b/console/exec/dol.c @@ -0,0 +1,72 @@ +// this code was contributed by shagkur of the devkitpro team, thx! + +#include +#include +#include + +#include +#include + +#include "../../retroarch_logger.h" + +typedef struct _dolheader +{ + uint32_t text_pos[7]; + uint32_t data_pos[11]; + uint32_t text_start[7]; + uint32_t data_start[11]; + uint32_t text_size[7]; + uint32_t data_size[11]; + uint32_t bss_start; + uint32_t bss_size; + uint32_t entry_point; +} dolheader; + +uint32_t load_dol_image (void *dolstart) +{ + uint32_t i; + dolheader *dolfile; + + if(dolstart) + { + dolfile = (dolheader *) dolstart; + for(i = 0; i < 7; i++) + { + if ((!dolfile->text_size[i]) || (dolfile->text_start[i] < 0x100)) + continue; + + RARCH_LOG("loading text section %u @ 0x%08x (0x%08x bytes)\n", + i, dolfile->text_start[i], dolfile->text_size[i]); + + ICInvalidateRange ((void *) dolfile->text_start[i], + dolfile->text_size[i]); + + memmove ((void *) dolfile->text_start[i], dolstart+dolfile->text_pos[i], + dolfile->text_size[i]); + } + + for(i = 0; i < 11; i++) + { + if ((!dolfile->data_size[i]) || (dolfile->data_start[i] < 0x100)) + continue; + + RARCH_LOG("loading data section %u @ 0x%08x (0x%08x bytes)\n", i, + dolfile->data_start[i], dolfile->data_size[i]); + + memmove ((void*) dolfile->data_start[i], dolstart+dolfile->data_pos[i], + dolfile->data_size[i]); + + DCFlushRangeNoSync ((void *) dolfile->data_start[i], dolfile->data_size[i]); + } + + RARCH_LOG("clearing bss\n"); + + memset ((void *) dolfile->bss_start, 0, dolfile->bss_size); + DCFlushRange((void *) dolfile->bss_start, dolfile->bss_size); + + return dolfile->entry_point; + } + + return 0; +} + diff --git a/console/exec/dol.h b/console/exec/dol.h new file mode 100644 index 0000000000..8b23889a56 --- /dev/null +++ b/console/exec/dol.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2008 dhewg, #wiidev efnet + * + * this file is part of geckoloader + * http://wiibrew.org/index.php?title=Geckoloader + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _DOL_H_ +#define _DOL_H_ + +#include + +u32 load_dol_image (void *dolstart); + +extern void __exception_closeall(void); +extern int32_t __IOS_ShutdownSubSystems(void); + +#endif + diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index dda6547f5c..8eb34c3037 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -32,6 +32,10 @@ CONSOLE EXTENSIONS #include "../rarch_console_main_wrap.c" #endif +#if defined(GEKKO) +#include "../exec/dol.c" +#endif + #ifdef HAVE_RARCH_EXEC #include "../rarch_console_exec.c" #endif diff --git a/console/rarch_console_exec.c b/console/rarch_console_exec.c index 5f2e35673d..4234017c0e 100644 --- a/console/rarch_console_exec.c +++ b/console/rarch_console_exec.c @@ -25,6 +25,9 @@ #include #elif defined(_XBOX) #include +#elif defined(GEKKO) +#include +#include "exec/dol.h" #endif #include "rarch_console_exec.h" @@ -63,6 +66,29 @@ void rarch_console_exec(const char *path) sys_net_finalize_network(); cellSysmoduleUnloadModule(CELL_SYSMODULE_SYSUTIL_NP); cellSysmoduleUnloadModule(CELL_SYSMODULE_NET); +#elif defined(GEKKO) + uint32_t level; + FILE * fp = fopen(path, "rb"); + if (fp == NULL) + { + RARCH_ERR("Could not execute DOL file.\n"); + return; + } + fseek(fp, 0, SEEK_END); + size_t size = ftell(fp); + fseek(fp, 0, SEEK_SET); + u8 *mem = (u8 *)0x92000000; // should be safe for this small program to use + fread(mem, 1, size, fp); + fclose(fp); + void (*ep)() = (void(*)())load_dol_image(mem); + RARCH_LOG("jumping to 0x%08X\n", (unsigned int)ep); + + __IOS_ShutdownSubsystems(); + _CPU_ISR_Disable (level); + __exception_closeall (); + RARCH_LOG("__exception_closeall() done. Jumping to ep now...\n"); + ep(); + _CPU_ISR_Restore (level); #else RARCH_WARN("External loading of executables is not supported for this platform.\n"); #endif diff --git a/wii/frontend/main.c b/wii/frontend/main.c index 8a5c281ecf..4ab9903bb8 100644 --- a/wii/frontend/main.c +++ b/wii/frontend/main.c @@ -23,6 +23,7 @@ #include "../../console/rgui/rgui.h" +#include "../../console/rarch_console_exec.h" #include "../../console/rarch_console_input.h" #include "../../console/rarch_console_main_wrap.h" @@ -235,6 +236,7 @@ int main(void) #endif config_set_defaults(); + input_wii.init(); retro_get_system_info(&wii_core_info); RARCH_LOG("Core: %s\n", wii_core_info.library_name); @@ -244,8 +246,12 @@ int main(void) g_console.block_config_read = true; wii_video_init(); - input_wii.init(); - rarch_input_set_controls_default(&input_wii); + + const char *extension = default_paths.executable_extension; + + rarch_settings_set_default(&input_wii); + rarch_config_load(default_paths.config_file, /* path_prefix */ NULL, extension, /* find_libretro_file */ false); + init_libretro_sym(); input_wii.post_init(); @@ -269,6 +275,9 @@ int main(void) audio_stop_func(); } + if(path_file_exists(default_paths.config_file)) + rarch_config_save(default_paths.config_file); + if(g_console.emulator_initialized) rarch_main_deinit(); @@ -283,6 +292,10 @@ int main(void) #endif rgui_free(rgui); + + if(g_console.return_to_launcher) + rarch_console_exec(g_console.launch_app_on_exit); + return ret; } From abc16197d85982ddcfa4f037f59204537e7cb238 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 6 Aug 2012 00:06:01 +0200 Subject: [PATCH 061/492] (RARCH_EXEC Wii) Change u32 to uint32_t --- console/exec/dol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/console/exec/dol.h b/console/exec/dol.h index 8b23889a56..f686bc4138 100644 --- a/console/exec/dol.h +++ b/console/exec/dol.h @@ -24,7 +24,7 @@ #include -u32 load_dol_image (void *dolstart); +uint32_t load_dol_image (void *dolstart); extern void __exception_closeall(void); extern int32_t __IOS_ShutdownSubSystems(void); From 07ae3a873ceac2ab984b51aac4857fc8aa218c0d Mon Sep 17 00:00:00 2001 From: Toad King Date: Sun, 5 Aug 2012 18:36:03 -0400 Subject: [PATCH 062/492] (Wii) updated launcher code --- console/rarch_console_exec.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/console/rarch_console_exec.c b/console/rarch_console_exec.c index 4234017c0e..4802f0accd 100644 --- a/console/rarch_console_exec.c +++ b/console/rarch_console_exec.c @@ -26,7 +26,8 @@ #elif defined(_XBOX) #include #elif defined(GEKKO) -#include +#include +#include #include "exec/dol.h" #endif @@ -67,7 +68,6 @@ void rarch_console_exec(const char *path) cellSysmoduleUnloadModule(CELL_SYSMODULE_SYSUTIL_NP); cellSysmoduleUnloadModule(CELL_SYSMODULE_NET); #elif defined(GEKKO) - uint32_t level; FILE * fp = fopen(path, "rb"); if (fp == NULL) { @@ -77,18 +77,21 @@ void rarch_console_exec(const char *path) fseek(fp, 0, SEEK_END); size_t size = ftell(fp); fseek(fp, 0, SEEK_SET); - u8 *mem = (u8 *)0x92000000; // should be safe for this small program to use + uint8_t *mem = (uint8_t *)0x92000000; // should be safe for this small program to use fread(mem, 1, size, fp); fclose(fp); +#ifdef HW_RVL + fatUnmount("sd:"); + fatUnmount("usb:"); +#endif + fatUnmount("carda:"); + fatUnmount("cardb:"); void (*ep)() = (void(*)())load_dol_image(mem); - RARCH_LOG("jumping to 0x%08X\n", (unsigned int)ep); + RARCH_LOG("jumping to 0x%08X\n", (uint32_t)ep); - __IOS_ShutdownSubsystems(); - _CPU_ISR_Disable (level); - __exception_closeall (); - RARCH_LOG("__exception_closeall() done. Jumping to ep now...\n"); - ep(); - _CPU_ISR_Restore (level); + SYS_ResetSystem(SYS_SHUTDOWN,0,0); + + __lwp_thread_stopmultitasking(ep); #else RARCH_WARN("External loading of executables is not supported for this platform.\n"); #endif From fec81d2ee4ddb4c3a598b97dd49a68f236a21800 Mon Sep 17 00:00:00 2001 From: Toad King Date: Sun, 5 Aug 2012 18:36:23 -0400 Subject: [PATCH 063/492] (Wii) don't list "boot.dol" in core selector --- wii/frontend/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wii/frontend/main.c b/wii/frontend/main.c index 4ab9903bb8..2d5c8e1228 100644 --- a/wii/frontend/main.c +++ b/wii/frontend/main.c @@ -113,7 +113,8 @@ static bool folder_cb(const char *directory, rgui_file_enum_cb_t file_cb, if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode)) continue; - if (core_chooser && strstr(entry->d_name, ".dol") != entry->d_name + strlen(entry->d_name) - 4) + if (core_chooser && (strstr(entry->d_name, ".dol") != entry->d_name + strlen(entry->d_name) - 4 || + strcasecmp(entry->d_name, "boot.dol") == 0)) continue; file_cb(ctx, From 465c2f9e338f43871edabff105ca662a00cb1e77 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 6 Aug 2012 02:07:57 +0200 Subject: [PATCH 064/492] (Salamander) Custom versions of Salamander --- Makefile.ps3.salamander | 2 +- .../RetroArch-Salamander.vcxproj | 4 +- ps3/salamander/main.c | 226 ++++++++++++++++++ xdk/salamander/main.c | 190 +++++++++++++++ 4 files changed, 419 insertions(+), 3 deletions(-) create mode 100644 ps3/salamander/main.c create mode 100644 xdk/salamander/main.c diff --git a/Makefile.ps3.salamander b/Makefile.ps3.salamander index 72be7c7e78..b20c90e3f5 100644 --- a/Makefile.ps3.salamander +++ b/Makefile.ps3.salamander @@ -8,7 +8,7 @@ include $(CELL_MK_DIR)/sdk.makedef.mk STRIP = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-strip.exe PPU_CFLAGS += -I. -D__CELLOS_LV2__ -DIS_SALAMANDER -PPU_SRCS = console/salamander/main.c console/rarch_console_exec.c console/rarch_console_libretro_mgmt.c file_path.c compat/compat.c conf/config_file.c +PPU_SRCS = ps3/salamander/main.c console/rarch_console_exec.c console/rarch_console_libretro_mgmt.c file_path.c compat/compat.c conf/config_file.c ifeq ($(HAVE_LOGGER), 1) PPU_CFLAGS += -DHAVE_LOGGER -Iconsole/logger diff --git a/msvc/RetroArch-360-Salamander/RetroArch-Salamander.vcxproj b/msvc/RetroArch-360-Salamander/RetroArch-Salamander.vcxproj index a1aa152d84..1f9ffc0353 100644 --- a/msvc/RetroArch-360-Salamander/RetroArch-Salamander.vcxproj +++ b/msvc/RetroArch-360-Salamander/RetroArch-Salamander.vcxproj @@ -272,7 +272,7 @@ CompileAsCpp CompileAsCpp - + CompileAsCpp CompileAsCpp CompileAsCpp @@ -294,4 +294,4 @@ - \ No newline at end of file + diff --git a/ps3/salamander/main.c b/ps3/salamander/main.c new file mode 100644 index 0000000000..31c80fb774 --- /dev/null +++ b/ps3/salamander/main.c @@ -0,0 +1,226 @@ +/* RetroArch - A frontend for libretro. + * RetroArch Salamander - A frontend for managing some pre-launch tasks. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * Copyright (C) 2011-2012 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../compat/strl.h" +#include "../../conf/config_file.h" + +#define NP_POOL_SIZE (128*1024) + +#ifndef PATH_MAX +#define PATH_MAX 512 +#endif + +#include "../../console/rarch_console_libretro_mgmt.h" +#include "../../console/rarch_console_exec.h" + +#include "../../retroarch_logger.h" +#include "../../file.h" + +static uint8_t np_pool[NP_POOL_SIZE]; +char usrDirPath[PATH_MAX]; +SYS_PROCESS_PARAM(1001, 0x100000) + +char LIBRETRO_DIR_PATH[PATH_MAX]; +char SYS_CONFIG_FILE[PATH_MAX]; +char libretro_path[PATH_MAX]; + +static void find_and_set_first_file(void) +{ + //Last fallback - we'll need to start the first executable file + // we can find in the RetroArch cores directory + + char first_file[PATH_MAX]; + rarch_manage_libretro_set_first_file(first_file, sizeof(first_file), + LIBRETRO_DIR_PATH, "SELF"); + + if(first_file) + strlcpy(libretro_path, first_file, sizeof(libretro_path)); + else + RARCH_ERR("Failed last fallback - RetroArch Salamander will exit.\n"); +} + +static void init_settings(void) +{ + char tmp_str[PATH_MAX]; + bool config_file_exists; + + if(!path_file_exists(SYS_CONFIG_FILE)) + { + FILE * f; + config_file_exists = false; + RARCH_ERR("Config file \"%s\" doesn't exist. Creating...\n", SYS_CONFIG_FILE); + f = fopen(SYS_CONFIG_FILE, "w"); + fclose(f); + } + else + config_file_exists = true; + + //try to find CORE executable + char core_executable[1024]; + snprintf(core_executable, sizeof(core_executable), "%s/CORE.SELF", LIBRETRO_DIR_PATH); + + if(path_file_exists(core_executable)) + { + //Start CORE executable + snprintf(libretro_path, sizeof(libretro_path), core_executable); + RARCH_LOG("Start [%s].\n", libretro_path); + } + else + { + if(config_file_exists) + { + config_file_t * conf = config_file_new(SYS_CONFIG_FILE); + config_get_array(conf, "libretro_path", tmp_str, sizeof(tmp_str)); + snprintf(libretro_path, sizeof(libretro_path), tmp_str); + } + + if(!config_file_exists || !strcmp(libretro_path, "")) + find_and_set_first_file(); + else + { + RARCH_LOG("Start [%s] found in retroarch.cfg.\n", libretro_path); + } + } +} + +static void get_environment_settings (void) +{ + unsigned int get_type; + unsigned int get_attributes; + CellGameContentSize size; + char dirName[CELL_GAME_DIRNAME_SIZE]; + char contentInfoPath[PATH_MAX]; + + memset(&size, 0x00, sizeof(CellGameContentSize)); + + int ret = cellGameBootCheck(&get_type, &get_attributes, &size, dirName); + if(ret < 0) + { + RARCH_ERR("cellGameBootCheck() Error: 0x%x.\n", ret); + } + else + { + RARCH_LOG("cellGameBootCheck() OK.\n"); + RARCH_LOG("Directory name: [%s].\n", dirName); + RARCH_LOG(" HDD Free Size (in KB) = [%d] Size (in KB) = [%d] System Size (in KB) = [%d].\n", size.hddFreeSizeKB, size.sizeKB, size.sysSizeKB); + + switch(get_type) + { + case CELL_GAME_GAMETYPE_DISC: + RARCH_LOG("RetroArch was launched on Optical Disc Drive.\n"); + break; + case CELL_GAME_GAMETYPE_HDD: + RARCH_LOG("RetroArch was launched on HDD.\n"); + break; + } + + if((get_attributes & CELL_GAME_ATTRIBUTE_APP_HOME) == CELL_GAME_ATTRIBUTE_APP_HOME) + RARCH_LOG("RetroArch was launched from host machine (APP_HOME).\n"); + + ret = cellGameContentPermit(contentInfoPath, usrDirPath); + + if(ret < 0) + { + RARCH_ERR("cellGameContentPermit() Error: 0x%x\n", ret); + } + else + { + RARCH_LOG("cellGameContentPermit() OK.\n"); + RARCH_LOG("contentInfoPath : [%s].\n", contentInfoPath); + RARCH_LOG("usrDirPath : [%s].\n", usrDirPath); + } + + /* now we fill in all the variables */ + snprintf(SYS_CONFIG_FILE, sizeof(SYS_CONFIG_FILE), "%s/retroarch.cfg", usrDirPath); + snprintf(LIBRETRO_DIR_PATH, sizeof(LIBRETRO_DIR_PATH), "%s/cores", usrDirPath); + } +} + +//dummy - just to avoid the emitted warnings + +static void callback_sysutil_exit(uint64_t status, uint64_t param, void *userdata) +{ + (void) param; + (void) userdata; + (void) status; +} + +int main(int argc, char *argv[]) +{ + CellPadData pad_data; + + cellSysutilRegisterCallback(0, callback_sysutil_exit, NULL); + + cellSysmoduleLoadModule(CELL_SYSMODULE_IO); + cellSysmoduleLoadModule(CELL_SYSMODULE_FS); + cellSysmoduleLoadModule(CELL_SYSMODULE_SYSUTIL_GAME); + cellSysmoduleLoadModule(CELL_SYSMODULE_NET); + + cellSysmoduleLoadModule(CELL_SYSMODULE_SYSUTIL_NP); + + sys_net_initialize_network(); + +#ifdef HAVE_LOGGER + logger_init(); +#endif + + sceNpInit(NP_POOL_SIZE, np_pool); + + get_environment_settings(); + + cellPadInit(7); + + cellPadGetData(0, &pad_data); + + if(pad_data.button[CELL_PAD_BTN_OFFSET_DIGITAL2] & CELL_PAD_CTRL_TRIANGLE) + { + //override path, boot first executable in cores directory + RARCH_LOG("Fallback - Will boot first executable in RetroArch cores/ directory.\n"); + find_and_set_first_file(); + } + else + { + //normal executable loading path + init_settings(); + } + + cellPadEnd(); + +#ifdef HAVE_LOGGER + logger_shutdown(); +#endif + + rarch_console_exec(libretro_path); + + cellSysmoduleUnloadModule(CELL_SYSMODULE_SYSUTIL_GAME); + cellSysmoduleLoadModule(CELL_SYSMODULE_FS); + cellSysmoduleLoadModule(CELL_SYSMODULE_IO); + + return 1; +} diff --git a/xdk/salamander/main.c b/xdk/salamander/main.c new file mode 100644 index 0000000000..e41b5e668b --- /dev/null +++ b/xdk/salamander/main.c @@ -0,0 +1,190 @@ +/* RetroArch - A frontend for libretro. + * RetroArch Salamander - A frontend for managing some pre-launch tasks. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * Copyright (C) 2011-2012 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include +#include + +#include + +#include "../../compat/strl.h" +#include "../../conf/config_file.h" + +#include "../../msvc/msvc_compat.h" + +#ifndef PATH_MAX +#define PATH_MAX 512 +#endif + +#include "../../console/rarch_console_libretro_mgmt.h" +#include "../../console/rarch_console_exec.h" + +#include "../../retroarch_logger.h" +#include "../../file.h" + +DWORD volume_device_type; + +char LIBRETRO_DIR_PATH[PATH_MAX]; +char SYS_CONFIG_FILE[PATH_MAX]; +char libretro_path[PATH_MAX]; + +static void find_and_set_first_file(void) +{ + //Last fallback - we'll need to start the first executable file + // we can find in the RetroArch cores directory + + char first_file[PATH_MAX]; + rarch_manage_libretro_set_first_file(first_file, sizeof(first_file), +#if defined(_XBOX360) + "game:\\", "xex" +#elif defined(_XBOX1) + "D:\\", "xbe" +#endif +); + + if(first_file) + strlcpy(libretro_path, first_file, sizeof(libretro_path)); + else + RARCH_ERR("Failed last fallback - RetroArch Salamander will exit.\n"); +} + +static void init_settings(void) +{ + char tmp_str[PATH_MAX]; + bool config_file_exists; + + if(!path_file_exists(SYS_CONFIG_FILE)) + { + FILE * f; + config_file_exists = false; + RARCH_ERR("Config file \"%s\" doesn't exist. Creating...\n", SYS_CONFIG_FILE); + f = fopen(SYS_CONFIG_FILE, "w"); + fclose(f); + } + else + config_file_exists = true; + + //try to find CORE executable + char core_executable[1024]; +#if defined(_XBOX360) + snprintf(core_executable, sizeof(core_executable), "game:\\CORE.xex"); +#elif defined(_XBOX1) + snprintf(core_executable, sizeof(core_executable), "D:\\CORE.xbe"); +#endif + + if(path_file_exists(core_executable)) + { + //Start CORE executable + snprintf(libretro_path, sizeof(libretro_path), core_executable); + RARCH_LOG("Start [%s].\n", libretro_path); + } + else + { + if(config_file_exists) + { + config_file_t * conf = config_file_new(SYS_CONFIG_FILE); + config_get_array(conf, "libretro_path", tmp_str, sizeof(tmp_str)); + snprintf(libretro_path, sizeof(libretro_path), tmp_str); + } + + if(!config_file_exists || !strcmp(libretro_path, "")) + find_and_set_first_file(); + else + { + RARCH_LOG("Start [%s] found in retroarch.cfg.\n", libretro_path); + } + } +} + +static void get_environment_settings (void) +{ +#if defined(_XBOX360) + //for devkits only, we will need to mount all partitions for retail + //in a different way + //DmMapDevkitDrive(); + + int result_filecache = XSetFileCacheSize(0x100000); + + if(result_filecache != TRUE) + { + RARCH_ERR("Couldn't change number of bytes reserved for file system cache.\n"); + } + unsigned long result = XMountUtilityDriveEx(XMOUNTUTILITYDRIVE_FORMAT0,8192, 0); + + if(result != ERROR_SUCCESS) + { + RARCH_ERR("Couldn't mount/format utility drive.\n"); + } + + // detect install environment + unsigned long license_mask; + + if (XContentGetLicenseMask(&license_mask, NULL) != ERROR_SUCCESS) + { + RARCH_LOG("RetroArch was launched as a standalone DVD, or using DVD emulation, or from the development area of the HDD.\n"); + } + else + { + XContentQueryVolumeDeviceType("GAME",&volume_device_type, NULL); + + switch(volume_device_type) + { + case XCONTENTDEVICETYPE_HDD: + RARCH_LOG("RetroArch was launched from a content package on HDD.\n"); + break; + case XCONTENTDEVICETYPE_MU: + RARCH_LOG("RetroArch was launched from a content package on USB or Memory Unit.\n"); + break; + case XCONTENTDEVICETYPE_ODD: + RARCH_LOG("RetroArch was launched from a content package on Optical Disc Drive.\n"); + break; + default: + RARCH_LOG("RetroArch was launched from a content package on an unknown device type.\n"); + break; + } + } +#elif defined(_XBOX1) + strlcpy(SYS_CONFIG_FILE, "D:\\retroarch.cfg", sizeof(SYS_CONFIG_FILE)); +#endif +} + +int main(int argc, char *argv[]) +{ + XINPUT_STATE state; + + get_environment_settings(); + + //WIP - no Xbox 1 controller input yet +#ifdef _XBOX360 + XInputGetState(0, &state); + + if(state.Gamepad.wButtons & XINPUT_GAMEPAD_Y) + { + //override path, boot first executable in cores directory + RARCH_LOG("Fallback - Will boot first executable in RetroArch cores directory.\n"); + find_and_set_first_file(); + } + else +#endif + { + //normal executable loading path + init_settings(); + } + + rarch_console_exec(libretro_path); + + return 1; +} From f9489dedcd46b43971e524cb2274ce6bf0de5ce0 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 6 Aug 2012 02:36:41 +0200 Subject: [PATCH 065/492] (Wii Salamander) Salamander for Wii (WIP) --- Makefile.ps3.salamander | 2 +- Makefile.wii | 2 +- Makefile.wii.salamander | 73 ++++++++++++++++++ console/rarch_console_exec.c | 1 + wii/salamander/main.c | 141 +++++++++++++++++++++++++++++++++++ 5 files changed, 217 insertions(+), 2 deletions(-) create mode 100644 Makefile.wii.salamander create mode 100644 wii/salamander/main.c diff --git a/Makefile.ps3.salamander b/Makefile.ps3.salamander index b20c90e3f5..383fc95baf 100644 --- a/Makefile.ps3.salamander +++ b/Makefile.ps3.salamander @@ -15,7 +15,7 @@ PPU_CFLAGS += -DHAVE_LOGGER -Iconsole/logger PPU_SRCS += console/logger/logger.c endif -PPU_TARGET = retroarch-salamander.elf +PPU_TARGET = retroarch-salamander_ps3.elf ifeq ($(CELL_BUILD_TOOLS),SNC) PPU_CFLAGS += -Xbranchless=1 -Xfastmath=1 -Xassumecorrectsign=1 -Xassumecorrectalignment=1 -Xunroll=1 -Xautovecreg=1 diff --git a/Makefile.wii b/Makefile.wii index 8193c53ba0..e8d636d264 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -62,7 +62,7 @@ $(ELF_TARGET): $(OBJ) $(LD) -r -b binary -o $@ $< pkg: all - cp -r $(DOL_TARGET) wii/pkg/boot.dol + cp -r $(DOL_TARGET) wii/pkg/CORE.dol clean: rm -f $(DOL_TARGET) diff --git a/Makefile.wii.salamander b/Makefile.wii.salamander new file mode 100644 index 0000000000..0b1f7fbb77 --- /dev/null +++ b/Makefile.wii.salamander @@ -0,0 +1,73 @@ +### +## +# Makefile for RetroArch Wii. +## + +DEBUG = 0 +HAVE_LOGGER = 0 +HAVE_FILE_LOGGER = 0 + +PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.7" +PC_DEVELOPMENT_UDP_PORT = 3490 + +CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc +CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++ +LD = $(DEVKITPPC)/bin/powerpc-eabi-ld + +DOL_TARGET := retroarch-salamander_gx.dol +ELF_TARGET := retroarch-salamander_gx.elf + +INCLUDE := -I. -I$(DEVKITPRO)/libogc/include +LIBDIRS := -L$(DEVKITPRO)/libogc/lib/wii -L. + +MACHDEP := -DGEKKO -DHW_RVL -mrvl -mcpu=750 -meabi -mhard-float +CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE) +LDFLAGS := $(MACHDEP) +LIBS := -lfat -lretro_wii -lwiiuse -logc -lbte + +OBJ = wii/salamander/main.o console/rarch_console_exec.o console/rarch_console_libretro_mgmt.o file_path.o compat/compat.o conf/config_file.o console/exec/dol.o + +ifeq ($(HAVE_LOGGER), 1) +CFLAGS += -DHAVE_LOGGER +CFLAGS += -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) +CFLAGS += -Iconsole/logger +OBJ += console/logger/logger.o +endif + +ifeq ($(HAVE_FILE_LOGGER), 1) +CFLAGS += -DHAVE_FILE_LOGGER +CFLAGS += -Iconsole/logger +endif + +CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DIS_SALAMANDER -DRARCH_CONSOLE -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DPACKAGE_VERSION=\"0.9.6\" -Wno-char-subscripts + +ifeq ($(DEBUG), 1) + CFLAGS += -O0 -g +else + CFLAGS += -O3 +endif + +all: $(DOL_TARGET) + +%.dol: %.elf + $(DEVKITPPC)/bin/elf2dol $< $@ + +$(ELF_TARGET): $(OBJ) + $(CXX) -o $@ $(LDFLAGS) $(LIBDIRS) $(OBJ) $(LIBS) + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.bmpobj: %.bmp + $(LD) -r -b binary -o $@ $< + +pkg: all + cp -r $(DOL_TARGET) wii/pkg/boot.dol + +clean: + rm -f $(DOL_TARGET) + rm -f $(ELF_TARGET) + rm -f $(OBJ) + +.PHONY: clean + diff --git a/console/rarch_console_exec.c b/console/rarch_console_exec.c index 4802f0accd..e863808ede 100644 --- a/console/rarch_console_exec.c +++ b/console/rarch_console_exec.c @@ -28,6 +28,7 @@ #elif defined(GEKKO) #include #include +#include #include "exec/dol.h" #endif diff --git a/wii/salamander/main.c b/wii/salamander/main.c new file mode 100644 index 0000000000..08a0cd9118 --- /dev/null +++ b/wii/salamander/main.c @@ -0,0 +1,141 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * Copyright (C) 2011-2012 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include +#include "../../boolean.h" +#include +#include + +#include +#include +#include + +#include "../gx_input.h" + +#include "../../console/rarch_console.h" +#include "../../console/rarch_console_exec.h" +#include "../../console/rarch_console_libretro_mgmt.h" +#include "../../console/rarch_console_input.h" +#include "../../console/rarch_console_config.h" +#include "../../console/rarch_console_settings.h" +#include "../../console/rarch_console_main_wrap.h" +#include "../../conf/config_file.h" +#include "../../conf/config_file_macros.h" +#include "../../general.h" +#include "../../file.h" + +char LIBRETRO_DIR_PATH[512]; +char SYS_CONFIG_FILE[512]; +char libretro_path[512]; +char PORT_DIR[512]; +char app_dir[512]; + +static void find_and_set_first_file(void) +{ + //Last fallback - we'll need to start the first executable file + // we can find in the RetroArch cores directory + + char first_file[512]; + rarch_manage_libretro_set_first_file(first_file, sizeof(first_file), + LIBRETRO_DIR_PATH, "dol"); + + if(first_file) + strlcpy(libretro_path, first_file, sizeof(libretro_path)); + else + RARCH_ERR("Failed last fallback - RetroArch Salamander will exit.\n"); +} + +static void init_settings(void) +{ + char tmp_str[512]; + bool config_file_exists; + + if(!path_file_exists(SYS_CONFIG_FILE)) + { + FILE * f; + config_file_exists = false; + RARCH_ERR("Config file \"%s\" doesn't exist. Creating...\n", SYS_CONFIG_FILE); + f = fopen(SYS_CONFIG_FILE, "w"); + fclose(f); + } + else + config_file_exists = true; + + //try to find CORE executable + char core_executable[1024]; + snprintf(core_executable, sizeof(core_executable), "%s/CORE.dol", LIBRETRO_DIR_PATH); + + if(path_file_exists(core_executable)) + { + //Start CORE executable + snprintf(libretro_path, sizeof(libretro_path), core_executable); + RARCH_LOG("Start [%s].\n", libretro_path); + } + else + { + if(config_file_exists) + { + config_file_t * conf = config_file_new(SYS_CONFIG_FILE); + config_get_array(conf, "libretro_path", tmp_str, sizeof(tmp_str)); + snprintf(libretro_path, sizeof(libretro_path), tmp_str); + } + + if(!config_file_exists || !strcmp(libretro_path, "")) + find_and_set_first_file(); + else + { + RARCH_LOG("Start [%s] found in retroarch.cfg.\n", libretro_path); + } + } +} + +static void get_environment_settings(void) +{ + getcwd(PORT_DIR, MAXPATHLEN); + snprintf(SYS_CONFIG_FILE, sizeof(SYS_CONFIG_FILE), "%sretroarch.cfg", PORT_DIR); + snprintf(LIBRETRO_DIR_PATH, sizeof(LIBRETRO_DIR_PATH), PORT_DIR); +} + +int main(int argc, char *argv[]) +{ +#ifdef HAVE_LOGGER + g_extern.verbose = true; + logger_init(); +#endif + +#ifdef HW_RVL + L2Enhance(); +#endif + + fatInitDefault(); + getcwd(app_dir, sizeof(app_dir)); + + get_environment_settings(); + + //TODO: Add control options later - for 'set_first_file' + { + //normal executable loading path + init_settings(); + } + +#ifdef HAVE_LOGGER + logger_shutdown(); +#endif + + rarch_console_exec(libretro_path); + + return 1; +} From 8fd7ca74b13b0c347e5ef5401f373ee2af79d2b9 Mon Sep 17 00:00:00 2001 From: Toad King Date: Sun, 5 Aug 2012 20:52:15 -0400 Subject: [PATCH 066/492] (Wii) compile salamander with correct link options --- Makefile.wii.salamander | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.wii.salamander b/Makefile.wii.salamander index 0b1f7fbb77..b07a77a26b 100644 --- a/Makefile.wii.salamander +++ b/Makefile.wii.salamander @@ -22,7 +22,7 @@ LIBDIRS := -L$(DEVKITPRO)/libogc/lib/wii -L. MACHDEP := -DGEKKO -DHW_RVL -mrvl -mcpu=750 -meabi -mhard-float CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE) -LDFLAGS := $(MACHDEP) +LDFLAGS := $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x81200000 LIBS := -lfat -lretro_wii -lwiiuse -logc -lbte OBJ = wii/salamander/main.o console/rarch_console_exec.o console/rarch_console_libretro_mgmt.o file_path.o compat/compat.o conf/config_file.o console/exec/dol.o From 4b4b704182d6cc428b2a5cf8abebcb50f7dc06e9 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 6 Aug 2012 03:07:09 +0200 Subject: [PATCH 067/492] (PS3) Quick build fix - update RetroArch ELF name --- Makefile.ps3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.ps3 b/Makefile.ps3 index 82eb6fc8eb..32dfcaeb49 100644 --- a/Makefile.ps3 +++ b/Makefile.ps3 @@ -22,7 +22,7 @@ CELL_MK_DIR ?= $(CELL_SDK)/samples/mk include $(CELL_MK_DIR)/sdk.makedef.mk PPU_TARGET = retroarch.elf -SALAMANDER_TARGET = retroarch-salamander.elf +SALAMANDER_TARGET = retroarch-salamander_ps3.elf EBOOT_PATH = ps3/pkg/USRDIR/EBOOT.BIN CORE_PATH = ps3/pkg/USRDIR/cores/CORE.SELF From fd3ee5a9dd8eaa31553b70e9b3d97e25be9ec2f7 Mon Sep 17 00:00:00 2001 From: Toad King Date: Sun, 5 Aug 2012 22:25:34 -0400 Subject: [PATCH 068/492] (Wii) salamander fixes --- Makefile.wii.salamander | 2 +- wii/salamander/main.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile.wii.salamander b/Makefile.wii.salamander index b07a77a26b..48dc20eaf4 100644 --- a/Makefile.wii.salamander +++ b/Makefile.wii.salamander @@ -22,7 +22,7 @@ LIBDIRS := -L$(DEVKITPRO)/libogc/lib/wii -L. MACHDEP := -DGEKKO -DHW_RVL -mrvl -mcpu=750 -meabi -mhard-float CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE) -LDFLAGS := $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x81200000 +LDFLAGS := $(MACHDEP) -Wl,-Map,$(notdir $(ELF_TARGET)).map,--section-start,.init=0x81200000 LIBS := -lfat -lretro_wii -lwiiuse -logc -lbte OBJ = wii/salamander/main.o console/rarch_console_exec.o console/rarch_console_libretro_mgmt.o file_path.o compat/compat.o conf/config_file.o console/exec/dol.o diff --git a/wii/salamander/main.c b/wii/salamander/main.c index 08a0cd9118..b24187fdd8 100644 --- a/wii/salamander/main.c +++ b/wii/salamander/main.c @@ -112,7 +112,6 @@ static void get_environment_settings(void) int main(int argc, char *argv[]) { #ifdef HAVE_LOGGER - g_extern.verbose = true; logger_init(); #endif From 7fb25a76c83c9dbfde3947a82f6d14989704630d Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 6 Aug 2012 05:05:16 +0200 Subject: [PATCH 069/492] (RGL) Tweaks --- console/rgl/ps3/rgl.cpp | 513 ++++++++++++++++++++-------------------- console/rgl/ps3/rgl.h | 16 +- 2 files changed, 256 insertions(+), 273 deletions(-) diff --git a/console/rgl/ps3/rgl.cpp b/console/rgl/ps3/rgl.cpp index a92a8cbfe1..11ce94b456 100644 --- a/console/rgl/ps3/rgl.cpp +++ b/console/rgl/ps3/rgl.cpp @@ -107,7 +107,7 @@ GLuint nvFenceCounter = 0; #define DECLARE_TYPE(TYPE,CTYPE,MAXVAL) \ typedef CTYPE type_##TYPE; \ -static inline type_##TYPE _RGLFloatTo_##TYPE(float v) { return (type_##TYPE)(_RGLClampf(v)*MAXVAL); } \ +static inline type_##TYPE _RGLFloatTo_##TYPE(float v) { return (type_##TYPE)((MAX(MIN(v, 1.f), 0.f)) * MAXVAL); } \ static inline float _RGLFloatFrom_##TYPE(type_##TYPE v) { return ((float)v)/MAXVAL; } DECLARE_C_TYPES #undef DECLARE_TYPE @@ -256,55 +256,51 @@ static inline void _RGLFifoGlVertexAttribPointer GLuint offset ) { - switch ( size ) - { - case 0: - stride = 0; - normalized = 0; - type = RGL_FLOAT; - offset = 0; - break; - case 1: - case 2: - case 3: - case 4: - break; - default: - break; - } + + switch(size) + { + case 0: + stride = 0; + normalized = 0; + type = RGL_FLOAT; + offset = 0; + break; + case 1: + case 2: + case 3: + case 4: + break; + default: + break; + } uint8_t gcmType = 0; switch ( type ) { - case RGL_UNSIGNED_BYTE: - if (normalized) - gcmType = CELL_GCM_VERTEX_UB; - else - gcmType = CELL_GCM_VERTEX_UB256; - break; - - case RGL_SHORT: - gcmType = normalized ? CELL_GCM_VERTEX_S1 : CELL_GCM_VERTEX_S32K; - break; - - case RGL_FLOAT: - gcmType = CELL_GCM_VERTEX_F; - break; - - case RGL_HALF_FLOAT: - gcmType = CELL_GCM_VERTEX_SF; - break; - - case RGL_CMP: - size = 1; - gcmType = CELL_GCM_VERTEX_CMP; - break; - - default: - break; + case RGL_UNSIGNED_BYTE: + if (normalized) + gcmType = CELL_GCM_VERTEX_UB; + else + gcmType = CELL_GCM_VERTEX_UB256; + break; + case RGL_SHORT: + gcmType = normalized ? CELL_GCM_VERTEX_S1 : CELL_GCM_VERTEX_S32K; + break; + case RGL_FLOAT: + gcmType = CELL_GCM_VERTEX_F; + break; + case RGL_HALF_FLOAT: + gcmType = CELL_GCM_VERTEX_SF; + break; + case RGL_CMP: + size = 1; + gcmType = CELL_GCM_VERTEX_CMP; + break; + default: + break; } - cellGcmSetVertexDataArrayInline( &_RGLState.fifo, index, frequency, stride, size, gcmType, CELL_GCM_LOCATION_LOCAL, offset ); + cellGcmSetVertexDataArrayInline( &_RGLState.fifo, index, frequency, stride, size, gcmType, CELL_GCM_LOCATION_LOCAL, offset ); } static void _RGLResetAttributeState( jsAttributeState* as ) @@ -350,9 +346,9 @@ static void _RGLResetAttributeState( jsAttributeState* as ) static jsAttribSet* _RGLCreateAttribSet( void ) { - jsAttribSet* attribSet = ( jsAttribSet * )memalign( 16, sizeof( jsAttribSet ) ); + jsAttribSet* attribSet = (jsAttribSet*)memalign(16, sizeof(jsAttribSet)); - _RGLResetAttributeState( &attribSet->attribs ); + _RGLResetAttributeState(&attribSet->attribs); attribSet->dirty = GL_TRUE; attribSet->beenUpdatedMask = 0; @@ -379,8 +375,10 @@ static void _RGLAttribSetDeleteBuffer( PSGLcontext *LContext, GLuint buffName ) jsAttribSet *attribSet = bufferObject->attribSets[i]; for(GLuint j = 0; j < MAX_VERTEX_ATTRIBS; ++j) - if ( attribSet->attribs.attrib[j].arrayBuffer == buffName ) + { + if(attribSet->attribs.attrib[j].arrayBuffer == buffName) attribSet->attribs.attrib[j].arrayBuffer = 0; + } attribSet->dirty = GL_TRUE; } @@ -390,8 +388,8 @@ static void _RGLAttribSetDeleteBuffer( PSGLcontext *LContext, GLuint buffName ) static jsBufferObject *_RGLCreateBufferObject (void) { - GLuint size = sizeof( jsBufferObject ) + sizeof( RGLBufferObject); - jsBufferObject *buffer = ( jsBufferObject * )malloc( size ); + GLuint size = sizeof(jsBufferObject) + sizeof(RGLBufferObject); + jsBufferObject *buffer = (jsBufferObject*)malloc(size); if( !buffer ) return NULL; @@ -407,9 +405,9 @@ static jsBufferObject *_RGLCreateBufferObject (void) static void _RGLPlatformDestroyBufferObject( jsBufferObject* bufferObject ) { - RGLBufferObject *jsBuffer = ( RGLBufferObject * )bufferObject->platformBufferObject; + RGLBufferObject *jsBuffer = (RGLBufferObject*)bufferObject->platformBufferObject; - switch ( jsBuffer->pool ) + switch(jsBuffer->pool) { case SURFACE_POOL_SYSTEM: case SURFACE_POOL_LINEAR: @@ -427,11 +425,12 @@ static void _RGLPlatformDestroyBufferObject( jsBufferObject* bufferObject ) static void _RGLFreeBufferObject( jsBufferObject *buffer ) { - if ( --buffer->refCount == 0 ) + if(--buffer->refCount == 0) { _RGLPlatformDestroyBufferObject( buffer ); buffer->textureReferences.~Vector(); buffer->attribSets.~Vector(); + if(buffer != NULL) free( buffer ); } @@ -448,7 +447,7 @@ GLAPI void APIENTRY glBindBuffer( GLenum target, GLuint name ) if(name) _RGLTexNameSpaceCreateNameLazy( &LContext->bufferObjectNameSpace, name ); - switch ( target ) + switch(target) { case GL_ARRAY_BUFFER: LContext->ArrayBuffer = name; @@ -479,8 +478,10 @@ GLAPI void APIENTRY glDeleteBuffers(GLsizei n, const GLuint *buffers) if(buffers[i] ) { GLuint name = buffers[i]; + if(LContext->ArrayBuffer == name) LContext->ArrayBuffer = 0; + if(LContext->PixelUnpackBuffer == name) LContext->PixelUnpackBuffer = 0; @@ -504,11 +505,6 @@ GLAPI void APIENTRY glGenBuffers(GLsizei n, GLuint *buffers) _RGLTexNameSpaceGenNames( &LContext->bufferObjectNameSpace, n, buffers ); } -static inline jsFramebuffer *_RGLGetFramebuffer(PSGLcontext *LContext, GLuint name) -{ - return (jsFramebuffer *)LContext->framebufferNameSpace.data[name]; -} - static inline void _RGLTextureTouchFBOs(jsTexture *texture) { PSGLcontext *LContext = _CurrentContext; @@ -516,9 +512,10 @@ static inline void _RGLTextureTouchFBOs(jsTexture *texture) return; GLuint fbCount = texture->framebuffers.getCount(); + if(fbCount > 0) { - jsFramebuffer *contextFramebuffer = LContext->framebuffer ? _RGLGetFramebuffer( LContext, LContext->framebuffer ) : NULL; + jsFramebuffer *contextFramebuffer = LContext->framebuffer ? (jsFramebuffer *)LContext->framebufferNameSpace.data[LContext->framebuffer] : NULL; for (GLuint i = 0; i < fbCount; ++i) { @@ -530,23 +527,23 @@ static inline void _RGLTextureTouchFBOs(jsTexture *texture) } } -static void _RGLAllocateBuffer( jsBufferObject* bufferObject ) +static void _RGLAllocateBuffer(jsBufferObject* bufferObject) { - RGLBufferObject *jsBuffer = ( RGLBufferObject * )bufferObject->platformBufferObject; + RGLBufferObject *jsBuffer = (RGLBufferObject *)bufferObject->platformBufferObject; - _RGLPlatformDestroyBufferObject( bufferObject ); + _RGLPlatformDestroyBufferObject(bufferObject); jsBuffer->pool = SURFACE_POOL_LINEAR; jsBuffer->bufferId = gmmAlloc(0, jsBuffer->bufferSize); jsBuffer->pitch = 0; - if ( jsBuffer->bufferId == GMM_ERROR ) + if(jsBuffer->bufferId == GMM_ERROR) jsBuffer->pool = SURFACE_POOL_NONE; GLuint referenceCount = bufferObject->textureReferences.getCount(); - if ( referenceCount > 0 ) + if(referenceCount > 0) { - for ( GLuint i = 0;i < referenceCount;++i ) + for (GLuint i = 0;i < referenceCount; ++i) { jsTexture *texture = bufferObject->textureReferences[i]; RGLTexture *gcmTexture = ( RGLTexture * )texture->platformTexture; @@ -641,36 +638,37 @@ static void _RGLPlatformBufferObjectSetData( jsBufferObject* bufferObject, GLint memcpy( gmmIdToAddress( jsBuffer->bufferId ) + offset, data, size ); else { - unsigned int dstId = jsBuffer->bufferId; - unsigned int pitch = jsBuffer->pitch; - const char *src = (const char *)data; - switch ( bufferObject->usage ) - { - case GL_STREAM_DRAW: - case GL_STREAM_READ: - case GL_STREAM_COPY: - case GL_DYNAMIC_DRAW: - case GL_DYNAMIC_READ: - case GL_DYNAMIC_COPY: - { - GLuint id = gmmAlloc(0, size); + unsigned int dstId = jsBuffer->bufferId; + unsigned int pitch = jsBuffer->pitch; + const char *src = (const char *)data; - memcpy( gmmIdToAddress(id), src, size ); - _RGLMemcpy( dstId, offset, pitch, id, size ); + switch ( bufferObject->usage ) + { + case GL_STREAM_DRAW: + case GL_STREAM_READ: + case GL_STREAM_COPY: + case GL_DYNAMIC_DRAW: + case GL_DYNAMIC_READ: + case GL_DYNAMIC_COPY: + { + GLuint id = gmmAlloc(0, size); - gmmFree( id ); - } - break; - default: - cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo); - _RGLFifoFinish( &_RGLState.fifo ); - memcpy( gmmIdToAddress( dstId ) + offset, src, size ); - break; - }; + memcpy( gmmIdToAddress(id), src, size ); + _RGLMemcpy( dstId, offset, pitch, id, size ); + + gmmFree( id ); + } + break; + default: + cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo); + _RGLFifoFinish( &_RGLState.fifo ); + memcpy( gmmIdToAddress( dstId ) + offset, src, size ); + break; + }; } } - ((RGLDriver *)_CurrentDevice->rasterDriver)->invalidateVertexCache = GL_TRUE; + ((RGLDriver *)_CurrentDevice->rasterDriver)->invalidateVertexCache = GL_TRUE; } static GLboolean _RGLPlatformCreateBufferObject( jsBufferObject* bufferObject ) @@ -683,7 +681,7 @@ static GLboolean _RGLPlatformCreateBufferObject( jsBufferObject* bufferObject ) jsBuffer->mapAccess = GL_NONE; jsBuffer->bufferSize = _RGLPad( bufferObject->size, _RGL_BUFFER_OBJECT_BLOCK_SIZE ); - _RGLAllocateBuffer( bufferObject ); + _RGLAllocateBuffer(bufferObject); return jsBuffer->bufferId != GMM_ERROR; } @@ -835,52 +833,56 @@ static void _RGLFramebufferGetAttachmentTexture( jsTexture** texture) { PSGLcontext* LContext = _CurrentContext; - switch ( attachment->type ) - { - case FRAMEBUFFER_ATTACHMENT_NONE: - *texture = NULL; - break; - case FRAMEBUFFER_ATTACHMENT_RENDERBUFFER: - break; - case FRAMEBUFFER_ATTACHMENT_TEXTURE: - *texture = _RGLTexNameSpaceIsName( &LContext->textureNameSpace, attachment->name ) ? ( jsTexture* )LContext->textureNameSpace.data[attachment->name] : NULL; - break; - default: - *texture = NULL; - break; - } + + switch ( attachment->type ) + { + case FRAMEBUFFER_ATTACHMENT_NONE: + *texture = NULL; + break; + case FRAMEBUFFER_ATTACHMENT_RENDERBUFFER: + break; + case FRAMEBUFFER_ATTACHMENT_TEXTURE: + *texture = _RGLTexNameSpaceIsName( &LContext->textureNameSpace, attachment->name ) ? ( jsTexture* )LContext->textureNameSpace.data[attachment->name] : NULL; + break; + default: + *texture = NULL; + break; + } } -static GLboolean _RGLTextureIsValid( const jsTexture* texture ) +static GLboolean _RGLTextureIsValid(const jsTexture* texture) { - if ( texture->imageCount < 1 ) - return GL_FALSE; - if ( !texture->image ) - return GL_FALSE; - const jsImage* image = texture->image; + if(texture->imageCount < 1) + return GL_FALSE; + if ( !texture->image ) + return GL_FALSE; - int width = image->width; - int height = image->height; - GLenum format = image->format; - GLenum type = image->type; - GLenum internalFormat = image->internalFormat; - if (( internalFormat == 0 ) || ( format == 0 ) || ( type == 0 ) ) - return GL_FALSE; + const jsImage* image = texture->image; - if ( !image->isSet ) - return GL_FALSE; - if ( width != image->width ) - return GL_FALSE; - if ( height != image->height ) - return GL_FALSE; - if ( format != image->format ) - return GL_FALSE; - if ( type != image->type ) - return GL_FALSE; - if ( internalFormat != image->internalFormat ) - return GL_FALSE; + int width = image->width; + int height = image->height; - return GL_TRUE; + GLenum format = image->format; + GLenum type = image->type; + GLenum internalFormat = image->internalFormat; + + if (( internalFormat == 0 ) || ( format == 0 ) || ( type == 0 ) ) + return GL_FALSE; + + if(!image->isSet) + return GL_FALSE; + if(width != image->width) + return GL_FALSE; + if(height != image->height) + return GL_FALSE; + if(format != image->format) + return GL_FALSE; + if(type != image->type) + return GL_FALSE; + if(internalFormat != image->internalFormat) + return GL_FALSE; + + return GL_TRUE; } static GLenum _RGLPlatformFramebufferCheckStatus(jsFramebuffer* framebuffer) @@ -933,29 +935,36 @@ static GLenum _RGLPlatformFramebufferCheckStatus(jsFramebuffer* framebuffer) return GL_FRAMEBUFFER_COMPLETE_OES; } -enum _RGLTextureStrategy { - _RGL_TEXTURE_STRATEGY_END, - _RGL_TEXTURE_STRATEGY_UNTILED_ALLOC, - _RGL_TEXTURE_STRATEGY_UNTILED_CLEAR, +enum _RGLTextureStrategy +{ + TEXTURE_STRATEGY_END, + TEXTURE_STRATEGY_UNTILED_ALLOC, + TEXTURE_STRATEGY_UNTILED_CLEAR, }; static enum _RGLTextureStrategy linearGPUStrategy[] = { - _RGL_TEXTURE_STRATEGY_UNTILED_ALLOC, - _RGL_TEXTURE_STRATEGY_UNTILED_CLEAR, - _RGL_TEXTURE_STRATEGY_UNTILED_ALLOC, - _RGL_TEXTURE_STRATEGY_END, + TEXTURE_STRATEGY_UNTILED_ALLOC, + TEXTURE_STRATEGY_UNTILED_CLEAR, + TEXTURE_STRATEGY_UNTILED_ALLOC, + TEXTURE_STRATEGY_END, }; static void _RGLImageAllocCPUStorage( jsImage *image ) { - if (( image->storageSize > image->mallocStorageSize ) || ( !image->mallocData ) ) - { - if ( image->mallocData ) free( image->mallocData ); - image->mallocData = ( char * )malloc( image->storageSize + 128 ); - image->mallocStorageSize = image->storageSize; - } - image->data = _RGLPadPtr( image->mallocData, 128 ); + if((image->storageSize > image->mallocStorageSize) || (!image->mallocData)) + { + if(image->mallocData) + free( image->mallocData ); + + image->mallocData = ( char * )malloc( image->storageSize + 128 ); + image->mallocStorageSize = image->storageSize; + } + + intptr_t x = (intptr_t)image->mallocData; + x = ( x + 128 - 1 ) / 128 * 128; + image->data = (char*)x; + } static inline int _RGLGetComponentCount( GLenum format ) @@ -1272,11 +1281,6 @@ int _RGLGetPixelSize( GLenum format, GLenum type ) return _RGLGetComponentCount( format )*componentSize; } -static inline int _RGLGetStorageSize( GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth ) -{ - return _RGLGetPixelSize( format, type )*width*height*depth; -} - static void _RGLPlatformChooseGPUFormatAndLayout( const jsTexture* texture, GLboolean forceLinear, @@ -1289,18 +1293,20 @@ static void _RGLPlatformChooseGPUFormatAndLayout( newLayout->baseHeight = image->height; newLayout->internalFormat = ( RGLEnum )image->internalFormat; newLayout->pixelBits = _RGLPlatformGetBitsPerPixel( newLayout->internalFormat ); - newLayout->pitch = pitch ? pitch : _RGLPad( _RGLGetStorageSize( texture->image->format, texture->image->type, texture->image->width, 1, 1 ), 64 ); + newLayout->pitch = pitch ? pitch : _RGLPad( _RGLGetPixelSize( texture->image->format, texture->image->type )*texture->image->width, 64); } -void _RGLPlatformDropUnboundTextures( GLenum pool ) +void _RGLPlatformDropUnboundTextures(GLenum pool) { PSGLcontext* LContext = _CurrentContext; GLuint i, j; + for (i = 0; i < LContext->textureNameSpace.capacity; ++i) { GLboolean bound = GL_FALSE; jsTexture *texture = ( jsTexture * )LContext->textureNameSpace.data[i]; - if ( !texture || ( texture->referenceBuffer != 0 ) ) continue; + if(!texture || (texture->referenceBuffer != 0)) + continue; for (j = 0; j < _RGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++j) { @@ -1355,7 +1361,7 @@ static void _RGLPlatformReallocateGcmTexture( jsTexture* texture ) switch ( *step++ ) { - case _RGL_TEXTURE_STRATEGY_UNTILED_ALLOC: + case TEXTURE_STRATEGY_UNTILED_ALLOC: _RGLPlatformChooseGPUFormatAndLayout( texture, GL_TRUE, 0, &newLayout ); size = _RGLPad( newLayout.baseHeight * newLayout.pitch, 1); @@ -1388,10 +1394,10 @@ static void _RGLPlatformReallocateGcmTexture( jsTexture* texture ) } } break; - case _RGL_TEXTURE_STRATEGY_UNTILED_CLEAR: + case TEXTURE_STRATEGY_UNTILED_CLEAR: _RGLPlatformDropUnboundTextures(SURFACE_POOL_LINEAR); break; - case _RGL_TEXTURE_STRATEGY_END: + case TEXTURE_STRATEGY_END: _RGLSetError( GL_OUT_OF_MEMORY ); done = GL_TRUE; break; @@ -1511,10 +1517,10 @@ static void _RGLPlatformValidateTextureResources( jsTexture *texture ) GLuint gamma = 0; GLuint remap = texture->gammaRemap; - gamma |= ( remap & RGL_GAMMA_REMAP_RED_BIT ) ? CELL_GCM_TEXTURE_GAMMA_R : 0; - gamma |= ( remap & RGL_GAMMA_REMAP_GREEN_BIT ) ? CELL_GCM_TEXTURE_GAMMA_G : 0; - gamma |= ( remap & RGL_GAMMA_REMAP_BLUE_BIT ) ? CELL_GCM_TEXTURE_GAMMA_B : 0; - gamma |= ( remap & RGL_GAMMA_REMAP_ALPHA_BIT ) ? CELL_GCM_TEXTURE_GAMMA_A : 0; + gamma |= (remap & RGL_GAMMA_REMAP_RED_BIT) ? CELL_GCM_TEXTURE_GAMMA_R : 0; + gamma |= (remap & RGL_GAMMA_REMAP_GREEN_BIT) ? CELL_GCM_TEXTURE_GAMMA_G : 0; + gamma |= (remap & RGL_GAMMA_REMAP_BLUE_BIT) ? CELL_GCM_TEXTURE_GAMMA_B : 0; + gamma |= (remap & RGL_GAMMA_REMAP_ALPHA_BIT) ? CELL_GCM_TEXTURE_GAMMA_A : 0; platformTexture->gcmMethods.address.gamma = gamma; @@ -1534,7 +1540,7 @@ static void _RGLPlatformValidateTextureResources( jsTexture *texture ) platformTexture->gcmTexture.cubemap = CELL_GCM_FALSE; platformTexture->gcmTexture.dimension = CELL_GCM_TEXTURE_DIMENSION_2; - if ( gmmIdIsMain(platformTexture->gpuAddressId) ) + if(gmmIdIsMain(platformTexture->gpuAddressId)) platformTexture->gcmTexture.location = CELL_GCM_LOCATION_MAIN; else platformTexture->gcmTexture.location = CELL_GCM_LOCATION_LOCAL; @@ -1558,7 +1564,8 @@ static void jsPlatformFramebuffer_validate( jsPlatformFramebuffer * fb, PSGLcont GLuint defaultPitch = 0; GLuint defaultId = GMM_ERROR; GLuint defaultIdOffset = 0; - for ( int i = 0; i < RGL_SETRENDERTARGET_MAXCOUNT; ++i ) + + for(int i = 0; i < RGL_SETRENDERTARGET_MAXCOUNT; ++i) { jsTexture* colorTexture = NULL; _RGLFramebufferGetAttachmentTexture(&fb->color[i], &colorTexture); @@ -1618,7 +1625,7 @@ static void _RGLValidateFramebuffer( void ) if(LContext->framebuffer) { - jsPlatformFramebuffer* framebuffer = static_cast( _RGLGetFramebuffer( LContext, LContext->framebuffer ) ); + jsPlatformFramebuffer* framebuffer = static_cast((jsFramebuffer *)LContext->framebufferNameSpace.data[LContext->framebuffer] ); if ( framebuffer->needValidate ) jsPlatformFramebuffer_validate( framebuffer, LContext ); @@ -1721,10 +1728,10 @@ GLAPI void APIENTRY glClearColor( GLclampf red, GLclampf green, GLclampf blue, G { PSGLcontext *LContext = _CurrentContext; - LContext->ClearColor.R = _RGLClampf( red ); - LContext->ClearColor.G = _RGLClampf( green ); - LContext->ClearColor.B = _RGLClampf( blue ); - LContext->ClearColor.A = _RGLClampf( alpha ); + LContext->ClearColor.R = MAX(MIN(red, 1.f), 0.f); + LContext->ClearColor.G = MAX(MIN(green, 1.f), 0.f); + LContext->ClearColor.B = MAX(MIN(blue, 1.f), 0.f); + LContext->ClearColor.A = MAX(MIN(alpha, 1.f), 0.f); } GLAPI void APIENTRY glBlendEquation( GLenum mode ) @@ -1735,19 +1742,18 @@ GLAPI void APIENTRY glBlendEquation( GLenum mode ) LContext->needValidate |= PSGL_VALIDATE_BLENDING; } -GLAPI void APIENTRY glBlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) +GLAPI void APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { PSGLcontext* LContext = _CurrentContext; - LContext->BlendColor.R = _RGLClampf( red ); - LContext->BlendColor.G = _RGLClampf( green ); - LContext->BlendColor.B = _RGLClampf( blue ); - LContext->BlendColor.A = _RGLClampf( alpha ); + LContext->BlendColor.R = MAX(MIN(red, 1.f), 0.f); + LContext->BlendColor.G = MAX(MIN(green, 1.f), 0.f); + LContext->BlendColor.B = MAX(MIN(blue, 1.f), 0.f); + LContext->BlendColor.A = MAX(MIN(alpha, 1.f), 0.f); LContext->needValidate |= PSGL_VALIDATE_BLENDING; } - -GLAPI void APIENTRY glBlendFunc( GLenum sfactor, GLenum dfactor ) +GLAPI void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor) { PSGLcontext *LContext = _CurrentContext; @@ -1814,7 +1820,7 @@ GLAPI GLenum APIENTRY glCheckFramebufferStatusOES( GLenum target ) if ( LContext->framebuffer ) { - jsFramebuffer* framebuffer = _RGLGetFramebuffer( LContext, LContext->framebuffer ); + jsFramebuffer* framebuffer = (jsFramebuffer *)LContext->framebufferNameSpace.data[LContext->framebuffer]; return _RGLPlatformFramebufferCheckStatus( framebuffer ); } @@ -1825,7 +1831,7 @@ GLAPI void APIENTRY glFramebufferTexture2DOES( GLenum target, GLenum attachment, { PSGLcontext* LContext = _CurrentContext; - jsFramebuffer* framebuffer = _RGLGetFramebuffer( LContext, LContext->framebuffer ); + jsFramebuffer* framebuffer = (jsFramebuffer *)LContext->framebufferNameSpace.data[LContext->framebuffer]; jsFramebufferAttachment* attach = _RGLFramebufferGetAttachment( framebuffer, GL_COLOR_ATTACHMENT0_EXT ); @@ -2095,10 +2101,7 @@ static uint32_t gmmInitFixedAllocator (void) return CELL_OK; } -static void gmmRemovePendingFree( - GmmAllocator *pAllocator, - GmmBlock *pBlock -) +static void gmmRemovePendingFree(GmmAllocator *pAllocator, GmmBlock *pBlock) { if (pBlock == pAllocator->pPendingFreeHead) pAllocator->pPendingFreeHead = pBlock->pNextFree; @@ -3268,10 +3271,10 @@ template inline static void swapandsetfp( int ucodeSize, unsigned int unsigned short count = *( ec++ ); for ( unsigned long offsetIndex = 0; offsetIndex < count; ++offsetIndex ) { - void *pointer=NULL; + void *ptr = NULL; const int paddedSIZE = (SIZE + 1) & ~1; - cellGcmSetInlineTransferPointerInline( &_RGLState.fifo, gmmIdToOffset( loadProgramId ) + loadProgramOffset + *(ec++), paddedSIZE, &pointer); - float *fp = (float*)pointer; + cellGcmSetInlineTransferPointerInline( &_RGLState.fifo, gmmIdToOffset( loadProgramId ) + loadProgramOffset + *(ec++), paddedSIZE, &ptr); + float *fp = (float*)ptr; float *src = (float*)v; for (uint32_t j=0; j static void setVectorTypefp( CgRuntimeParameter* __restrict p CgParameterResource *parameterResource = _RGLGetParameterResource( ptr->program, ptr->parameterEntry ); unsigned short resource = parameterResource->resource; unsigned short *ec = ( unsigned short * )( ptr->program->resources ) + resource + 1; + if ( RGL_LIKELY( *ec ) ) { - swapandsetfp( program->header.instructionCount*16, program->loadProgramId, program->loadProgramOffset, ec, ( unsigned int * )data ); + swapandsetfp(program->header.instructionCount*16, program->loadProgramId, program->loadProgramOffset, ec, (unsigned int *)data); } } @@ -3309,8 +3313,8 @@ template static void setVectorTypeSharedvpIndex( CgRuntimeParameter* _ const float * __restrict f = ( const float * __restrict )v; const CgParameterResource *parameterResource = _RGLGetParameterResource( ptr->program, ptr->parameterEntry ); unsigned short resource = parameterResource->resource; - float * __restrict dst = ( float * __restrict )ptr->pushBufferPointer; - for ( long i = 0; i < SIZE; ++ i ) + float * __restrict dst = (float * __restrict)ptr->pushBufferPointer; + for (long i = 0; i < SIZE; ++i) dst[i] = f[i]; _RGLPlatformSetVertexRegister4fv( resource, dst ); } @@ -3407,11 +3411,10 @@ template static void setMatrixSharedvpIndex( CgR float tmp[ROWS*4]; for ( long row = 0; row < ROWS; ++row ) { - for ( long col = 0; col < COLS; ++col ) - { - tmp[row*4 + col] = dst[row * 4 + col] = ( ORDER == ROW_MAJOR ) ? f[row * COLS + col] : f[col * ROWS + row]; - } - for ( long col = COLS; col < 4; ++col ) tmp[row*4 + col] = dst[row*4+col]; + for(long col = 0; col < COLS; ++col) + tmp[row*4 + col] = dst[row * 4 + col] = ( ORDER == ROW_MAJOR ) ? f[row * COLS + col] : f[col * ROWS + row]; + for(long col = COLS; col < 4; ++col) + tmp[row*4 + col] = dst[row*4+col]; } cellGcmSetVertexProgramParameterBlockInline( &_RGLState.fifo, resource, ROWS, (const float*)tmp); @@ -4407,13 +4410,6 @@ static void _RGLPlatformDestroyTexture( jsTexture* texture ) _RGLTextureTouchFBOs( texture ); } -// Get size of texture in GPU layout -static inline GLuint _RGLPlatformTextureGetGPUSize( const jsTexture* texture ) -{ - RGLTexture *gcmTexture = ( RGLTexture * )texture->platformTexture; - return _RGLPad( gcmTexture->gpuLayout.baseHeight * gcmTexture->gpuLayout.pitch, 1); -} - #include static void _RGLPlatformValidateTextureStage( int unit, jsTexture* texture ) @@ -4573,9 +4569,7 @@ static GLenum _RGLPlatformChooseInternalStorage( jsImage* image, GLenum internal image->internalFormat = platformInternalFormat; _RGLPlatformExpandInternalFormat( platformInternalFormat, &image->format, &image->type ); - image->storageSize = _RGLGetStorageSize( - image->format, image->type, - image->width, image->height, 1 ); + image->storageSize = _RGLGetPixelSize(image->format, image->type) * image->width * image->height; return GL_NO_ERROR; } @@ -4662,9 +4656,7 @@ static GLboolean _RGLPlatformTexturePBOImage( if ( LContext->PixelUnpackBuffer == 0 ) return GL_FALSE; - const GLuint pboPitch = _RGLPad( - _RGLGetStorageSize( format, type, width, 1, 1 ), - LContext->unpackAlignment ); + const GLuint pboPitch = _RGLPad(_RGLGetPixelSize(format, type) * width, LContext->unpackAlignment ); if (( pboPitch&3 ) != 0 ) { RARCH_WARN("PBO image pitch not a multiple of 4, using slow path.\n" ); @@ -4722,14 +4714,15 @@ static GLboolean _RGLPlatformTexturePBOImage( { gcmTexture->gpuLayout = newLayout; if ( gcmTexture->gpuAddressId != GMM_ERROR && gcmTexture->pbo == NULL ) - { - _RGLPlatformFreeGcmTexture( texture ); - } + _RGLPlatformFreeGcmTexture( texture ); + gcmTexture->pbo = bufferObject; gcmTexture->gpuAddressId = gpuId; gcmTexture->gpuAddressIdOffset = gpuIdOffset; gcmTexture->pool = SURFACE_POOL_LINEAR; - gcmTexture->gpuSize = _RGLPlatformTextureGetGPUSize( texture ); + RGLTexture *gcmTexture = ( RGLTexture * )texture->platformTexture; + // Get size of texture in GPU layout + gcmTexture->gpuSize = _RGLPad( gcmTexture->gpuLayout.baseHeight * gcmTexture->gpuLayout.pitch, 1); ++bufferObject->refCount; } else @@ -6464,7 +6457,7 @@ GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const G LContext->needValidate |= PSGL_VALIDATE_TEXTURES_USED | PSGL_VALIDATE_VERTEX_TEXTURES_USED; } -GLAPI void APIENTRY glActiveTexture( GLenum texture ) +GLAPI void APIENTRY glActiveTexture(GLenum texture) { PSGLcontext* LContext = _CurrentContext; @@ -6474,13 +6467,13 @@ GLAPI void APIENTRY glActiveTexture( GLenum texture ) LContext->CurrentCoordsUnit = unit < _RGL_MAX_TEXTURE_COORDS ? LContext->TextureCoordsUnits + unit : NULL; } -GLAPI void APIENTRY glClientActiveTexture( GLenum texture ) +GLAPI void APIENTRY glClientActiveTexture(GLenum texture) { PSGLcontext* LContext = _CurrentContext; LContext->CS_ActiveTexture = texture - GL_TEXTURE0; } -GLAPI void APIENTRY glPixelStorei( GLenum pname, GLint param ) +GLAPI void APIENTRY glPixelStorei(GLenum pname, GLint param) { PSGLcontext* LContext = _CurrentContext; @@ -6584,7 +6577,7 @@ static _CGprogram* _RGLCgProgramFindPrev( _CGcontext* ctx, _CGprogram* prog ) { _CGprogram* ptr = ctx->programList; - while ( NULL != ptr && prog != ptr->next ) + while ( ptr != NULL && prog != ptr->next ) ptr = ptr->next; return ptr; @@ -6775,7 +6768,7 @@ static CGprogram _RGLCgCreateProgram( CGcontext ctx, CGprofile profile, const Cg // The parameters and the actual program are generated from the ABI specific calls. _CGprogram* prog = ( _CGprogram* )malloc( sizeof( _CGprogram ) ); - if ( prog == NULL ) + if(prog == NULL) { _RGLCgRaiseError( CG_MEMORY_ALLOC_ERROR ); return NULL; @@ -6792,9 +6785,9 @@ static CGprogram _RGLCgCreateProgram( CGcontext ctx, CGprofile profile, const Cg // create a name for the program and record it in the object CGprogram id = ( CGprogram )_RGLCreateName( &_CurrentContext->cgProgramNameSpace, prog ); - if ( !id ) + if(!id) { - free( prog ); + free(prog); _RGLCgRaiseError( CG_MEMORY_ALLOC_ERROR ); return NULL; } @@ -6837,8 +6830,10 @@ static CGprogram _RGLCgCreateProgram( CGcontext ctx, CGprofile profile, const Cg } // success! add the program to the program list in the context. - _RGLCgProgramPushFront( prog->parentContext, prog ); - if ( _cgProgramCreateHook ) _cgProgramCreateHook( prog ); + _RGLCgProgramPushFront(prog->parentContext, prog); + + if(_cgProgramCreateHook) + _cgProgramCreateHook(prog); // everything worked. return id; @@ -6878,10 +6873,10 @@ CG_API CGprogram cgCreateProgram( CGcontext ctx, char* compiled_program = NULL; if ( program_type == CG_SOURCE ) { - if ( _cgRTCgcCompileProgramHook ) + if(_cgRTCgcCompileProgramHook) { _cgRTCgcCompileProgramHook( program, cgGetProfileString(profile), entry, args, &compiled_program ); - if ( !compiled_program ) + if(!compiled_program) { _RGLCgRaiseError( CG_COMPILER_ERROR ); return NULL; @@ -6931,7 +6926,7 @@ CG_API CGprogram cgCreateProgram( CGcontext ctx, else totalSize = nvProgram->totalSize; - int res = convertNvToElfFromMemory( binaryBuffer, totalSize, 2, 0, ( void** ) & runtimeElfShader, &compiled_program_size, stringTableArray, defaultValuesArray ); + int res = convertNvToElfFromMemory( binaryBuffer, totalSize, 2, 0, ( void** )&runtimeElfShader, &compiled_program_size, stringTableArray, defaultValuesArray ); if ( res != 0 ) { RARCH_ERR("Invalid CG binary program.\n"); @@ -6990,13 +6985,13 @@ CG_API CGprogram cgCreateProgram( CGcontext ctx, return NULL; } bool res = cgOpenElf( binaryBuffer, 0, &elfBinary ); - if ( !res ) + if(!res) { RARCH_ERR("Not a valid ELF.\n"); _RGLCgRaiseError( CG_PROGRAM_LOAD_ERROR ); return NULL; } - if ( !cgGetElfProgramByName( &elfBinary, entry, &elfProgram ) ) + if(!cgGetElfProgramByName( &elfBinary, entry, &elfProgram)) { RARCH_ERR("Couldn't find the shader entry in the CG binary.\n"); return NULL; @@ -7011,10 +7006,10 @@ CG_API CGprogram cgCreateProgram( CGcontext ctx, CGprogram prog = _RGLCgCreateProgram( ctx, profile, programHeader, ucode, parameterHeader, stringTable, defaultValues ); - if ( bConvertedToElf ) + if(bConvertedToElf) { - _CGprogram* ptr = _cgGetProgPtr( prog ); - ptr->runtimeElf = programHeader; + _CGprogram* ptr = _cgGetProgPtr( prog ); + ptr->runtimeElf = programHeader; } return prog; @@ -7033,10 +7028,10 @@ CG_API CGprogram cgCreateProgramFromFile( CGcontext ctx, profile = CG_PROFILE_SCE_FP_RSX; if ( program_type == CG_ROW_MAJOR ) - program_type = CG_BINARY; + program_type = CG_BINARY; if ( !_RGLCgCreateProgramChecks( ctx, profile, program_type ) ) - return NULL; + return NULL; FILE* fp = NULL; if ( RGL_LIKELY( program_type == CG_BINARY ) ) @@ -7074,12 +7069,12 @@ CG_API CGprogram cgCreateProgramFromFile( CGcontext ctx, return ret; else { - fp = fopen( program_file, "rb" ); + fp = fopen( program_file, "rb"); if ( fp == NULL ) { _RGLCgRaiseError( CG_FILE_READ_ERROR ); - return ( CGprogram )NULL; + return (CGprogram)NULL; } unsigned int filetag = 0; @@ -7132,12 +7127,12 @@ CG_API CGprogram cgCreateProgramFromFile( CGcontext ctx, } size_t file_size = 0; - fseek( fp, 0, SEEK_END ); - file_size = ftell( fp ); - rewind( fp ); + fseek(fp, 0, SEEK_END); + file_size = ftell(fp); + rewind(fp); - char* ptr = ( char* )malloc( file_size + 1 ); - if ( ptr == NULL ) + char* ptr = (char*)malloc( file_size + 1 ); + if (ptr == NULL) { _RGLCgRaiseError( CG_MEMORY_ALLOC_ERROR ); fclose( fp ); @@ -7176,17 +7171,17 @@ CG_API CGprogram cgCopyProgram( CGprogram program ) size_t ucodeSize = 0; if (prog->header.profile == CG_PROFILE_SCE_FP_TYPEB || prog->header.profile == CG_PROFILE_SCE_FP_RSX) - { - paddedProgramSize = _RGLPad( sizeof( _CGprogram ), 16); - ucodeSize = prog->header.instructionCount * 16; - newprog = ( _CGprogram* )malloc( paddedProgramSize + ucodeSize ); - } + { + paddedProgramSize = _RGLPad( sizeof( _CGprogram ), 16); + ucodeSize = prog->header.instructionCount * 16; + newprog = ( _CGprogram* )malloc(paddedProgramSize + ucodeSize); + } else - { - newprog = ( _CGprogram* )malloc( sizeof( _CGprogram ) ); - } + { + newprog = (_CGprogram*)malloc(sizeof(_CGprogram)); + } - if ( newprog == NULL ) + if(newprog == NULL) { _RGLCgRaiseError( CG_MEMORY_ALLOC_ERROR ); return ( CGprogram )NULL; @@ -7221,10 +7216,10 @@ CG_API CGprogram cgCopyProgram( CGprogram program ) } if (prog->header.profile == CG_PROFILE_SCE_FP_TYPEB || prog->header.profile == CG_PROFILE_SCE_FP_RSX) - { - newprog->ucode = (char*)newprog + paddedProgramSize; - memcpy((char*)newprog->ucode, (char*)prog->ucode, ucodeSize); - } + { + newprog->ucode = (char*)newprog + paddedProgramSize; + memcpy((char*)newprog->ucode, (char*)prog->ucode, ucodeSize); + } if ( prog->programGroup ) { @@ -7233,9 +7228,10 @@ CG_API CGprogram cgCopyProgram( CGprogram program ) _RGLCgUpdateProgramAtIndex( newprog->programGroup, -1, 1 ); } - _RGLCgProgramPushFront( newprog->parentContext, newprog ); + _RGLCgProgramPushFront(newprog->parentContext, newprog); - if ( _cgProgramCopyHook ) _cgProgramCopyHook( newprog, prog ); + if(_cgProgramCopyHook) + _cgProgramCopyHook(newprog, prog); return newprog->id; } @@ -7248,7 +7244,9 @@ CG_API void cgDestroyProgram( CGprogram program ) _RGLCgRaiseError( CG_INVALID_PROGRAM_HANDLE_ERROR ); return; } + _CGprogram* ptr = _cgGetProgPtr( program ); + if ( ptr == NULL ) { _RGLCgRaiseError( CG_INVALID_PROGRAM_HANDLE_ERROR ); @@ -7282,7 +7280,7 @@ CG_API void cgDestroyProgram( CGprogram program ) ctx->programList = p->next; _RGLCgProgramErase( p ); if(p != NULL) - free( p ); + free( p ); } else { @@ -8109,12 +8107,6 @@ CGGL_API void cgGLEnableTextureParameter( CGparameter param ) ptr->samplerSetter( ptr, NULL, 0 ); } -static void _RGLCgContextZero( _CGcontext* p ) -{ - memset( p, 0, sizeof( *p ) ); - p->compileType = CG_UNKNOWN; -} - static void _RGLCgContextPushFront(_CGcontext* ctx) { if(_CurrentContext->RGLcgContextHead) @@ -8131,7 +8123,9 @@ static void destroy_context(_CGcontext*ctx) _cgContextDestroyHook(ctx); _RGLEraseName( &_CurrentContext->cgContextNameSpace, ( jsName )ctx->id ); - _RGLCgContextZero( ctx ); + memset(ctx, 0, sizeof( *ctx ) ); + ctx->compileType = CG_UNKNOWN; + free( ctx ); } @@ -8146,7 +8140,8 @@ CG_API CGcontext cgCreateContext(void) return ( CGcontext )NULL; } - _RGLCgContextZero( ptr ); + memset( ptr, 0, sizeof( *ptr ) ); + ptr->compileType = CG_UNKNOWN; CGcontext result = ( CGcontext )_RGLCreateName( &_CurrentContext->cgContextNameSpace, ptr ); if ( !result ) diff --git a/console/rgl/ps3/rgl.h b/console/rgl/ps3/rgl.h index e9d80263f8..09a909e97d 100644 --- a/console/rgl/ps3/rgl.h +++ b/console/rgl/ps3/rgl.h @@ -550,11 +550,6 @@ struct PSGLcontext #define RGL_LIKELY(COND) (COND) #define RGL_UNLIKELY(COND) (COND) -static inline float _RGLClampf( const float value ) -{ - return MAX( MIN( value, 1.f ), 0.f ); -} - static inline unsigned int endianSwapWord( unsigned int v ) { return ( v&0xff ) << 24 | ( v&0xff00 ) << 8 | @@ -577,13 +572,6 @@ static inline unsigned long _RGLPad(unsigned long x, unsigned long pad) return ( x + pad - 1 ) / pad*pad; } -static inline char* _RGLPadPtr(const char* p, unsigned int pad) -{ - intptr_t x = (intptr_t)p; - x = ( x + pad - 1 ) / pad * pad; - return ( char* )x; -} - typedef struct MemoryBlockManager_t_ { char *memory; @@ -798,7 +786,7 @@ struct RGLResource char * dmaPushBuffer; GLuint dmaPushBufferSize; void* dmaControl; - RGLSemaphoreMemory *semaphores; + RGLSemaphoreMemory *semaphores; }; typedef volatile struct @@ -927,7 +915,7 @@ static inline GLuint _RGLPlatformGetBitsPerPixel( GLenum internalFormat ) } -void static inline _RGLFifoGlViewport( GLint x, GLint y, GLsizei width, GLsizei height, GLclampf zNear = 0.0f, GLclampf zFar = 1.0f ) +static inline void _RGLFifoGlViewport( GLint x, GLint y, GLsizei width, GLsizei height, GLclampf zNear = 0.0f, GLclampf zFar = 1.0f ) { RGLViewportState *vp = &_RGLState.state.viewport; RGLRenderTarget *rt = &_RGLState.renderTarget; From 0da3b628c63c7845647ac7f4291fed9dfe3258e4 Mon Sep 17 00:00:00 2001 From: freakdave Date: Mon, 6 Aug 2012 15:08:10 +0200 Subject: [PATCH 070/492] (Xbox 1) Fixed lockups that occurred due to negative viewport coordinates (X,Y in Resize Mode) --- console/rmenu/rmenu.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index b8af014e50..360278d9cf 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -1874,9 +1874,11 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) gfx_ctx_set_aspect_ratio(NULL, g_console.aspect_ratio_index); if(input & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_LEFT)) - g_console.viewports.custom_vp.x -= 4; + if(g_console.viewports.custom_vp.x >= 4) + g_console.viewports.custom_vp.x -= 4; else if(input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) - g_console.viewports.custom_vp.x -= 1; + if(g_console.viewports.custom_vp.x > 0) + g_console.viewports.custom_vp.x -= 1; if(input & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_RIGHT)) g_console.viewports.custom_vp.x += 4; @@ -1889,9 +1891,11 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) g_console.viewports.custom_vp.y += 1; if(input & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_DOWN)) - g_console.viewports.custom_vp.y -= 4; + if(g_console.viewports.custom_vp.y >= 4) + g_console.viewports.custom_vp.y -= 4; else if(input & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)) - g_console.viewports.custom_vp.y -= 1; + if(g_console.viewports.custom_vp.y > 0) + g_console.viewports.custom_vp.y -= 1; if(input & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_LEFT)) g_console.viewports.custom_vp.width -= 4; From 64ef86ce06546bb6018a0db5929604b7422c6329 Mon Sep 17 00:00:00 2001 From: freakdave Date: Mon, 6 Aug 2012 15:15:58 +0200 Subject: [PATCH 071/492] (Xbox 1) Added ifdef's to the viewport fix, i don't know if other platforms allow negative values. --- console/rmenu/rmenu.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index 360278d9cf..e5c4ac60d9 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -1874,10 +1874,14 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) gfx_ctx_set_aspect_ratio(NULL, g_console.aspect_ratio_index); if(input & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_LEFT)) +#ifdef _XBOX1 if(g_console.viewports.custom_vp.x >= 4) +#endif g_console.viewports.custom_vp.x -= 4; else if(input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) +#ifdef _XBOX1 if(g_console.viewports.custom_vp.x > 0) +#endif g_console.viewports.custom_vp.x -= 1; if(input & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_RIGHT)) @@ -1891,10 +1895,14 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) g_console.viewports.custom_vp.y += 1; if(input & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_DOWN)) +#ifdef _XBOX1 if(g_console.viewports.custom_vp.y >= 4) +#endif g_console.viewports.custom_vp.y -= 4; else if(input & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)) +#ifdef _XBOX1 if(g_console.viewports.custom_vp.y > 0) +#endif g_console.viewports.custom_vp.y -= 1; if(input & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_LEFT)) From fe5a11b051d12f43fc1eae2568bf9e457a5b4dcf Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 6 Aug 2012 18:24:35 +0200 Subject: [PATCH 072/492] (RGL) Cleanups --- console/rgl/ps3/rgl.cpp | 185 +++++++++++++++++++--------------------- console/rgl/ps3/rgl.h | 19 ++--- 2 files changed, 96 insertions(+), 108 deletions(-) diff --git a/console/rgl/ps3/rgl.cpp b/console/rgl/ps3/rgl.cpp index 11ce94b456..7fdffaba08 100644 --- a/console/rgl/ps3/rgl.cpp +++ b/console/rgl/ps3/rgl.cpp @@ -436,10 +436,6 @@ static void _RGLFreeBufferObject( jsBufferObject *buffer ) } } -static void _RGLUnbindBufferObject( PSGLcontext *LContext, GLuint name ) -{ -} - GLAPI void APIENTRY glBindBuffer( GLenum target, GLuint name ) { PSGLcontext *LContext = _CurrentContext; @@ -1207,14 +1203,15 @@ static void _RGLPlatformCopyGPUTexture( jsTexture* texture ) } } -static void _RGLPlatformFreeGcmTexture( jsTexture* texture ) +static void _RGLPlatformFreeGcmTexture(jsTexture* texture) { - RGLTexture *gcmTexture = ( RGLTexture * )texture->platformTexture; - switch ( gcmTexture->pool ) + RGLTexture *gcmTexture = (RGLTexture *)texture->platformTexture; + + switch (gcmTexture->pool) { case SURFACE_POOL_LINEAR: case SURFACE_POOL_SYSTEM: - gmmFree( gcmTexture->gpuAddressId ); + gmmFree(gcmTexture->gpuAddressId); case SURFACE_POOL_NONE: break; default: @@ -1229,6 +1226,7 @@ static void _RGLPlatformFreeGcmTexture( jsTexture* texture ) void _RGLPlatformDropTexture( jsTexture *texture ) { RGLTexture * gcmTexture = (RGLTexture *)texture->platformTexture; + if(gcmTexture->pbo != NULL) { _RGLPlatformCopyGPUTexture(texture); @@ -1291,7 +1289,7 @@ static void _RGLPlatformChooseGPUFormatAndLayout( newLayout->baseWidth = image->width; newLayout->baseHeight = image->height; - newLayout->internalFormat = ( RGLEnum )image->internalFormat; + newLayout->internalFormat = (RGLEnum)image->internalFormat; newLayout->pixelBits = _RGLPlatformGetBitsPerPixel( newLayout->internalFormat ); newLayout->pitch = pitch ? pitch : _RGLPad( _RGLGetPixelSize( texture->image->format, texture->image->type )*texture->image->width, 64); } @@ -1308,7 +1306,7 @@ void _RGLPlatformDropUnboundTextures(GLenum pool) if(!texture || (texture->referenceBuffer != 0)) continue; - for (j = 0; j < _RGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++j) + for (j = 0; j < MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++j) { if (LContext->VertexTextureImages[j] == texture) { @@ -1317,7 +1315,7 @@ void _RGLPlatformDropUnboundTextures(GLenum pool) } } - for ( j = 0; j < _RGL_MAX_TEXTURE_IMAGE_UNITS; ++j) + for ( j = 0; j < MAX_TEXTURE_IMAGE_UNITS; ++j) { jsTextureImageUnit *tu = LContext->TextureImageUnits + j; if (tu->bound2D == i) @@ -1872,24 +1870,7 @@ void cgRTCgcFree( void ) _cgRTCgcFreeCompiledProgramHook = 0; } -void _RGLInitNameSpace( jsNameSpace * name ) -{ - name->data = NULL; - name->firstFree = NULL; - name->capacity = 0; -} - -void _RGLFreeNameSpace( jsNameSpace * ns ) -{ - if ( ns->data ) - free( ns->data ); - - ns->data = NULL; - ns->capacity = 0; - ns->firstFree = NULL; -} - -jsName _RGLCreateName( jsNameSpace * ns, void* object ) +jsName _RGLCreateName(jsNameSpace * ns, void* object) { if ( ns->firstFree == NULL ) { @@ -1923,7 +1904,7 @@ jsName _RGLCreateName( jsNameSpace * ns, void* object ) return result + 1; } -unsigned int _RGLIsName( jsNameSpace* ns, jsName name ) +unsigned int _RGLIsName(jsNameSpace* ns, jsName name) { if ( RGL_UNLIKELY( name == 0 ) ) return 0; @@ -1936,15 +1917,15 @@ unsigned int _RGLIsName( jsNameSpace* ns, jsName name ) void** value = ( void** )ns->data[name]; if ( RGL_UNLIKELY( value == NULL || - ( value >= ns->data && value < ns->data + ns->capacity ) ) ) + (value >= ns->data && value < ns->data + ns->capacity))) return 0; return 1; } -void _RGLEraseName( jsNameSpace* ns, jsName name ) +void _RGLEraseName(jsNameSpace* ns, jsName name) { - if ( _RGLIsName( ns, name ) ) + if(_RGLIsName( ns, name)) { --name; ns->data[name] = ns->firstFree; @@ -1963,7 +1944,7 @@ void _RGLTexNameSpaceInit( jsTexNameSpace *ns, jsTexNameSpaceCreateFunction crea void _RGLTexNameSpaceFree( jsTexNameSpace *ns ) { - for ( GLuint i = 1;i < ns->capacity;++i ) + for(GLuint i = 1; i < ns->capacity; ++i) if ( ns->data[i] ) ns->destroy( ns->data[i] ); if(ns->data != NULL) @@ -2000,15 +1981,17 @@ GLboolean _RGLTexNameSpaceCreateNameLazy( jsTexNameSpace *ns, GLuint name ) if ( name >= ns->capacity ) { int newCapacity = name >= ns->capacity + CAPACITY_INCR ? name + 1 : ns->capacity + CAPACITY_INCR; - void **newData = ( void ** )realloc( ns->data, newCapacity * sizeof( void * ) ); - memset( newData + ns->capacity, 0, ( newCapacity - ns->capacity )*sizeof( void * ) ); + void **newData = (void**)realloc(ns->data, newCapacity * sizeof(void*)); + memset( newData + ns->capacity, 0, (newCapacity - ns->capacity )*sizeof(void*)); ns->data = newData; ns->capacity = newCapacity; } - if ( !ns->data[name] ) + + if (!ns->data[name]) { ns->data[name] = ns->create(); - if ( ns->data[name] ) return GL_TRUE; + if(ns->data[name]) + return GL_TRUE; } return GL_FALSE; } @@ -4774,17 +4757,17 @@ static GLboolean _RGLPlatformTexturePBOImage( static GLboolean _RGLPlatformTextureReference( jsTexture *texture, GLuint pitch, jsBufferObject *bufferObject, GLintptr offset ) { - RGLTexture *gcmTexture = ( RGLTexture * )texture->platformTexture; + RGLTexture *gcmTexture = (RGLTexture *)texture->platformTexture; RGLTextureLayout newLayout; - _RGLPlatformChooseGPUFormatAndLayout( texture, GL_TRUE, pitch, &newLayout ); + _RGLPlatformChooseGPUFormatAndLayout(texture, GL_TRUE, pitch, &newLayout); texture->isRenderTarget = GL_TRUE; - if ( gcmTexture->gpuAddressId != GMM_ERROR ) + if(gcmTexture->gpuAddressId != GMM_ERROR) _RGLPlatformDestroyTexture( texture ); - RGLBufferObject *gcmBuffer = ( RGLBufferObject * ) & bufferObject->platformBufferObject; + RGLBufferObject *gcmBuffer = (RGLBufferObject *)& bufferObject->platformBufferObject; gcmTexture->gpuLayout = newLayout; gcmTexture->pool = gcmBuffer->pool; @@ -4792,9 +4775,9 @@ static GLboolean _RGLPlatformTextureReference( jsTexture *texture, GLuint pitch, gcmTexture->gpuAddressIdOffset = offset; gcmTexture->gpuSize = _RGLPad( newLayout.baseHeight * newLayout.pitch, 1); - texture->revalidate &= ~( TEXTURE_REVALIDATE_LAYOUT | TEXTURE_REVALIDATE_IMAGES ); + texture->revalidate &= ~(TEXTURE_REVALIDATE_LAYOUT | TEXTURE_REVALIDATE_IMAGES); texture->revalidate |= TEXTURE_REVALIDATE_PARAMETERS; - _RGLTextureTouchFBOs( texture ); + _RGLTextureTouchFBOs(texture); return GL_TRUE; } @@ -5108,7 +5091,7 @@ static GLuint _RGLValidateStates( void ) if ( RGL_UNLIKELY( needValidate & PSGL_VALIDATE_VERTEX_TEXTURES_USED ) ) { - for ( int unit = 0; unit < _RGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++unit ) + for ( int unit = 0; unit < MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++unit ) { jsTexture *texture = LContext->VertexTextureImages[unit]; if ( texture ) @@ -5230,9 +5213,6 @@ static void _RGLResetContext( PSGLcontext *LContext ) _RGLTexNameSpaceResetNames( &LContext->framebufferNameSpace ); _RGLTexNameSpaceResetNames( &LContext->attribSetNameSpace ); - LContext->InverseModelViewValid = GL_FALSE; - LContext->ScalingFactor = 1.f; - LContext->ViewPort.X = 0; LContext->ViewPort.Y = 0; LContext->ViewPort.XSize = 0; @@ -5242,10 +5222,6 @@ static void _RGLResetContext( PSGLcontext *LContext ) LContext->ClearColor.G = 0.f; LContext->ClearColor.B = 0.f; LContext->ClearColor.A = 0.f; - LContext->AccumClearColor.R = 0.f; - LContext->AccumClearColor.G = 0.f; - LContext->AccumClearColor.B = 0.f; - LContext->AccumClearColor.A = 0.f; LContext->ShaderSRGBRemap = GL_FALSE; @@ -5264,13 +5240,13 @@ static void _RGLResetContext( PSGLcontext *LContext ) LContext->BlendFactorSrcAlpha = GL_ONE; LContext->BlendFactorDestAlpha = GL_ZERO; - for ( int i = 0;i < _RGL_MAX_TEXTURE_COORDS;++i ) + for ( int i = 0;i < MAX_TEXTURE_COORDS;++i ) { jsTextureCoordsUnit *tu = LContext->TextureCoordsUnits + i; tu->revalidate = 0; _RGLMatrixStackReset( &( tu->TextureMatrixStack ) ); } - for ( int i = 0;i < _RGL_MAX_TEXTURE_IMAGE_UNITS;++i ) + for ( int i = 0;i < MAX_TEXTURE_IMAGE_UNITS;++i ) { jsTextureImageUnit *tu = LContext->TextureImageUnits + i; tu->bound2D = 0; @@ -5285,7 +5261,7 @@ static void _RGLResetContext( PSGLcontext *LContext ) tu->currentTexture = NULL; } - for ( int i = 0;i < _RGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS;++i ) + for(int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i) LContext->VertexTextureImages[i] = NULL; LContext->ActiveTexture = 0; @@ -5400,7 +5376,7 @@ PSGLcontext* psglCreateContext (void) return NULL; } - for ( int i = 0; i < _RGL_MAX_TEXTURE_COORDS; i++ ) + for ( int i = 0; i < MAX_TEXTURE_COORDS; i++ ) { _RGLMatrixStackInit(&( LContext->TextureCoordsUnits[i].TextureMatrixStack), MAX_TEXTURE_STACK_DEPTH); if ( !LContext->TextureCoordsUnits[i].TextureMatrixStack.MatrixStackf ) @@ -5412,7 +5388,7 @@ PSGLcontext* psglCreateContext (void) _RGLTexNameSpaceInit( &LContext->textureNameSpace, ( jsTexNameSpaceCreateFunction )_RGLAllocateTexture, ( jsTexNameSpaceDestroyFunction )_RGLFreeTexture ); - for ( int i = 0;i < _RGL_MAX_TEXTURE_IMAGE_UNITS;++i ) + for ( int i = 0;i < MAX_TEXTURE_IMAGE_UNITS;++i ) { jsTextureImageUnit *tu = LContext->TextureImageUnits + i; @@ -5436,9 +5412,17 @@ PSGLcontext* psglCreateContext (void) LContext->RGLcgErrorCallbackFunction = NULL; LContext->RGLcgContextHead = ( CGcontext )NULL; - _RGLInitNameSpace( &LContext->cgProgramNameSpace ); - _RGLInitNameSpace( &LContext->cgParameterNameSpace ); - _RGLInitNameSpace( &LContext->cgContextNameSpace ); + LContext->cgProgramNameSpace.data = NULL; + LContext->cgProgramNameSpace.firstFree = NULL; + LContext->cgProgramNameSpace.capacity = 0; + + LContext->cgParameterNameSpace.data = NULL; + LContext->cgParameterNameSpace.firstFree = NULL; + LContext->cgParameterNameSpace.capacity = 0; + + LContext->cgContextNameSpace.data = NULL; + LContext->cgContextNameSpace.firstFree = NULL; + LContext->cgContextNameSpace.capacity = 0; _RGLResetContext( LContext ); @@ -5483,19 +5467,37 @@ void psglDestroyContext( PSGLcontext* LContext ) cgDestroyContext( LContext->RGLcgContextHead ); _CurrentContext = current; } - _RGLFreeNameSpace( &LContext->cgProgramNameSpace ); - _RGLFreeNameSpace( &LContext->cgParameterNameSpace ); - _RGLFreeNameSpace( &LContext->cgContextNameSpace ); + + if (LContext->cgProgramNameSpace.data) + free( LContext->cgProgramNameSpace.data ); + + LContext->cgProgramNameSpace.data = NULL; + LContext->cgProgramNameSpace.capacity = 0; + LContext->cgProgramNameSpace.firstFree = NULL; + + if (LContext->cgParameterNameSpace.data) + free( LContext->cgParameterNameSpace.data ); + + LContext->cgParameterNameSpace.data = NULL; + LContext->cgParameterNameSpace.capacity = 0; + LContext->cgParameterNameSpace.firstFree = NULL; + + if (LContext->cgContextNameSpace.data) + free( LContext->cgContextNameSpace.data ); + + LContext->cgContextNameSpace.data = NULL; + LContext->cgContextNameSpace.capacity = 0; + LContext->cgContextNameSpace.firstFree = NULL; if ( _RGLContextDestroyHook ) _RGLContextDestroyHook( LContext ); _RGLMatrixStackClear( &( LContext->ModelViewMatrixStack ) ); _RGLMatrixStackClear( &( LContext->ProjectionMatrixStack ) ); - for ( int i = 0; i < _RGL_MAX_TEXTURE_COORDS; i++ ) + for ( int i = 0; i < MAX_TEXTURE_COORDS; i++ ) _RGLMatrixStackClear( &( LContext->TextureCoordsUnits[i].TextureMatrixStack ) ); - for ( int i = 0; i < _RGL_MAX_TEXTURE_IMAGE_UNITS; ++i ) + for ( int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i ) { jsTextureImageUnit* tu = LContext->TextureImageUnits + i; if ( tu->default2D ) _RGLFreeTexture( tu->default2D ); @@ -5912,8 +5914,6 @@ GLAPI void APIENTRY glOrthof( GLfloat left, GLfloat right, GLfloat bottom, GLflo LMatrix[15] = L30 * m03 + L31 * m13 + L32 * m23 + L33; LMatrixStack->dirty = GL_TRUE; - if ( LContext->MatrixMode == GL_MODELVIEW ) - LContext->InverseModelViewValid = GL_FALSE; } GLAPI void APIENTRY glVertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid* pointer ) @@ -6255,7 +6255,7 @@ GLAPI void APIENTRY glGenTextures( GLsizei n, GLuint *textures ) static void _RGLTextureUnbind( PSGLcontext* context, GLuint name ) { int unit; - for (unit = 0; unit < _RGL_MAX_TEXTURE_IMAGE_UNITS; ++unit) + for (unit = 0; unit < MAX_TEXTURE_IMAGE_UNITS; ++unit) { jsTextureImageUnit *tu = context->TextureImageUnits + unit; GLboolean dirty = GL_FALSE; @@ -6273,7 +6273,7 @@ static void _RGLTextureUnbind( PSGLcontext* context, GLuint name ) if(_RGLTexNameSpaceIsName( &context->textureNameSpace, name)) { jsTexture*texture = ( jsTexture * )context->textureNameSpace.data[name]; - for ( unit = 0;unit < _RGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++unit ) + for ( unit = 0;unit < MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++unit ) { if ( context->VertexTextureImages[unit] == texture ) { @@ -6287,12 +6287,14 @@ static void _RGLTextureUnbind( PSGLcontext* context, GLuint name ) GLAPI void APIENTRY glDeleteTextures( GLsizei n, const GLuint *textures ) { PSGLcontext* LContext = _CurrentContext; - for ( int i = 0;i < n;++i ) - if ( textures[i] ) - _RGLTextureUnbind( LContext, textures[i] ); + + for(int i = 0;i < n; ++i) + if(textures[i]) + _RGLTextureUnbind(LContext, textures[i]); _RGLTexNameSpaceDeleteNames( &LContext->textureNameSpace, n, textures ); } + GLAPI void APIENTRY glTexParameteri( GLenum target, GLenum pname, GLint param ) { PSGLcontext* LContext = _CurrentContext; @@ -6303,8 +6305,7 @@ GLAPI void APIENTRY glTexParameteri( GLenum target, GLenum pname, GLint param ) case GL_TEXTURE_MIN_FILTER: texture->minFilter = param; if ( texture->referenceBuffer == 0 ) - { - texture->revalidate |= TEXTURE_REVALIDATE_LAYOUT; } + texture->revalidate |= TEXTURE_REVALIDATE_LAYOUT; break; case GL_TEXTURE_MAG_FILTER: texture->magFilter = param; @@ -6333,8 +6334,10 @@ GLAPI void APIENTRY glTexParameteri( GLenum target, GLenum pname, GLint param ) case GL_TEXTURE_GAMMA_REMAP_A_SCE: { GLuint bit = 1 << ( pname - GL_TEXTURE_GAMMA_REMAP_R_SCE ); - if ( param ) texture->gammaRemap |= bit; - else texture->gammaRemap &= ~bit; + if(param) + texture->gammaRemap |= bit; + else + texture->gammaRemap &= ~bit; } break; default: @@ -6372,22 +6375,6 @@ static void _RGLReallocateImages( jsTexture *texture, GLsizei dimension ) texture->imageCount = n; } -static int _RGLGetImage( GLenum target, GLint level, jsTexture **texture, jsImage **image, GLsizei reallocateSize ) -{ - PSGLcontext* LContext = _CurrentContext; - jsTextureImageUnit *unit = LContext->CurrentImageUnit; - - jsTexture *tex = _RGLGetCurrentTexture( unit, GL_TEXTURE_2D ); - - if ( level >= ( int )tex->imageCount ) - _RGLReallocateImages( tex, reallocateSize ); - - *image = tex->image; - *texture = tex; - return 0; -} - - GLAPI void APIENTRY glTexImage2D( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels ) { @@ -6395,7 +6382,15 @@ GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const G jsTexture *texture; jsImage *image; - _RGLGetImage( GL_TEXTURE_2D, 0, &texture, &image, MAX( width, height ) ); + jsTextureImageUnit *unit = LContext->CurrentImageUnit; + + jsTexture *tex = _RGLGetCurrentTexture(unit, GL_TEXTURE_2D); + + if(0 >= (int)tex->imageCount) + _RGLReallocateImages(tex, MAX(width, height)); + + image = tex->image; + texture = tex; image->dataState = IMAGE_DATASTATE_UNSET; @@ -6463,8 +6458,8 @@ GLAPI void APIENTRY glActiveTexture(GLenum texture) int unit = texture - GL_TEXTURE0; LContext->ActiveTexture = unit; - LContext->CurrentImageUnit = unit < _RGL_MAX_TEXTURE_IMAGE_UNITS ? LContext->TextureImageUnits + unit : NULL; - LContext->CurrentCoordsUnit = unit < _RGL_MAX_TEXTURE_COORDS ? LContext->TextureCoordsUnits + unit : NULL; + LContext->CurrentImageUnit = unit < MAX_TEXTURE_IMAGE_UNITS ? LContext->TextureImageUnits + unit : NULL; + LContext->CurrentCoordsUnit = unit < MAX_TEXTURE_COORDS ? LContext->TextureCoordsUnits + unit : NULL; } GLAPI void APIENTRY glClientActiveTexture(GLenum texture) diff --git a/console/rgl/ps3/rgl.h b/console/rgl/ps3/rgl.h index 09a909e97d..0fb0a4d9e6 100644 --- a/console/rgl/ps3/rgl.h +++ b/console/rgl/ps3/rgl.h @@ -261,9 +261,9 @@ typedef struct } jsTexture; -#define _RGL_MAX_TEXTURE_COORDS 8 -#define _RGL_MAX_TEXTURE_IMAGE_UNITS 16 -#define _RGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 4 +#define MAX_TEXTURE_COORDS 8 +#define MAX_TEXTURE_IMAGE_UNITS 16 +#define MAX_VERTEX_TEXTURE_IMAGE_UNITS 4 #define MAX_TEXTURE_UNITS 4 @@ -491,10 +491,6 @@ struct PSGLcontext int MatrixMode; jsMatrixStack ModelViewMatrixStack; jsMatrixStack ProjectionMatrixStack; - GLfloat LocalToScreenMatrixf[ELEMENTS_IN_MATRIX]; - GLfloat InverseModelViewMatrixf[ELEMENTS_IN_MATRIX]; - GLboolean InverseModelViewValid; - GLfloat ScalingFactor; jsViewPort ViewPort; jsAttributeState defaultAttribs0; jsAttributeState *attribs; @@ -502,7 +498,6 @@ struct PSGLcontext GLuint attribSetName; GLboolean attribSetDirty; jsColorRGBAf ClearColor; - jsColorRGBAf AccumClearColor; GLboolean ShaderSRGBRemap; GLboolean Blending; GLboolean BlendingMrt[3]; @@ -516,11 +511,11 @@ struct PSGLcontext jsTexNameSpace textureNameSpace; GLuint ActiveTexture; GLuint CS_ActiveTexture; - jsTextureImageUnit TextureImageUnits[_RGL_MAX_TEXTURE_IMAGE_UNITS]; + jsTextureImageUnit TextureImageUnits[MAX_TEXTURE_IMAGE_UNITS]; jsTextureImageUnit* CurrentImageUnit; - jsTextureCoordsUnit TextureCoordsUnits[_RGL_MAX_TEXTURE_COORDS]; + jsTextureCoordsUnit TextureCoordsUnits[MAX_TEXTURE_COORDS]; jsTextureCoordsUnit* CurrentCoordsUnit; - jsTexture *VertexTextureImages[_RGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + jsTexture *VertexTextureImages[MAX_VERTEX_TEXTURE_IMAGE_UNITS]; GLsizei packAlignment; GLsizei unpackAlignment; jsTexNameSpace bufferObjectNameSpace; @@ -585,8 +580,6 @@ typedef struct MemoryBlockManager_t_ typedef unsigned long jsName; -void _RGLInitNameSpace( struct jsNameSpace * name ); -void _RGLFreeNameSpace( struct jsNameSpace * name ); jsName _RGLCreateName( struct jsNameSpace * ns, void* object ); unsigned int _RGLIsName( struct jsNameSpace* ns, jsName name ); void _RGLEraseName( struct jsNameSpace* ns, jsName name ); From cc52ee9754f9c4e64a00e983b66a81075b8ad940 Mon Sep 17 00:00:00 2001 From: Toad King Date: Mon, 6 Aug 2012 13:35:14 -0400 Subject: [PATCH 073/492] (Wii) forward arguments to loaded DOL files, fixes paths --- console/exec/dol.c | 28 +++++++++++++++++++++------- console/exec/dol.h | 6 ++---- console/rarch_console_exec.c | 11 ++++++++--- wii/salamander/main.c | 16 ++++++++-------- 4 files changed, 39 insertions(+), 22 deletions(-) diff --git a/console/exec/dol.c b/console/exec/dol.c index 280bade59f..343cf218fa 100644 --- a/console/exec/dol.c +++ b/console/exec/dol.c @@ -5,6 +5,7 @@ #include #include +#include #include #include "../../retroarch_logger.h" @@ -22,7 +23,9 @@ typedef struct _dolheader uint32_t entry_point; } dolheader; -uint32_t load_dol_image (void *dolstart) +static char dol_argv_commandline[1024]; + +uint32_t *load_dol_image (void *dolstart) { uint32_t i; dolheader *dolfile; @@ -35,7 +38,7 @@ uint32_t load_dol_image (void *dolstart) if ((!dolfile->text_size[i]) || (dolfile->text_start[i] < 0x100)) continue; - RARCH_LOG("loading text section %u @ 0x%08x (0x%08x bytes)\n", + RARCH_LOG("loading text section %u @ 0x%08x (0x%08x bytes)\n", i, dolfile->text_start[i], dolfile->text_size[i]); ICInvalidateRange ((void *) dolfile->text_start[i], @@ -50,13 +53,13 @@ uint32_t load_dol_image (void *dolstart) if ((!dolfile->data_size[i]) || (dolfile->data_start[i] < 0x100)) continue; - RARCH_LOG("loading data section %u @ 0x%08x (0x%08x bytes)\n", i, + RARCH_LOG("loading data section %u @ 0x%08x (0x%08x bytes)\n", i, dolfile->data_start[i], dolfile->data_size[i]); - memmove ((void*) dolfile->data_start[i], dolstart+dolfile->data_pos[i], + memmove ((void*) dolfile->data_start[i], dolstart+dolfile->data_pos[i], dolfile->data_size[i]); - DCFlushRangeNoSync ((void *) dolfile->data_start[i], dolfile->data_size[i]); + DCFlushRangeNoSync ((void *) dolfile->data_start[i], dolfile->data_size[i]); } RARCH_LOG("clearing bss\n"); @@ -64,9 +67,20 @@ uint32_t load_dol_image (void *dolstart) memset ((void *) dolfile->bss_start, 0, dolfile->bss_size); DCFlushRange((void *) dolfile->bss_start, dolfile->bss_size); - return dolfile->entry_point; + return (uint32_t *) dolfile->entry_point; } - return 0; + return NULL; } +// NOTE: this does not update the path to point to the new loading .dol file. +// we only ues it for keeping the current path anyway. +void dol_copy_argv(struct __argv *argv) +{ + memcpy(dol_argv_commandline, __system_argv->commandLine, __system_argv->length); + DCFlushRange((void *) dol_argv_commandline, sizeof(dol_argv_commandline)); + argv->argvMagic = ARGV_MAGIC; + argv->commandLine = dol_argv_commandline; + argv->length = __system_argv->length; + DCFlushRange((void *) argv, sizeof(struct __argv)); +} diff --git a/console/exec/dol.h b/console/exec/dol.h index f686bc4138..ca21b56d77 100644 --- a/console/exec/dol.h +++ b/console/exec/dol.h @@ -24,10 +24,8 @@ #include -uint32_t load_dol_image (void *dolstart); - -extern void __exception_closeall(void); -extern int32_t __IOS_ShutdownSubSystems(void); +uint32_t *load_dol_image (void *dolstart); +void dol_copy_argv(struct __argv *argv); #endif diff --git a/console/rarch_console_exec.c b/console/rarch_console_exec.c index e863808ede..29b94fdbbe 100644 --- a/console/rarch_console_exec.c +++ b/console/rarch_console_exec.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "exec/dol.h" #endif @@ -87,12 +88,16 @@ void rarch_console_exec(const char *path) #endif fatUnmount("carda:"); fatUnmount("cardb:"); - void (*ep)() = (void(*)())load_dol_image(mem); - RARCH_LOG("jumping to 0x%08X\n", (uint32_t)ep); + uint32_t *ep = load_dol_image(mem); + + if (ep[1] == ARGV_MAGIC) + dol_copy_argv((struct __argv *) &ep[2]); + + RARCH_LOG("jumping to 0x%08X\n", (uint32_t) ep); SYS_ResetSystem(SYS_SHUTDOWN,0,0); - __lwp_thread_stopmultitasking(ep); + __lwp_thread_stopmultitasking((void(*)()) ep); #else RARCH_WARN("External loading of executables is not supported for this platform.\n"); #endif diff --git a/wii/salamander/main.c b/wii/salamander/main.c index b24187fdd8..262904199b 100644 --- a/wii/salamander/main.c +++ b/wii/salamander/main.c @@ -48,11 +48,11 @@ static void find_and_set_first_file(void) //Last fallback - we'll need to start the first executable file // we can find in the RetroArch cores directory - char first_file[512]; + char first_file[512] = {0}; rarch_manage_libretro_set_first_file(first_file, sizeof(first_file), LIBRETRO_DIR_PATH, "dol"); - if(first_file) + if(first_file[0]) strlcpy(libretro_path, first_file, sizeof(libretro_path)); else RARCH_ERR("Failed last fallback - RetroArch Salamander will exit.\n"); @@ -89,8 +89,8 @@ static void init_settings(void) if(config_file_exists) { config_file_t * conf = config_file_new(SYS_CONFIG_FILE); - config_get_array(conf, "libretro_path", tmp_str, sizeof(tmp_str)); - snprintf(libretro_path, sizeof(libretro_path), tmp_str); + config_get_array(conf, "libretro_path", tmp_str, sizeof(tmp_str)); + snprintf(libretro_path, sizeof(libretro_path), tmp_str); } if(!config_file_exists || !strcmp(libretro_path, "")) @@ -111,14 +111,14 @@ static void get_environment_settings(void) int main(int argc, char *argv[]) { -#ifdef HAVE_LOGGER - logger_init(); -#endif - #ifdef HW_RVL L2Enhance(); #endif +#ifdef HAVE_LOGGER + logger_init(); +#endif + fatInitDefault(); getcwd(app_dir, sizeof(app_dir)); From b64207a8aafc8facb0120a3be1db1114e2afb061 Mon Sep 17 00:00:00 2001 From: Toad King Date: Mon, 6 Aug 2012 15:12:59 -0400 Subject: [PATCH 074/492] Do not open config files on console in append mode --- conf/config_file.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/conf/config_file.c b/conf/config_file.c index 0edf06e309..ff008f9c98 100644 --- a/conf/config_file.c +++ b/conf/config_file.c @@ -329,13 +329,7 @@ static config_file_t *config_file_new_internal(const char *path, unsigned depth) } conf->include_depth = depth; - -#ifdef RARCH_CONSOLE - // This will create the file if it doesn't exist, and start reading at beginning. - FILE *file = fopen(path, "a+"); -#else - FILE *file = fopen(path, "r"); -#endif + FILE *file = fopen(path, "r+"); if (!file) { From c53f9ff9827d01ee00ef94e77c270132164f6907 Mon Sep 17 00:00:00 2001 From: Toad King Date: Mon, 6 Aug 2012 15:13:37 -0400 Subject: [PATCH 075/492] (Wii) config file changes (Consoles) save audio rate control --- console/rarch_console_config.c | 4 ++++ wii/frontend/main.c | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/console/rarch_console_config.c b/console/rarch_console_config.c index 1c303ac7c5..e05768e75c 100644 --- a/console/rarch_console_config.c +++ b/console/rarch_console_config.c @@ -67,6 +67,8 @@ void rarch_config_load(const char * conf_name, const char * libretro_dir_path, c CONFIG_GET_BOOL(video.vsync, "video_vsync"); CONFIG_GET_FLOAT(video.aspect_ratio, "video_aspect_ratio"); CONFIG_GET_STRING(audio.device, "audio_device"); + CONFIG_GET_BOOL(audio.rate_control, "audio_rate_control"); + CONFIG_GET_FLOAT(audio.rate_control_delta, "audio_rate_control_delta"); for (unsigned i = 0; i < 7; i++) { @@ -133,6 +135,8 @@ void rarch_config_save(const char * conf_name) config_set_bool(conf, "video_smooth", g_settings.video.smooth); config_set_bool(conf, "video_vsync", g_settings.video.vsync); config_set_string(conf, "audio_device", g_settings.audio.device); + config_set_bool(conf, "audio_rate_control", g_settings.audio.rate_control); + config_set_float(conf, "audio_rate_control_delta", g_settings.audio.rate_control_delta); for (unsigned i = 0; i < 7; i++) { diff --git a/wii/frontend/main.c b/wii/frontend/main.c index 2d5c8e1228..f615d089bb 100644 --- a/wii/frontend/main.c +++ b/wii/frontend/main.c @@ -242,10 +242,6 @@ int main(void) retro_get_system_info(&wii_core_info); RARCH_LOG("Core: %s\n", wii_core_info.library_name); - g_settings.audio.rate_control = true; - g_settings.audio.rate_control_delta = 0.006; - g_console.block_config_read = true; - wii_video_init(); const char *extension = default_paths.executable_extension; From 0b47c01ef5377c1bf2ca8ecddfd9005cb80e1d31 Mon Sep 17 00:00:00 2001 From: Toad King Date: Mon, 6 Aug 2012 15:24:17 -0400 Subject: [PATCH 076/492] (Wii) change default values for audio rate control --- config.def.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/config.def.h b/config.def.h index 5d8caa6afe..e9f1b38f32 100644 --- a/config.def.h +++ b/config.def.h @@ -247,10 +247,18 @@ static const int out_latency = 64; static const bool audio_sync = true; // Experimental rate control +#ifdef GEKKO +static const bool rate_control = true; +#else static const bool rate_control = false; +#endif // Rate control delta. Defines how much rate_control is allowed to adjust input rate. +#ifdef GEKKO +static const float rate_control_delta = 0.006; +#else static const float rate_control_delta = 0.005; +#endif ////////////// // Misc From ca82b46a3c87c537871a91542bc780b1c89b1093 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 6 Aug 2012 21:32:06 +0200 Subject: [PATCH 077/492] (Wii) CORE.dol file is now renamed to sane filename - libretro management code seems to be more or less up and running now --- Makefile.wii | 2 +- wii/frontend/main.c | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Makefile.wii b/Makefile.wii index e8d636d264..44208a10c4 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -39,7 +39,7 @@ CFLAGS += -DHAVE_FILE_LOGGER CFLAGS += -Iconsole/logger endif -CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_RGUI -DRARCH_CONSOLE -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"0.9.6\" -Dmain=rarch_main -Wno-char-subscripts +CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_RGUI -DRARCH_CONSOLE -DHAVE_LIBRETRO_MANAGEMENT -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"0.9.6\" -Dmain=rarch_main -Wno-char-subscripts ifeq ($(DEBUG), 1) CFLAGS += -O0 -g diff --git a/wii/frontend/main.c b/wii/frontend/main.c index f615d089bb..35d21140e5 100644 --- a/wii/frontend/main.c +++ b/wii/frontend/main.c @@ -205,7 +205,7 @@ extern uint8_t _binary_console_font_bmp_start[]; static void get_environment_settings(void) { getcwd(default_paths.port_dir, MAXPATHLEN); - snprintf(default_paths.core_dir, sizeof(default_paths.core_dir), "%scores", default_paths.port_dir); + snprintf(default_paths.core_dir, sizeof(default_paths.core_dir), default_paths.port_dir); snprintf(default_paths.config_file, sizeof(default_paths.config_file), "%sretroarch.cfg", default_paths.port_dir); snprintf(default_paths.system_dir, sizeof(default_paths.system_dir), "%s/system", default_paths.core_dir); snprintf(default_paths.savestate_dir, sizeof(default_paths.savestate_dir), "%s/savestates", default_paths.core_dir); @@ -244,10 +244,19 @@ int main(void) wii_video_init(); + char tmp_path[PATH_MAX]; const char *extension = default_paths.executable_extension; + snprintf(tmp_path, sizeof(tmp_path), default_paths.core_dir); + const char *path_prefix = tmp_path; + + char full_path[1024]; + snprintf(full_path, sizeof(full_path), "%sCORE%s", path_prefix, extension); + + bool find_libretro_file = rarch_configure_libretro_core(full_path, path_prefix, path_prefix, + default_paths.config_file, extension); rarch_settings_set_default(&input_wii); - rarch_config_load(default_paths.config_file, /* path_prefix */ NULL, extension, /* find_libretro_file */ false); + rarch_config_load(default_paths.config_file, path_prefix, extension, find_libretro_file); init_libretro_sym(); input_wii.post_init(); From f2343569bcaec198d4da21f4281870c6e00f7586 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 6 Aug 2012 21:44:25 +0200 Subject: [PATCH 078/492] Add rarch_settings_set_default - default rate control/enable for GEKKO --- console/rarch_console_settings.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/console/rarch_console_settings.c b/console/rarch_console_settings.c index d49e28b0e3..214cf7b5ef 100644 --- a/console/rarch_console_settings.c +++ b/console/rarch_console_settings.c @@ -331,6 +331,11 @@ void rarch_settings_set_default (const input_driver_t *input) g_settings.video.fbo_scale_y = 2.0f; #endif +#ifdef GEKKO + g_settings.audio.rate_control_delta = 0.006; + g_settings.audio.rate_control = true; +#endif + g_settings.video.render_to_texture = true; g_settings.video.smooth = true; g_settings.video.vsync = true; From 61d5977054b4ddef34b3b9d60931f2857defd968 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 6 Aug 2012 22:00:35 +0200 Subject: [PATCH 079/492] (Wii) Change WII_ prefixes to GX_ --- wii/frontend/main.c | 58 +++--- wii/gx_input.c | 464 ++++++++++++++++++++++---------------------- wii/gx_input.h | 294 ++++++++++++++-------------- 3 files changed, 411 insertions(+), 405 deletions(-) diff --git a/wii/frontend/main.c b/wii/frontend/main.c index 35d21140e5..19588b01f7 100644 --- a/wii/frontend/main.c +++ b/wii/frontend/main.c @@ -50,15 +50,15 @@ char app_dir[PATH_MAX]; struct retro_system_info wii_core_info; static const struct retro_keybind _wii_nav_binds[] = { - { 0, 0, 0, WII_GC_UP | WII_GC_LSTICK_UP | WII_GC_RSTICK_UP | WII_CLASSIC_UP | WII_CLASSIC_LSTICK_UP | WII_CLASSIC_RSTICK_UP | WII_WIIMOTE_UP | WII_NUNCHUK_UP, 0 }, - { 0, 0, 0, WII_GC_DOWN | WII_GC_LSTICK_DOWN | WII_GC_RSTICK_DOWN | WII_CLASSIC_DOWN | WII_CLASSIC_LSTICK_DOWN | WII_CLASSIC_RSTICK_DOWN | WII_WIIMOTE_DOWN | WII_NUNCHUK_DOWN, 0 }, - { 0, 0, 0, WII_GC_LEFT | WII_GC_LSTICK_LEFT | WII_GC_RSTICK_LEFT | WII_CLASSIC_LEFT | WII_CLASSIC_LSTICK_LEFT | WII_CLASSIC_RSTICK_LEFT | WII_WIIMOTE_LEFT | WII_NUNCHUK_LEFT, 0 }, - { 0, 0, 0, WII_GC_RIGHT | WII_GC_LSTICK_RIGHT | WII_GC_RSTICK_RIGHT | WII_CLASSIC_RIGHT | WII_CLASSIC_LSTICK_RIGHT | WII_CLASSIC_RSTICK_RIGHT | WII_WIIMOTE_RIGHT | WII_NUNCHUK_RIGHT, 0 }, - { 0, 0, 0, WII_GC_A | WII_CLASSIC_A | WII_WIIMOTE_A | WII_WIIMOTE_2, 0 }, - { 0, 0, 0, WII_GC_B | WII_CLASSIC_B | WII_WIIMOTE_B | WII_WIIMOTE_1, 0 }, - { 0, 0, 0, WII_GC_START | WII_CLASSIC_PLUS | WII_WIIMOTE_PLUS, 0 }, - { 0, 0, 0, WII_GC_Z_TRIGGER | WII_CLASSIC_MINUS | WII_WIIMOTE_MINUS, 0 }, - { 0, 0, 0, WII_WIIMOTE_HOME | WII_CLASSIC_HOME, 0 }, + { 0, 0, 0, GX_GC_UP | GX_GC_LSTICK_UP | GX_GC_RSTICK_UP | GX_CLASSIC_UP | GX_CLASSIC_LSTICK_UP | GX_CLASSIC_RSTICK_UP | GX_WIIMOTE_UP | GX_NUNCHUK_UP, 0 }, + { 0, 0, 0, GX_GC_DOWN | GX_GC_LSTICK_DOWN | GX_GC_RSTICK_DOWN | GX_CLASSIC_DOWN | GX_CLASSIC_LSTICK_DOWN | GX_CLASSIC_RSTICK_DOWN | GX_WIIMOTE_DOWN | GX_NUNCHUK_DOWN, 0 }, + { 0, 0, 0, GX_GC_LEFT | GX_GC_LSTICK_LEFT | GX_GC_RSTICK_LEFT | GX_CLASSIC_LEFT | GX_CLASSIC_LSTICK_LEFT | GX_CLASSIC_RSTICK_LEFT | GX_WIIMOTE_LEFT | GX_NUNCHUK_LEFT, 0 }, + { 0, 0, 0, GX_GC_RIGHT | GX_GC_LSTICK_RIGHT | GX_GC_RSTICK_RIGHT | GX_CLASSIC_RIGHT | GX_CLASSIC_LSTICK_RIGHT | GX_CLASSIC_RSTICK_RIGHT | GX_WIIMOTE_RIGHT | GX_NUNCHUK_RIGHT, 0 }, + { 0, 0, 0, GX_GC_A | GX_CLASSIC_A | GX_WIIMOTE_A | GX_WIIMOTE_2, 0 }, + { 0, 0, 0, GX_GC_B | GX_CLASSIC_B | GX_WIIMOTE_B | GX_WIIMOTE_1, 0 }, + { 0, 0, 0, GX_GC_START | GX_CLASSIC_PLUS | GX_WIIMOTE_PLUS, 0 }, + { 0, 0, 0, GX_GC_Z_TRIGGER | GX_CLASSIC_MINUS | GX_WIIMOTE_MINUS, 0 }, + { 0, 0, 0, GX_WIIMOTE_HOME | GX_CLASSIC_HOME, 0 }, }; static const struct retro_keybind *wii_nav_binds[] = { @@ -67,16 +67,16 @@ static const struct retro_keybind *wii_nav_binds[] = { enum { - WII_DEVICE_NAV_UP = 0, - WII_DEVICE_NAV_DOWN, - WII_DEVICE_NAV_LEFT, - WII_DEVICE_NAV_RIGHT, - WII_DEVICE_NAV_A, - WII_DEVICE_NAV_B, - WII_DEVICE_NAV_START, - WII_DEVICE_NAV_SELECT, - WII_DEVICE_NAV_EXIT, - WII_DEVICE_NAV_LAST + GX_DEVICE_NAV_UP = 0, + GX_DEVICE_NAV_DOWN, + GX_DEVICE_NAV_LEFT, + GX_DEVICE_NAV_RIGHT, + GX_DEVICE_NAV_A, + GX_DEVICE_NAV_B, + GX_DEVICE_NAV_START, + GX_DEVICE_NAV_SELECT, + GX_DEVICE_NAV_EXIT, + GX_DEVICE_NAV_LAST }; static bool folder_cb(const char *directory, rgui_file_enum_cb_t file_cb, @@ -138,7 +138,7 @@ static bool get_rom_path(rgui_handle_t *rgui) input_wii.poll(NULL); - for (unsigned i = 0; i < WII_DEVICE_NAV_LAST; i++) + for (unsigned i = 0; i < GX_DEVICE_NAV_LAST; i++) { input_state |= input_wii.input_state(NULL, wii_nav_binds, 0, RETRO_DEVICE_JOYPAD, 0, i) ? (1 << i) : 0; @@ -150,7 +150,7 @@ static bool get_rom_path(rgui_handle_t *rgui) // don't run anything first frame, only capture held inputs for old_input_state if (!first) { - if (trigger_state & (1 << WII_DEVICE_NAV_EXIT)) + if (trigger_state & (1 << GX_DEVICE_NAV_EXIT)) { if (can_quit) return false; @@ -158,21 +158,21 @@ static bool get_rom_path(rgui_handle_t *rgui) else can_quit = true; - if (trigger_state & (1 << WII_DEVICE_NAV_B)) + if (trigger_state & (1 << GX_DEVICE_NAV_B)) action = RGUI_ACTION_CANCEL; - else if (trigger_state & (1 << WII_DEVICE_NAV_A)) + else if (trigger_state & (1 << GX_DEVICE_NAV_A)) action = RGUI_ACTION_OK; - else if (trigger_state & (1 << WII_DEVICE_NAV_UP)) + else if (trigger_state & (1 << GX_DEVICE_NAV_UP)) action = RGUI_ACTION_UP; - else if (trigger_state & (1 << WII_DEVICE_NAV_DOWN)) + else if (trigger_state & (1 << GX_DEVICE_NAV_DOWN)) action = RGUI_ACTION_DOWN; - else if (trigger_state & (1 << WII_DEVICE_NAV_LEFT)) + else if (trigger_state & (1 << GX_DEVICE_NAV_LEFT)) action = RGUI_ACTION_LEFT; - else if (trigger_state & (1 << WII_DEVICE_NAV_RIGHT)) + else if (trigger_state & (1 << GX_DEVICE_NAV_RIGHT)) action = RGUI_ACTION_RIGHT; - else if (trigger_state & (1 << WII_DEVICE_NAV_START)) + else if (trigger_state & (1 << GX_DEVICE_NAV_START)) action = RGUI_ACTION_START; - else if (trigger_state & (1 << WII_DEVICE_NAV_SELECT)) + else if (trigger_state & (1 << GX_DEVICE_NAV_SELECT)) action = RGUI_ACTION_SETTINGS; } else diff --git a/wii/gx_input.c b/wii/gx_input.c index 77d6560f7d..65bb1ab581 100644 --- a/wii/gx_input.c +++ b/wii/gx_input.c @@ -40,91 +40,91 @@ static uint64_t pad_state[MAX_PADS]; const struct platform_bind platform_keys[] = { - { WII_GC_A, "GC A button" }, - { WII_GC_B, "GC B button" }, - { WII_GC_X, "GC X button" }, - { WII_GC_Y, "GC Y button" }, - { WII_GC_UP, "GC D-Pad Up" }, - { WII_GC_DOWN, "GC D-Pad Down" }, - { WII_GC_LEFT, "GC D-Pad Left" }, - { WII_GC_RIGHT, "GC D-Pad Right" }, - { WII_GC_Z_TRIGGER, "GC Z Trigger" }, - { WII_GC_START, "GC Start button" }, - { WII_GC_L_TRIGGER, "GC Left Trigger" }, - { WII_GC_R_TRIGGER, "GC Right Trigger" }, - { WII_GC_LSTICK_LEFT, "GC Main Stick Left" }, - { WII_GC_LSTICK_RIGHT, "GC Main Stick Right" }, - { WII_GC_LSTICK_UP, "GC Main Stick Up" }, - { WII_GC_LSTICK_DOWN, "GC Main Stick Down" }, - { WII_GC_LSTICK_LEFT | WII_GC_LEFT, "GC Main Stick D-Pad Left" }, - { WII_GC_LSTICK_RIGHT | WII_GC_RIGHT, "GC Main Stick D-Pad Right" }, - { WII_GC_LSTICK_UP | WII_GC_UP, "GC Main Stick D-Pad Up" }, - { WII_GC_LSTICK_DOWN | WII_GC_DOWN, "GC Main Stick D-Pad Down" }, - { WII_GC_RSTICK_LEFT, "GC C-Stick Left" }, - { WII_GC_RSTICK_RIGHT, "GC C-Stick Right" }, - { WII_GC_RSTICK_UP, "GC C-Stick Up" }, - { WII_GC_RSTICK_DOWN, "GC C-Stick Down" }, - { WII_GC_RSTICK_LEFT | WII_GC_LEFT, "GC C-Stick D-Pad Left" }, - { WII_GC_RSTICK_RIGHT | WII_GC_RIGHT, "GC C-Stick D-Pad Right" }, - { WII_GC_RSTICK_UP | WII_GC_UP, "GC C-Stick D-Pad Up" }, - { WII_GC_RSTICK_DOWN | WII_GC_DOWN, "GC C-Stick D-Pad Down" }, + { GX_GC_A, "GC A button" }, + { GX_GC_B, "GC B button" }, + { GX_GC_X, "GC X button" }, + { GX_GC_Y, "GC Y button" }, + { GX_GC_UP, "GC D-Pad Up" }, + { GX_GC_DOWN, "GC D-Pad Down" }, + { GX_GC_LEFT, "GC D-Pad Left" }, + { GX_GC_RIGHT, "GC D-Pad Right" }, + { GX_GC_Z_TRIGGER, "GC Z Trigger" }, + { GX_GC_START, "GC Start button" }, + { GX_GC_L_TRIGGER, "GC Left Trigger" }, + { GX_GC_R_TRIGGER, "GC Right Trigger" }, + { GX_GC_LSTICK_LEFT, "GC Main Stick Left" }, + { GX_GC_LSTICK_RIGHT, "GC Main Stick Right" }, + { GX_GC_LSTICK_UP, "GC Main Stick Up" }, + { GX_GC_LSTICK_DOWN, "GC Main Stick Down" }, + { GX_GC_LSTICK_LEFT | GX_GC_LEFT, "GC Main Stick D-Pad Left" }, + { GX_GC_LSTICK_RIGHT | GX_GC_RIGHT, "GC Main Stick D-Pad Right" }, + { GX_GC_LSTICK_UP | GX_GC_UP, "GC Main Stick D-Pad Up" }, + { GX_GC_LSTICK_DOWN | GX_GC_DOWN, "GC Main Stick D-Pad Down" }, + { GX_GC_RSTICK_LEFT, "GC C-Stick Left" }, + { GX_GC_RSTICK_RIGHT, "GC C-Stick Right" }, + { GX_GC_RSTICK_UP, "GC C-Stick Up" }, + { GX_GC_RSTICK_DOWN, "GC C-Stick Down" }, + { GX_GC_RSTICK_LEFT | GX_GC_LEFT, "GC C-Stick D-Pad Left" }, + { GX_GC_RSTICK_RIGHT | GX_GC_RIGHT, "GC C-Stick D-Pad Right" }, + { GX_GC_RSTICK_UP | GX_GC_UP, "GC C-Stick D-Pad Up" }, + { GX_GC_RSTICK_DOWN | GX_GC_DOWN, "GC C-Stick D-Pad Down" }, #ifdef HW_RVL // CLASSIC CONTROLLER - { WII_CLASSIC_A, "Classic A button" }, - { WII_CLASSIC_B, "Classic B button" }, - { WII_CLASSIC_X, "Classic X button" }, - { WII_CLASSIC_Y, "Classic Y button" }, - { WII_CLASSIC_UP, "Classic D-Pad Up" }, - { WII_CLASSIC_DOWN, "Classic D-Pad Down" }, - { WII_CLASSIC_LEFT, "Classic D-Pad Left" }, - { WII_CLASSIC_RIGHT, "Classic D-Pad Right" }, - { WII_CLASSIC_PLUS, "Classic Plus button" }, - { WII_CLASSIC_MINUS, "Classic Minus button" }, - { WII_CLASSIC_HOME, "Classic Home button" }, - { WII_CLASSIC_L_TRIGGER, "Classic L Trigger" }, - { WII_CLASSIC_R_TRIGGER, "Classic R Trigger" }, - { WII_CLASSIC_ZL_TRIGGER, "Classic ZL Trigger" }, - { WII_CLASSIC_ZR_TRIGGER, "Classic ZR Trigger" }, - { WII_CLASSIC_LSTICK_LEFT, "Classic LStick Left" }, - { WII_CLASSIC_LSTICK_RIGHT, "Classic LStick Right" }, - { WII_CLASSIC_LSTICK_UP, "Classic LStick Up" }, - { WII_CLASSIC_LSTICK_DOWN, "Classic LStick Down" }, - { WII_CLASSIC_LSTICK_LEFT | WII_CLASSIC_LEFT, "Classic LStick D-Pad Left" }, - { WII_CLASSIC_LSTICK_RIGHT | WII_CLASSIC_RIGHT, "Classic LStick D-Pad Right" }, - { WII_CLASSIC_LSTICK_UP | WII_CLASSIC_UP, "Classic LStick D-Pad Up" }, - { WII_CLASSIC_LSTICK_DOWN | WII_CLASSIC_DOWN, "Classic LStick D-Pad Down" }, - { WII_CLASSIC_RSTICK_LEFT, "Classic RStick Left" }, - { WII_CLASSIC_RSTICK_RIGHT, "Classic RStick Right" }, - { WII_CLASSIC_RSTICK_UP, "Classic RStick Up" }, - { WII_CLASSIC_RSTICK_DOWN, "Classic RStick Down" }, - { WII_CLASSIC_RSTICK_LEFT | WII_CLASSIC_LEFT, "Classic RStick D-Pad Left" }, - { WII_CLASSIC_RSTICK_RIGHT | WII_CLASSIC_RIGHT, "Classic RStick D-Pad Right" }, - { WII_CLASSIC_RSTICK_UP | WII_CLASSIC_UP, "Classic RStick D-Pad Up" }, - { WII_CLASSIC_RSTICK_DOWN | WII_CLASSIC_DOWN, "Classic RStick D-Pad Down" }, + { GX_CLASSIC_A, "Classic A button" }, + { GX_CLASSIC_B, "Classic B button" }, + { GX_CLASSIC_X, "Classic X button" }, + { GX_CLASSIC_Y, "Classic Y button" }, + { GX_CLASSIC_UP, "Classic D-Pad Up" }, + { GX_CLASSIC_DOWN, "Classic D-Pad Down" }, + { GX_CLASSIC_LEFT, "Classic D-Pad Left" }, + { GX_CLASSIC_RIGHT, "Classic D-Pad Right" }, + { GX_CLASSIC_PLUS, "Classic Plus button" }, + { GX_CLASSIC_MINUS, "Classic Minus button" }, + { GX_CLASSIC_HOME, "Classic Home button" }, + { GX_CLASSIC_L_TRIGGER, "Classic L Trigger" }, + { GX_CLASSIC_R_TRIGGER, "Classic R Trigger" }, + { GX_CLASSIC_ZL_TRIGGER, "Classic ZL Trigger" }, + { GX_CLASSIC_ZR_TRIGGER, "Classic ZR Trigger" }, + { GX_CLASSIC_LSTICK_LEFT, "Classic LStick Left" }, + { GX_CLASSIC_LSTICK_RIGHT, "Classic LStick Right" }, + { GX_CLASSIC_LSTICK_UP, "Classic LStick Up" }, + { GX_CLASSIC_LSTICK_DOWN, "Classic LStick Down" }, + { GX_CLASSIC_LSTICK_LEFT | GX_CLASSIC_LEFT, "Classic LStick D-Pad Left" }, + { GX_CLASSIC_LSTICK_RIGHT | GX_CLASSIC_RIGHT, "Classic LStick D-Pad Right" }, + { GX_CLASSIC_LSTICK_UP | GX_CLASSIC_UP, "Classic LStick D-Pad Up" }, + { GX_CLASSIC_LSTICK_DOWN | GX_CLASSIC_DOWN, "Classic LStick D-Pad Down" }, + { GX_CLASSIC_RSTICK_LEFT, "Classic RStick Left" }, + { GX_CLASSIC_RSTICK_RIGHT, "Classic RStick Right" }, + { GX_CLASSIC_RSTICK_UP, "Classic RStick Up" }, + { GX_CLASSIC_RSTICK_DOWN, "Classic RStick Down" }, + { GX_CLASSIC_RSTICK_LEFT | GX_CLASSIC_LEFT, "Classic RStick D-Pad Left" }, + { GX_CLASSIC_RSTICK_RIGHT | GX_CLASSIC_RIGHT, "Classic RStick D-Pad Right" }, + { GX_CLASSIC_RSTICK_UP | GX_CLASSIC_UP, "Classic RStick D-Pad Up" }, + { GX_CLASSIC_RSTICK_DOWN | GX_CLASSIC_DOWN, "Classic RStick D-Pad Down" }, // WIIMOTE (PLUS OPTIONAL NUNCHUK) - { WII_WIIMOTE_A, "Wiimote A button" }, - { WII_WIIMOTE_B, "Wiimote B button" }, - { WII_WIIMOTE_1, "Wiimote 1 button" }, - { WII_WIIMOTE_2, "Wiimote 2 button" }, - { WII_WIIMOTE_UP, "Wiimote D-Pad Up" }, - { WII_WIIMOTE_DOWN, "Wiimote D-Pad Down" }, - { WII_WIIMOTE_LEFT, "Wiimote D-Pad Left" }, - { WII_WIIMOTE_RIGHT, "Wiimote D-Pad Right" }, - { WII_WIIMOTE_PLUS, "Wiimote Plus button" }, - { WII_WIIMOTE_MINUS, "Wiimote Minus button" }, - { WII_WIIMOTE_HOME, "Wiimote Home button" }, - { WII_NUNCHUK_Z, "Nunchuk Z button" }, - { WII_NUNCHUK_C, "Nunchuk C button" }, - { WII_NUNCHUK_LEFT, "Nunchuk Stick Left" }, - { WII_NUNCHUK_RIGHT, "Nunchuk Stick Right" }, - { WII_NUNCHUK_UP, "Nunchuk Stick Up" }, - { WII_NUNCHUK_DOWN, "Nunchuk Stick Down" }, - { WII_NUNCHUK_LEFT | WII_WIIMOTE_LEFT, "Nunchuk Stick D-Pad Left" }, - { WII_NUNCHUK_RIGHT | WII_WIIMOTE_RIGHT, "Nunchuk Stick D-Pad Right" }, - { WII_NUNCHUK_UP | WII_WIIMOTE_UP, "Nunchuk Stick D-Pad Up" }, - { WII_NUNCHUK_DOWN | WII_WIIMOTE_DOWN, "Nunchuk Stick D-Pad Down" }, + { GX_WIIMOTE_A, "Wiimote A button" }, + { GX_WIIMOTE_B, "Wiimote B button" }, + { GX_WIIMOTE_1, "Wiimote 1 button" }, + { GX_WIIMOTE_2, "Wiimote 2 button" }, + { GX_WIIMOTE_UP, "Wiimote D-Pad Up" }, + { GX_WIIMOTE_DOWN, "Wiimote D-Pad Down" }, + { GX_WIIMOTE_LEFT, "Wiimote D-Pad Left" }, + { GX_WIIMOTE_RIGHT, "Wiimote D-Pad Right" }, + { GX_WIIMOTE_PLUS, "Wiimote Plus button" }, + { GX_WIIMOTE_MINUS, "Wiimote Minus button" }, + { GX_WIIMOTE_HOME, "Wiimote Home button" }, + { GX_NUNCHUK_Z, "Nunchuk Z button" }, + { GX_NUNCHUK_C, "Nunchuk C button" }, + { GX_NUNCHUK_LEFT, "Nunchuk Stick Left" }, + { GX_NUNCHUK_RIGHT, "Nunchuk Stick Right" }, + { GX_NUNCHUK_UP, "Nunchuk Stick Up" }, + { GX_NUNCHUK_DOWN, "Nunchuk Stick Down" }, + { GX_NUNCHUK_LEFT | GX_WIIMOTE_LEFT, "Nunchuk Stick D-Pad Left" }, + { GX_NUNCHUK_RIGHT | GX_WIIMOTE_RIGHT, "Nunchuk Stick D-Pad Right" }, + { GX_NUNCHUK_UP | GX_WIIMOTE_UP, "Nunchuk Stick D-Pad Up" }, + { GX_NUNCHUK_DOWN | GX_WIIMOTE_DOWN, "Nunchuk Stick D-Pad Down" }, #endif }; @@ -158,72 +158,74 @@ static void wii_input_set_analog_dpad_mapping(unsigned device, unsigned map_dpad { switch (device) { - case WII_DEVICE_WIIMOTE: - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_UP].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_DOWN].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_LEFT].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_RIGHT].joykey; +#ifdef HW_RVL + case GX_DEVICE_WIIMOTE: + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_UP].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_DOWN].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_LEFT].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_RIGHT].joykey; break; - case WII_DEVICE_NUNCHUK: + case GX_DEVICE_NUNCHUK: if (map_dpad_enum == DPAD_EMULATION_NONE) { - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_UP].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_DOWN].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_LEFT].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_RIGHT].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_UP].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_DOWN].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_LEFT].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_RIGHT].joykey; } else { - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[WII_DEVICE_WIIMOTE_ID_LSTICK_UP_DPAD].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[WII_DEVICE_WIIMOTE_ID_LSTICK_DOWN_DPAD].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[WII_DEVICE_WIIMOTE_ID_LSTICK_LEFT_DPAD].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[WII_DEVICE_WIIMOTE_ID_LSTICK_RIGHT_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[GX_DEVICE_WIIMOTE_ID_LSTICK_UP_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[GX_DEVICE_WIIMOTE_ID_LSTICK_DOWN_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[GX_DEVICE_WIIMOTE_ID_LSTICK_LEFT_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[GX_DEVICE_WIIMOTE_ID_LSTICK_RIGHT_DPAD].joykey; } break; - case WII_DEVICE_CLASSIC: + case GX_DEVICE_CLASSIC: if (map_dpad_enum == DPAD_EMULATION_NONE) { - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[WII_DEVICE_CLASSIC_ID_JOYPAD_UP].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[WII_DEVICE_CLASSIC_ID_JOYPAD_DOWN].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[WII_DEVICE_CLASSIC_ID_JOYPAD_LEFT].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[WII_DEVICE_CLASSIC_ID_JOYPAD_RIGHT].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[GX_DEVICE_CLASSIC_ID_JOYPAD_UP].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[GX_DEVICE_CLASSIC_ID_JOYPAD_DOWN].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[GX_DEVICE_CLASSIC_ID_JOYPAD_LEFT].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[GX_DEVICE_CLASSIC_ID_JOYPAD_RIGHT].joykey; } else if (map_dpad_enum == DPAD_EMULATION_LSTICK) { - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[WII_DEVICE_CLASSIC_ID_LSTICK_UP_DPAD].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[WII_DEVICE_CLASSIC_ID_LSTICK_DOWN_DPAD].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[WII_DEVICE_CLASSIC_ID_LSTICK_LEFT_DPAD].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[WII_DEVICE_CLASSIC_ID_LSTICK_RIGHT_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[GX_DEVICE_CLASSIC_ID_LSTICK_UP_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[GX_DEVICE_CLASSIC_ID_LSTICK_DOWN_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[GX_DEVICE_CLASSIC_ID_LSTICK_LEFT_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[GX_DEVICE_CLASSIC_ID_LSTICK_RIGHT_DPAD].joykey; } else if (map_dpad_enum == DPAD_EMULATION_RSTICK) { - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[WII_DEVICE_CLASSIC_ID_RSTICK_UP_DPAD].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[WII_DEVICE_CLASSIC_ID_RSTICK_DOWN_DPAD].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[WII_DEVICE_CLASSIC_ID_RSTICK_LEFT_DPAD].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[WII_DEVICE_CLASSIC_ID_RSTICK_RIGHT_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[GX_DEVICE_CLASSIC_ID_RSTICK_UP_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[GX_DEVICE_CLASSIC_ID_RSTICK_DOWN_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[GX_DEVICE_CLASSIC_ID_RSTICK_LEFT_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[GX_DEVICE_CLASSIC_ID_RSTICK_RIGHT_DPAD].joykey; } break; - case WII_DEVICE_GAMECUBE: +#endif + case GX_DEVICE_GAMECUBE: if (map_dpad_enum == DPAD_EMULATION_NONE) { - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[WII_DEVICE_GC_ID_JOYPAD_UP].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[WII_DEVICE_GC_ID_JOYPAD_DOWN].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[WII_DEVICE_GC_ID_JOYPAD_LEFT].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[WII_DEVICE_GC_ID_JOYPAD_RIGHT].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[GX_DEVICE_GC_ID_JOYPAD_UP].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[GX_DEVICE_GC_ID_JOYPAD_DOWN].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[GX_DEVICE_GC_ID_JOYPAD_LEFT].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[GX_DEVICE_GC_ID_JOYPAD_RIGHT].joykey; } else if (map_dpad_enum == DPAD_EMULATION_LSTICK) { - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[WII_DEVICE_GC_ID_LSTICK_UP_DPAD].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[WII_DEVICE_GC_ID_LSTICK_DOWN_DPAD].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[WII_DEVICE_GC_ID_LSTICK_LEFT_DPAD].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[WII_DEVICE_GC_ID_LSTICK_RIGHT_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[GX_DEVICE_GC_ID_LSTICK_UP_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[GX_DEVICE_GC_ID_LSTICK_DOWN_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[GX_DEVICE_GC_ID_LSTICK_LEFT_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[GX_DEVICE_GC_ID_LSTICK_RIGHT_DPAD].joykey; } else if (map_dpad_enum == DPAD_EMULATION_RSTICK) { - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[WII_DEVICE_GC_ID_RSTICK_UP_DPAD].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[WII_DEVICE_GC_ID_RSTICK_DOWN_DPAD].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[WII_DEVICE_GC_ID_RSTICK_LEFT_DPAD].joykey; - g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[WII_DEVICE_GC_ID_RSTICK_RIGHT_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[GX_DEVICE_GC_ID_RSTICK_UP_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[GX_DEVICE_GC_ID_RSTICK_DOWN_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[GX_DEVICE_GC_ID_RSTICK_LEFT_DPAD].joykey; + g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[GX_DEVICE_GC_ID_RSTICK_RIGHT_DPAD].joykey; } break; default: @@ -268,29 +270,29 @@ static void wii_input_poll(void *data) { uint16_t down = PAD_ButtonsHeld(port); - state |= (down & PAD_BUTTON_A) ? WII_GC_A : 0; - state |= (down & PAD_BUTTON_B) ? WII_GC_B : 0; - state |= (down & PAD_BUTTON_X) ? WII_GC_X : 0; - state |= (down & PAD_BUTTON_Y) ? WII_GC_Y : 0; - state |= (down & PAD_BUTTON_UP) ? WII_GC_UP : 0; - state |= (down & PAD_BUTTON_DOWN) ? WII_GC_DOWN : 0; - state |= (down & PAD_BUTTON_LEFT) ? WII_GC_LEFT : 0; - state |= (down & PAD_BUTTON_RIGHT) ? WII_GC_RIGHT : 0; - state |= (down & PAD_BUTTON_START) ? WII_GC_START : 0; - state |= (down & PAD_TRIGGER_Z) ? WII_GC_Z_TRIGGER : 0; - state |= (PAD_TriggerL(port) > 127) ? WII_GC_L_TRIGGER : 0; - state |= (PAD_TriggerR(port) > 127) ? WII_GC_R_TRIGGER : 0; + state |= (down & PAD_BUTTON_A) ? GX_GC_A : 0; + state |= (down & PAD_BUTTON_B) ? GX_GC_B : 0; + state |= (down & PAD_BUTTON_X) ? GX_GC_X : 0; + state |= (down & PAD_BUTTON_Y) ? GX_GC_Y : 0; + state |= (down & PAD_BUTTON_UP) ? GX_GC_UP : 0; + state |= (down & PAD_BUTTON_DOWN) ? GX_GC_DOWN : 0; + state |= (down & PAD_BUTTON_LEFT) ? GX_GC_LEFT : 0; + state |= (down & PAD_BUTTON_RIGHT) ? GX_GC_RIGHT : 0; + state |= (down & PAD_BUTTON_START) ? GX_GC_START : 0; + state |= (down & PAD_TRIGGER_Z) ? GX_GC_Z_TRIGGER : 0; + state |= (PAD_TriggerL(port) > 127) ? GX_GC_L_TRIGGER : 0; + state |= (PAD_TriggerR(port) > 127) ? GX_GC_R_TRIGGER : 0; s8 x = PAD_StickX(port); s8 y = PAD_StickY(port); if (abs(x) > JOYSTICK_THRESHOLD) { - state |= x > 0 ? WII_GC_LSTICK_RIGHT : WII_GC_LSTICK_LEFT; + state |= x > 0 ? GX_GC_LSTICK_RIGHT : GX_GC_LSTICK_LEFT; } if (abs(y) > JOYSTICK_THRESHOLD) { - state |= y > 0 ? WII_GC_LSTICK_UP : WII_GC_LSTICK_DOWN; + state |= y > 0 ? GX_GC_LSTICK_UP : GX_GC_LSTICK_DOWN; } x = PAD_SubStickX(port); @@ -298,11 +300,11 @@ static void wii_input_poll(void *data) if (abs(x) > JOYSTICK_THRESHOLD) { - state |= x > 0 ? WII_GC_RSTICK_RIGHT : WII_GC_RSTICK_LEFT; + state |= x > 0 ? GX_GC_RSTICK_RIGHT : GX_GC_RSTICK_LEFT; } if (abs(y) > JOYSTICK_THRESHOLD) { - state |= y > 0 ? WII_GC_RSTICK_UP : WII_GC_RSTICK_DOWN; + state |= y > 0 ? GX_GC_RSTICK_UP : GX_GC_RSTICK_DOWN; } } @@ -310,13 +312,13 @@ static void wii_input_poll(void *data) { uint32_t down = WPAD_ButtonsHeld(port); - state |= (down & WPAD_BUTTON_A) ? WII_WIIMOTE_A : 0; - state |= (down & WPAD_BUTTON_B) ? WII_WIIMOTE_B : 0; - state |= (down & WPAD_BUTTON_1) ? WII_WIIMOTE_1 : 0; - state |= (down & WPAD_BUTTON_2) ? WII_WIIMOTE_2 : 0; - state |= (down & WPAD_BUTTON_PLUS) ? WII_WIIMOTE_PLUS : 0; - state |= (down & WPAD_BUTTON_MINUS) ? WII_WIIMOTE_MINUS : 0; - state |= (down & WPAD_BUTTON_HOME) ? WII_WIIMOTE_HOME : 0; + state |= (down & WPAD_BUTTON_A) ? GX_WIIMOTE_A : 0; + state |= (down & WPAD_BUTTON_B) ? GX_WIIMOTE_B : 0; + state |= (down & WPAD_BUTTON_1) ? GX_WIIMOTE_1 : 0; + state |= (down & WPAD_BUTTON_2) ? GX_WIIMOTE_2 : 0; + state |= (down & WPAD_BUTTON_PLUS) ? GX_WIIMOTE_PLUS : 0; + state |= (down & WPAD_BUTTON_MINUS) ? GX_WIIMOTE_MINUS : 0; + state |= (down & WPAD_BUTTON_HOME) ? GX_WIIMOTE_HOME : 0; expansion_t exp; WPAD_Expansion(port, &exp); @@ -325,55 +327,55 @@ static void wii_input_poll(void *data) case WPAD_EXP_NUNCHUK: { // wiimote is held upright with nunchuk, do not change d-pad orientation - state |= (down & WPAD_BUTTON_UP) ? WII_WIIMOTE_UP : 0; - state |= (down & WPAD_BUTTON_DOWN) ? WII_WIIMOTE_DOWN : 0; - state |= (down & WPAD_BUTTON_LEFT) ? WII_WIIMOTE_LEFT : 0; - state |= (down & WPAD_BUTTON_RIGHT) ? WII_WIIMOTE_RIGHT : 0; + state |= (down & WPAD_BUTTON_UP) ? GX_WIIMOTE_UP : 0; + state |= (down & WPAD_BUTTON_DOWN) ? GX_WIIMOTE_DOWN : 0; + state |= (down & WPAD_BUTTON_LEFT) ? GX_WIIMOTE_LEFT : 0; + state |= (down & WPAD_BUTTON_RIGHT) ? GX_WIIMOTE_RIGHT : 0; - state |= (down & WPAD_NUNCHUK_BUTTON_Z) ? WII_NUNCHUK_Z : 0; - state |= (down & WPAD_NUNCHUK_BUTTON_C) ? WII_NUNCHUK_C : 0; + state |= (down & WPAD_NUNCHUK_BUTTON_Z) ? GX_NUNCHUK_Z : 0; + state |= (down & WPAD_NUNCHUK_BUTTON_C) ? GX_NUNCHUK_C : 0; s8 x = wii_stick_x(exp.nunchuk.js); s8 y = wii_stick_y(exp.nunchuk.js); if (abs(x) > JOYSTICK_THRESHOLD) { - state |= x > 0 ? WII_NUNCHUK_RIGHT : WII_NUNCHUK_LEFT; + state |= x > 0 ? GX_NUNCHUK_RIGHT : GX_NUNCHUK_LEFT; } if (abs(y) > JOYSTICK_THRESHOLD) { - state |= y > 0 ? WII_NUNCHUK_UP : WII_NUNCHUK_DOWN; + state |= y > 0 ? GX_NUNCHUK_UP : GX_NUNCHUK_DOWN; } break; } case WPAD_EXP_CLASSIC: { - state |= (down & WPAD_CLASSIC_BUTTON_A) ? WII_CLASSIC_A : 0; - state |= (down & WPAD_CLASSIC_BUTTON_B) ? WII_CLASSIC_B : 0; - state |= (down & WPAD_CLASSIC_BUTTON_X) ? WII_CLASSIC_X : 0; - state |= (down & WPAD_CLASSIC_BUTTON_Y) ? WII_CLASSIC_Y : 0; - state |= (down & WPAD_CLASSIC_BUTTON_UP) ? WII_CLASSIC_UP : 0; - state |= (down & WPAD_CLASSIC_BUTTON_DOWN) ? WII_CLASSIC_DOWN : 0; - state |= (down & WPAD_CLASSIC_BUTTON_LEFT) ? WII_CLASSIC_LEFT : 0; - state |= (down & WPAD_CLASSIC_BUTTON_RIGHT) ? WII_CLASSIC_RIGHT : 0; - state |= (down & WPAD_CLASSIC_BUTTON_PLUS) ? WII_CLASSIC_PLUS : 0; - state |= (down & WPAD_CLASSIC_BUTTON_MINUS) ? WII_CLASSIC_MINUS : 0; - state |= (down & WPAD_CLASSIC_BUTTON_HOME) ? WII_CLASSIC_HOME : 0; - state |= (down & WPAD_CLASSIC_BUTTON_FULL_L) ? WII_CLASSIC_L_TRIGGER : 0; - state |= (down & WPAD_CLASSIC_BUTTON_FULL_R) ? WII_CLASSIC_R_TRIGGER : 0; - state |= (down & WPAD_CLASSIC_BUTTON_ZL) ? WII_CLASSIC_ZL_TRIGGER : 0; - state |= (down & WPAD_CLASSIC_BUTTON_ZR) ? WII_CLASSIC_ZR_TRIGGER : 0; + state |= (down & WPAD_CLASSIC_BUTTON_A) ? GX_CLASSIC_A : 0; + state |= (down & WPAD_CLASSIC_BUTTON_B) ? GX_CLASSIC_B : 0; + state |= (down & WPAD_CLASSIC_BUTTON_X) ? GX_CLASSIC_X : 0; + state |= (down & WPAD_CLASSIC_BUTTON_Y) ? GX_CLASSIC_Y : 0; + state |= (down & WPAD_CLASSIC_BUTTON_UP) ? GX_CLASSIC_UP : 0; + state |= (down & WPAD_CLASSIC_BUTTON_DOWN) ? GX_CLASSIC_DOWN : 0; + state |= (down & WPAD_CLASSIC_BUTTON_LEFT) ? GX_CLASSIC_LEFT : 0; + state |= (down & WPAD_CLASSIC_BUTTON_RIGHT) ? GX_CLASSIC_RIGHT : 0; + state |= (down & WPAD_CLASSIC_BUTTON_PLUS) ? GX_CLASSIC_PLUS : 0; + state |= (down & WPAD_CLASSIC_BUTTON_MINUS) ? GX_CLASSIC_MINUS : 0; + state |= (down & WPAD_CLASSIC_BUTTON_HOME) ? GX_CLASSIC_HOME : 0; + state |= (down & WPAD_CLASSIC_BUTTON_FULL_L) ? GX_CLASSIC_L_TRIGGER : 0; + state |= (down & WPAD_CLASSIC_BUTTON_FULL_R) ? GX_CLASSIC_R_TRIGGER : 0; + state |= (down & WPAD_CLASSIC_BUTTON_ZL) ? GX_CLASSIC_ZL_TRIGGER : 0; + state |= (down & WPAD_CLASSIC_BUTTON_ZR) ? GX_CLASSIC_ZR_TRIGGER : 0; s8 x = wii_stick_x(exp.classic.ljs); s8 y = wii_stick_y(exp.classic.ljs); if (abs(x) > JOYSTICK_THRESHOLD) { - state |= x > 0 ? WII_CLASSIC_LSTICK_RIGHT : WII_CLASSIC_LSTICK_LEFT; + state |= x > 0 ? GX_CLASSIC_LSTICK_RIGHT : GX_CLASSIC_LSTICK_LEFT; } if (abs(y) > JOYSTICK_THRESHOLD) { - state |= y > 0 ? WII_CLASSIC_LSTICK_UP : WII_CLASSIC_LSTICK_DOWN; + state |= y > 0 ? GX_CLASSIC_LSTICK_UP : GX_CLASSIC_LSTICK_DOWN; } x = wii_stick_x(exp.classic.rjs); @@ -381,28 +383,28 @@ static void wii_input_poll(void *data) if (abs(x) > JOYSTICK_THRESHOLD) { - state |= x > 0 ? WII_CLASSIC_RSTICK_RIGHT : WII_CLASSIC_RSTICK_LEFT; + state |= x > 0 ? GX_CLASSIC_RSTICK_RIGHT : GX_CLASSIC_RSTICK_LEFT; } if (abs(y) > JOYSTICK_THRESHOLD) { - state |= y > 0 ? WII_CLASSIC_RSTICK_UP : WII_CLASSIC_RSTICK_DOWN; + state |= y > 0 ? GX_CLASSIC_RSTICK_UP : GX_CLASSIC_RSTICK_DOWN; } // do not return, fall through for wiimote d-pad } default: // rotated d-pad - state |= (down & WPAD_BUTTON_UP) ? WII_WIIMOTE_LEFT : 0; - state |= (down & WPAD_BUTTON_DOWN) ? WII_WIIMOTE_RIGHT : 0; - state |= (down & WPAD_BUTTON_LEFT) ? WII_WIIMOTE_DOWN : 0; - state |= (down & WPAD_BUTTON_RIGHT) ? WII_WIIMOTE_UP : 0; + state |= (down & WPAD_BUTTON_UP) ? GX_WIIMOTE_LEFT : 0; + state |= (down & WPAD_BUTTON_DOWN) ? GX_WIIMOTE_RIGHT : 0; + state |= (down & WPAD_BUTTON_LEFT) ? GX_WIIMOTE_DOWN : 0; + state |= (down & WPAD_BUTTON_RIGHT) ? GX_WIIMOTE_UP : 0; break; } } #endif - if ((state & (WII_GC_START | WII_GC_Z_TRIGGER | WII_GC_L_TRIGGER | WII_GC_R_TRIGGER)) == (WII_GC_START | WII_GC_Z_TRIGGER | WII_GC_L_TRIGGER | WII_GC_R_TRIGGER)) + if ((state & (GX_GC_START | GX_GC_Z_TRIGGER | GX_GC_L_TRIGGER | GX_GC_R_TRIGGER)) == (GX_GC_START | GX_GC_Z_TRIGGER | GX_GC_L_TRIGGER | GX_GC_R_TRIGGER)) { - state |= WII_WIIMOTE_HOME; + state |= GX_WIIMOTE_HOME; } pad_state[port] = state; @@ -410,7 +412,7 @@ static void wii_input_poll(void *data) if (g_quit) { - pad_state[0] |= WII_WIIMOTE_HOME; + pad_state[0] |= GX_WIIMOTE_HOME; g_quit = false; } } @@ -421,7 +423,7 @@ static bool wii_key_pressed(void *data, int key) switch (key) { case RARCH_QUIT_KEY: - return pad_state[0] & (WII_CLASSIC_HOME | WII_WIIMOTE_HOME) ? true : false; + return pad_state[0] & (GX_CLASSIC_HOME | GX_WIIMOTE_HOME) ? true : false; default: return false; } @@ -433,17 +435,18 @@ static void wii_set_default_keybind_lut(unsigned device, unsigned port) switch (device) { - case WII_DEVICE_WIIMOTE: - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_B] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_B].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_Y] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_A].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_SELECT] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_MINUS].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_START] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_PLUS].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_UP] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_UP].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_DOWN] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_DOWN].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_LEFT] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_LEFT].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_RIGHT].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_1].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_2].joykey; +#ifdef HW_RVL + case GX_DEVICE_WIIMOTE: + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_B] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_B].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_Y] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_A].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_SELECT] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_MINUS].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_START] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_PLUS].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_UP] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_UP].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_DOWN] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_DOWN].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_LEFT] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_LEFT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_RIGHT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_1].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_2].joykey; rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = 0; rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = 0; rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = 0; @@ -451,55 +454,56 @@ static void wii_set_default_keybind_lut(unsigned device, unsigned port) rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L3] = 0; rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R3] = 0; break; - case WII_DEVICE_NUNCHUK: - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_B] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_B].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_Y] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_2].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_SELECT] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_MINUS].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_START] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_PLUS].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_UP] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_UP].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_DOWN] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_DOWN].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_LEFT] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_LEFT].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_RIGHT].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_A].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_1].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_Z].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[WII_DEVICE_WIIMOTE_ID_JOYPAD_C].joykey;; + case GX_DEVICE_NUNCHUK: + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_B] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_B].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_Y] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_2].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_SELECT] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_MINUS].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_START] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_PLUS].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_UP] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_UP].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_DOWN] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_DOWN].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_LEFT] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_LEFT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_RIGHT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_A].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_1].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_Z].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[GX_DEVICE_WIIMOTE_ID_JOYPAD_C].joykey;; rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = 0; rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = 0; rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L3] = 0; rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R3] = 0; break; - case WII_DEVICE_CLASSIC: - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_B] = platform_keys[WII_DEVICE_CLASSIC_ID_JOYPAD_B].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_Y] = platform_keys[WII_DEVICE_CLASSIC_ID_JOYPAD_Y].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_SELECT] = platform_keys[WII_DEVICE_CLASSIC_ID_JOYPAD_MINUS].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_START] = platform_keys[WII_DEVICE_CLASSIC_ID_JOYPAD_PLUS].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_UP] = platform_keys[WII_DEVICE_CLASSIC_ID_JOYPAD_UP].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_DOWN] = platform_keys[WII_DEVICE_CLASSIC_ID_JOYPAD_DOWN].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_LEFT] = platform_keys[WII_DEVICE_CLASSIC_ID_JOYPAD_LEFT].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[WII_DEVICE_CLASSIC_ID_JOYPAD_RIGHT].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[WII_DEVICE_CLASSIC_ID_JOYPAD_A].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[WII_DEVICE_CLASSIC_ID_JOYPAD_X].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[WII_DEVICE_CLASSIC_ID_JOYPAD_L_TRIGGER].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[WII_DEVICE_CLASSIC_ID_JOYPAD_R_TRIGGER].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[WII_DEVICE_CLASSIC_ID_JOYPAD_ZL_TRIGGER].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[WII_DEVICE_CLASSIC_ID_JOYPAD_ZR_TRIGGER].joykey; + case GX_DEVICE_CLASSIC: + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_B] = platform_keys[GX_DEVICE_CLASSIC_ID_JOYPAD_B].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_Y] = platform_keys[GX_DEVICE_CLASSIC_ID_JOYPAD_Y].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_SELECT] = platform_keys[GX_DEVICE_CLASSIC_ID_JOYPAD_MINUS].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_START] = platform_keys[GX_DEVICE_CLASSIC_ID_JOYPAD_PLUS].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_UP] = platform_keys[GX_DEVICE_CLASSIC_ID_JOYPAD_UP].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_DOWN] = platform_keys[GX_DEVICE_CLASSIC_ID_JOYPAD_DOWN].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_LEFT] = platform_keys[GX_DEVICE_CLASSIC_ID_JOYPAD_LEFT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[GX_DEVICE_CLASSIC_ID_JOYPAD_RIGHT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[GX_DEVICE_CLASSIC_ID_JOYPAD_A].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[GX_DEVICE_CLASSIC_ID_JOYPAD_X].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[GX_DEVICE_CLASSIC_ID_JOYPAD_L_TRIGGER].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[GX_DEVICE_CLASSIC_ID_JOYPAD_R_TRIGGER].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[GX_DEVICE_CLASSIC_ID_JOYPAD_ZL_TRIGGER].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[GX_DEVICE_CLASSIC_ID_JOYPAD_ZR_TRIGGER].joykey; rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L3] = 0; rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R3] = 0; break; - case WII_DEVICE_GAMECUBE: - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_B] = platform_keys[WII_DEVICE_GC_ID_JOYPAD_B].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_Y] = platform_keys[WII_DEVICE_GC_ID_JOYPAD_Y].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_SELECT] = platform_keys[WII_DEVICE_GC_ID_JOYPAD_Z_TRIGGER].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_START] = platform_keys[WII_DEVICE_GC_ID_JOYPAD_START].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_UP] = platform_keys[WII_DEVICE_GC_ID_JOYPAD_UP].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_DOWN] = platform_keys[WII_DEVICE_GC_ID_JOYPAD_DOWN].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_LEFT] = platform_keys[WII_DEVICE_GC_ID_JOYPAD_LEFT].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[WII_DEVICE_GC_ID_JOYPAD_RIGHT].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[WII_DEVICE_GC_ID_JOYPAD_A].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[WII_DEVICE_GC_ID_JOYPAD_X].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[WII_DEVICE_GC_ID_JOYPAD_L_TRIGGER].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[WII_DEVICE_GC_ID_JOYPAD_R_TRIGGER].joykey; +#endif + case GX_DEVICE_GAMECUBE: + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_B] = platform_keys[GX_DEVICE_GC_ID_JOYPAD_B].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_Y] = platform_keys[GX_DEVICE_GC_ID_JOYPAD_Y].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_SELECT] = platform_keys[GX_DEVICE_GC_ID_JOYPAD_Z_TRIGGER].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_START] = platform_keys[GX_DEVICE_GC_ID_JOYPAD_START].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_UP] = platform_keys[GX_DEVICE_GC_ID_JOYPAD_UP].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_DOWN] = platform_keys[GX_DEVICE_GC_ID_JOYPAD_DOWN].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_LEFT] = platform_keys[GX_DEVICE_GC_ID_JOYPAD_LEFT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[GX_DEVICE_GC_ID_JOYPAD_RIGHT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[GX_DEVICE_GC_ID_JOYPAD_A].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[GX_DEVICE_GC_ID_JOYPAD_X].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[GX_DEVICE_GC_ID_JOYPAD_L_TRIGGER].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[GX_DEVICE_GC_ID_JOYPAD_R_TRIGGER].joykey; rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = 0; rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = 0; rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L3] = 0; diff --git a/wii/gx_input.h b/wii/gx_input.h index 9296bbd91c..86f9e24d7d 100644 --- a/wii/gx_input.h +++ b/wii/gx_input.h @@ -15,160 +15,162 @@ * If not, see . */ -#ifndef _WII_INPUT_H -#define _WII_INPUT_H +#ifndef _GX_INPUT_H +#define _GX_INPUT_H enum { - WII_GC_A = 1ULL << 0, - WII_GC_B = 1ULL << 1, - WII_GC_X = 1ULL << 2, - WII_GC_Y = 1ULL << 3, - WII_GC_START = 1ULL << 4, - WII_GC_Z_TRIGGER = 1ULL << 5, - WII_GC_L_TRIGGER = 1ULL << 6, - WII_GC_R_TRIGGER = 1ULL << 7, - WII_GC_UP = 1ULL << 8, - WII_GC_DOWN = 1ULL << 9, - WII_GC_LEFT = 1ULL << 10, - WII_GC_RIGHT = 1ULL << 11, - WII_GC_LSTICK_UP = 1ULL << 12, - WII_GC_LSTICK_DOWN = 1ULL << 13, - WII_GC_LSTICK_LEFT = 1ULL << 14, - WII_GC_LSTICK_RIGHT = 1ULL << 15, - WII_GC_RSTICK_UP = 1ULL << 16, - WII_GC_RSTICK_DOWN = 1ULL << 17, - WII_GC_RSTICK_LEFT = 1ULL << 18, - WII_GC_RSTICK_RIGHT = 1ULL << 19, - WII_CLASSIC_A = 1ULL << 20, - WII_CLASSIC_B = 1ULL << 21, - WII_CLASSIC_X = 1ULL << 22, - WII_CLASSIC_Y = 1ULL << 23, - WII_CLASSIC_PLUS = 1ULL << 24, - WII_CLASSIC_MINUS = 1ULL << 25, - WII_CLASSIC_HOME = 1ULL << 26, - WII_CLASSIC_L_TRIGGER = 1ULL << 27, - WII_CLASSIC_R_TRIGGER = 1ULL << 28, - WII_CLASSIC_ZL_TRIGGER = 1ULL << 29, - WII_CLASSIC_ZR_TRIGGER = 1ULL << 30, - WII_CLASSIC_UP = 1ULL << 31, - WII_CLASSIC_DOWN = 1ULL << 32, - WII_CLASSIC_LEFT = 1ULL << 33, - WII_CLASSIC_RIGHT = 1ULL << 34, - WII_CLASSIC_LSTICK_UP = 1ULL << 35, - WII_CLASSIC_LSTICK_DOWN = 1ULL << 36, - WII_CLASSIC_LSTICK_LEFT = 1ULL << 37, - WII_CLASSIC_LSTICK_RIGHT = 1ULL << 38, - WII_CLASSIC_RSTICK_UP = 1ULL << 39, - WII_CLASSIC_RSTICK_DOWN = 1ULL << 40, - WII_CLASSIC_RSTICK_LEFT = 1ULL << 41, - WII_CLASSIC_RSTICK_RIGHT = 1ULL << 42, - WII_WIIMOTE_A = 1ULL << 43, - WII_WIIMOTE_B = 1ULL << 44, - WII_WIIMOTE_1 = 1ULL << 45, - WII_WIIMOTE_2 = 1ULL << 46, - WII_WIIMOTE_PLUS = 1ULL << 47, - WII_WIIMOTE_MINUS = 1ULL << 48, - WII_WIIMOTE_HOME = 1ULL << 49, - WII_WIIMOTE_UP = 1ULL << 50, - WII_WIIMOTE_DOWN = 1ULL << 51, - WII_WIIMOTE_LEFT = 1ULL << 52, - WII_WIIMOTE_RIGHT = 1ULL << 53, - WII_NUNCHUK_Z = 1ULL << 54, - WII_NUNCHUK_C = 1ULL << 55, - WII_NUNCHUK_UP = 1ULL << 56, - WII_NUNCHUK_DOWN = 1ULL << 57, - WII_NUNCHUK_LEFT = 1ULL << 58, - WII_NUNCHUK_RIGHT = 1ULL << 59, + GX_GC_A = 1ULL << 0, + GX_GC_B = 1ULL << 1, + GX_GC_X = 1ULL << 2, + GX_GC_Y = 1ULL << 3, + GX_GC_START = 1ULL << 4, + GX_GC_Z_TRIGGER = 1ULL << 5, + GX_GC_L_TRIGGER = 1ULL << 6, + GX_GC_R_TRIGGER = 1ULL << 7, + GX_GC_UP = 1ULL << 8, + GX_GC_DOWN = 1ULL << 9, + GX_GC_LEFT = 1ULL << 10, + GX_GC_RIGHT = 1ULL << 11, + GX_GC_LSTICK_UP = 1ULL << 12, + GX_GC_LSTICK_DOWN = 1ULL << 13, + GX_GC_LSTICK_LEFT = 1ULL << 14, + GX_GC_LSTICK_RIGHT = 1ULL << 15, + GX_GC_RSTICK_UP = 1ULL << 16, + GX_GC_RSTICK_DOWN = 1ULL << 17, + GX_GC_RSTICK_LEFT = 1ULL << 18, + GX_GC_RSTICK_RIGHT = 1ULL << 19, +#ifdef HW_RVL + GX_CLASSIC_A = 1ULL << 20, + GX_CLASSIC_B = 1ULL << 21, + GX_CLASSIC_X = 1ULL << 22, + GX_CLASSIC_Y = 1ULL << 23, + GX_CLASSIC_PLUS = 1ULL << 24, + GX_CLASSIC_MINUS = 1ULL << 25, + GX_CLASSIC_HOME = 1ULL << 26, + GX_CLASSIC_L_TRIGGER = 1ULL << 27, + GX_CLASSIC_R_TRIGGER = 1ULL << 28, + GX_CLASSIC_ZL_TRIGGER = 1ULL << 29, + GX_CLASSIC_ZR_TRIGGER = 1ULL << 30, + GX_CLASSIC_UP = 1ULL << 31, + GX_CLASSIC_DOWN = 1ULL << 32, + GX_CLASSIC_LEFT = 1ULL << 33, + GX_CLASSIC_RIGHT = 1ULL << 34, + GX_CLASSIC_LSTICK_UP = 1ULL << 35, + GX_CLASSIC_LSTICK_DOWN = 1ULL << 36, + GX_CLASSIC_LSTICK_LEFT = 1ULL << 37, + GX_CLASSIC_LSTICK_RIGHT = 1ULL << 38, + GX_CLASSIC_RSTICK_UP = 1ULL << 39, + GX_CLASSIC_RSTICK_DOWN = 1ULL << 40, + GX_CLASSIC_RSTICK_LEFT = 1ULL << 41, + GX_CLASSIC_RSTICK_RIGHT = 1ULL << 42, + GX_WIIMOTE_A = 1ULL << 43, + GX_WIIMOTE_B = 1ULL << 44, + GX_WIIMOTE_1 = 1ULL << 45, + GX_WIIMOTE_2 = 1ULL << 46, + GX_WIIMOTE_PLUS = 1ULL << 47, + GX_WIIMOTE_MINUS = 1ULL << 48, + GX_WIIMOTE_HOME = 1ULL << 49, + GX_WIIMOTE_UP = 1ULL << 50, + GX_WIIMOTE_DOWN = 1ULL << 51, + GX_WIIMOTE_LEFT = 1ULL << 52, + GX_WIIMOTE_RIGHT = 1ULL << 53, + GX_NUNCHUK_Z = 1ULL << 54, + GX_NUNCHUK_C = 1ULL << 55, + GX_NUNCHUK_UP = 1ULL << 56, + GX_NUNCHUK_DOWN = 1ULL << 57, + GX_NUNCHUK_LEFT = 1ULL << 58, + GX_NUNCHUK_RIGHT = 1ULL << 59, +#endif }; enum wii_device_id { - WII_DEVICE_GC_ID_JOYPAD_A = 0, - WII_DEVICE_GC_ID_JOYPAD_B, - WII_DEVICE_GC_ID_JOYPAD_X, - WII_DEVICE_GC_ID_JOYPAD_Y, - WII_DEVICE_GC_ID_JOYPAD_UP, - WII_DEVICE_GC_ID_JOYPAD_DOWN, - WII_DEVICE_GC_ID_JOYPAD_LEFT, - WII_DEVICE_GC_ID_JOYPAD_RIGHT, - WII_DEVICE_GC_ID_JOYPAD_Z_TRIGGER, - WII_DEVICE_GC_ID_JOYPAD_START, - WII_DEVICE_GC_ID_JOYPAD_L_TRIGGER, - WII_DEVICE_GC_ID_JOYPAD_R_TRIGGER, - WII_DEVICE_GC_ID_LSTICK_LEFT, - WII_DEVICE_GC_ID_LSTICK_RIGHT, - WII_DEVICE_GC_ID_LSTICK_UP, - WII_DEVICE_GC_ID_LSTICK_DOWN, - WII_DEVICE_GC_ID_LSTICK_LEFT_DPAD, - WII_DEVICE_GC_ID_LSTICK_RIGHT_DPAD, - WII_DEVICE_GC_ID_LSTICK_UP_DPAD, - WII_DEVICE_GC_ID_LSTICK_DOWN_DPAD, - WII_DEVICE_GC_ID_RSTICK_LEFT, - WII_DEVICE_GC_ID_RSTICK_RIGHT, - WII_DEVICE_GC_ID_RSTICK_UP, - WII_DEVICE_GC_ID_RSTICK_DOWN, - WII_DEVICE_GC_ID_RSTICK_LEFT_DPAD, - WII_DEVICE_GC_ID_RSTICK_RIGHT_DPAD, - WII_DEVICE_GC_ID_RSTICK_UP_DPAD, - WII_DEVICE_GC_ID_RSTICK_DOWN_DPAD, + GX_DEVICE_GC_ID_JOYPAD_A = 0, + GX_DEVICE_GC_ID_JOYPAD_B, + GX_DEVICE_GC_ID_JOYPAD_X, + GX_DEVICE_GC_ID_JOYPAD_Y, + GX_DEVICE_GC_ID_JOYPAD_UP, + GX_DEVICE_GC_ID_JOYPAD_DOWN, + GX_DEVICE_GC_ID_JOYPAD_LEFT, + GX_DEVICE_GC_ID_JOYPAD_RIGHT, + GX_DEVICE_GC_ID_JOYPAD_Z_TRIGGER, + GX_DEVICE_GC_ID_JOYPAD_START, + GX_DEVICE_GC_ID_JOYPAD_L_TRIGGER, + GX_DEVICE_GC_ID_JOYPAD_R_TRIGGER, + GX_DEVICE_GC_ID_LSTICK_LEFT, + GX_DEVICE_GC_ID_LSTICK_RIGHT, + GX_DEVICE_GC_ID_LSTICK_UP, + GX_DEVICE_GC_ID_LSTICK_DOWN, + GX_DEVICE_GC_ID_LSTICK_LEFT_DPAD, + GX_DEVICE_GC_ID_LSTICK_RIGHT_DPAD, + GX_DEVICE_GC_ID_LSTICK_UP_DPAD, + GX_DEVICE_GC_ID_LSTICK_DOWN_DPAD, + GX_DEVICE_GC_ID_RSTICK_LEFT, + GX_DEVICE_GC_ID_RSTICK_RIGHT, + GX_DEVICE_GC_ID_RSTICK_UP, + GX_DEVICE_GC_ID_RSTICK_DOWN, + GX_DEVICE_GC_ID_RSTICK_LEFT_DPAD, + GX_DEVICE_GC_ID_RSTICK_RIGHT_DPAD, + GX_DEVICE_GC_ID_RSTICK_UP_DPAD, + GX_DEVICE_GC_ID_RSTICK_DOWN_DPAD, #ifdef HW_RVL // CLASSIC CONTROLLER - WII_DEVICE_CLASSIC_ID_JOYPAD_A, - WII_DEVICE_CLASSIC_ID_JOYPAD_B, - WII_DEVICE_CLASSIC_ID_JOYPAD_X, - WII_DEVICE_CLASSIC_ID_JOYPAD_Y, - WII_DEVICE_CLASSIC_ID_JOYPAD_UP, - WII_DEVICE_CLASSIC_ID_JOYPAD_DOWN, - WII_DEVICE_CLASSIC_ID_JOYPAD_LEFT, - WII_DEVICE_CLASSIC_ID_JOYPAD_RIGHT, - WII_DEVICE_CLASSIC_ID_JOYPAD_PLUS, - WII_DEVICE_CLASSIC_ID_JOYPAD_MINUS, - WII_DEVICE_CLASSIC_ID_JOYPAD_HOME, - WII_DEVICE_CLASSIC_ID_JOYPAD_L_TRIGGER, - WII_DEVICE_CLASSIC_ID_JOYPAD_R_TRIGGER, - WII_DEVICE_CLASSIC_ID_JOYPAD_ZL_TRIGGER, - WII_DEVICE_CLASSIC_ID_JOYPAD_ZR_TRIGGER, - WII_DEVICE_CLASSIC_ID_LSTICK_LEFT, - WII_DEVICE_CLASSIC_ID_LSTICK_RIGHT, - WII_DEVICE_CLASSIC_ID_LSTICK_UP, - WII_DEVICE_CLASSIC_ID_LSTICK_DOWN, - WII_DEVICE_CLASSIC_ID_LSTICK_LEFT_DPAD, - WII_DEVICE_CLASSIC_ID_LSTICK_RIGHT_DPAD, - WII_DEVICE_CLASSIC_ID_LSTICK_UP_DPAD, - WII_DEVICE_CLASSIC_ID_LSTICK_DOWN_DPAD, - WII_DEVICE_CLASSIC_ID_RSTICK_LEFT, - WII_DEVICE_CLASSIC_ID_RSTICK_RIGHT, - WII_DEVICE_CLASSIC_ID_RSTICK_UP, - WII_DEVICE_CLASSIC_ID_RSTICK_DOWN, - WII_DEVICE_CLASSIC_ID_RSTICK_LEFT_DPAD, - WII_DEVICE_CLASSIC_ID_RSTICK_RIGHT_DPAD, - WII_DEVICE_CLASSIC_ID_RSTICK_UP_DPAD, - WII_DEVICE_CLASSIC_ID_RSTICK_DOWN_DPAD, + GX_DEVICE_CLASSIC_ID_JOYPAD_A, + GX_DEVICE_CLASSIC_ID_JOYPAD_B, + GX_DEVICE_CLASSIC_ID_JOYPAD_X, + GX_DEVICE_CLASSIC_ID_JOYPAD_Y, + GX_DEVICE_CLASSIC_ID_JOYPAD_UP, + GX_DEVICE_CLASSIC_ID_JOYPAD_DOWN, + GX_DEVICE_CLASSIC_ID_JOYPAD_LEFT, + GX_DEVICE_CLASSIC_ID_JOYPAD_RIGHT, + GX_DEVICE_CLASSIC_ID_JOYPAD_PLUS, + GX_DEVICE_CLASSIC_ID_JOYPAD_MINUS, + GX_DEVICE_CLASSIC_ID_JOYPAD_HOME, + GX_DEVICE_CLASSIC_ID_JOYPAD_L_TRIGGER, + GX_DEVICE_CLASSIC_ID_JOYPAD_R_TRIGGER, + GX_DEVICE_CLASSIC_ID_JOYPAD_ZL_TRIGGER, + GX_DEVICE_CLASSIC_ID_JOYPAD_ZR_TRIGGER, + GX_DEVICE_CLASSIC_ID_LSTICK_LEFT, + GX_DEVICE_CLASSIC_ID_LSTICK_RIGHT, + GX_DEVICE_CLASSIC_ID_LSTICK_UP, + GX_DEVICE_CLASSIC_ID_LSTICK_DOWN, + GX_DEVICE_CLASSIC_ID_LSTICK_LEFT_DPAD, + GX_DEVICE_CLASSIC_ID_LSTICK_RIGHT_DPAD, + GX_DEVICE_CLASSIC_ID_LSTICK_UP_DPAD, + GX_DEVICE_CLASSIC_ID_LSTICK_DOWN_DPAD, + GX_DEVICE_CLASSIC_ID_RSTICK_LEFT, + GX_DEVICE_CLASSIC_ID_RSTICK_RIGHT, + GX_DEVICE_CLASSIC_ID_RSTICK_UP, + GX_DEVICE_CLASSIC_ID_RSTICK_DOWN, + GX_DEVICE_CLASSIC_ID_RSTICK_LEFT_DPAD, + GX_DEVICE_CLASSIC_ID_RSTICK_RIGHT_DPAD, + GX_DEVICE_CLASSIC_ID_RSTICK_UP_DPAD, + GX_DEVICE_CLASSIC_ID_RSTICK_DOWN_DPAD, // WIIMOTE (PLUS OPTIONAL NUNCHUK) - WII_DEVICE_WIIMOTE_ID_JOYPAD_A, - WII_DEVICE_WIIMOTE_ID_JOYPAD_B, - WII_DEVICE_WIIMOTE_ID_JOYPAD_1, - WII_DEVICE_WIIMOTE_ID_JOYPAD_2, - WII_DEVICE_WIIMOTE_ID_JOYPAD_UP, - WII_DEVICE_WIIMOTE_ID_JOYPAD_DOWN, - WII_DEVICE_WIIMOTE_ID_JOYPAD_LEFT, - WII_DEVICE_WIIMOTE_ID_JOYPAD_RIGHT, - WII_DEVICE_WIIMOTE_ID_JOYPAD_PLUS, - WII_DEVICE_WIIMOTE_ID_JOYPAD_MINUS, - WII_DEVICE_WIIMOTE_ID_JOYPAD_HOME, - WII_DEVICE_WIIMOTE_ID_JOYPAD_Z, - WII_DEVICE_WIIMOTE_ID_JOYPAD_C, - WII_DEVICE_WIIMOTE_ID_LSTICK_LEFT, - WII_DEVICE_WIIMOTE_ID_LSTICK_RIGHT, - WII_DEVICE_WIIMOTE_ID_LSTICK_UP, - WII_DEVICE_WIIMOTE_ID_LSTICK_DOWN, - WII_DEVICE_WIIMOTE_ID_LSTICK_LEFT_DPAD, - WII_DEVICE_WIIMOTE_ID_LSTICK_RIGHT_DPAD, - WII_DEVICE_WIIMOTE_ID_LSTICK_UP_DPAD, - WII_DEVICE_WIIMOTE_ID_LSTICK_DOWN_DPAD, + GX_DEVICE_WIIMOTE_ID_JOYPAD_A, + GX_DEVICE_WIIMOTE_ID_JOYPAD_B, + GX_DEVICE_WIIMOTE_ID_JOYPAD_1, + GX_DEVICE_WIIMOTE_ID_JOYPAD_2, + GX_DEVICE_WIIMOTE_ID_JOYPAD_UP, + GX_DEVICE_WIIMOTE_ID_JOYPAD_DOWN, + GX_DEVICE_WIIMOTE_ID_JOYPAD_LEFT, + GX_DEVICE_WIIMOTE_ID_JOYPAD_RIGHT, + GX_DEVICE_WIIMOTE_ID_JOYPAD_PLUS, + GX_DEVICE_WIIMOTE_ID_JOYPAD_MINUS, + GX_DEVICE_WIIMOTE_ID_JOYPAD_HOME, + GX_DEVICE_WIIMOTE_ID_JOYPAD_Z, + GX_DEVICE_WIIMOTE_ID_JOYPAD_C, + GX_DEVICE_WIIMOTE_ID_LSTICK_LEFT, + GX_DEVICE_WIIMOTE_ID_LSTICK_RIGHT, + GX_DEVICE_WIIMOTE_ID_LSTICK_UP, + GX_DEVICE_WIIMOTE_ID_LSTICK_DOWN, + GX_DEVICE_WIIMOTE_ID_LSTICK_LEFT_DPAD, + GX_DEVICE_WIIMOTE_ID_LSTICK_RIGHT_DPAD, + GX_DEVICE_WIIMOTE_ID_LSTICK_UP_DPAD, + GX_DEVICE_WIIMOTE_ID_LSTICK_DOWN_DPAD, #endif RARCH_LAST_PLATFORM_KEY @@ -176,10 +178,10 @@ enum wii_device_id enum { - WII_DEVICE_GAMECUBE = 0, - WII_DEVICE_WIIMOTE, - WII_DEVICE_NUNCHUK, - WII_DEVICE_CLASSIC, + GX_DEVICE_GAMECUBE = 0, + GX_DEVICE_WIIMOTE, + GX_DEVICE_NUNCHUK, + GX_DEVICE_CLASSIC, RARCH_DEVICE_LAST }; From 72b7ecaaff5b12eaae80854e6339b34b4d0f68a0 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 6 Aug 2012 22:49:10 +0200 Subject: [PATCH 080/492] (RMenu) Take out some unused Xbox 1 definitions --- console/rmenu/rmenu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index e5c4ac60d9..c5674a33c1 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -606,7 +606,6 @@ static void display_menubar(menu *current_menu) float x_position = POSITION_X; #ifdef _XBOX1 - float current_y_position = m_menuMainRomListPos_y; float font_size = m_menuMainRomListPos_y; #else float font_size = HARDCODE_FONT_SIZE; From 8dae2d2179b2350442e2583046d8681032fefcdd Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 6 Aug 2012 22:53:57 +0200 Subject: [PATCH 081/492] (Xbox1/RMenu) Move Xbox init code to xdk/frontend/main.c --- console/rmenu/rmenu.c | 11 ----------- xdk/frontend/main.c | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index c5674a33c1..1620175518 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -71,7 +71,6 @@ #define MENU_ITEM_SELECTED(index) (menuitem_colors[index]) #ifdef _XBOX1 -#include "../../xbox1/frontend/RetroLaunch/IoSupport.h" #include "../../gfx/fonts/xdk1_xfonts.h" #define ROM_PANEL_WIDTH 510 @@ -2263,16 +2262,6 @@ void menu_init (void) filebrowser_set_root(&tmpBrowser, default_paths.filesystem_root_dir); #ifdef _XBOX1 - // Set file cache size - XSetFileCacheSize(8 * 1024 * 1024); - - // Mount drives - xbox_io_mount("A:", "cdrom0"); - xbox_io_mount("E:", "Harddisk0\\Partition1"); - xbox_io_mount("Z:", "Harddisk0\\Partition2"); - xbox_io_mount("F:", "Harddisk0\\Partition6"); - xbox_io_mount("G:", "Harddisk0\\Partition7"); - // Backbuffer width int width = device_ptr->d3dpp.BackBufferWidth; diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index 85085af5d7..c78af2302a 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -25,6 +25,7 @@ #include "../../360/frontend-xdk/menu.h" #include "../../xdk/menu_shared.h" #elif defined(_XBOX1) +#include "../../xbox1/frontend/RetroLaunch/IoSupport.h" #include "../../console/rmenu/rmenu.h" #endif @@ -124,6 +125,21 @@ static void get_environment_settings (void) #endif } +static void system_init(void) +{ +#ifdef _XBOX1 + // Set file cache size + XSetFileCacheSize(8 * 1024 * 1024); + + // Mount drives + xbox_io_mount("A:", "cdrom0"); + xbox_io_mount("E:", "Harddisk0\\Partition1"); + xbox_io_mount("Z:", "Harddisk0\\Partition2"); + xbox_io_mount("F:", "Harddisk0\\Partition6"); + xbox_io_mount("G:", "Harddisk0\\Partition7"); +#endif +} + int main(int argc, char *argv[]) { rarch_main_clear_state(); @@ -160,6 +176,8 @@ int main(int argc, char *argv[]) video_null.start(); #endif + system_init(); + menu_init(); begin_loop: From a6424f02b0d907680d68b7d7f688c56cee3308ae Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 6 Aug 2012 23:37:53 +0200 Subject: [PATCH 082/492] (RMenu) Cleanup --- console/rmenu/rmenu.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index 1620175518..bcdd202ddb 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -604,11 +604,7 @@ static void display_menubar(menu *current_menu) char current_path[256], rarch_version[128]; float x_position = POSITION_X; -#ifdef _XBOX1 - float font_size = m_menuMainRomListPos_y; -#else float font_size = HARDCODE_FONT_SIZE; -#endif float current_path_y_position = CURRENT_PATH_Y_POSITION; float current_path_font_size = CURRENT_PATH_FONT_SIZE; float msg_prev_next_y_position = MSG_PREV_NEXT_Y_POSITION; From cc154d21abed40820da6a77729a3f750e083df66 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 7 Aug 2012 00:23:25 +0200 Subject: [PATCH 083/492] (Xbox 1) Add RetroArch Salamander project + fix config_file.c --- conf/config_file.c | 2 +- console/rarch_console_config.c | 4 +- .../RetroArch-Salamander.vcproj | 482 ++++++++++++++++++ msvc/RetroArch-Xbox1.sln | 2 +- 4 files changed, 486 insertions(+), 4 deletions(-) create mode 100644 msvc/RetroArch-Xbox1-Salamander/RetroArch-Salamander.vcproj diff --git a/conf/config_file.c b/conf/config_file.c index ff008f9c98..70ae2c217c 100644 --- a/conf/config_file.c +++ b/conf/config_file.c @@ -329,7 +329,7 @@ static config_file_t *config_file_new_internal(const char *path, unsigned depth) } conf->include_depth = depth; - FILE *file = fopen(path, "r+"); + FILE *file = fopen(path, "r"); if (!file) { diff --git a/console/rarch_console_config.c b/console/rarch_console_config.c index e05768e75c..5515e27582 100644 --- a/console/rarch_console_config.c +++ b/console/rarch_console_config.c @@ -29,8 +29,6 @@ void rarch_config_load(const char * conf_name, const char * libretro_dir_path, c if(!conf) return; - // g_settings - #ifdef HAVE_LIBRETRO_MANAGEMENT if(find_libretro_path) { @@ -46,6 +44,8 @@ void rarch_config_load(const char * conf_name, const char * libretro_dir_path, c } #endif + // g_settings + CONFIG_GET_STRING(system_directory, "system_directory"); #ifdef HAVE_XML CONFIG_GET_STRING(cheat_database, "cheat_database"); diff --git a/msvc/RetroArch-Xbox1-Salamander/RetroArch-Salamander.vcproj b/msvc/RetroArch-Xbox1-Salamander/RetroArch-Salamander.vcproj new file mode 100644 index 0000000000..f0e1685e13 --- /dev/null +++ b/msvc/RetroArch-Xbox1-Salamander/RetroArch-Salamander.vcproj @@ -0,0 +1,482 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msvc/RetroArch-Xbox1.sln b/msvc/RetroArch-Xbox1.sln index cbabddb331..f147e5cd09 100644 --- a/msvc/RetroArch-Xbox1.sln +++ b/msvc/RetroArch-Xbox1.sln @@ -3,7 +3,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RetroArch", "RetroArch-Xbox ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RetroArch-Salamander", "RetroArch-Salamander\RetroArch-Salamander.vcproj", "{EA17F7A7-7E66-4E32-9BA3-DEC11E4BBA8E}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RetroArch-Salamander", "RetroArch-Xbox1-Salamander\RetroArch-Salamander.vcproj", "{EA17F7A7-7E66-4E32-9BA3-DEC11E4BBA8E}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject From 4a328960a4d744c096d3c80df6bd29c352768b4b Mon Sep 17 00:00:00 2001 From: Toad King Date: Mon, 6 Aug 2012 22:30:18 -0400 Subject: [PATCH 084/492] (Wii) prepare RGUI/gx_video for in-game menu --- console/rgui/rgui.c | 46 ++++++++++++++-------------- console/rgui/rgui.h | 2 +- wii/driver.h | 2 +- wii/frontend/main.c | 12 ++++---- wii/gx_video.c | 73 +++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 98 insertions(+), 37 deletions(-) diff --git a/console/rgui/rgui.c b/console/rgui/rgui.c index 3dc8c363ef..408c0a27b2 100644 --- a/console/rgui/rgui.c +++ b/console/rgui/rgui.c @@ -35,7 +35,7 @@ extern char app_dir[PATH_MAX]; struct rgui_handle { - uint16_t *frame_buf; + uint32_t *frame_buf; size_t frame_buf_pitch; const uint8_t *font_buf; @@ -49,8 +49,8 @@ struct rgui_handle char path_buf[PATH_MAX]; - uint16_t font_white[256][FONT_HEIGHT][FONT_WIDTH]; - uint16_t font_green[256][FONT_HEIGHT][FONT_WIDTH]; + uint32_t font_white[256][FONT_HEIGHT][FONT_WIDTH]; + uint32_t font_green[256][FONT_HEIGHT][FONT_WIDTH]; }; static const char *rgui_device_lables[] = { @@ -89,8 +89,8 @@ static inline bool rgui_is_filebrowser_menu(rgui_file_type_t menu_type) return (menu_type == RGUI_FILE_DIRECTORY || menu_type == RGUI_FILE_DEVICE || menu_type == RGUI_SETTINGS_CORE); } -static void copy_glyph(uint16_t glyph_white[FONT_HEIGHT][FONT_WIDTH], - uint16_t glyph_green[FONT_HEIGHT][FONT_WIDTH], +static void copy_glyph(uint32_t glyph_white[FONT_HEIGHT][FONT_WIDTH], + uint32_t glyph_green[FONT_HEIGHT][FONT_WIDTH], const uint8_t *buf) { for (int y = 0; y < FONT_HEIGHT; y++) @@ -102,8 +102,8 @@ static void copy_glyph(uint16_t glyph_white[FONT_HEIGHT][FONT_WIDTH], ((uint32_t)buf[3 * (-y * 256 + x) + 1] << 8) | ((uint32_t)buf[3 * (-y * 256 + x) + 2] << 16); - glyph_white[y][x] = col == 0xff ? 0 : 0x7fff; - glyph_green[y][x] = col == 0xff ? 0 : (5 << 10) | (20 << 5) | (5 << 0); + glyph_white[y][x] = col == 0xff ? 0 : 0xffffffff; + glyph_green[y][x] = col == 0xff ? 0 : (255 << 24) | (40 << 16) | (160 << 8) | (40 << 0); } } } @@ -121,7 +121,7 @@ static void init_font(rgui_handle_t *rgui, const char *path) } rgui_handle_t *rgui_init(const char *base_path, - uint16_t *buf, size_t buf_pitch, + uint32_t *buf, size_t buf_pitch, const uint8_t *font_buf, rgui_folder_enum_cb_t folder_cb, void *userdata) { @@ -150,32 +150,32 @@ void rgui_free(rgui_handle_t *rgui) free(rgui); } -static uint16_t gray_filler(unsigned x, unsigned y) +static uint32_t gray_filler(unsigned x, unsigned y) { x >>= 1; y >>= 1; - uint16_t col = ((x + y) & 1) + 1; - col <<= 1; - return (col << 0) | (col << 5) | (col << 10); + unsigned col = ((x + y) & 1) + 1; + col <<= 4; + return (224 << 24) | (col << 16) | (col << 8) | (col << 0); } -static uint16_t green_filler(unsigned x, unsigned y) +static uint32_t green_filler(unsigned x, unsigned y) { x >>= 1; y >>= 1; - uint16_t col = ((x + y) & 1) + 1; - col <<= 1; - return (col << 0) | (col << 6) | (col << 10); + unsigned col = ((x + y) & 1) + 1; + col <<= 3; + return (224 << 24) | (col << 16) | (col << 10) | (col << 0); } -static void fill_rect(uint16_t *buf, unsigned pitch, +static void fill_rect(uint32_t *buf, unsigned pitch, unsigned x, unsigned y, unsigned width, unsigned height, - uint16_t (*col)(unsigned x, unsigned y)) + uint32_t (*col)(unsigned x, unsigned y)) { for (unsigned j = y; j < y + height; j++) for (unsigned i = x; i < x + width; i++) - buf[j * (pitch >> 1) + i] = col(i, j); + buf[j * (pitch >> 2) + i] = col(i, j); } static void blit_line(rgui_handle_t *rgui, @@ -187,12 +187,12 @@ static void blit_line(rgui_handle_t *rgui, { for (unsigned i = 0; i < FONT_WIDTH; i++) { - uint16_t col = green ? + uint32_t col = green ? rgui->font_green[(unsigned char)*message][j][i] : rgui->font_white[(unsigned char)*message][j][i]; if (col) - rgui->frame_buf[(y + j) * (rgui->frame_buf_pitch >> 1) + (x + i)] = col; + rgui->frame_buf[(y + j) * (rgui->frame_buf_pitch >> 2) + (x + i)] = col; } } @@ -511,7 +511,7 @@ static const char *rgui_settings_iterate(rgui_handle_t *rgui, rgui_action_t acti label = app_dir; const char *dir = 0; rgui_file_type_t menu_type = 0; - size_t directory_ptr; + size_t directory_ptr = 0; rgui_list_back(rgui->path_stack, &dir, &menu_type, &directory_ptr); if (rgui->need_refresh) @@ -588,7 +588,7 @@ const char *rgui_iterate(rgui_handle_t *rgui, rgui_action_t action) bool found = false; const char *dir = 0; rgui_file_type_t menu_type = 0; - size_t directory_ptr; + size_t directory_ptr = 0; rgui_list_back(rgui->path_stack, &dir, &menu_type, &directory_ptr); if (menu_type == RGUI_SETTINGS || rgui_is_controller_menu(menu_type)) diff --git a/console/rgui/rgui.h b/console/rgui/rgui.h index 5e74acce10..c1875f0a6d 100644 --- a/console/rgui/rgui.h +++ b/console/rgui/rgui.h @@ -86,7 +86,7 @@ typedef bool (*rgui_folder_enum_cb_t)(const char *directory, #define RGUI_HEIGHT 240 rgui_handle_t *rgui_init(const char *base_path, - uint16_t *framebuf, size_t framebuf_pitch, + uint32_t *framebuf, size_t framebuf_pitch, const uint8_t *font_buf, rgui_folder_enum_cb_t folder_cb, void *userdata); diff --git a/wii/driver.h b/wii/driver.h index 4dcac411da..20cc5fc8c2 100644 --- a/wii/driver.h +++ b/wii/driver.h @@ -16,7 +16,7 @@ #ifndef WII_VIDEO_H__ #define WII_VIDEO_H__ -void wii_video_init(void); +void wii_video_init(uint32_t *menu_buffer); void wii_video_deinit(void); void wii_input_init(void); diff --git a/wii/frontend/main.c b/wii/frontend/main.c index 19588b01f7..1e7fd69bbf 100644 --- a/wii/frontend/main.c +++ b/wii/frontend/main.c @@ -44,7 +44,7 @@ FILE * log_fp; #endif -static uint16_t menu_framebuf[RGUI_WIDTH * RGUI_HEIGHT]; +static uint32_t menu_framebuf[RGUI_WIDTH * RGUI_HEIGHT]; char app_dir[PATH_MAX]; struct retro_system_info wii_core_info; @@ -181,9 +181,9 @@ static bool get_rom_path(rgui_handle_t *rgui) } const char *ret = rgui_iterate(rgui, action); - video_wii.frame(NULL, menu_framebuf, - RGUI_WIDTH, RGUI_HEIGHT, - RGUI_WIDTH * sizeof(uint16_t), NULL); + video_wii.frame(NULL, NULL, + 0, 0, + 0, NULL); if (ret) { @@ -242,7 +242,7 @@ int main(void) retro_get_system_info(&wii_core_info); RARCH_LOG("Core: %s\n", wii_core_info.library_name); - wii_video_init(); + wii_video_init(menu_framebuf); char tmp_path[PATH_MAX]; const char *extension = default_paths.executable_extension; @@ -262,7 +262,7 @@ int main(void) input_wii.post_init(); rgui_handle_t *rgui = rgui_init("", - menu_framebuf, RGUI_WIDTH * sizeof(uint16_t), + menu_framebuf, RGUI_WIDTH * sizeof(uint32_t), _binary_console_font_bmp_start, folder_cb, NULL); rgui_iterate(rgui, RGUI_ACTION_REFRESH); diff --git a/wii/gx_video.c b/wii/gx_video.c index 0f2d47665f..238463fc99 100644 --- a/wii/gx_video.c +++ b/wii/gx_video.c @@ -38,6 +38,14 @@ struct GXTexObj obj; } static g_tex ATTRIBUTE_ALIGN(32); +struct +{ + uint32_t data[240 * 320]; + GXTexObj obj; +} static menu_tex ATTRIBUTE_ALIGN(32); + +static uint32_t *menu_data; + static uint8_t gx_fifo[256 * 1024] ATTRIBUTE_ALIGN(32); static uint8_t display_list[1024] ATTRIBUTE_ALIGN(32); static size_t display_list_size; @@ -120,6 +128,8 @@ static void init_vtx(GXRModeObj *mode) GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLORNULL); GX_InvVtxCache(); + GX_SetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_INVSRCALPHA, 0); + GX_Flush(); } @@ -127,7 +137,8 @@ static void init_texture(unsigned width, unsigned height) { GX_InitTexObj(&g_tex.obj, g_tex.data, width, height, GX_TF_RGB5A3, GX_CLAMP, GX_CLAMP, GX_FALSE); GX_InitTexObjLOD(&g_tex.obj, g_filter, g_filter, 0, 0, 0, GX_TRUE, GX_FALSE, GX_ANISO_1); - GX_LoadTexObj(&g_tex.obj, GX_TEXMAP0); + GX_InitTexObj(&menu_tex.obj, menu_tex.data, 320, 240, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); + GX_InitTexObjLOD(&menu_tex.obj, g_filter, g_filter, 0, 0, 0, GX_TRUE, GX_FALSE, GX_ANISO_1); GX_InvalidateTexAll(); } @@ -145,7 +156,7 @@ static void build_disp_list(void) display_list_size = GX_EndDispList(); } -void wii_video_init(void) +void wii_video_init(uint32_t *menu_buffer) { VIDEO_Init(); GXRModeObj *mode = VIDEO_GetPreferredMode(NULL); @@ -161,6 +172,7 @@ void wii_video_init(void) g_filter = true; g_vsync = true; + menu_data = menu_buffer; } void wii_video_deinit(void) @@ -289,6 +301,20 @@ static void update_texture_asm(const uint32_t *src, src += pitch; \ } +#define BLIT_16(x) \ +{ \ + block[0 + 0 ] = line[x][0]; \ + block[0 + 16] = line[x][1]; \ + block[1 + 0 ] = line[x][2]; \ + block[1 + 16] = line[x][3]; \ + block[2 + 0 ] = line[x][4]; \ + block[2 + 16] = line[x][5]; \ + block[3 + 0 ] = line[x][6]; \ + block[3 + 16] = line[x][7]; \ + block += 4; \ + line[x] += 8; \ +} + static void update_texture(const uint32_t *src, unsigned width, unsigned height, unsigned pitch) { @@ -317,8 +343,33 @@ static void update_texture(const uint32_t *src, } } + // TODO: only convert when menu is visible + { + uint16_t *block = (uint16_t *) menu_tex.data; + uint16_t *line[4]; + for (uint32_t y = 0; y < 240; y += 4) + { + // fetch the next 4 scanlines + line[0] = (uint16_t *) &menu_data[(y + 0) * 320]; + line[1] = (uint16_t *) &menu_data[(y + 1) * 320]; + line[2] = (uint16_t *) &menu_data[(y + 2) * 320]; + line[3] = (uint16_t *) &menu_data[(y + 3) * 320]; + + for (unsigned x = 0; x < 320; x += 4) + { + BLIT_16(0) + BLIT_16(1) + BLIT_16(2) + BLIT_16(3) + + block += 16; + } + } + } + init_texture(width, height); DCFlushRange(g_tex.data, sizeof(g_tex.data)); + DCFlushRange(menu_tex.data, sizeof(menu_tex.data)); GX_InvalidateTexAll(); } @@ -329,8 +380,8 @@ static bool wii_frame(void *data, const void *frame, (void)data; (void)msg; - if(!frame) - return true; + //if(!frame) + // return true; while (g_vsync && !g_draw_done) LWP_ThreadSleep(g_video_cond); @@ -338,8 +389,18 @@ static bool wii_frame(void *data, const void *frame, g_draw_done = false; g_current_framebuf ^= 1; update_texture(frame, width, height, pitch); - GX_CallDispList(display_list, display_list_size); - GX_DrawDone(); + if (frame) + { + GX_LoadTexObj(&g_tex.obj, GX_TEXMAP0); + GX_CallDispList(display_list, display_list_size); + GX_DrawDone(); + } + else // TODO: in-game menu still needs this + { + GX_LoadTexObj(&menu_tex.obj, GX_TEXMAP0); + GX_CallDispList(display_list, display_list_size); + GX_DrawDone(); + } GX_CopyDisp(g_framebuf[g_current_framebuf], GX_TRUE); GX_Flush(); From 46210fce540a26e939c0eb14fc415f6fcc180037 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Tue, 7 Aug 2012 05:24:12 +0200 Subject: [PATCH 085/492] (Wii) Rename all Wii files to gx/ --- Makefile.wii | 2 +- Makefile.wii.salamander | 4 ++-- console/griffin/griffin.c | 8 ++++---- {wii => gx}/frontend/main.c | 0 {wii => gx}/gx_audio.c | 0 {wii => gx}/gx_input.c | 0 {wii => gx}/gx_input.h | 0 {wii => gx}/gx_video.c | 2 +- wii/driver.h => gx/gx_video.h | 4 ++-- {wii => gx}/pkg/cores/presets/.empty | 0 {wii => gx}/pkg/cores/presets/input/.empty | 0 {wii => gx}/pkg/cores/savestates/.empty | 0 {wii => gx}/pkg/cores/sram/.empty | 0 {wii => gx}/pkg/cores/system/.empty | 0 {wii => gx}/pkg/icon.png | Bin {wii => gx}/pkg/meta.xml | 4 ++-- {wii => gx}/salamander/main.c | 0 17 files changed, 12 insertions(+), 12 deletions(-) rename {wii => gx}/frontend/main.c (100%) rename {wii => gx}/gx_audio.c (100%) rename {wii => gx}/gx_input.c (100%) rename {wii => gx}/gx_input.h (100%) rename {wii => gx}/gx_video.c (99%) rename wii/driver.h => gx/gx_video.h (95%) rename {wii => gx}/pkg/cores/presets/.empty (100%) rename {wii => gx}/pkg/cores/presets/input/.empty (100%) rename {wii => gx}/pkg/cores/savestates/.empty (100%) rename {wii => gx}/pkg/cores/sram/.empty (100%) rename {wii => gx}/pkg/cores/system/.empty (100%) rename {wii => gx}/pkg/icon.png (100%) rename {wii => gx}/pkg/meta.xml (76%) rename {wii => gx}/salamander/main.c (100%) diff --git a/Makefile.wii b/Makefile.wii index 44208a10c4..5286a768a4 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -62,7 +62,7 @@ $(ELF_TARGET): $(OBJ) $(LD) -r -b binary -o $@ $< pkg: all - cp -r $(DOL_TARGET) wii/pkg/CORE.dol + cp -r $(DOL_TARGET) gx/pkg/CORE.dol clean: rm -f $(DOL_TARGET) diff --git a/Makefile.wii.salamander b/Makefile.wii.salamander index 48dc20eaf4..8f51129ba3 100644 --- a/Makefile.wii.salamander +++ b/Makefile.wii.salamander @@ -25,7 +25,7 @@ CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE) LDFLAGS := $(MACHDEP) -Wl,-Map,$(notdir $(ELF_TARGET)).map,--section-start,.init=0x81200000 LIBS := -lfat -lretro_wii -lwiiuse -logc -lbte -OBJ = wii/salamander/main.o console/rarch_console_exec.o console/rarch_console_libretro_mgmt.o file_path.o compat/compat.o conf/config_file.o console/exec/dol.o +OBJ = gx/salamander/main.o console/rarch_console_exec.o console/rarch_console_libretro_mgmt.o file_path.o compat/compat.o conf/config_file.o console/exec/dol.o ifeq ($(HAVE_LOGGER), 1) CFLAGS += -DHAVE_LOGGER @@ -62,7 +62,7 @@ $(ELF_TARGET): $(OBJ) $(LD) -r -b binary -o $@ $< pkg: all - cp -r $(DOL_TARGET) wii/pkg/boot.dol + cp -r $(DOL_TARGET) gx/pkg/boot.dol clean: rm -f $(DOL_TARGET) diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index 8eb34c3037..23cfd05181 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -127,7 +127,7 @@ VIDEO DRIVER #if defined(HAVE_OPENGL) #include "../../gfx/gl.c" #elif defined(GEKKO) -#include "../../wii/gx_video.c" +#include "../../gx/gx_video.c" #endif #include "../../gfx/gfx_common.c" @@ -161,7 +161,7 @@ INPUT #if defined(__CELLOS_LV2__) #include "../../ps3/ps3_input.c" #elif defined(GEKKO) -#include "../../wii/gx_input.c" +#include "../../gx/gx_input.c" #elif defined(_XBOX) #include "../../xdk/xdk_xinput_input.c" #endif @@ -213,7 +213,7 @@ AUDIO #elif defined(_XBOX360) #include "../../360/xdk360_audio.cpp" #elif defined(GEKKO) -#include "../../wii/gx_audio.c" +#include "../../gx/gx_audio.c" #endif #ifdef HAVE_DSOUND @@ -262,7 +262,7 @@ MAIN #if defined(_XBOX) #include "../../xdk/frontend/main.c" #elif defined(GEKKO) -#include "../../wii/frontend/main.c" +#include "../../gx/frontend/main.c" #endif /*============================================================ diff --git a/wii/frontend/main.c b/gx/frontend/main.c similarity index 100% rename from wii/frontend/main.c rename to gx/frontend/main.c diff --git a/wii/gx_audio.c b/gx/gx_audio.c similarity index 100% rename from wii/gx_audio.c rename to gx/gx_audio.c diff --git a/wii/gx_input.c b/gx/gx_input.c similarity index 100% rename from wii/gx_input.c rename to gx/gx_input.c diff --git a/wii/gx_input.h b/gx/gx_input.h similarity index 100% rename from wii/gx_input.h rename to gx/gx_input.h diff --git a/wii/gx_video.c b/gx/gx_video.c similarity index 99% rename from wii/gx_video.c rename to gx/gx_video.c index 238463fc99..52148b9295 100644 --- a/wii/gx_video.c +++ b/gx/gx_video.c @@ -15,7 +15,7 @@ #include "../driver.h" #include "../general.h" -#include "driver.h" +#include "gx_video.h" #include #include #include diff --git a/wii/driver.h b/gx/gx_video.h similarity index 95% rename from wii/driver.h rename to gx/gx_video.h index 20cc5fc8c2..53cf20bd7d 100644 --- a/wii/driver.h +++ b/gx/gx_video.h @@ -13,8 +13,8 @@ * If not, see . */ -#ifndef WII_VIDEO_H__ -#define WII_VIDEO_H__ +#ifndef _GX_VIDEO_H__ +#define _GX_VIDEO_H__ void wii_video_init(uint32_t *menu_buffer); void wii_video_deinit(void); diff --git a/wii/pkg/cores/presets/.empty b/gx/pkg/cores/presets/.empty similarity index 100% rename from wii/pkg/cores/presets/.empty rename to gx/pkg/cores/presets/.empty diff --git a/wii/pkg/cores/presets/input/.empty b/gx/pkg/cores/presets/input/.empty similarity index 100% rename from wii/pkg/cores/presets/input/.empty rename to gx/pkg/cores/presets/input/.empty diff --git a/wii/pkg/cores/savestates/.empty b/gx/pkg/cores/savestates/.empty similarity index 100% rename from wii/pkg/cores/savestates/.empty rename to gx/pkg/cores/savestates/.empty diff --git a/wii/pkg/cores/sram/.empty b/gx/pkg/cores/sram/.empty similarity index 100% rename from wii/pkg/cores/sram/.empty rename to gx/pkg/cores/sram/.empty diff --git a/wii/pkg/cores/system/.empty b/gx/pkg/cores/system/.empty similarity index 100% rename from wii/pkg/cores/system/.empty rename to gx/pkg/cores/system/.empty diff --git a/wii/pkg/icon.png b/gx/pkg/icon.png similarity index 100% rename from wii/pkg/icon.png rename to gx/pkg/icon.png diff --git a/wii/pkg/meta.xml b/gx/pkg/meta.xml similarity index 76% rename from wii/pkg/meta.xml rename to gx/pkg/meta.xml index 9ccfc75bca..3378a0916b 100644 --- a/wii/pkg/meta.xml +++ b/gx/pkg/meta.xml @@ -1,7 +1,7 @@ - RetroArch Wii - Themaister, Squarepusher2, ToadKing + RetroArch GX + Maister, Squarepusher2, ToadKing 0.9.6 2012 Multi-system emulator diff --git a/wii/salamander/main.c b/gx/salamander/main.c similarity index 100% rename from wii/salamander/main.c rename to gx/salamander/main.c From d78cab023bcbd8723e2e01113e9104e3af9bf5e0 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Tue, 7 Aug 2012 05:27:27 +0200 Subject: [PATCH 086/492] (GX) Add HW_RVL ifdef --- gx/frontend/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gx/frontend/main.c b/gx/frontend/main.c index 1e7fd69bbf..5eb12cac09 100644 --- a/gx/frontend/main.c +++ b/gx/frontend/main.c @@ -36,7 +36,9 @@ #include #include +#ifdef HW_RVL #include +#endif #include #include From a413b4126f2eb8f1341e002ac584eaad731bd7e6 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Tue, 7 Aug 2012 05:30:14 +0200 Subject: [PATCH 087/492] (GX) Take out some unused and unimplemented stubs --- gx/gx_input.h | 2 ++ gx/gx_video.h | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/gx/gx_input.h b/gx/gx_input.h index 86f9e24d7d..2b35da0c10 100644 --- a/gx/gx_input.h +++ b/gx/gx_input.h @@ -179,9 +179,11 @@ enum wii_device_id enum { GX_DEVICE_GAMECUBE = 0, +#ifdef HW_RVL GX_DEVICE_WIIMOTE, GX_DEVICE_NUNCHUK, GX_DEVICE_CLASSIC, +#endif RARCH_DEVICE_LAST }; diff --git a/gx/gx_video.h b/gx/gx_video.h index 53cf20bd7d..0082d75a9b 100644 --- a/gx/gx_video.h +++ b/gx/gx_video.h @@ -19,8 +19,5 @@ void wii_video_init(uint32_t *menu_buffer); void wii_video_deinit(void); -void wii_input_init(void); -void wii_input_deinit(void); - #endif From 0fc1a37872c34b8d87cf654e595c9b17313e07d8 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Tue, 7 Aug 2012 06:04:17 +0200 Subject: [PATCH 088/492] (GX) Get rid of static variables in gx_video.c --- gx/gx_video.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/gx/gx_video.c b/gx/gx_video.c index 52148b9295..9c65cd9ffb 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -24,31 +24,31 @@ // All very hardcoded for now. -static void *g_framebuf[2]; -static unsigned g_current_framebuf; +void *g_framebuf[2]; +unsigned g_current_framebuf; -static unsigned g_filter; -static bool g_vsync; -static lwpq_t g_video_cond; -static volatile bool g_draw_done; +unsigned g_filter; +bool g_vsync; +lwpq_t g_video_cond; +volatile bool g_draw_done; struct { uint32_t data[512 * 256]; GXTexObj obj; -} static g_tex ATTRIBUTE_ALIGN(32); +} g_tex ATTRIBUTE_ALIGN(32); struct { uint32_t data[240 * 320]; GXTexObj obj; -} static menu_tex ATTRIBUTE_ALIGN(32); +} menu_tex ATTRIBUTE_ALIGN(32); -static uint32_t *menu_data; +uint32_t *menu_data; -static uint8_t gx_fifo[256 * 1024] ATTRIBUTE_ALIGN(32); -static uint8_t display_list[1024] ATTRIBUTE_ALIGN(32); -static size_t display_list_size; +uint8_t gx_fifo[256 * 1024] ATTRIBUTE_ALIGN(32); +uint8_t display_list[1024] ATTRIBUTE_ALIGN(32); +size_t display_list_size; static void retrace_callback(u32 retrace_count) { @@ -78,14 +78,14 @@ static void setup_video_mode(GXRModeObj *mode) VIDEO_WaitVSync(); } -static float verts[16] ATTRIBUTE_ALIGN(32) = { +float verts[16] ATTRIBUTE_ALIGN(32) = { -1, 1, -0.5, -1, -1, -0.5, 1, -1, -0.5, 1, 1, -0.5, }; -static float tex_coords[8] ATTRIBUTE_ALIGN(32) = { +float tex_coords[8] ATTRIBUTE_ALIGN(32) = { 0, 0, 0, 1, 1, 1, From ee77a2dac7d173c2638b995ba8dbceb4b5973531 Mon Sep 17 00:00:00 2001 From: freakdave Date: Tue, 7 Aug 2012 14:39:27 +0200 Subject: [PATCH 089/492] (Xbox 1) Fixed screen rotation code --- console/salamander/main.c | 2 +- xbox1/xdk_d3d8.cpp | 27 +++++++++++++-------------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/console/salamander/main.c b/console/salamander/main.c index d5b944ac19..be23b1573f 100644 --- a/console/salamander/main.c +++ b/console/salamander/main.c @@ -249,7 +249,7 @@ static void callback_sysutil_exit(uint64_t status, uint64_t param, void *userdat int main(int argc, char *argv[]) { #if defined(_XBOX) - XINPUT_STATE state; + XINPUT_STATE state; //C4101 get_environment_settings(); diff --git a/xbox1/xdk_d3d8.cpp b/xbox1/xdk_d3d8.cpp index 462b266153..90c7e49bfb 100644 --- a/xbox1/xdk_d3d8.cpp +++ b/xbox1/xdk_d3d8.cpp @@ -33,6 +33,7 @@ wchar_t strw_buffer[128]; unsigned font_x, font_y; +FLOAT angle; static void check_window(xdk_d3d_video_t *d3d) { @@ -147,31 +148,26 @@ static void xdk_d3d_set_rotation(void * data, unsigned orientation) { (void)data; xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)data; - FLOAT angle; switch(orientation) { case ORIENTATION_NORMAL: angle = M_PI * 0 / 180; + RARCH_LOG("D3D8: Set rotation to ORIENTATION_NORMAL\n"); break; case ORIENTATION_VERTICAL: angle = M_PI * 270 / 180; + RARCH_LOG("D3D8: Set rotation to ORIENTATION_VERTICAL\n"); break; case ORIENTATION_FLIPPED: angle = M_PI * 180 / 180; + RARCH_LOG("D3D8: Set rotation to ORIENTATION_FLIPPED\n"); break; case ORIENTATION_FLIPPED_ROTATED: angle = M_PI * 90 / 180; + RARCH_LOG("D3D8: Set rotation to ORIENTATION_FLIPPED_ROTATED\n"); break; } - - /* - D3DXMATRIX p_out; - D3DXMatrixIdentity(&p_out); - d3d->d3d_render_device->SetTransform(D3DTS_PROJECTION, &p_out); - - d3d->should_resize = TRUE; - */ } static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **input, void **input_data) @@ -187,7 +183,7 @@ static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **inpu if (!d3d->d3d_device) { free(d3d); - RARCH_ERR("Failed to create a D3D8 object.\n"); + RARCH_ERR("D3D8: Failed to create a D3D8 object.\n"); return NULL; } @@ -429,13 +425,16 @@ static bool xdk_d3d_frame(void *data, const void *frame, d3d->d3d_render_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); d3d->d3d_render_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); - D3DXMATRIX p_out; + d3d->d3d_render_device->SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1); + + D3DXMATRIX p_out, p_rotate; D3DXMatrixIdentity(&p_out); - d3d->d3d_render_device->SetTransform(D3DTS_WORLD, &p_out); + D3DXMatrixRotationZ(&p_rotate, angle); + + d3d->d3d_render_device->SetTransform(D3DTS_WORLD, &p_rotate); d3d->d3d_render_device->SetTransform(D3DTS_VIEW, &p_out); d3d->d3d_render_device->SetTransform(D3DTS_PROJECTION, &p_out); - d3d->d3d_render_device->SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1); d3d->d3d_render_device->SetStreamSource(0, d3d->vertex_buf, sizeof(DrawVerticeFormats)); d3d->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0); @@ -483,7 +482,7 @@ static void xdk_d3d_set_nonblock_state(void *data, bool state) if(d3d->vsync) { - RARCH_LOG("D3D Vsync => %s\n", state ? "off" : "on"); + RARCH_LOG("D3D8: Vsync => %s\n", state ? "off" : "on"); gfx_ctx_set_swap_interval(state ? 0 : 1, TRUE); } } From b174eb3f7a312f69926911573e96481bfa24e1a6 Mon Sep 17 00:00:00 2001 From: freakdave Date: Tue, 7 Aug 2012 16:26:12 +0200 Subject: [PATCH 090/492] (Xbox 1) Small but necessary bug fix in screen resize code (rmenu) --- console/rmenu/rmenu.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index bcdd202ddb..ae8671141e 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -1868,15 +1868,23 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) gfx_ctx_set_aspect_ratio(NULL, g_console.aspect_ratio_index); if(input & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_LEFT)) -#ifdef _XBOX1 + { +#ifdef _XBOX if(g_console.viewports.custom_vp.x >= 4) #endif + { g_console.viewports.custom_vp.x -= 4; + } + } else if(input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) -#ifdef _XBOX1 + { +#ifdef _XBOX if(g_console.viewports.custom_vp.x > 0) #endif + { g_console.viewports.custom_vp.x -= 1; + } + } if(input & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_RIGHT)) g_console.viewports.custom_vp.x += 4; @@ -1889,15 +1897,23 @@ static void ingame_menu_resize(item *items, menu *current_menu, uint64_t input) g_console.viewports.custom_vp.y += 1; if(input & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_DOWN)) -#ifdef _XBOX1 + { +#ifdef _XBOX if(g_console.viewports.custom_vp.y >= 4) #endif + { g_console.viewports.custom_vp.y -= 4; + } + } else if(input & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)) -#ifdef _XBOX1 + { +#ifdef _XBOX if(g_console.viewports.custom_vp.y > 0) #endif + { g_console.viewports.custom_vp.y -= 1; + } + } if(input & (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_RIGHT_DPAD_LEFT)) g_console.viewports.custom_vp.width -= 4; From 565e7e0a6dcd1a196581a2db87fcee631951bce1 Mon Sep 17 00:00:00 2001 From: freakdave Date: Tue, 7 Aug 2012 16:36:29 +0200 Subject: [PATCH 091/492] (Xbox 1) Set SDFilter to default value (disabled), leave FFilter at 1 though --- gfx/context/xdk_ctx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/context/xdk_ctx.c b/gfx/context/xdk_ctx.c index 8b69a01594..67e4ae0878 100644 --- a/gfx/context/xdk_ctx.c +++ b/gfx/context/xdk_ctx.c @@ -88,7 +88,7 @@ void gfx_ctx_clear(void) #ifdef _XBOX1 device_ptr->d3d_render_device->BeginScene(); device_ptr->d3d_render_device->SetFlickerFilter(1); - device_ptr->d3d_render_device->SetSoftDisplayFilter(1); + device_ptr->d3d_render_device->SetSoftDisplayFilter(false); #endif } From a9de8e41e5c572ed30d0a41e14953bd6391286f9 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 7 Aug 2012 18:26:52 +0200 Subject: [PATCH 092/492] (Xbox 1) Add flicker filter and soft display filter options in Settings menu --- console/rmenu/rmenu.c | 38 +++++++++++++++++++++++++++++++++++ console/rmenu/rmenu.h | 4 ++++ console/rmenu/rmenu_entries.h | 22 ++++++++++++++++++++ general.h | 4 ++++ gfx/context/xdk_ctx.c | 7 +++++-- xbox1/xdk_d3d8.cpp | 4 ++++ 6 files changed, 77 insertions(+), 2 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index ae8671141e..cd3657496c 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -190,6 +190,16 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "%fx (X) / %fx (Y)", g_settings.video.fbo_scale_x, g_settings.video.fbo_scale_y); snprintf(items[currentsetting].comment, sizeof(items[currentsetting].comment), "INFO - [Custom Scaling Factor] is set to: '%fx (X) / %fx (Y)'.", g_settings.video.fbo_scale_x, g_settings.video.fbo_scale_y); break; +#endif +#ifdef _XBOX1 + case SETTING_FLICKER_FILTER: + set_setting_label_color(items,g_console.flicker_filter == 0, currentsetting); + snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "%d", g_console.flicker_filter); + break; + case SETTING_SOFT_DISPLAY_FILTER: + set_setting_label_write_on_or_off(items, g_console.soft_display_filter_enable, currentsetting); + set_setting_label_color(items,g_console.soft_display_filter_enable, currentsetting); + break; #endif case SETTING_HW_OVERSCAN_AMOUNT: set_setting_label_color(items,g_console.overscan_amount == 0.0f, currentsetting); @@ -1267,6 +1277,34 @@ static void producesettingentry(menu *current_menu, item *items, unsigned switch apply_scaling(FBO_INIT); } break; +#endif +#ifdef _XBOX1 + case SETTING_FLICKER_FILTER: + if(input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) + { + if(g_console.flicker_filter > 0) + g_console.flicker_filter--; + } + if(input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) + { + if(g_console.flicker_filter < 5) + g_console.flicker_filter++; + } + if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) + { + g_console.flicker_filter = 0; + } + break; + case SETTING_SOFT_DISPLAY_FILTER: + if(input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input & (1 << RETRO_DEVICE_ID_JOYPAD_B))) + { + g_console.soft_display_filter_enable = !g_console.soft_display_filter_enable; + } + if(input & (1 << RETRO_DEVICE_ID_JOYPAD_START)) + { + g_console.soft_display_filter_enable = true; + } + break; #endif case SETTING_HW_OVERSCAN_AMOUNT: if(input & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) diff --git a/console/rmenu/rmenu.h b/console/rmenu/rmenu.h index 9ed18c6ed3..dab170cfee 100644 --- a/console/rmenu/rmenu.h +++ b/console/rmenu/rmenu.h @@ -145,6 +145,10 @@ enum SETTING_HW_TEXTURE_FILTER_2, SETTING_SCALE_ENABLED, SETTING_SCALE_FACTOR, +#endif +#ifdef _XBOX1 + SETTING_FLICKER_FILTER, + SETTING_SOFT_DISPLAY_FILTER, #endif SETTING_HW_OVERSCAN_AMOUNT, SETTING_THROTTLE_MODE, diff --git a/console/rmenu/rmenu_entries.h b/console/rmenu/rmenu_entries.h index d60700b283..71361a0463 100644 --- a/console/rmenu/rmenu_entries.h +++ b/console/rmenu/rmenu_entries.h @@ -121,6 +121,28 @@ item rmenu_items[MAX_NO_OF_CONTROLS_SETTINGS] = "INFO - [Custom Scaling Factor] is set to '2x'.", WHITE, }, +#endif +#ifdef _XBOX1 + { + SETTING_FLICKER_FILTER, + "Flicker Filter", + "", + 0.0f, + 0.0f, + YELLOW, + "INFO - Toggle the [Flicker Filter].", + WHITE, + }, + { + SETTING_SOFT_DISPLAY_FILTER, + "Soft Display Filter", + "", + 0.0f, + 0.0f, + YELLOW, + "INFO - Toggle the [Soft Display Filter].", + WHITE, + }, #endif { SETTING_HW_OVERSCAN_AMOUNT, diff --git a/general.h b/general.h index 288a806585..cae185b275 100644 --- a/general.h +++ b/general.h @@ -211,6 +211,10 @@ struct console_settings bool frame_advance_enable; #ifdef _XBOX bool menus_hd_enable; +#endif +#ifdef _XBOX1 + unsigned flicker_filter; + bool soft_display_filter_enable; #endif bool initialize_rarch_enable; bool info_msg_enable; diff --git a/gfx/context/xdk_ctx.c b/gfx/context/xdk_ctx.c index 67e4ae0878..fc28810283 100644 --- a/gfx/context/xdk_ctx.c +++ b/gfx/context/xdk_ctx.c @@ -83,12 +83,15 @@ void gfx_ctx_swap_buffers(void) void gfx_ctx_clear(void) { xdk_d3d_video_t *device_ptr = (xdk_d3d_video_t*)driver.video_data; + unsigned flicker_filter = g_console.flicker_filter; + bool soft_filter_enable = g_console.soft_display_filter_enable; + device_ptr->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0); #ifdef _XBOX1 device_ptr->d3d_render_device->BeginScene(); - device_ptr->d3d_render_device->SetFlickerFilter(1); - device_ptr->d3d_render_device->SetSoftDisplayFilter(false); + device_ptr->d3d_render_device->SetFlickerFilter(flicker_filter); + device_ptr->d3d_render_device->SetSoftDisplayFilter(soft_filter_enable); #endif } diff --git a/xbox1/xdk_d3d8.cpp b/xbox1/xdk_d3d8.cpp index 90c7e49bfb..0836d4f4a3 100644 --- a/xbox1/xdk_d3d8.cpp +++ b/xbox1/xdk_d3d8.cpp @@ -365,6 +365,8 @@ static bool xdk_d3d_frame(void *data, const void *frame, xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)data; bool menu_enabled = g_console.menu_enable; bool fps_enable = g_console.fps_info_msg_enable; + unsigned flicker_filter = g_console.flicker_filter; + bool soft_filter_enable = g_console.soft_display_filter_enable; if (d3d->last_width != width || d3d->last_height != height) //240*160 { @@ -439,6 +441,8 @@ static bool xdk_d3d_frame(void *data, const void *frame, d3d->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0); d3d->d3d_render_device->BeginScene(); + d3d->d3d_render_device->SetFlickerFilter(flicker_filter); + d3d->d3d_render_device->SetSoftDisplayFilter(soft_filter_enable); d3d->d3d_render_device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); d3d->d3d_render_device->EndScene(); From ae7292b1114705a69d42baaa5bed215700ba8f6c Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 7 Aug 2012 18:33:16 +0200 Subject: [PATCH 093/492] (Xbox 1) Save flicker filter and soft filter in config file --- console/rarch_console_config.c | 18 +++++++++++++----- console/rarch_console_settings.c | 4 ++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/console/rarch_console_config.c b/console/rarch_console_config.c index 5515e27582..2278ac22fa 100644 --- a/console/rarch_console_config.c +++ b/console/rarch_console_config.c @@ -58,10 +58,6 @@ void rarch_config_load(const char * conf_name, const char * libretro_dir_path, c CONFIG_GET_FLOAT(video.fbo_scale_y, "video_fbo_scale_y"); CONFIG_GET_BOOL(video.render_to_texture, "video_render_to_texture"); CONFIG_GET_BOOL(video.second_pass_smooth, "video_second_pass_smooth"); -#endif -#ifdef _XBOX360 - CONFIG_GET_BOOL_CONSOLE(gamma_correction_enable, "gamma_correction_enable"); - CONFIG_GET_INT_CONSOLE(color_format, "color_format"); #endif CONFIG_GET_BOOL(video.smooth, "video_smooth"); CONFIG_GET_BOOL(video.vsync, "video_vsync"); @@ -100,6 +96,14 @@ void rarch_config_load(const char * conf_name, const char * libretro_dir_path, c CONFIG_GET_INT_CONSOLE(sound_mode, "sound_mode"); #ifdef HAVE_ZLIB CONFIG_GET_INT_CONSOLE(zip_extract_mode, "zip_extract_mode"); +#endif +#ifdef _XBOX360 + CONFIG_GET_BOOL_CONSOLE(gamma_correction_enable, "gamma_correction_enable"); + CONFIG_GET_INT_CONSOLE(color_format, "color_format"); +#endif +#ifdef _XBOX1 + CONFIG_GET_INT_CONSOLE(flicker_filter, "fliker_filter"); + CONFIG_GET_BOOL_CONSOLE(soft_display_filter_enable, "soft_display_filter_enable"); #endif CONFIG_GET_STRING_CONSOLE(default_rom_startup_dir, "default_rom_startup_dir"); CONFIG_GET_FLOAT_CONSOLE(menu_font_size, "menu_font_size"); @@ -152,9 +156,13 @@ void rarch_config_save(const char * conf_name) #endif config_set_bool(conf, "overscan_enable", g_console.overscan_enable); config_set_bool(conf, "screenshots_enable", g_console.screenshots_enable); -#ifdef _XBOX +#ifdef _XBOX360 config_set_bool(conf, "gamma_correction_enable", g_console.gamma_correction_enable); config_set_int(conf, "color_format", g_console.color_format); +#endif +#ifdef _XBOX1 + config_set_bool(conf, "soft_display_filter_enable", g_console.soft_display_filter_enable); + config_set_int(conf, "flicker_filter", g_console.flicker_filter); #endif config_set_bool(conf, "throttle_enable", g_console.throttle_enable); config_set_bool(conf, "triple_buffering_enable", g_console.triple_buffering_enable); diff --git a/console/rarch_console_settings.c b/console/rarch_console_settings.c index 214cf7b5ef..aad9a1d802 100644 --- a/console/rarch_console_settings.c +++ b/console/rarch_console_settings.c @@ -386,6 +386,10 @@ void rarch_settings_set_default (const input_driver_t *input) g_console.color_format = 0; g_console.gamma_correction_enable = 1; #endif +#ifdef _XBOX1 + g_console.flicker_filter = 1; + g_console.soft_display_filter_enable = false; +#endif #ifdef HAVE_ZLIB g_console.zip_extract_mode = 0; #endif From c850fa956fac8138e724cc7bac603d46aed8fc0f Mon Sep 17 00:00:00 2001 From: Toad King Date: Tue, 7 Aug 2012 13:12:51 -0400 Subject: [PATCH 094/492] (GX) video changes --- gx/frontend/main.c | 9 ++++-- gx/gx_video.c | 74 ++++++++++++++++++++++++++++++---------------- gx/gx_video.h | 6 ++-- 3 files changed, 58 insertions(+), 31 deletions(-) diff --git a/gx/frontend/main.c b/gx/frontend/main.c index 5eb12cac09..4163fab3fb 100644 --- a/gx/frontend/main.c +++ b/gx/frontend/main.c @@ -46,7 +46,7 @@ FILE * log_fp; #endif -static uint32_t menu_framebuf[RGUI_WIDTH * RGUI_HEIGHT]; +uint32_t menu_framebuf[320 * 240]; char app_dir[PATH_MAX]; struct retro_system_info wii_core_info; @@ -244,7 +244,10 @@ int main(void) retro_get_system_info(&wii_core_info); RARCH_LOG("Core: %s\n", wii_core_info.library_name); - wii_video_init(menu_framebuf); + video_wii.start(); + + gx_video_t *gx = (gx_video_t*)driver.video_data; + gx->menu_data = menu_framebuf; char tmp_path[PATH_MAX]; const char *extension = default_paths.executable_extension; @@ -289,7 +292,7 @@ int main(void) if(g_console.emulator_initialized) rarch_main_deinit(); - wii_video_deinit(); + video_wii.stop(); input_wii.free(NULL); #ifdef HAVE_FILE_LOGGER diff --git a/gx/gx_video.c b/gx/gx_video.c index 9c65cd9ffb..51811dcc05 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -44,8 +44,6 @@ struct GXTexObj obj; } menu_tex ATTRIBUTE_ALIGN(32); -uint32_t *menu_data; - uint8_t gx_fifo[256 * 1024] ATTRIBUTE_ALIGN(32); uint8_t display_list[1024] ATTRIBUTE_ALIGN(32); size_t display_list_size; @@ -156,8 +154,50 @@ static void build_disp_list(void) display_list_size = GX_EndDispList(); } -void wii_video_init(uint32_t *menu_buffer) +static void gx_stop(void) { + GX_AbortFrame(); + GX_Flush(); + VIDEO_SetBlack(true); + VIDEO_Flush(); + + for (unsigned i = 0; i < 2; i++) + free(MEM_K1_TO_K0(g_framebuf[i])); +} + +static void gx_restart(void) +{ +} + +static void *wii_init(const video_info_t *video, + const input_driver_t **input, void **input_data) +{ + if (driver.video_data) + return driver.video_data; + + gx_video_t *gx = (gx_video_t*)calloc(1, sizeof(gx_video_t)); + if (!gx) + return NULL; + + g_filter = video->smooth ? GX_LINEAR : GX_NEAR; + g_vsync = video->vsync; + + return gx; +} + +static void gx_start(void) +{ + video_info_t video_info = {0}; + + video_info.vsync = g_settings.video.vsync; + video_info.force_aspect = false; + video_info.fullscreen = true; + video_info.smooth = g_settings.video.smooth; + video_info.input_scale = 2; + + driver.video_data = wii_init(&video_info, NULL, NULL); + + //gx_video_t *gx = (gx_video_t*)driver.video_data; VIDEO_Init(); GXRModeObj *mode = VIDEO_GetPreferredMode(NULL); setup_video_mode(mode); @@ -172,29 +212,6 @@ void wii_video_init(uint32_t *menu_buffer) g_filter = true; g_vsync = true; - menu_data = menu_buffer; -} - -void wii_video_deinit(void) -{ - GX_AbortFrame(); - GX_Flush(); - VIDEO_SetBlack(true); - VIDEO_Flush(); - - for (unsigned i = 0; i < 2; i++) - free(MEM_K1_TO_K0(g_framebuf[i])); -} - -static void *wii_init(const video_info_t *video, - const input_driver_t **input, void **input_data) -{ - g_filter = video->smooth ? GX_LINEAR : GX_NEAR; - g_vsync = video->vsync; - - *input = NULL; - *input_data = NULL; - return (void*)-1; } #if 0 @@ -318,6 +335,7 @@ static void update_texture_asm(const uint32_t *src, static void update_texture(const uint32_t *src, unsigned width, unsigned height, unsigned pitch) { + gx_video_t *gx = (gx_video_t*)driver.video_data; #if 0 if (!(width & 3) && !(height & 3)) { @@ -349,6 +367,7 @@ static void update_texture(const uint32_t *src, uint16_t *line[4]; for (uint32_t y = 0; y < 240; y += 4) { + uint32_t *menu_data = gx->menu_data; // fetch the next 4 scanlines line[0] = (uint16_t *) &menu_data[(y + 0) * 320]; line[1] = (uint16_t *) &menu_data[(y + 1) * 320]; @@ -450,4 +469,7 @@ const video_driver_t video_wii = { .free = wii_free, .ident = "wii", .set_rotation = wii_set_rotation, + .start = gx_start, + .stop = gx_stop, + .restart = gx_restart, }; diff --git a/gx/gx_video.h b/gx/gx_video.h index 0082d75a9b..0640f7ed66 100644 --- a/gx/gx_video.h +++ b/gx/gx_video.h @@ -16,8 +16,10 @@ #ifndef _GX_VIDEO_H__ #define _GX_VIDEO_H__ -void wii_video_init(uint32_t *menu_buffer); -void wii_video_deinit(void); +typedef struct gx_video +{ + uint32_t *menu_data; +} gx_video_t; #endif From 54353961e1212edd0a2b390f0966e792a308683f Mon Sep 17 00:00:00 2001 From: Themaister Date: Tue, 7 Aug 2012 21:27:59 +0200 Subject: [PATCH 095/492] Fix build for Win32. --- Makefile.win | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.win b/Makefile.win index 9211afe4dd..c1f788f906 100644 --- a/Makefile.win +++ b/Makefile.win @@ -115,7 +115,7 @@ ifeq ($(HAVE_DYLIB), 1) endif ifeq ($(HAVE_NETPLAY), 1) - DEFINES += -DHAVE_NETPLAY -DHAVE_NETWORK_CMD + DEFINES += -DHAVE_NETPLAY -DHAVE_NETWORK_CMD -DHAVE_COMMAND OBJ += netplay.o command.o LIBS += -lws2_32 endif From 01f9ad8d8d9357db14f7c315f841ac2a73731a85 Mon Sep 17 00:00:00 2001 From: Themaister Date: Tue, 7 Aug 2012 21:31:43 +0200 Subject: [PATCH 096/492] Build in STDIN_CMD on Win32. --- Makefile.win | 10 ++++++++-- command.c | 3 +-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Makefile.win b/Makefile.win index c1f788f906..f02a6d15ca 100644 --- a/Makefile.win +++ b/Makefile.win @@ -35,6 +35,7 @@ HAVE_SDL = 1 HAVE_OPENGL = 1 HAVE_DYLIB = 1 HAVE_NETPLAY = 1 +HAVE_STDIN_CMD = 1 HAVE_THREADS = 1 DYNAMIC = 1 @@ -114,9 +115,14 @@ ifeq ($(HAVE_DYLIB), 1) DEFINES += -DHAVE_DYLIB endif +ifeq ($(HAVE_STDIN_CMD), 1) + DEFINES += -DHAVE_COMMAND -DHAVE_STDIN_CMD + OBJ += command.o +endif + ifeq ($(HAVE_NETPLAY), 1) - DEFINES += -DHAVE_NETPLAY -DHAVE_NETWORK_CMD -DHAVE_COMMAND - OBJ += netplay.o command.o + DEFINES += -DHAVE_NETPLAY -DHAVE_NETWORK_CMD + OBJ += netplay.o LIBS += -lws2_32 endif diff --git a/command.c b/command.c index 91b5288b0b..06f32c110f 100644 --- a/command.c +++ b/command.c @@ -267,8 +267,7 @@ static size_t read_stdin(char *buf, size_t size) avail = size; DWORD has_read = 0; - ret = ReadFile(hnd, buf, avail, &has_read, NULL); - if (!ret) + if (!ReadFile(hnd, buf, avail, &has_read, NULL)) return 0; return has_read; From c76a4b4092ada7e8067f85f7b43b18dc24bf1cda Mon Sep 17 00:00:00 2001 From: Themaister Date: Tue, 7 Aug 2012 22:36:44 +0200 Subject: [PATCH 097/492] Nonblock console reads appear to work on Win32. --- command.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/command.c b/command.c index 06f32c110f..b34e6ceaeb 100644 --- a/command.c +++ b/command.c @@ -238,7 +238,6 @@ static void network_cmd_pre_frame(rarch_cmd_t *handle) #ifdef _WIN32 // Oh you, Win32 ... <_< -// TODO: Untested! Might not compile nor work. static size_t read_stdin(char *buf, size_t size) { HANDLE hnd = GetStdHandle(STD_INPUT_HANDLE); @@ -248,16 +247,45 @@ static size_t read_stdin(char *buf, size_t size) // Check first if we're a pipe // (not console). DWORD avail = 0; + bool echo = false; // If not a pipe, check if we're running in a console. if (!PeekNamedPipe(hnd, NULL, 0, NULL, &avail, NULL)) { - DWORD mode; + DWORD mode = 0; if (!GetConsoleMode(hnd, &mode)) return 0; - if (!GetNumberOfConsoleInputEvents(hnd, &avail)) + if ((mode & (ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT)) + && !SetConsoleMode(hnd, mode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT))) return 0; + + // Win32, Y U NO SANE NONBLOCK READ!? + DWORD has_read = 0; + INPUT_RECORD recs[256]; + if (!PeekConsoleInput(hnd, recs, sizeof(recs) / sizeof(recs[0]), &has_read)) + return 0; + + bool has_key = false; + for (DWORD i = 0; i < has_read; i++) + { + // Very crude, but should get the job done ... + if (recs[i].EventType == KEY_EVENT && + recs[i].Event.KeyEvent.bKeyDown && + (isgraph(recs[i].Event.KeyEvent.wVirtualKeyCode) || recs[i].Event.KeyEvent.wVirtualKeyCode == VK_RETURN)) + { + has_key = true; + echo = true; + avail = size; + break; + } + } + + if (!has_key) + { + FlushConsoleInputBuffer(hnd); + return 0; + } } if (!avail) @@ -270,6 +298,21 @@ static size_t read_stdin(char *buf, size_t size) if (!ReadFile(hnd, buf, avail, &has_read, NULL)) return 0; + for (DWORD i = 0; i < has_read; i++) + if (buf[i] == '\r') + buf[i] = '\n'; + + // Console won't echo for us while in non-line mode, so do it manually ... + if (echo) + { + HANDLE hnd_out = GetStdHandle(STD_OUTPUT_HANDLE); + if (hnd_out != INVALID_HANDLE_VALUE) + { + DWORD has_written; + WriteConsole(hnd_out, buf, has_read, &has_written, NULL); + } + } + return has_read; } #else @@ -297,7 +340,7 @@ static void stdin_cmd_pre_frame(rarch_cmd_t *handle) if (!handle->stdin_enable) return; - size_t ret = read_stdin(handle->stdin_buf, STDIN_BUF_SIZE - handle->stdin_buf_ptr - 1); + size_t ret = read_stdin(handle->stdin_buf + handle->stdin_buf_ptr, STDIN_BUF_SIZE - handle->stdin_buf_ptr - 1); if (ret == 0) return; From ab0ce82b1e5811b1b95e939fe1e8e0b6702cc694 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Tue, 7 Aug 2012 23:52:09 +0200 Subject: [PATCH 098/492] (GX) Alpha blended image overlay when exiting back to menu --- gx/frontend/main.c | 10 +++++++--- gx/gx_video.c | 12 +++++++++--- gx/gx_video.h | 1 + 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/gx/frontend/main.c b/gx/frontend/main.c index 4163fab3fb..baebf45678 100644 --- a/gx/frontend/main.c +++ b/gx/frontend/main.c @@ -130,10 +130,14 @@ static bool folder_cb(const char *directory, rgui_file_enum_cb_t file_cb, static bool get_rom_path(rgui_handle_t *rgui) { + gx_video_t *gx = (gx_video_t*)driver.video_data; + uint16_t old_input_state = 0; bool can_quit = false; bool first = true; + gx->menu_render = true; + for (;;) { uint16_t input_state = 0; @@ -183,9 +187,8 @@ static bool get_rom_path(rgui_handle_t *rgui) } const char *ret = rgui_iterate(rgui, action); - video_wii.frame(NULL, NULL, - 0, 0, - 0, NULL); + + rarch_render_cached_frame(); if (ret) { @@ -275,6 +278,7 @@ int main(void) while (get_rom_path(rgui) && ret == 0) { + gx->menu_render = false; bool repeat = false; input_wii.poll(NULL); diff --git a/gx/gx_video.c b/gx/gx_video.c index 51811dcc05..aa1f7da454 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -362,6 +362,7 @@ static void update_texture(const uint32_t *src, } // TODO: only convert when menu is visible + if(gx->menu_render) { uint16_t *block = (uint16_t *) menu_tex.data; uint16_t *line[4]; @@ -396,11 +397,14 @@ static bool wii_frame(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch, const char *msg) { + gx_video_t *gx = (gx_video_t*)driver.video_data; + bool menu_render = gx->menu_render; + (void)data; (void)msg; - //if(!frame) - // return true; + if(!frame && !menu_render) + return true; while (g_vsync && !g_draw_done) LWP_ThreadSleep(g_video_cond); @@ -408,13 +412,15 @@ static bool wii_frame(void *data, const void *frame, g_draw_done = false; g_current_framebuf ^= 1; update_texture(frame, width, height, pitch); + if (frame) { GX_LoadTexObj(&g_tex.obj, GX_TEXMAP0); GX_CallDispList(display_list, display_list_size); GX_DrawDone(); } - else // TODO: in-game menu still needs this + + if(menu_render) { GX_LoadTexObj(&menu_tex.obj, GX_TEXMAP0); GX_CallDispList(display_list, display_list_size); diff --git a/gx/gx_video.h b/gx/gx_video.h index 0640f7ed66..47108ea1b2 100644 --- a/gx/gx_video.h +++ b/gx/gx_video.h @@ -18,6 +18,7 @@ typedef struct gx_video { + bool menu_render; uint32_t *menu_data; } gx_video_t; From ba2323c443b718ec9a4de3c6bd029dfbf2c1b520 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 8 Aug 2012 00:12:10 +0200 Subject: [PATCH 099/492] (GX) Update icon - no more SSNES icon --- gx/pkg/icon.png | Bin 9087 -> 7421 bytes gx/pkg/meta.xml | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gx/pkg/icon.png b/gx/pkg/icon.png index 8238b90e20f83b3571572c923f0285ce9a078e31..23d1a0762edcb301d9f6765e836ba495783e9970 100644 GIT binary patch delta 7367 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 RetroArch GX - Maister, Squarepusher2, ToadKing + Maister, Squarepusher, ToadKing 0.9.6 2012 Multi-system emulator - A port of RetroArch to the Wii. + A port of RetroArch to the GameCube/Wii. From a5f8651dcd35e839da32234c96da7eb6240587ad Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 8 Aug 2012 00:36:47 +0200 Subject: [PATCH 100/492] (GX) Add 90/180/270 degree rotation tex coord matrices - wii_set_rotation just needs to be implemented now --- gx/gx_video.c | 51 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/gx/gx_video.c b/gx/gx_video.c index aa1f7da454..7964f4dd17 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -22,8 +22,6 @@ #include #include -// All very hardcoded for now. - void *g_framebuf[2]; unsigned g_current_framebuf; @@ -48,6 +46,41 @@ uint8_t gx_fifo[256 * 1024] ATTRIBUTE_ALIGN(32); uint8_t display_list[1024] ATTRIBUTE_ALIGN(32); size_t display_list_size; +float verts[16] ATTRIBUTE_ALIGN(32) = { + -1, 1, -0.5, + -1, -1, -0.5, + 1, -1, -0.5, + 1, 1, -0.5, +}; + +float tex_coords[8] ATTRIBUTE_ALIGN(32) = { + 0, 0, + 0, 1, + 1, 1, + 1, 0, +}; + +float vertexes_90[8] ATTRIBUTE_ALIGN(32) = { + 0, 1, + 1, 1, + 1, 0, + 0, 0 +}; + +float vertexes_180[8] ATTRIBUTE_ALIGN(32) = { + 1, 1, + 1, 0, + 0, 0, + 0, 1 +}; + +float vertexes_270[8] ATTRIBUTE_ALIGN(32) = { + 1, 0, + 0, 0, + 0, 1, + 1, 1 +}; + static void retrace_callback(u32 retrace_count) { (void)retrace_count; @@ -76,20 +109,6 @@ static void setup_video_mode(GXRModeObj *mode) VIDEO_WaitVSync(); } -float verts[16] ATTRIBUTE_ALIGN(32) = { - -1, 1, -0.5, - -1, -1, -0.5, - 1, -1, -0.5, - 1, 1, -0.5, -}; - -float tex_coords[8] ATTRIBUTE_ALIGN(32) = { - 0, 0, - 0, 1, - 1, 1, - 1, 0, -}; - static void init_vtx(GXRModeObj *mode) { GX_SetViewport(0, 0, mode->fbWidth, mode->efbHeight, 0, 1); From 54a5845321f9439f6f51e836fe85870803729c9c Mon Sep 17 00:00:00 2001 From: Toad King Date: Tue, 7 Aug 2012 23:40:17 -0400 Subject: [PATCH 101/492] (GX) initial in-game menu --- gx/frontend/main.c | 124 +++++++++++++++++++++++++++++++++------------ gx/gx_input.c | 21 +++++++- gx/gx_video.c | 9 ++-- gx/gx_video.h | 1 + 4 files changed, 118 insertions(+), 37 deletions(-) diff --git a/gx/frontend/main.c b/gx/frontend/main.c index baebf45678..84126118c3 100644 --- a/gx/frontend/main.c +++ b/gx/frontend/main.c @@ -47,6 +47,7 @@ FILE * log_fp; #endif uint32_t menu_framebuf[320 * 240]; +rgui_handle_t *rgui; char app_dir[PATH_MAX]; struct retro_system_info wii_core_info; @@ -81,6 +82,8 @@ enum GX_DEVICE_NAV_LAST }; +extern uint8_t _binary_console_font_bmp_start[]; + static bool folder_cb(const char *directory, rgui_file_enum_cb_t file_cb, void *userdata, void *ctx) { @@ -128,19 +131,25 @@ static bool folder_cb(const char *directory, rgui_file_enum_cb_t file_cb, return true; } -static bool get_rom_path(rgui_handle_t *rgui) +static void menu_loop(void) { gx_video_t *gx = (gx_video_t*)driver.video_data; - uint16_t old_input_state = 0; - bool can_quit = false; + uint64_t old_input_state = 0; bool first = true; + g_console.menu_enable = true; + + if(g_console.ingame_menu_enable) + { + //TODO: fill in some stuff here to bring up ingame menu + } + gx->menu_render = true; - for (;;) + do { - uint16_t input_state = 0; + uint64_t input_state = 0; input_wii.poll(NULL); @@ -150,19 +159,30 @@ static bool get_rom_path(rgui_handle_t *rgui) RETRO_DEVICE_JOYPAD, 0, i) ? (1 << i) : 0; } - uint16_t trigger_state = input_state & ~old_input_state; + static const struct retro_keybind _quit_binds[] = { + { 0, 0, (enum retro_key)0, (GX_CLASSIC_HOME), 0 }, + { 0, 0, (enum retro_key)0, (GX_WIIMOTE_HOME), 0 }, + }; + + const struct retro_keybind *quit_binds[] = { + _quit_binds + }; + + input_state |= input_wii.input_state(NULL, quit_binds, false, + RETRO_DEVICE_JOYPAD, 0, 0) ? (GX_CLASSIC_HOME) : 0; + + input_state |= input_wii.input_state(NULL, quit_binds, false, + RETRO_DEVICE_JOYPAD, 0, 1) ? (GX_WIIMOTE_HOME) : 0; + + + uint64_t trigger_state = input_state & ~old_input_state; rgui_action_t action = RGUI_ACTION_NOOP; // don't run anything first frame, only capture held inputs for old_input_state if (!first) { if (trigger_state & (1 << GX_DEVICE_NAV_EXIT)) - { - if (can_quit) - return false; - } - else - can_quit = true; + g_console.mode_switch = MODE_EXIT; if (trigger_state & (1 << GX_DEVICE_NAV_B)) action = RGUI_ACTION_CANCEL; @@ -188,24 +208,58 @@ static bool get_rom_path(rgui_handle_t *rgui) const char *ret = rgui_iterate(rgui, action); + (void)ret; + rarch_render_cached_frame(); - if (ret) + old_input_state = input_state; + + bool quit_key_pressed = ((trigger_state & GX_WIIMOTE_HOME) || (trigger_state & GX_CLASSIC_HOME)) ? true : false; + + if(IS_TIMER_EXPIRED(gx)) { - g_console.initialize_rarch_enable = true; - strlcpy(g_console.rom_path, ret, sizeof(g_console.rom_path)); - if (rarch_startup(NULL)) - return true; + // if we want to force goto the emulation loop, skip this + if(g_console.mode_switch != MODE_EMULATION) + { + if(quit_key_pressed) + { + g_console.menu_enable = (quit_key_pressed && g_console.emulator_initialized) ? false : true; + g_console.mode_switch = g_console.menu_enable ? MODE_MENU : MODE_EMULATION; + } + } } - old_input_state = input_state; - rarch_sleep(10); - } + // set a timer delay so that we don't instantly switch back to the menu when + // press and holding QUIT in the emulation loop (lasts for 30 frame ticks) + if(g_console.mode_switch == MODE_EMULATION) + { + SET_TIMER_EXPIRATION(gx, 30); + } + + }while(g_console.menu_enable); + + gx->menu_render = false; + + g_console.ingame_menu_enable = false; +} + +static void menu_init(void) +{ + rgui = rgui_init("", + menu_framebuf, RGUI_WIDTH * sizeof(uint32_t), + _binary_console_font_bmp_start, folder_cb, NULL); + rgui_iterate(rgui, RGUI_ACTION_REFRESH); + + g_console.mode_switch = MODE_MENU; +} + +static void menu_free(void) +{ + rgui_free(rgui); } int rarch_main(int argc, char **argv); -extern uint8_t _binary_console_font_bmp_start[]; static void get_environment_settings(void) { @@ -269,19 +323,15 @@ int main(void) input_wii.post_init(); - rgui_handle_t *rgui = rgui_init("", - menu_framebuf, RGUI_WIDTH * sizeof(uint32_t), - _binary_console_font_bmp_start, folder_cb, NULL); - rgui_iterate(rgui, RGUI_ACTION_REFRESH); + menu_init(); - int ret = 0; - - while (get_rom_path(rgui) && ret == 0) +begin_loop: + if(g_console.mode_switch == MODE_EMULATION) { - gx->menu_render = false; bool repeat = false; input_wii.poll(NULL); + audio_start_func(); do{ repeat = rarch_main_iterate(); @@ -289,15 +339,25 @@ int main(void) audio_stop_func(); } + else if(g_console.mode_switch == MODE_MENU) + { + menu_loop(); + rarch_startup(default_paths.config_file); + } + else + goto begin_shutdown; + goto begin_loop; +begin_shutdown: if(path_file_exists(default_paths.config_file)) rarch_config_save(default_paths.config_file); if(g_console.emulator_initialized) rarch_main_deinit(); - video_wii.stop(); input_wii.free(NULL); + video_wii.stop(); + menu_free(); #ifdef HAVE_FILE_LOGGER fclose(log_fp); @@ -306,11 +366,9 @@ int main(void) logger_shutdown(); #endif - rgui_free(rgui); - if(g_console.return_to_launcher) rarch_console_exec(g_console.launch_app_on_exit); - return ret; + return 1; } diff --git a/gx/gx_input.c b/gx/gx_input.c index 65bb1ab581..e08d86ac2e 100644 --- a/gx/gx_input.c +++ b/gx/gx_input.c @@ -420,10 +420,29 @@ static void wii_input_poll(void *data) static bool wii_key_pressed(void *data, int key) { (void)data; + + gx_video_t *gx = driver.video_data; + switch (key) { case RARCH_QUIT_KEY: - return pad_state[0] & (GX_CLASSIC_HOME | GX_WIIMOTE_HOME) ? true : false; + if(IS_TIMER_EXPIRED(gx)) + { + uint64_t quit_pressed_classic = pad_state[0] & GX_CLASSIC_HOME; + uint64_t quit_pressed_wiimote = pad_state[0] & GX_WIIMOTE_HOME; + bool retval = false; + g_console.menu_enable = ((quit_pressed_classic || quit_pressed_wiimote) && IS_TIMER_EXPIRED(gx)); + + if(g_console.menu_enable) + { + g_console.mode_switch = MODE_MENU; + SET_TIMER_EXPIRATION(gx, 30); + retval = g_console.menu_enable; + } + + retval = g_console.menu_enable; + return retval; + } default: return false; } diff --git a/gx/gx_video.c b/gx/gx_video.c index 7964f4dd17..6d491f2abe 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -1,5 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * Copyright (C) 2011-2012 - Daniel De Matteis + * Copyright (C) 2012 - Michael Lelli * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- @@ -25,7 +27,6 @@ void *g_framebuf[2]; unsigned g_current_framebuf; -unsigned g_filter; bool g_vsync; lwpq_t g_video_cond; volatile bool g_draw_done; @@ -152,6 +153,8 @@ static void init_vtx(GXRModeObj *mode) static void init_texture(unsigned width, unsigned height) { + unsigned g_filter = g_settings.video.smooth ? GX_LINEAR : GX_NEAR; + GX_InitTexObj(&g_tex.obj, g_tex.data, width, height, GX_TF_RGB5A3, GX_CLAMP, GX_CLAMP, GX_FALSE); GX_InitTexObjLOD(&g_tex.obj, g_filter, g_filter, 0, 0, 0, GX_TRUE, GX_FALSE, GX_ANISO_1); GX_InitTexObj(&menu_tex.obj, menu_tex.data, 320, 240, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); @@ -198,7 +201,6 @@ static void *wii_init(const video_info_t *video, if (!gx) return NULL; - g_filter = video->smooth ? GX_LINEAR : GX_NEAR; g_vsync = video->vsync; return gx; @@ -229,7 +231,6 @@ static void gx_start(void) init_vtx(mode); build_disp_list(); - g_filter = true; g_vsync = true; } @@ -425,6 +426,8 @@ static bool wii_frame(void *data, const void *frame, if(!frame && !menu_render) return true; + gx->frame_count++; + while (g_vsync && !g_draw_done) LWP_ThreadSleep(g_video_cond); diff --git a/gx/gx_video.h b/gx/gx_video.h index 47108ea1b2..8a1b5bd5b7 100644 --- a/gx/gx_video.h +++ b/gx/gx_video.h @@ -19,6 +19,7 @@ typedef struct gx_video { bool menu_render; + uint32_t frame_count; uint32_t *menu_data; } gx_video_t; From c48d8e45a933854a8e560bf7b97278b3a0dae26f Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 8 Aug 2012 06:56:56 +0200 Subject: [PATCH 102/492] (GX) Quit shortcut combos added - for Wiimote (Home + B) - for Classic (Home + ZL + ZR) and Gamecube (L + R + Z + Start + A) --- gx/frontend/main.c | 17 ++++++++++++++--- gx/gx_input.c | 25 ++++++++++++++++++++++--- gx/gx_input.h | 1 + 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/gx/frontend/main.c b/gx/frontend/main.c index 84126118c3..e6619de2ad 100644 --- a/gx/frontend/main.c +++ b/gx/frontend/main.c @@ -162,6 +162,7 @@ static void menu_loop(void) static const struct retro_keybind _quit_binds[] = { { 0, 0, (enum retro_key)0, (GX_CLASSIC_HOME), 0 }, { 0, 0, (enum retro_key)0, (GX_WIIMOTE_HOME), 0 }, + { 0, 0, (enum retro_key)0, (GX_QUIT_KEY), 0 }, }; const struct retro_keybind *quit_binds[] = { @@ -174,6 +175,9 @@ static void menu_loop(void) input_state |= input_wii.input_state(NULL, quit_binds, false, RETRO_DEVICE_JOYPAD, 0, 1) ? (GX_WIIMOTE_HOME) : 0; + input_state |= input_wii.input_state(NULL, quit_binds, false, + RETRO_DEVICE_JOYPAD, 0, 2) ? (GX_QUIT_KEY) : 0; + uint64_t trigger_state = input_state & ~old_input_state; rgui_action_t action = RGUI_ACTION_NOOP; @@ -214,21 +218,28 @@ static void menu_loop(void) old_input_state = input_state; - bool quit_key_pressed = ((trigger_state & GX_WIIMOTE_HOME) || (trigger_state & GX_CLASSIC_HOME)) ? true : false; + bool goto_menu_key_pressed = ((trigger_state & GX_WIIMOTE_HOME) || (trigger_state & GX_CLASSIC_HOME)) ? true : false; + bool quit_key_pressed = (trigger_state & GX_QUIT_KEY) ? true : false; if(IS_TIMER_EXPIRED(gx)) { // if we want to force goto the emulation loop, skip this if(g_console.mode_switch != MODE_EMULATION) { - if(quit_key_pressed) + if(goto_menu_key_pressed) { - g_console.menu_enable = (quit_key_pressed && g_console.emulator_initialized) ? false : true; + g_console.menu_enable = (goto_menu_key_pressed && g_console.emulator_initialized) ? false : true; g_console.mode_switch = g_console.menu_enable ? MODE_MENU : MODE_EMULATION; } } } + if(quit_key_pressed) + { + g_console.menu_enable = false; + g_console.mode_switch = MODE_EXIT; + } + // set a timer delay so that we don't instantly switch back to the menu when // press and holding QUIT in the emulation loop (lasts for 30 frame ticks) if(g_console.mode_switch == MODE_EMULATION) diff --git a/gx/gx_input.c b/gx/gx_input.c index e08d86ac2e..24a75eaa57 100644 --- a/gx/gx_input.c +++ b/gx/gx_input.c @@ -258,6 +258,9 @@ static void wii_input_post_init(void) static void wii_input_poll(void *data) { (void)data; + bool quit_gc = false; + bool quit_classic = false; + bool quit_wiimote = false; PAD_ScanPads(); #ifdef HW_RVL @@ -283,6 +286,9 @@ static void wii_input_poll(void *data) state |= (PAD_TriggerL(port) > 127) ? GX_GC_L_TRIGGER : 0; state |= (PAD_TriggerR(port) > 127) ? GX_GC_R_TRIGGER : 0; + if((down & PAD_BUTTON_A) && (PAD_TriggerL(port) > 127) && (PAD_TriggerR(port) > 127) && (down & PAD_TRIGGER_Z) && (down & PAD_BUTTON_START) && (down & PAD_BUTTON_A)) + quit_gc = true; + s8 x = PAD_StickX(port); s8 y = PAD_StickY(port); @@ -320,6 +326,9 @@ static void wii_input_poll(void *data) state |= (down & WPAD_BUTTON_MINUS) ? GX_WIIMOTE_MINUS : 0; state |= (down & WPAD_BUTTON_HOME) ? GX_WIIMOTE_HOME : 0; + if((down & WPAD_BUTTON_HOME) && (down & WPAD_BUTTON_B)) + quit_wiimote = true; + expansion_t exp; WPAD_Expansion(port, &exp); switch (exp.type) @@ -366,6 +375,9 @@ static void wii_input_poll(void *data) state |= (down & WPAD_CLASSIC_BUTTON_ZL) ? GX_CLASSIC_ZL_TRIGGER : 0; state |= (down & WPAD_CLASSIC_BUTTON_ZR) ? GX_CLASSIC_ZR_TRIGGER : 0; + if((down & WPAD_CLASSIC_BUTTON_HOME) && (down & WPAD_CLASSIC_BUTTON_ZL) && (down & WPAD_CLASSIC_BUTTON_ZR)) + quit_classic = true; + s8 x = wii_stick_x(exp.classic.ljs); s8 y = wii_stick_y(exp.classic.ljs); @@ -407,6 +419,9 @@ static void wii_input_poll(void *data) state |= GX_WIIMOTE_HOME; } + if (quit_gc || quit_wiimote || quit_classic) + state |= GX_QUIT_KEY; + pad_state[port] = state; } @@ -428,10 +443,11 @@ static bool wii_key_pressed(void *data, int key) case RARCH_QUIT_KEY: if(IS_TIMER_EXPIRED(gx)) { - uint64_t quit_pressed_classic = pad_state[0] & GX_CLASSIC_HOME; - uint64_t quit_pressed_wiimote = pad_state[0] & GX_WIIMOTE_HOME; + uint64_t goto_menu_pressed_classic = pad_state[0] & GX_CLASSIC_HOME; + uint64_t goto_menu_pressed_wiimote = pad_state[0] & GX_WIIMOTE_HOME; + uint64_t quit_rarch = pad_state[0] & GX_QUIT_KEY; bool retval = false; - g_console.menu_enable = ((quit_pressed_classic || quit_pressed_wiimote) && IS_TIMER_EXPIRED(gx)); + g_console.menu_enable = ((goto_menu_pressed_classic || goto_menu_pressed_wiimote || quit_rarch) && IS_TIMER_EXPIRED(gx)); if(g_console.menu_enable) { @@ -440,6 +456,9 @@ static bool wii_key_pressed(void *data, int key) retval = g_console.menu_enable; } + if(quit_rarch) + g_console.mode_switch = MODE_EXIT; + retval = g_console.menu_enable; return retval; } diff --git a/gx/gx_input.h b/gx/gx_input.h index 2b35da0c10..41a3ef41a1 100644 --- a/gx/gx_input.h +++ b/gx/gx_input.h @@ -82,6 +82,7 @@ enum GX_NUNCHUK_LEFT = 1ULL << 58, GX_NUNCHUK_RIGHT = 1ULL << 59, #endif + GX_QUIT_KEY = 1ULL << 60, }; enum wii_device_id From e3a2bf146357cd36802f79bb82b3604819a1cff8 Mon Sep 17 00:00:00 2001 From: Themaister Date: Wed, 8 Aug 2012 07:40:00 +0200 Subject: [PATCH 103/492] Fix build if --disable-netplay is used. --- command.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/command.c b/command.c index b34e6ceaeb..47d032125f 100644 --- a/command.c +++ b/command.c @@ -27,6 +27,11 @@ #include #include +#ifndef _WIN32 +#include +#include +#endif + #define DEFAULT_NETWORK_CMD_PORT 55355 #define STDIN_BUF_SIZE 4096 @@ -114,7 +119,9 @@ rarch_cmd_t *rarch_cmd_new(bool stdin_enable, bool network_enable, uint16_t port (void)stdin_enable; #endif +#ifdef HAVE_NETWORK_CMD freeaddrinfo(res); +#endif return handle; error: @@ -128,8 +135,10 @@ error: void rarch_cmd_free(rarch_cmd_t *handle) { +#ifdef HAVE_NETWORK_CMD if (handle->net_fd >= 0) close(handle->net_fd); +#endif free(handle); } From 50980263fba6ea73b5ee07fe6e2457553b87fb67 Mon Sep 17 00:00:00 2001 From: Themaister Date: Wed, 8 Aug 2012 07:47:10 +0200 Subject: [PATCH 104/492] Correctly use RETRO_DEVICE_KEYBOARD in ext_gfx. --- gfx/ext_gfx.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/gfx/ext_gfx.c b/gfx/ext_gfx.c index b3edeea887..1215058103 100644 --- a/gfx/ext_gfx.c +++ b/gfx/ext_gfx.c @@ -63,21 +63,30 @@ static int16_t input_ext_input_state(void *data, const struct retro_keybind **re unsigned player = port + 1; - if (id < RARCH_BIND_LIST_END) - { - const struct retro_keybind *rarch_bind = &retro_keybinds[player - 1][id]; - if (!rarch_bind->valid) - return 0; - - struct rarch_keybind bind = {0}; - bind.key = rarch_bind->key; - bind.joykey = rarch_bind->joykey; - bind.joyaxis = rarch_bind->joyaxis; - - return ext->driver->input_state(ext->handle, &bind, player); - } - else + if (id >= RARCH_BIND_LIST_END) return 0; + + const struct retro_keybind *rarch_bind = &retro_keybinds[player - 1][id]; + if (!rarch_bind->valid) + return 0; + + struct rarch_keybind bind = {0}; + + switch (device) + { + case RETRO_DEVICE_KEYBOARD: + bind.key = id; + bind.joykey = NO_BTN; + bind.joyaxis = AXIS_NONE; + break; + + default: + bind.key = rarch_bind->key; + bind.joykey = rarch_bind->joykey; + bind.joyaxis = rarch_bind->joyaxis; + } + + return ext->driver->input_state(ext->handle, &bind, player); } static bool input_ext_key_pressed(void *data, int key) @@ -91,8 +100,8 @@ static bool input_ext_key_pressed(void *data, int key) return false; struct rarch_keybind bind = {0}; - bind.key = rarch_bind->key; - bind.joykey = rarch_bind->joykey; + bind.key = rarch_bind->key; + bind.joykey = rarch_bind->joykey; bind.joyaxis = rarch_bind->joyaxis; return ext->driver->input_state(ext->handle, &bind, 1); From 2dfd32d69420a07aaaa619d06b94a9006b233eb1 Mon Sep 17 00:00:00 2001 From: Themaister Date: Wed, 8 Aug 2012 07:52:20 +0200 Subject: [PATCH 105/492] Do not return early if id is large (likely so with RETROK_). --- gfx/ext_gfx.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/gfx/ext_gfx.c b/gfx/ext_gfx.c index 1215058103..092f508784 100644 --- a/gfx/ext_gfx.c +++ b/gfx/ext_gfx.c @@ -59,31 +59,34 @@ static void input_ext_poll(void *data) static int16_t input_ext_input_state(void *data, const struct retro_keybind **retro_keybinds, unsigned port, unsigned device, unsigned index, unsigned id) { - input_ext_t *ext = (input_ext_t*)data; - - unsigned player = port + 1; - - if (id >= RARCH_BIND_LIST_END) - return 0; - - const struct retro_keybind *rarch_bind = &retro_keybinds[player - 1][id]; - if (!rarch_bind->valid) - return 0; - + input_ext_t *ext = (input_ext_t*)data; + unsigned player = port + 1; struct rarch_keybind bind = {0}; switch (device) { case RETRO_DEVICE_KEYBOARD: + if (id >= RETROK_LAST) + return 0; + bind.key = id; bind.joykey = NO_BTN; bind.joyaxis = AXIS_NONE; break; default: + { + if (id >= RARCH_BIND_LIST_END) + return 0; + + const struct retro_keybind *rarch_bind = &retro_keybinds[player - 1][id]; + if (!rarch_bind->valid) + return 0; + bind.key = rarch_bind->key; bind.joykey = rarch_bind->joykey; bind.joyaxis = rarch_bind->joyaxis; + } } return ext->driver->input_state(ext->handle, &bind, player); From 2f9585829ed26b8b72acf57b84619f53c3719d43 Mon Sep 17 00:00:00 2001 From: Themaister Date: Wed, 8 Aug 2012 08:33:44 +0200 Subject: [PATCH 106/492] Implement for JOYPAD explicitly. Defaults to 0. --- gfx/ext_gfx.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/gfx/ext_gfx.c b/gfx/ext_gfx.c index 092f508784..451ae6e710 100644 --- a/gfx/ext_gfx.c +++ b/gfx/ext_gfx.c @@ -65,16 +65,7 @@ static int16_t input_ext_input_state(void *data, const struct retro_keybind **re switch (device) { - case RETRO_DEVICE_KEYBOARD: - if (id >= RETROK_LAST) - return 0; - - bind.key = id; - bind.joykey = NO_BTN; - bind.joyaxis = AXIS_NONE; - break; - - default: + case RETRO_DEVICE_JOYPAD: { if (id >= RARCH_BIND_LIST_END) return 0; @@ -86,7 +77,22 @@ static int16_t input_ext_input_state(void *data, const struct retro_keybind **re bind.key = rarch_bind->key; bind.joykey = rarch_bind->joykey; bind.joyaxis = rarch_bind->joyaxis; + break; } + + // TODO: RETRO_DEVICE_ANALOG. + + case RETRO_DEVICE_KEYBOARD: + if (id >= RETROK_LAST) + return 0; + + bind.key = id; + bind.joykey = NO_BTN; + bind.joyaxis = AXIS_NONE; + break; + + default: + return 0; } return ext->driver->input_state(ext->handle, &bind, player); From 5e2307d9c9ca7f82782040825b045e7ac75ac5c4 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 8 Aug 2012 18:46:48 +0200 Subject: [PATCH 107/492] (GX) Add rotation options in settings menu --- console/rgui/rgui.c | 31 +++++++++++++++++++++++++++++++ console/rgui/rgui.h | 1 + gx/gx_video.c | 28 +++++++++++++++++++++++----- xbox1/xdk_d3d8.cpp | 4 ---- 4 files changed, 55 insertions(+), 9 deletions(-) diff --git a/console/rgui/rgui.c b/console/rgui/rgui.c index 408c0a27b2..06f4296b42 100644 --- a/console/rgui/rgui.c +++ b/console/rgui/rgui.c @@ -319,6 +319,13 @@ static void render_text(rgui_handle_t *rgui) case RGUI_SETTINGS_VIDEO_FILTER: snprintf(type_str, sizeof(type_str), g_settings.video.smooth ? "Bilinear filtering" : "Point filtering"); break; + case RGUI_SETTINGS_VIDEO_ROTATION: + { + char rotate_msg[64]; + rarch_settings_create_menu_item_label(rotate_msg, S_LBL_ROTATION, sizeof(rotate_msg)); + snprintf(type_str, sizeof(type_str), rotate_msg); + } + break; case RGUI_SETTINGS_AUDIO_MUTE: snprintf(type_str, sizeof(type_str), g_extern.audio_data.mute ? "ON" : "OFF"); break; @@ -382,6 +389,29 @@ static void rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t else rarch_settings_change(S_HW_TEXTURE_FILTER); break; + case RGUI_SETTINGS_VIDEO_ROTATION: + if (action == RGUI_ACTION_START) + { + rarch_settings_default(S_DEF_AUDIO_CONTROL_RATE); +#ifdef GEKKO + video_wii.set_rotation(NULL, g_console.screen_orientation); +#endif + } + else if (action == RGUI_ACTION_LEFT) + { + rarch_settings_change(S_ROTATION_DECREMENT); +#ifdef GEKKO + video_wii.set_rotation(NULL, g_console.screen_orientation); +#endif + } + else if (action == RGUI_ACTION_RIGHT) + { + rarch_settings_change(S_ROTATION_INCREMENT); +#ifdef GEKKO + video_wii.set_rotation(NULL, g_console.screen_orientation); +#endif + } + break; case RGUI_SETTINGS_AUDIO_MUTE: if (action == RGUI_ACTION_START) rarch_settings_default(S_DEF_AUDIO_MUTE); @@ -470,6 +500,7 @@ static void rgui_settings_populate_entries(rgui_handle_t *rgui) rgui_list_clear(rgui->folder_buf); RGUI_MENU_ITEM("Hardware filtering", RGUI_SETTINGS_VIDEO_FILTER); + RGUI_MENU_ITEM("Rotation", RGUI_SETTINGS_VIDEO_ROTATION); RGUI_MENU_ITEM("Mute Audio", RGUI_SETTINGS_AUDIO_MUTE); RGUI_MENU_ITEM("Audio Control Rate", RGUI_SETTINGS_AUDIO_CONTROL_RATE); RGUI_MENU_ITEM("Core", RGUI_SETTINGS_CORE); diff --git a/console/rgui/rgui.h b/console/rgui/rgui.h index c1875f0a6d..0f7a895300 100644 --- a/console/rgui/rgui.h +++ b/console/rgui/rgui.h @@ -34,6 +34,7 @@ typedef enum // settings options are done here too RGUI_SETTINGS_VIDEO_FILTER, + RGUI_SETTINGS_VIDEO_ROTATION, RGUI_SETTINGS_AUDIO_MUTE, RGUI_SETTINGS_AUDIO_CONTROL_RATE, RGUI_SETTINGS_CORE, diff --git a/gx/gx_video.c b/gx/gx_video.c index 6d491f2abe..968fa32a64 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -61,27 +61,29 @@ float tex_coords[8] ATTRIBUTE_ALIGN(32) = { 1, 0, }; -float vertexes_90[8] ATTRIBUTE_ALIGN(32) = { +float tex_coords_90[8] ATTRIBUTE_ALIGN(32) = { 0, 1, 1, 1, 1, 0, 0, 0 }; -float vertexes_180[8] ATTRIBUTE_ALIGN(32) = { +float tex_coords_180[8] ATTRIBUTE_ALIGN(32) = { 1, 1, 1, 0, 0, 0, 0, 1 }; -float vertexes_270[8] ATTRIBUTE_ALIGN(32) = { +float tex_coords_270[8] ATTRIBUTE_ALIGN(32) = { 1, 0, 0, 0, 0, 1, 1, 1 }; +float *vertex_ptr = tex_coords; + static void retrace_callback(u32 retrace_count) { (void)retrace_count; @@ -138,7 +140,7 @@ static void init_vtx(GXRModeObj *mode) GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); GX_SetArray(GX_VA_POS, verts, 3 * sizeof(float)); - GX_SetArray(GX_VA_TEX0, tex_coords, 2 * sizeof(float)); + GX_SetArray(GX_VA_TEX0, vertex_ptr, 2 * sizeof(float)); GX_SetNumTexGens(1); GX_SetNumChans(0); @@ -485,7 +487,23 @@ static void wii_set_rotation(void * data, uint32_t orientation) (void)data; (void)orientation; - /* TODO */ + switch(orientation) + { + case ORIENTATION_NORMAL: + vertex_ptr = tex_coords; + break; + case ORIENTATION_VERTICAL: + vertex_ptr = tex_coords_90; + break; + case ORIENTATION_FLIPPED: + vertex_ptr = tex_coords_180; + break; + case ORIENTATION_FLIPPED_ROTATED: + vertex_ptr = tex_coords_270; + break; + } + + GX_SetArray(GX_VA_TEX0, vertex_ptr, 2 * sizeof(float)); } const video_driver_t video_wii = { diff --git a/xbox1/xdk_d3d8.cpp b/xbox1/xdk_d3d8.cpp index 0836d4f4a3..da8ae2b10a 100644 --- a/xbox1/xdk_d3d8.cpp +++ b/xbox1/xdk_d3d8.cpp @@ -153,19 +153,15 @@ static void xdk_d3d_set_rotation(void * data, unsigned orientation) { case ORIENTATION_NORMAL: angle = M_PI * 0 / 180; - RARCH_LOG("D3D8: Set rotation to ORIENTATION_NORMAL\n"); break; case ORIENTATION_VERTICAL: angle = M_PI * 270 / 180; - RARCH_LOG("D3D8: Set rotation to ORIENTATION_VERTICAL\n"); break; case ORIENTATION_FLIPPED: angle = M_PI * 180 / 180; - RARCH_LOG("D3D8: Set rotation to ORIENTATION_FLIPPED\n"); break; case ORIENTATION_FLIPPED_ROTATED: angle = M_PI * 90 / 180; - RARCH_LOG("D3D8: Set rotation to ORIENTATION_FLIPPED_ROTATED\n"); break; } } From c6032be2561f78ae75966596c584068ea5db06f8 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 8 Aug 2012 19:55:38 +0200 Subject: [PATCH 108/492] (GX) Add gamma correction options in settings menu --- 360/frontend-xdk/menu.cpp | 6 ++--- 360/xdk_d3d9.cpp | 6 ++--- console/rarch_console_config.c | 4 +-- console/rarch_console_settings.c | 4 ++- console/rgui/rgui.c | 43 +++++++++++++++++++++++++++++++ console/rgui/rgui.h | 1 + general.h | 44 ++++++++++++++++---------------- gx/gx_video.c | 9 ++++++- gx/gx_video.h | 1 + 9 files changed, 86 insertions(+), 32 deletions(-) diff --git a/360/frontend-xdk/menu.cpp b/360/frontend-xdk/menu.cpp index bfc022a7e0..429e78ba48 100644 --- a/360/frontend-xdk/menu.cpp +++ b/360/frontend-xdk/menu.cpp @@ -248,7 +248,7 @@ HRESULT CRetroArchSettings::OnInit(XUIMessageInit * pInitData, BOOL& bHandled) m_settingslist.SetText(SETTING_EMU_REWIND_ENABLED, g_settings.rewind_enable ? L"Rewind: ON" : L"Rewind: OFF"); m_settingslist.SetText(SETTING_EMU_SHOW_INFO_MSG, g_console.info_msg_enable ? L"Info messages: ON" : L"Info messages: OFF"); m_settingslist.SetText(SETTING_EMU_MENUS, g_console.menus_hd_enable ? L"Menus: HD" : L"Menus: SD"); - m_settingslist.SetText(SETTING_GAMMA_CORRECTION_ENABLED, g_console.gamma_correction_enable ? L"Gamma correction: ON" : L"Gamma correction: OFF"); + m_settingslist.SetText(SETTING_GAMMA_CORRECTION_ENABLED, g_console.gamma_correction ? L"Gamma correction: ON" : L"Gamma correction: OFF"); m_settingslist.SetText(SETTING_HW_TEXTURE_FILTER, g_settings.video.smooth ? L"Hardware filtering shader #1: Linear interpolation" : L"Hardware filtering shader #1: Point filtering"); m_settingslist.SetText(SETTING_HW_TEXTURE_FILTER_2, g_settings.video.second_pass_smooth ? L"Hardware filtering shader #2: Linear interpolation" : L"Hardware filtering shader #2: Point filtering"); m_settingslist.SetText(SETTING_SCALE_ENABLED, g_console.fbo_enabled ? L"Custom Scaling/Dual Shaders: ON" : L"Custom Scaling/Dual Shaders: OFF"); @@ -672,8 +672,8 @@ HRESULT CRetroArchSettings::OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled m_settingslist.SetText(SETTING_EMU_MENUS, g_console.menus_hd_enable ? L"Menus: HD" : L"Menus: SD"); break; case SETTING_GAMMA_CORRECTION_ENABLED: - g_console.gamma_correction_enable = !g_console.gamma_correction_enable; - m_settingslist.SetText(SETTING_GAMMA_CORRECTION_ENABLED, g_console.gamma_correction_enable ? L"Gamma correction: ON" : L"Gamma correction: OFF"); + g_console.gamma_correction = g_console.gamma_correction ? 0 : 1; + m_settingslist.SetText(SETTING_GAMMA_CORRECTION_ENABLED, g_console.gamma_correction ? L"Gamma correction: ON" : L"Gamma correction: OFF"); if(g_console.info_msg_enable) rarch_settings_msg(S_MSG_RESTART_RARCH, S_DELAY_180); break; diff --git a/360/xdk_d3d9.cpp b/360/xdk_d3d9.cpp index 87fba8ff55..acf656d7e2 100644 --- a/360/xdk_d3d9.cpp +++ b/360/xdk_d3d9.cpp @@ -456,13 +456,13 @@ static void xdk_d3d_init_fbo(xdk_d3d_video_t *d3d) } d3d->d3d_render_device->CreateTexture(512 * g_settings.video.fbo_scale_x, 512 * g_settings.video.fbo_scale_y, - 1, 0, g_console.gamma_correction_enable ? ( D3DFORMAT )MAKESRGBFMT( D3DFMT_A8R8G8B8 ) : D3DFMT_A8R8G8B8, + 1, 0, g_console.gamma_correction ? ( D3DFORMAT )MAKESRGBFMT( D3DFMT_A8R8G8B8 ) : D3DFMT_A8R8G8B8, 0, &d3d->lpTexture_ot , NULL ); d3d->d3d_render_device->CreateRenderTarget(512 * g_settings.video.fbo_scale_x, 512 * g_settings.video.fbo_scale_y, - g_console.gamma_correction_enable ? ( D3DFORMAT )MAKESRGBFMT( D3DFMT_A8R8G8B8 ) : D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, + g_console.gamma_correction ? ( D3DFORMAT )MAKESRGBFMT( D3DFMT_A8R8G8B8 ) : D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, 0, &d3d->lpSurface, NULL); d3d->lpTexture_ot_as16srgb = *d3d->lpTexture_ot; @@ -504,7 +504,7 @@ static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **inpu d3d->d3dpp.BackBufferWidth = d3d->video_mode.fIsHiDef ? 1280 : 640; d3d->d3dpp.BackBufferHeight = d3d->video_mode.fIsHiDef ? 720 : 480; - if(g_console.gamma_correction_enable) + if(g_console.gamma_correction) { d3d->d3dpp.BackBufferFormat = g_console.color_format ? (D3DFORMAT)MAKESRGBFMT(D3DFMT_A8R8G8B8) : (D3DFORMAT)MAKESRGBFMT(D3DFMT_LIN_A1R5G5B5); d3d->d3dpp.FrontBufferFormat = (D3DFORMAT)MAKESRGBFMT(D3DFMT_LE_X8R8G8B8); diff --git a/console/rarch_console_config.c b/console/rarch_console_config.c index 2278ac22fa..a6b9ea8ec6 100644 --- a/console/rarch_console_config.c +++ b/console/rarch_console_config.c @@ -98,9 +98,9 @@ void rarch_config_load(const char * conf_name, const char * libretro_dir_path, c CONFIG_GET_INT_CONSOLE(zip_extract_mode, "zip_extract_mode"); #endif #ifdef _XBOX360 - CONFIG_GET_BOOL_CONSOLE(gamma_correction_enable, "gamma_correction_enable"); CONFIG_GET_INT_CONSOLE(color_format, "color_format"); #endif + CONFIG_GET_BOOL_CONSOLE(gamma_correction, "gamma_correction"); #ifdef _XBOX1 CONFIG_GET_INT_CONSOLE(flicker_filter, "fliker_filter"); CONFIG_GET_BOOL_CONSOLE(soft_display_filter_enable, "soft_display_filter_enable"); @@ -156,8 +156,8 @@ void rarch_config_save(const char * conf_name) #endif config_set_bool(conf, "overscan_enable", g_console.overscan_enable); config_set_bool(conf, "screenshots_enable", g_console.screenshots_enable); + config_set_bool(conf, "gamma_correction", g_console.gamma_correction); #ifdef _XBOX360 - config_set_bool(conf, "gamma_correction_enable", g_console.gamma_correction_enable); config_set_int(conf, "color_format", g_console.color_format); #endif #ifdef _XBOX1 diff --git a/console/rarch_console_settings.c b/console/rarch_console_settings.c index aad9a1d802..8101230fae 100644 --- a/console/rarch_console_settings.c +++ b/console/rarch_console_settings.c @@ -384,7 +384,9 @@ void rarch_settings_set_default (const input_driver_t *input) g_console.info_msg_enable = true; #ifdef _XBOX360 g_console.color_format = 0; - g_console.gamma_correction_enable = 1; +#endif +#if defined(_XBOX360) || defined(GEKKO) + g_console.gamma_correction = 1; #endif #ifdef _XBOX1 g_console.flicker_filter = 1; diff --git a/console/rgui/rgui.c b/console/rgui/rgui.c index 06f4296b42..18060985df 100644 --- a/console/rgui/rgui.c +++ b/console/rgui/rgui.c @@ -319,6 +319,9 @@ static void render_text(rgui_handle_t *rgui) case RGUI_SETTINGS_VIDEO_FILTER: snprintf(type_str, sizeof(type_str), g_settings.video.smooth ? "Bilinear filtering" : "Point filtering"); break; + case RGUI_SETTINGS_VIDEO_GAMMA: + snprintf(type_str, sizeof(type_str), "%d", g_console.gamma_correction); + break; case RGUI_SETTINGS_VIDEO_ROTATION: { char rotate_msg[64]; @@ -378,9 +381,19 @@ static void render_text(rgui_handle_t *rgui) render_messagebox(rgui, msg_queue_pull(g_extern.msg_queue)); } +#ifdef GEKKO +#define MAX_GAMMA_SETTING 2 +#else +#define MAX_GAMMA_SETTING 1 +#endif + static void rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t action, rgui_file_type_t menu_type) { unsigned port = menu_type - RGUI_SETTINGS_CONTROLLER_1; +#ifdef GEKKO + gx_video_t *gx = (gx_video_t*)driver.video_data; +#endif + switch (setting) { case RGUI_SETTINGS_VIDEO_FILTER: @@ -389,6 +402,35 @@ static void rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t else rarch_settings_change(S_HW_TEXTURE_FILTER); break; + case RGUI_SETTINGS_VIDEO_GAMMA: + if (action == RGUI_ACTION_START) + { + g_console.gamma_correction = 0; +#ifdef GEKKO + gx->should_resize = true; +#endif + } + else if (action == RGUI_ACTION_LEFT) + { + if(g_console.gamma_correction > 0) + { + g_console.gamma_correction--; +#ifdef GEKKO + gx->should_resize = true; +#endif + } + } + else if (action == RGUI_ACTION_RIGHT) + { + if(g_console.gamma_correction < MAX_GAMMA_SETTING) + { + g_console.gamma_correction++; +#ifdef GEKKO + gx->should_resize = true; +#endif + } + } + break; case RGUI_SETTINGS_VIDEO_ROTATION: if (action == RGUI_ACTION_START) { @@ -500,6 +542,7 @@ static void rgui_settings_populate_entries(rgui_handle_t *rgui) rgui_list_clear(rgui->folder_buf); RGUI_MENU_ITEM("Hardware filtering", RGUI_SETTINGS_VIDEO_FILTER); + RGUI_MENU_ITEM("Gamma", RGUI_SETTINGS_VIDEO_GAMMA); RGUI_MENU_ITEM("Rotation", RGUI_SETTINGS_VIDEO_ROTATION); RGUI_MENU_ITEM("Mute Audio", RGUI_SETTINGS_AUDIO_MUTE); RGUI_MENU_ITEM("Audio Control Rate", RGUI_SETTINGS_AUDIO_CONTROL_RATE); diff --git a/console/rgui/rgui.h b/console/rgui/rgui.h index 0f7a895300..7f79cca320 100644 --- a/console/rgui/rgui.h +++ b/console/rgui/rgui.h @@ -34,6 +34,7 @@ typedef enum // settings options are done here too RGUI_SETTINGS_VIDEO_FILTER, + RGUI_SETTINGS_VIDEO_GAMMA, RGUI_SETTINGS_VIDEO_ROTATION, RGUI_SETTINGS_AUDIO_MUTE, RGUI_SETTINGS_AUDIO_CONTROL_RATE, diff --git a/general.h b/general.h index cae185b275..654f859ed4 100644 --- a/general.h +++ b/general.h @@ -193,10 +193,10 @@ struct settings #ifdef RARCH_CONSOLE typedef struct { - uint32_t x; - uint32_t y; - uint32_t width; - uint32_t height; + unsigned x; + unsigned y; + unsigned width; + unsigned height; } rarch_viewport_t; struct console_settings @@ -218,7 +218,6 @@ struct console_settings #endif bool initialize_rarch_enable; bool info_msg_enable; - bool gamma_correction_enable; bool ingame_menu_enable; bool menu_enable; bool overscan_enable; @@ -227,31 +226,32 @@ struct console_settings bool throttle_enable; bool triple_buffering_enable; float overscan_amount; - uint32_t aspect_ratio_index; + unsigned aspect_ratio_index; struct { rarch_viewport_t custom_vp; } viewports; - uint32_t emulator_initialized; - uint32_t external_launcher_support; - uint32_t screen_orientation; - uint32_t current_resolution_index; - uint32_t current_resolution_id; - uint32_t ingame_menu_item; - uint32_t initial_resolution_id; - uint32_t map_dpad_to_stick; - uint32_t mode_switch; - uint32_t sound_mode; + unsigned gamma_correction; + unsigned emulator_initialized; + unsigned external_launcher_support; + unsigned screen_orientation; + unsigned current_resolution_index; + unsigned current_resolution_id; + unsigned ingame_menu_item; + unsigned initial_resolution_id; + unsigned map_dpad_to_stick; + unsigned mode_switch; + unsigned sound_mode; uint32_t *supported_resolutions; - uint32_t supported_resolutions_count; - uint32_t control_timer_expiration_frame_count; - uint32_t timer_expiration_frame_count; - uint32_t input_loop; + unsigned supported_resolutions_count; + unsigned control_timer_expiration_frame_count; + unsigned timer_expiration_frame_count; + unsigned input_loop; #ifdef HAVE_ZLIB - uint32_t zip_extract_mode; + unsigned zip_extract_mode; #endif #ifdef _XBOX - uint32_t color_format; + unsigned color_format; DWORD volume_device_type; #endif char cgp_path[PATH_MAX]; diff --git a/gx/gx_video.c b/gx/gx_video.c index 968fa32a64..5112e56967 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -226,7 +226,7 @@ static void gx_start(void) setup_video_mode(mode); GX_Init(gx_fifo, sizeof(gx_fifo)); - GX_SetDispCopyGamma(GX_GM_1_0); + GX_SetDispCopyGamma(g_console.gamma_correction); GX_SetCullMode(GX_CULL_NONE); GX_SetClipMode(GX_CLIP_DISABLE); @@ -421,6 +421,7 @@ static bool wii_frame(void *data, const void *frame, { gx_video_t *gx = (gx_video_t*)driver.video_data; bool menu_render = gx->menu_render; + bool should_resize = gx->should_resize; (void)data; (void)msg; @@ -430,6 +431,12 @@ static bool wii_frame(void *data, const void *frame, gx->frame_count++; + if(should_resize) + { + GX_SetDispCopyGamma(g_console.gamma_correction); + gx->should_resize = false; + } + while (g_vsync && !g_draw_done) LWP_ThreadSleep(g_video_cond); diff --git a/gx/gx_video.h b/gx/gx_video.h index 8a1b5bd5b7..118f670ab2 100644 --- a/gx/gx_video.h +++ b/gx/gx_video.h @@ -19,6 +19,7 @@ typedef struct gx_video { bool menu_render; + bool should_resize; uint32_t frame_count; uint32_t *menu_data; } gx_video_t; From 690ac65d3e5d56087e1d26135b31f2be69446ceb Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 8 Aug 2012 21:04:33 +0200 Subject: [PATCH 109/492] (GX) Add VI_Trap Filter (for Wii) --- console/griffin/griffin.c | 3 + console/rarch_console_settings.c | 12 +- console/rgui/rgui.c | 13 + console/rgui/rgui.h | 3 + general.h | 2 +- gx/gx_video.c | 4 + gx/vi_encoder.c | 561 +++++++++++++++++++++++++++++++ gx/vi_encoder.h | 79 +++++ 8 files changed, 672 insertions(+), 5 deletions(-) create mode 100644 gx/vi_encoder.c create mode 100644 gx/vi_encoder.h diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index 23cfd05181..b95be707ad 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -127,6 +127,9 @@ VIDEO DRIVER #if defined(HAVE_OPENGL) #include "../../gfx/gl.c" #elif defined(GEKKO) +#ifdef HW_RVL +#include "../../gx/vi_encoder.c" +#endif #include "../../gx/gx_video.c" #endif diff --git a/console/rarch_console_settings.c b/console/rarch_console_settings.c index 8101230fae..097833a9e4 100644 --- a/console/rarch_console_settings.c +++ b/console/rarch_console_settings.c @@ -312,6 +312,12 @@ void rarch_settings_create_menu_item_label(char * str, unsigned setting, size_t } } +#if defined(_XBOX360) +#define DEFAULT_GAMMA 1 +#elif defined(GEKKO) +#define DEFAULT_GAMMA 0 +#endif + void rarch_settings_set_default (const input_driver_t *input) { // g_settings @@ -385,13 +391,11 @@ void rarch_settings_set_default (const input_driver_t *input) #ifdef _XBOX360 g_console.color_format = 0; #endif -#if defined(_XBOX360) || defined(GEKKO) - g_console.gamma_correction = 1; -#endif + g_console.gamma_correction = DEFAULT_GAMMA; #ifdef _XBOX1 g_console.flicker_filter = 1; - g_console.soft_display_filter_enable = false; #endif + g_console.soft_display_filter_enable = true; #ifdef HAVE_ZLIB g_console.zip_extract_mode = 0; #endif diff --git a/console/rgui/rgui.c b/console/rgui/rgui.c index 18060985df..fdac3db0c6 100644 --- a/console/rgui/rgui.c +++ b/console/rgui/rgui.c @@ -319,6 +319,11 @@ static void render_text(rgui_handle_t *rgui) case RGUI_SETTINGS_VIDEO_FILTER: snprintf(type_str, sizeof(type_str), g_settings.video.smooth ? "Bilinear filtering" : "Point filtering"); break; +#ifdef HW_RVL + case RGUI_SETTINGS_VIDEO_SOFT_FILTER: + snprintf(type_str, sizeof(type_str), g_console.soft_display_filter_enable ? "ON" : "OFF"); + break; +#endif case RGUI_SETTINGS_VIDEO_GAMMA: snprintf(type_str, sizeof(type_str), "%d", g_console.gamma_correction); break; @@ -402,6 +407,11 @@ static void rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t else rarch_settings_change(S_HW_TEXTURE_FILTER); break; +#ifdef HW_RVL + case RGUI_SETTINGS_VIDEO_SOFT_FILTER: + g_console.soft_display_filter_enable = !g_console.soft_display_filter_enable; + break; +#endif case RGUI_SETTINGS_VIDEO_GAMMA: if (action == RGUI_ACTION_START) { @@ -542,6 +552,9 @@ static void rgui_settings_populate_entries(rgui_handle_t *rgui) rgui_list_clear(rgui->folder_buf); RGUI_MENU_ITEM("Hardware filtering", RGUI_SETTINGS_VIDEO_FILTER); +#ifdef HW_RVL + RGUI_MENU_ITEM("VI Trap filtering", RGUI_SETTINGS_VIDEO_SOFT_FILTER); +#endif RGUI_MENU_ITEM("Gamma", RGUI_SETTINGS_VIDEO_GAMMA); RGUI_MENU_ITEM("Rotation", RGUI_SETTINGS_VIDEO_ROTATION); RGUI_MENU_ITEM("Mute Audio", RGUI_SETTINGS_AUDIO_MUTE); diff --git a/console/rgui/rgui.h b/console/rgui/rgui.h index 7f79cca320..b629a18d37 100644 --- a/console/rgui/rgui.h +++ b/console/rgui/rgui.h @@ -34,6 +34,9 @@ typedef enum // settings options are done here too RGUI_SETTINGS_VIDEO_FILTER, +#ifdef HW_RVL + RGUI_SETTINGS_VIDEO_SOFT_FILTER, +#endif RGUI_SETTINGS_VIDEO_GAMMA, RGUI_SETTINGS_VIDEO_ROTATION, RGUI_SETTINGS_AUDIO_MUTE, diff --git a/general.h b/general.h index 654f859ed4..d4e359df5b 100644 --- a/general.h +++ b/general.h @@ -214,8 +214,8 @@ struct console_settings #endif #ifdef _XBOX1 unsigned flicker_filter; - bool soft_display_filter_enable; #endif + bool soft_display_filter_enable; bool initialize_rarch_enable; bool info_msg_enable; bool ingame_menu_enable; diff --git a/gx/gx_video.c b/gx/gx_video.c index 5112e56967..8b03be19a0 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -429,6 +429,10 @@ static bool wii_frame(void *data, const void *frame, if(!frame && !menu_render) return true; +#ifdef HW_RVL + VIDEO_SetTrapFilter(g_console.soft_display_filter_enable); +#endif + gx->frame_count++; if(should_resize) diff --git a/gx/vi_encoder.c b/gx/vi_encoder.c new file mode 100644 index 0000000000..24365bb0ca --- /dev/null +++ b/gx/vi_encoder.c @@ -0,0 +1,561 @@ +/**************************************************************************** + * vi_encoder.c + * + * Wii Audio/Video Encoder support + * + * Copyright (C) 2009 Eke-Eke, with some code from libogc (C) Hector Martin + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include +#include +#include +#include + +#include "vi_encoder.h" + +/**************************************************************************** + * I2C driver by Hector Martin (marcan) + * + ****************************************************************************/ + +#define _SHIFTL(v, s, w) \ + ((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s))) +#define _SHIFTR(v, s, w) \ + ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1))) + +extern void udelay(int us); + +static u32 i2cIdentFirst = 0; +static u32 i2cIdentFlag = 1; +static vu16* const _viReg = (u16*)0xCC002000; +static vu32* const _i2cReg = (u32*)0xCD800000; + +static inline void __viOpenI2C(u32 channel) +{ + u32 val = ((_i2cReg[49]&~0x8000)|0x4000); + val |= _SHIFTL(channel,15,1); + _i2cReg[49] = val; +} + +static inline u32 __viSetSCL(u32 channel) +{ + u32 val = (_i2cReg[48]&~0x4000); + val |= _SHIFTL(channel,14,1); + _i2cReg[48] = val; + return 1; +} +static inline u32 __viSetSDA(u32 channel) +{ + u32 val = (_i2cReg[48]&~0x8000); + val |= _SHIFTL(channel,15,1); + _i2cReg[48] = val; + return 1; +} + +static inline u32 __viGetSDA() +{ + return _SHIFTR(_i2cReg[50],15,1); +} + +static inline void __viCheckI2C() +{ + __viOpenI2C(0); + udelay(4); + + i2cIdentFlag = 0; + if(__viGetSDA()!=0) i2cIdentFlag = 1; +} + +static u32 __sendSlaveAddress(u8 addr) +{ + u32 i; + + __viSetSDA(i2cIdentFlag^1); + udelay(2); + + __viSetSCL(0); + for(i=0;i<8;i++) { + if(addr&0x80) __viSetSDA(i2cIdentFlag); + else __viSetSDA(i2cIdentFlag^1); + udelay(2); + + __viSetSCL(1); + udelay(2); + + __viSetSCL(0); + addr <<= 1; + } + + __viOpenI2C(0); + udelay(2); + + __viSetSCL(1); + udelay(2); + + if(i2cIdentFlag==1 && __viGetSDA()!=0) return 0; + + __viSetSDA(i2cIdentFlag^1); + __viOpenI2C(1); + __viSetSCL(0); + + return 1; +} + +static u32 __VISendI2CData(u8 addr,void *val,u32 len) +{ + u8 c; + s32 i,j; + u32 level,ret; + + if(i2cIdentFirst==0) { + __viCheckI2C(); + i2cIdentFirst = 1; + } + + _CPU_ISR_Disable(level); + + __viOpenI2C(1); + __viSetSCL(1); + + __viSetSDA(i2cIdentFlag); + udelay(4); + + ret = __sendSlaveAddress(addr); + if(ret==0) { + _CPU_ISR_Restore(level); + return 0; + } + + __viOpenI2C(1); + for(i=0;i> 8; + buf[2] = data & 0xFF; + __VISendI2CData(0xe0,buf,3); + udelay(2); +} + +static void __VIWriteI2CRegister32(u8 reg, u32 data) +{ + u8 buf[5]; + buf[0] = reg; + buf[1] = data >> 24; + buf[2] = (data >> 16) & 0xFF; + buf[3] = (data >> 8) & 0xFF; + buf[4] = data & 0xFF; + __VISendI2CData(0xe0,buf,5); + udelay(2); +} + +static void __VIWriteI2CRegisterBuf(u8 reg, int size, u8 *data) +{ + u8 buf[0x100]; + buf[0] = reg; + memcpy(&buf[1], data, size); + __VISendI2CData(0xe0,buf,size+1); + udelay(2); +} + +/**************************************************************************** + * A/V functions support (Eke-Eke) + * + ****************************************************************************/ +static const u8 gamma_coeffs[][33] = +{ + /* GM_0_0 */ + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + }, + + /* GM_0_1 */ + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x97, 0x3B, 0x49, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x80, 0x1B, 0x80, 0xEB, 0x00 + }, + + /* GM_0_2 */ + { + 0x00, 0x00, 0x00, 0x28, 0x00, 0x5A, 0x02, 0xDB, 0x0D, 0x8D, 0x30, 0x49, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x10, 0x00, 0x10, 0x40, 0x11, 0x00, 0x18, 0x80, 0x42, 0x00, 0xEB, 0x00 + }, + + /* GM_0_3 */ + { + 0x00, 0x00, 0x00, 0x7A, 0x02, 0x3C, 0x07, 0x6D, 0x12, 0x9C, 0x27, 0x24, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x10, 0x00, 0x10, 0xC0, 0x15, 0x80, 0x29, 0x00, 0x62, 0x00, 0xEB, 0x00 + }, + + /* GM_0_4 */ + { + 0x00, 0x4E, 0x01, 0x99, 0x05, 0x2D, 0x0B, 0x24, 0x14, 0x29, 0x20, 0xA4, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x00, 0x10, 0x10, 0x40, 0x12, 0xC0, 0x1D, 0xC0, 0x3B, 0x00, 0x78, 0xC0, 0xEB, 0x00 + }, + + /* GM_0_5 */ + { + 0x00, 0xEC, 0x03, 0xD7, 0x08, 0x00, 0x0D, 0x9E, 0x14, 0x3E, 0x1B, 0xDB, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x10, 0xC0, 0x16, 0xC0, 0x27, 0xC0, 0x4B, 0x80, 0x89, 0x80, 0xEB, 0x00 + }, + + /* GM_0_6 */ + { + 0x02, 0x76, 0x06, 0x66, 0x0A, 0x96, 0x0E, 0xF3, 0x13, 0xAC, 0x18, 0x49, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x12, 0x00, 0x1C, 0x00, 0x32, 0x80, 0x59, 0xC0, 0x96, 0x00, 0xEB, 0x00 + }, + + /* GM_0_7 */ + { + 0x04, 0xEC, 0x08, 0xF5, 0x0C, 0x96, 0x0F, 0xCF, 0x12, 0xC6, 0x15, 0x80, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x14, 0x00, 0x22, 0x00, 0x3C, 0xC0, 0x66, 0x40, 0x9F, 0xC0, 0xEB, 0x00 + }, + + /* GM_0_8 */ + { + 0x08, 0x00, 0x0B, 0xAE, 0x0E, 0x00, 0x10, 0x30, 0x11, 0xCB, 0x13, 0x49, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x16, 0x80, 0x28, 0xC0, 0x46, 0x80, 0x71, 0x00, 0xA7, 0x80, 0xEB, 0x00 + }, + + /* GM_0_9 */ + { + 0x0B, 0xB1, 0x0E, 0x14, 0x0F, 0x2D, 0x10, 0x18, 0x10, 0xE5, 0x11, 0x80, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x19, 0x80, 0x2F, 0x80, 0x4F, 0xC0, 0x7A, 0x00, 0xAD, 0xC0, 0xEB, 0x00 + }, + + /* GM_1_0 */ + { + 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, + 0x10, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xEB, + 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x60, 0x00, 0x80, 0x00, 0xA0, 0x00, 0xEB, 0x00 + }, + + /* GM_1_1 */ + { + 0x14, 0xEC, 0x11, 0xC2, 0x10, 0x78, 0x0F, 0xB6, 0x0F, 0x2F, 0x0E, 0xB6, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x21, 0x00, 0x3C, 0xC0, 0x5F, 0xC0, 0x89, 0x00, 0xB7, 0x80, 0xEB, 0x00 + }, + + /* GM_1_2 */ + { + 0x19, 0xD8, 0x13, 0x33, 0x10, 0xD2, 0x0F, 0x6D, 0x0E, 0x5E, 0x0D, 0xA4, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x25, 0x00, 0x43, 0x00, 0x66, 0xC0, 0x8F, 0x40, 0xBB, 0x40, 0xEB, 0x00 + }, + + /* GM_1_3 */ + { + 0x1E, 0xC4, 0x14, 0x7A, 0x11, 0x0F, 0xF, 0x0C, 0x0D, 0xA1, 0x0C, 0xB6, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x29, 0x00, 0x49, 0x00, 0x6D, 0x40, 0x94, 0xC0, 0xBE, 0x80, 0xEB, 0x00 + }, + + /* GM_1_4 */ + { + 0x24, 0x00, 0x15, 0x70, 0x11, 0x0F, 0x0E, 0xAA, 0x0D, 0x0F, 0x0B, 0xDB, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x2D, 0x40, 0x4E, 0xC0, 0x73, 0x00, 0x99, 0x80, 0xC1, 0x80, 0xEB, 0x00 + }, + + /* GM_1_5 */ + { + 0x29, 0x3B, 0x16, 0x3D, 0x11, 0x0F, 0x0E, 0x30, 0x0C, 0x7D, 0x0B, 0x24, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x31, 0x80, 0x54, 0x40, 0x78, 0x80, 0x9D, 0xC0, 0xC4, 0x00, 0xEB, 0x00 + }, + + /* GM_1_6 */ + { + 0x2E, 0x27, 0x17, 0x0A, 0x10, 0xD2, 0x0D, 0xE7, 0x0B, 0xEB, 0x0A, 0x80, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x35, 0x80, 0x59, 0x80, 0x7D, 0x40, 0xA1, 0xC0, 0xC6, 0x40, 0xEB, 0x00 + }, + + /* GM_1_7 */ + { + 0x33, 0x62, 0x17, 0x5C, 0x10, 0xD2, 0x0D, 0x6D, 0x0B, 0x6D, 0x09, 0xED, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x39, 0xC0, 0x5E, 0x40, 0x82, 0x00, 0xA5, 0x40, 0xC8, 0x40, 0xEB, 0x00 + }, + + /* GM_1_8 */ + { + 0x38, 0x4E, 0x17, 0xAE, 0x10, 0xB4, 0x0D, 0x0C, 0x0A, 0xF0, 0x09, 0x6D, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x3D, 0xC0, 0x62, 0xC0, 0x86, 0x40, 0xA8, 0x80, 0xCA, 0x00, 0xEB, 0x00 + }, + + /* GM_1_9 */ + { + 0x3D, 0x3B, 0x18, 0x00, 0x10, 0x5A, 0x0C, 0xC3, 0x0A, 0x72, 0x09, 0x00, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x41, 0xC0, 0x67, 0x40, 0x8A, 0x00, 0xAB, 0x80, 0xCB, 0x80, 0xEB, 0x00 + }, + + /* GM_2_0 */ + { + 0x41, 0xD8, 0x18, 0x28, 0x10, 0x3C, 0x0C, 0x49, 0x0A, 0x1F, 0x08, 0x92, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x45, 0x80, 0x6B, 0x40, 0x8D, 0xC0, 0xAE, 0x00, 0xCD, 0x00, 0xEB, 0x00 + }, + + /* GM_2_1 */ + { + 0x46, 0x76, 0x18, 0x51, 0x0F, 0xE1, 0x0C, 0x00, 0x09, 0xB6, 0x08, 0x36, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x49, 0x40, 0x6F, 0x40, 0x91, 0x00, 0xB0, 0x80, 0xCE, 0x40, 0xEB, 0x00 + }, + + /* GM_2_2 */ + { + 0x4A, 0xC4, 0x18, 0x7A, 0x0F, 0xA5, 0x0B, 0x9E, 0x09, 0x63, 0x07, 0xDB, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x4C, 0xC0, 0x73, 0x00, 0x94, 0x40, 0xB2, 0xC0, 0xCF, 0x80, 0xEB, 0x00 + }, + + /* GM_2_3 */ + { + 0x4F, 0x13, 0x18, 0x51, 0x0F, 0x69, 0x0B, 0x6D, 0x09, 0x0F, 0x07, 0x80, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x50, 0x40, 0x76, 0x40, 0x97, 0x00, 0xB5, 0x00, 0xD0, 0xC0, 0xEB, 0x00 + }, + + /* GM_2_4 */ + { + 0x53, 0x13, 0x18, 0x7A, 0x0F, 0x0F, 0x0B, 0x24, 0x08, 0xBC, 0x07, 0x36, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x53, 0x80, 0x79, 0xC0, 0x99, 0xC0, 0xB7, 0x00, 0xD1, 0xC0, 0xEB, 0x00 + }, + + /* GM_2_5 */ + { + 0x57, 0x13, 0x18, 0x51, 0x0E, 0xF0, 0x0A, 0xC3, 0x08, 0x7D, 0x06, 0xED, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x56, 0xC0, 0x7C, 0xC0, 0x9C, 0x80, 0xB8, 0xC0, 0xD2, 0xC0, 0xEB, 0x00 + }, + + /* GM_2_6 */ + { + 0x5B, 0x13, 0x18, 0x28, 0x0E, 0x96, 0x0A, 0x92, 0x08, 0x29, 0x06, 0xB6, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x5A, 0x00, 0x7F, 0xC0, 0x9E, 0xC0, 0xBA, 0x80, 0xD3, 0x80, 0xEB, 0x00 + }, + + /* GM_2_7 */ + { + 0x5E, 0xC4, 0x18, 0x00, 0x0E, 0x78, 0x0A, 0x30, 0x08, 0x00, 0x06, 0x6D, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x5D, 0x00, 0x82, 0x80, 0xA1, 0x40, 0xBC, 0x00, 0xD4, 0x80, 0xEB, 0x00 + }, + + /* GM_2_8 */ + { + 0x62, 0x76, 0x17, 0xD7, 0x0E, 0x1E, 0x0A, 0x00, 0x07, 0xC1, 0x06, 0x36, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x60, 0x00, 0x85, 0x40, 0xA3, 0x40, 0xBD, 0x80, 0xD5, 0x40, 0xEB, 0x00 + }, + + /* GM_2_9 */ + { + 0x65, 0xD8, 0x17, 0xAE, 0x0D, 0xE1, 0x09, 0xCF, 0x07, 0x82, 0x06, 0x00, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x62, 0xC0, 0x87, 0xC0, 0xA5, 0x40, 0xBF, 0x00, 0xD6, 0x00, 0xEB, 0x00 + }, + + /* GM_3_0 */ + { + 0x69, 0x3B, 0x17, 0x85, 0x0D, 0xA5, 0x09, 0x86, 0x07, 0x43, 0x05, 0xDB, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x65, 0x80, 0x8A, 0x40, 0xA7, 0x40, 0xC0, 0x40, 0xD6, 0x80, 0xEB, 0x00 + } +}; + +void __VISetTiming(u8 timing) +{ + __VIWriteI2CRegister8(0x00,timing); +} + +void __VISetYUVSEL(u8 dtvstatus) +{ + u8 vdacFlagRegion = 0; + u32 currTvMode = _SHIFTR(_viReg[1],8,2); + if(currTvMode==VI_PAL || currTvMode==VI_EURGB60) + vdacFlagRegion = 2; + else if(currTvMode==VI_MPAL) + vdacFlagRegion = 1; + + __VIWriteI2CRegister8(0x01, _SHIFTL(dtvstatus,5,3)|(vdacFlagRegion&0x1f)); +} + +void __VISetVBICtrl(u16 data) +{ + __VIWriteI2CRegister16(0x02, data); +} + +void __VISetTrapFilter(u8 disable) +{ + if (disable) + __VIWriteI2CRegister8(0x03, 0); + else + __VIWriteI2CRegister8(0x03, 1); +} + +void __VISet3in1Output(u8 enable) +{ + __VIWriteI2CRegister8(0x04,enable); +} + +void __VISetCGMS(u16 value) +{ + __VIWriteI2CRegister16(0x05, value); +} + +void __VISetWSS(u16 value) +{ + __VIWriteI2CRegister16(0x08, value); +} + +void __VISetRGBOverDrive(u8 value) +{ + u32 currTvMode = _SHIFTR(_viReg[1],8,2); + if (currTvMode == VI_DEBUG) + __VIWriteI2CRegister8(0x0A,(value<<1)|1); + else + __VIWriteI2CRegister8(0x0A,0); +} + +void __VISetOverSampling(void) +{ + __VIWriteI2CRegister8(0x65,1); +} + +void __VISetCCSEL(void) +{ + __VIWriteI2CRegister8(0x6a,1); +} + +void __VISetFilterEURGB60(u8 enable) +{ + __VIWriteI2CRegister8(0x6e, enable); +} + +void __VISetVolume(u16 value) +{ + __VIWriteI2CRegister16(0x71,value); +} + +void __VISetClosedCaption(u32 value) +{ + __VIWriteI2CRegister32(0x7a, value); +} + +void __VISetGamma(VIGamma gamma) +{ + u8 *data = (u8 *)&gamma_coeffs[gamma][0]; + __VIWriteI2CRegisterBuf(0x10, 0x21, data); +} + +/* User Configurable */ + +void VIDEO_SetGamma(VIGamma gamma) +{ + __VISetGamma(gamma); +} + +void VIDEO_SetTrapFilter(bool enable) +{ + if (enable) + __VISetTrapFilter(0); + else + __VISetTrapFilter(1); +} diff --git a/gx/vi_encoder.h b/gx/vi_encoder.h new file mode 100644 index 0000000000..f5290dc568 --- /dev/null +++ b/gx/vi_encoder.h @@ -0,0 +1,79 @@ +/**************************************************************************** + * vi_encoder.c + * + * Wii Audio/Video Encoder support + * + * Copyright (C) 2009 Eke-Eke, with some code from libogc (C) Hector Martin + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ +#ifdef HW_RVL + +typedef enum +{ + VI_GM_0_1=1, + VI_GM_0_2, + VI_GM_0_3, + VI_GM_0_4, + VI_GM_0_5, + VI_GM_0_6, + VI_GM_0_7, + VI_GM_0_8, + VI_GM_0_9, + VI_GM_1_0, + VI_GM_1_1, + VI_GM_1_2, + VI_GM_1_3, + VI_GM_1_4, + VI_GM_1_5, + VI_GM_1_6, + VI_GM_1_7, + VI_GM_1_8, + VI_GM_1_9, + VI_GM_2_0, + VI_GM_2_1, + VI_GM_2_2, + VI_GM_2_3, + VI_GM_2_4, + VI_GM_2_5, + VI_GM_2_6, + VI_GM_2_7, + VI_GM_2_8, + VI_GM_2_9, + VI_GM_3_0 +} VIGamma; + +extern void VIDEO_SetGamma(VIGamma gamma); +extern void VIDEO_SetTrapFilter(bool enable); + + +#endif From 827e69fabcac8673c12d0265ad36b5f5fcb5e256 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 8 Aug 2012 21:25:52 +0200 Subject: [PATCH 110/492] Revert "(GX) Add VI_Trap Filter (for Wii)" - noticeable audio pops for little gain This reverts commit 690ac65d3e5d56087e1d26135b31f2be69446ceb. --- console/griffin/griffin.c | 3 - console/rarch_console_settings.c | 12 +- console/rgui/rgui.c | 13 - console/rgui/rgui.h | 3 - general.h | 2 +- gx/gx_video.c | 4 - gx/vi_encoder.c | 561 ------------------------------- gx/vi_encoder.h | 79 ----- 8 files changed, 5 insertions(+), 672 deletions(-) delete mode 100644 gx/vi_encoder.c delete mode 100644 gx/vi_encoder.h diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index b95be707ad..23cfd05181 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -127,9 +127,6 @@ VIDEO DRIVER #if defined(HAVE_OPENGL) #include "../../gfx/gl.c" #elif defined(GEKKO) -#ifdef HW_RVL -#include "../../gx/vi_encoder.c" -#endif #include "../../gx/gx_video.c" #endif diff --git a/console/rarch_console_settings.c b/console/rarch_console_settings.c index 097833a9e4..8101230fae 100644 --- a/console/rarch_console_settings.c +++ b/console/rarch_console_settings.c @@ -312,12 +312,6 @@ void rarch_settings_create_menu_item_label(char * str, unsigned setting, size_t } } -#if defined(_XBOX360) -#define DEFAULT_GAMMA 1 -#elif defined(GEKKO) -#define DEFAULT_GAMMA 0 -#endif - void rarch_settings_set_default (const input_driver_t *input) { // g_settings @@ -391,11 +385,13 @@ void rarch_settings_set_default (const input_driver_t *input) #ifdef _XBOX360 g_console.color_format = 0; #endif - g_console.gamma_correction = DEFAULT_GAMMA; +#if defined(_XBOX360) || defined(GEKKO) + g_console.gamma_correction = 1; +#endif #ifdef _XBOX1 g_console.flicker_filter = 1; + g_console.soft_display_filter_enable = false; #endif - g_console.soft_display_filter_enable = true; #ifdef HAVE_ZLIB g_console.zip_extract_mode = 0; #endif diff --git a/console/rgui/rgui.c b/console/rgui/rgui.c index fdac3db0c6..18060985df 100644 --- a/console/rgui/rgui.c +++ b/console/rgui/rgui.c @@ -319,11 +319,6 @@ static void render_text(rgui_handle_t *rgui) case RGUI_SETTINGS_VIDEO_FILTER: snprintf(type_str, sizeof(type_str), g_settings.video.smooth ? "Bilinear filtering" : "Point filtering"); break; -#ifdef HW_RVL - case RGUI_SETTINGS_VIDEO_SOFT_FILTER: - snprintf(type_str, sizeof(type_str), g_console.soft_display_filter_enable ? "ON" : "OFF"); - break; -#endif case RGUI_SETTINGS_VIDEO_GAMMA: snprintf(type_str, sizeof(type_str), "%d", g_console.gamma_correction); break; @@ -407,11 +402,6 @@ static void rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t else rarch_settings_change(S_HW_TEXTURE_FILTER); break; -#ifdef HW_RVL - case RGUI_SETTINGS_VIDEO_SOFT_FILTER: - g_console.soft_display_filter_enable = !g_console.soft_display_filter_enable; - break; -#endif case RGUI_SETTINGS_VIDEO_GAMMA: if (action == RGUI_ACTION_START) { @@ -552,9 +542,6 @@ static void rgui_settings_populate_entries(rgui_handle_t *rgui) rgui_list_clear(rgui->folder_buf); RGUI_MENU_ITEM("Hardware filtering", RGUI_SETTINGS_VIDEO_FILTER); -#ifdef HW_RVL - RGUI_MENU_ITEM("VI Trap filtering", RGUI_SETTINGS_VIDEO_SOFT_FILTER); -#endif RGUI_MENU_ITEM("Gamma", RGUI_SETTINGS_VIDEO_GAMMA); RGUI_MENU_ITEM("Rotation", RGUI_SETTINGS_VIDEO_ROTATION); RGUI_MENU_ITEM("Mute Audio", RGUI_SETTINGS_AUDIO_MUTE); diff --git a/console/rgui/rgui.h b/console/rgui/rgui.h index b629a18d37..7f79cca320 100644 --- a/console/rgui/rgui.h +++ b/console/rgui/rgui.h @@ -34,9 +34,6 @@ typedef enum // settings options are done here too RGUI_SETTINGS_VIDEO_FILTER, -#ifdef HW_RVL - RGUI_SETTINGS_VIDEO_SOFT_FILTER, -#endif RGUI_SETTINGS_VIDEO_GAMMA, RGUI_SETTINGS_VIDEO_ROTATION, RGUI_SETTINGS_AUDIO_MUTE, diff --git a/general.h b/general.h index d4e359df5b..654f859ed4 100644 --- a/general.h +++ b/general.h @@ -214,8 +214,8 @@ struct console_settings #endif #ifdef _XBOX1 unsigned flicker_filter; -#endif bool soft_display_filter_enable; +#endif bool initialize_rarch_enable; bool info_msg_enable; bool ingame_menu_enable; diff --git a/gx/gx_video.c b/gx/gx_video.c index 8b03be19a0..5112e56967 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -429,10 +429,6 @@ static bool wii_frame(void *data, const void *frame, if(!frame && !menu_render) return true; -#ifdef HW_RVL - VIDEO_SetTrapFilter(g_console.soft_display_filter_enable); -#endif - gx->frame_count++; if(should_resize) diff --git a/gx/vi_encoder.c b/gx/vi_encoder.c deleted file mode 100644 index 24365bb0ca..0000000000 --- a/gx/vi_encoder.c +++ /dev/null @@ -1,561 +0,0 @@ -/**************************************************************************** - * vi_encoder.c - * - * Wii Audio/Video Encoder support - * - * Copyright (C) 2009 Eke-Eke, with some code from libogc (C) Hector Martin - * - * Redistribution and use of this code or any derivative works are permitted - * provided that the following conditions are met: - * - * - Redistributions may not be sold, nor may they be used in a commercial - * product or activity. - * - * - Redistributions that are modified from the original source must include the - * complete source code, including the source code for all components used by a - * binary built from the modified sources. However, as a special exception, the - * source code distributed need not include anything that is normally distributed - * (in either source or binary form) with the major components (compiler, kernel, - * and so on) of the operating system on which the executable runs, unless that - * component itself accompanies the executable. - * - * - Redistributions must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************************/ - -#include -#include -#include -#include - -#include "vi_encoder.h" - -/**************************************************************************** - * I2C driver by Hector Martin (marcan) - * - ****************************************************************************/ - -#define _SHIFTL(v, s, w) \ - ((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s))) -#define _SHIFTR(v, s, w) \ - ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1))) - -extern void udelay(int us); - -static u32 i2cIdentFirst = 0; -static u32 i2cIdentFlag = 1; -static vu16* const _viReg = (u16*)0xCC002000; -static vu32* const _i2cReg = (u32*)0xCD800000; - -static inline void __viOpenI2C(u32 channel) -{ - u32 val = ((_i2cReg[49]&~0x8000)|0x4000); - val |= _SHIFTL(channel,15,1); - _i2cReg[49] = val; -} - -static inline u32 __viSetSCL(u32 channel) -{ - u32 val = (_i2cReg[48]&~0x4000); - val |= _SHIFTL(channel,14,1); - _i2cReg[48] = val; - return 1; -} -static inline u32 __viSetSDA(u32 channel) -{ - u32 val = (_i2cReg[48]&~0x8000); - val |= _SHIFTL(channel,15,1); - _i2cReg[48] = val; - return 1; -} - -static inline u32 __viGetSDA() -{ - return _SHIFTR(_i2cReg[50],15,1); -} - -static inline void __viCheckI2C() -{ - __viOpenI2C(0); - udelay(4); - - i2cIdentFlag = 0; - if(__viGetSDA()!=0) i2cIdentFlag = 1; -} - -static u32 __sendSlaveAddress(u8 addr) -{ - u32 i; - - __viSetSDA(i2cIdentFlag^1); - udelay(2); - - __viSetSCL(0); - for(i=0;i<8;i++) { - if(addr&0x80) __viSetSDA(i2cIdentFlag); - else __viSetSDA(i2cIdentFlag^1); - udelay(2); - - __viSetSCL(1); - udelay(2); - - __viSetSCL(0); - addr <<= 1; - } - - __viOpenI2C(0); - udelay(2); - - __viSetSCL(1); - udelay(2); - - if(i2cIdentFlag==1 && __viGetSDA()!=0) return 0; - - __viSetSDA(i2cIdentFlag^1); - __viOpenI2C(1); - __viSetSCL(0); - - return 1; -} - -static u32 __VISendI2CData(u8 addr,void *val,u32 len) -{ - u8 c; - s32 i,j; - u32 level,ret; - - if(i2cIdentFirst==0) { - __viCheckI2C(); - i2cIdentFirst = 1; - } - - _CPU_ISR_Disable(level); - - __viOpenI2C(1); - __viSetSCL(1); - - __viSetSDA(i2cIdentFlag); - udelay(4); - - ret = __sendSlaveAddress(addr); - if(ret==0) { - _CPU_ISR_Restore(level); - return 0; - } - - __viOpenI2C(1); - for(i=0;i> 8; - buf[2] = data & 0xFF; - __VISendI2CData(0xe0,buf,3); - udelay(2); -} - -static void __VIWriteI2CRegister32(u8 reg, u32 data) -{ - u8 buf[5]; - buf[0] = reg; - buf[1] = data >> 24; - buf[2] = (data >> 16) & 0xFF; - buf[3] = (data >> 8) & 0xFF; - buf[4] = data & 0xFF; - __VISendI2CData(0xe0,buf,5); - udelay(2); -} - -static void __VIWriteI2CRegisterBuf(u8 reg, int size, u8 *data) -{ - u8 buf[0x100]; - buf[0] = reg; - memcpy(&buf[1], data, size); - __VISendI2CData(0xe0,buf,size+1); - udelay(2); -} - -/**************************************************************************** - * A/V functions support (Eke-Eke) - * - ****************************************************************************/ -static const u8 gamma_coeffs[][33] = -{ - /* GM_0_0 */ - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - - }, - - /* GM_0_1 */ - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x97, 0x3B, 0x49, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x80, 0x1B, 0x80, 0xEB, 0x00 - }, - - /* GM_0_2 */ - { - 0x00, 0x00, 0x00, 0x28, 0x00, 0x5A, 0x02, 0xDB, 0x0D, 0x8D, 0x30, 0x49, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x10, 0x00, 0x10, 0x40, 0x11, 0x00, 0x18, 0x80, 0x42, 0x00, 0xEB, 0x00 - }, - - /* GM_0_3 */ - { - 0x00, 0x00, 0x00, 0x7A, 0x02, 0x3C, 0x07, 0x6D, 0x12, 0x9C, 0x27, 0x24, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x10, 0x00, 0x10, 0xC0, 0x15, 0x80, 0x29, 0x00, 0x62, 0x00, 0xEB, 0x00 - }, - - /* GM_0_4 */ - { - 0x00, 0x4E, 0x01, 0x99, 0x05, 0x2D, 0x0B, 0x24, 0x14, 0x29, 0x20, 0xA4, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x00, 0x10, 0x10, 0x40, 0x12, 0xC0, 0x1D, 0xC0, 0x3B, 0x00, 0x78, 0xC0, 0xEB, 0x00 - }, - - /* GM_0_5 */ - { - 0x00, 0xEC, 0x03, 0xD7, 0x08, 0x00, 0x0D, 0x9E, 0x14, 0x3E, 0x1B, 0xDB, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x10, 0xC0, 0x16, 0xC0, 0x27, 0xC0, 0x4B, 0x80, 0x89, 0x80, 0xEB, 0x00 - }, - - /* GM_0_6 */ - { - 0x02, 0x76, 0x06, 0x66, 0x0A, 0x96, 0x0E, 0xF3, 0x13, 0xAC, 0x18, 0x49, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x12, 0x00, 0x1C, 0x00, 0x32, 0x80, 0x59, 0xC0, 0x96, 0x00, 0xEB, 0x00 - }, - - /* GM_0_7 */ - { - 0x04, 0xEC, 0x08, 0xF5, 0x0C, 0x96, 0x0F, 0xCF, 0x12, 0xC6, 0x15, 0x80, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x14, 0x00, 0x22, 0x00, 0x3C, 0xC0, 0x66, 0x40, 0x9F, 0xC0, 0xEB, 0x00 - }, - - /* GM_0_8 */ - { - 0x08, 0x00, 0x0B, 0xAE, 0x0E, 0x00, 0x10, 0x30, 0x11, 0xCB, 0x13, 0x49, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x16, 0x80, 0x28, 0xC0, 0x46, 0x80, 0x71, 0x00, 0xA7, 0x80, 0xEB, 0x00 - }, - - /* GM_0_9 */ - { - 0x0B, 0xB1, 0x0E, 0x14, 0x0F, 0x2D, 0x10, 0x18, 0x10, 0xE5, 0x11, 0x80, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x19, 0x80, 0x2F, 0x80, 0x4F, 0xC0, 0x7A, 0x00, 0xAD, 0xC0, 0xEB, 0x00 - }, - - /* GM_1_0 */ - { - 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, - 0x10, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xEB, - 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x60, 0x00, 0x80, 0x00, 0xA0, 0x00, 0xEB, 0x00 - }, - - /* GM_1_1 */ - { - 0x14, 0xEC, 0x11, 0xC2, 0x10, 0x78, 0x0F, 0xB6, 0x0F, 0x2F, 0x0E, 0xB6, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x21, 0x00, 0x3C, 0xC0, 0x5F, 0xC0, 0x89, 0x00, 0xB7, 0x80, 0xEB, 0x00 - }, - - /* GM_1_2 */ - { - 0x19, 0xD8, 0x13, 0x33, 0x10, 0xD2, 0x0F, 0x6D, 0x0E, 0x5E, 0x0D, 0xA4, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x25, 0x00, 0x43, 0x00, 0x66, 0xC0, 0x8F, 0x40, 0xBB, 0x40, 0xEB, 0x00 - }, - - /* GM_1_3 */ - { - 0x1E, 0xC4, 0x14, 0x7A, 0x11, 0x0F, 0xF, 0x0C, 0x0D, 0xA1, 0x0C, 0xB6, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x29, 0x00, 0x49, 0x00, 0x6D, 0x40, 0x94, 0xC0, 0xBE, 0x80, 0xEB, 0x00 - }, - - /* GM_1_4 */ - { - 0x24, 0x00, 0x15, 0x70, 0x11, 0x0F, 0x0E, 0xAA, 0x0D, 0x0F, 0x0B, 0xDB, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x2D, 0x40, 0x4E, 0xC0, 0x73, 0x00, 0x99, 0x80, 0xC1, 0x80, 0xEB, 0x00 - }, - - /* GM_1_5 */ - { - 0x29, 0x3B, 0x16, 0x3D, 0x11, 0x0F, 0x0E, 0x30, 0x0C, 0x7D, 0x0B, 0x24, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x31, 0x80, 0x54, 0x40, 0x78, 0x80, 0x9D, 0xC0, 0xC4, 0x00, 0xEB, 0x00 - }, - - /* GM_1_6 */ - { - 0x2E, 0x27, 0x17, 0x0A, 0x10, 0xD2, 0x0D, 0xE7, 0x0B, 0xEB, 0x0A, 0x80, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x35, 0x80, 0x59, 0x80, 0x7D, 0x40, 0xA1, 0xC0, 0xC6, 0x40, 0xEB, 0x00 - }, - - /* GM_1_7 */ - { - 0x33, 0x62, 0x17, 0x5C, 0x10, 0xD2, 0x0D, 0x6D, 0x0B, 0x6D, 0x09, 0xED, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x39, 0xC0, 0x5E, 0x40, 0x82, 0x00, 0xA5, 0x40, 0xC8, 0x40, 0xEB, 0x00 - }, - - /* GM_1_8 */ - { - 0x38, 0x4E, 0x17, 0xAE, 0x10, 0xB4, 0x0D, 0x0C, 0x0A, 0xF0, 0x09, 0x6D, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x3D, 0xC0, 0x62, 0xC0, 0x86, 0x40, 0xA8, 0x80, 0xCA, 0x00, 0xEB, 0x00 - }, - - /* GM_1_9 */ - { - 0x3D, 0x3B, 0x18, 0x00, 0x10, 0x5A, 0x0C, 0xC3, 0x0A, 0x72, 0x09, 0x00, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x41, 0xC0, 0x67, 0x40, 0x8A, 0x00, 0xAB, 0x80, 0xCB, 0x80, 0xEB, 0x00 - }, - - /* GM_2_0 */ - { - 0x41, 0xD8, 0x18, 0x28, 0x10, 0x3C, 0x0C, 0x49, 0x0A, 0x1F, 0x08, 0x92, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x45, 0x80, 0x6B, 0x40, 0x8D, 0xC0, 0xAE, 0x00, 0xCD, 0x00, 0xEB, 0x00 - }, - - /* GM_2_1 */ - { - 0x46, 0x76, 0x18, 0x51, 0x0F, 0xE1, 0x0C, 0x00, 0x09, 0xB6, 0x08, 0x36, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x49, 0x40, 0x6F, 0x40, 0x91, 0x00, 0xB0, 0x80, 0xCE, 0x40, 0xEB, 0x00 - }, - - /* GM_2_2 */ - { - 0x4A, 0xC4, 0x18, 0x7A, 0x0F, 0xA5, 0x0B, 0x9E, 0x09, 0x63, 0x07, 0xDB, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x4C, 0xC0, 0x73, 0x00, 0x94, 0x40, 0xB2, 0xC0, 0xCF, 0x80, 0xEB, 0x00 - }, - - /* GM_2_3 */ - { - 0x4F, 0x13, 0x18, 0x51, 0x0F, 0x69, 0x0B, 0x6D, 0x09, 0x0F, 0x07, 0x80, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x50, 0x40, 0x76, 0x40, 0x97, 0x00, 0xB5, 0x00, 0xD0, 0xC0, 0xEB, 0x00 - }, - - /* GM_2_4 */ - { - 0x53, 0x13, 0x18, 0x7A, 0x0F, 0x0F, 0x0B, 0x24, 0x08, 0xBC, 0x07, 0x36, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x53, 0x80, 0x79, 0xC0, 0x99, 0xC0, 0xB7, 0x00, 0xD1, 0xC0, 0xEB, 0x00 - }, - - /* GM_2_5 */ - { - 0x57, 0x13, 0x18, 0x51, 0x0E, 0xF0, 0x0A, 0xC3, 0x08, 0x7D, 0x06, 0xED, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x56, 0xC0, 0x7C, 0xC0, 0x9C, 0x80, 0xB8, 0xC0, 0xD2, 0xC0, 0xEB, 0x00 - }, - - /* GM_2_6 */ - { - 0x5B, 0x13, 0x18, 0x28, 0x0E, 0x96, 0x0A, 0x92, 0x08, 0x29, 0x06, 0xB6, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x5A, 0x00, 0x7F, 0xC0, 0x9E, 0xC0, 0xBA, 0x80, 0xD3, 0x80, 0xEB, 0x00 - }, - - /* GM_2_7 */ - { - 0x5E, 0xC4, 0x18, 0x00, 0x0E, 0x78, 0x0A, 0x30, 0x08, 0x00, 0x06, 0x6D, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x5D, 0x00, 0x82, 0x80, 0xA1, 0x40, 0xBC, 0x00, 0xD4, 0x80, 0xEB, 0x00 - }, - - /* GM_2_8 */ - { - 0x62, 0x76, 0x17, 0xD7, 0x0E, 0x1E, 0x0A, 0x00, 0x07, 0xC1, 0x06, 0x36, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x60, 0x00, 0x85, 0x40, 0xA3, 0x40, 0xBD, 0x80, 0xD5, 0x40, 0xEB, 0x00 - }, - - /* GM_2_9 */ - { - 0x65, 0xD8, 0x17, 0xAE, 0x0D, 0xE1, 0x09, 0xCF, 0x07, 0x82, 0x06, 0x00, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x62, 0xC0, 0x87, 0xC0, 0xA5, 0x40, 0xBF, 0x00, 0xD6, 0x00, 0xEB, 0x00 - }, - - /* GM_3_0 */ - { - 0x69, 0x3B, 0x17, 0x85, 0x0D, 0xA5, 0x09, 0x86, 0x07, 0x43, 0x05, 0xDB, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x65, 0x80, 0x8A, 0x40, 0xA7, 0x40, 0xC0, 0x40, 0xD6, 0x80, 0xEB, 0x00 - } -}; - -void __VISetTiming(u8 timing) -{ - __VIWriteI2CRegister8(0x00,timing); -} - -void __VISetYUVSEL(u8 dtvstatus) -{ - u8 vdacFlagRegion = 0; - u32 currTvMode = _SHIFTR(_viReg[1],8,2); - if(currTvMode==VI_PAL || currTvMode==VI_EURGB60) - vdacFlagRegion = 2; - else if(currTvMode==VI_MPAL) - vdacFlagRegion = 1; - - __VIWriteI2CRegister8(0x01, _SHIFTL(dtvstatus,5,3)|(vdacFlagRegion&0x1f)); -} - -void __VISetVBICtrl(u16 data) -{ - __VIWriteI2CRegister16(0x02, data); -} - -void __VISetTrapFilter(u8 disable) -{ - if (disable) - __VIWriteI2CRegister8(0x03, 0); - else - __VIWriteI2CRegister8(0x03, 1); -} - -void __VISet3in1Output(u8 enable) -{ - __VIWriteI2CRegister8(0x04,enable); -} - -void __VISetCGMS(u16 value) -{ - __VIWriteI2CRegister16(0x05, value); -} - -void __VISetWSS(u16 value) -{ - __VIWriteI2CRegister16(0x08, value); -} - -void __VISetRGBOverDrive(u8 value) -{ - u32 currTvMode = _SHIFTR(_viReg[1],8,2); - if (currTvMode == VI_DEBUG) - __VIWriteI2CRegister8(0x0A,(value<<1)|1); - else - __VIWriteI2CRegister8(0x0A,0); -} - -void __VISetOverSampling(void) -{ - __VIWriteI2CRegister8(0x65,1); -} - -void __VISetCCSEL(void) -{ - __VIWriteI2CRegister8(0x6a,1); -} - -void __VISetFilterEURGB60(u8 enable) -{ - __VIWriteI2CRegister8(0x6e, enable); -} - -void __VISetVolume(u16 value) -{ - __VIWriteI2CRegister16(0x71,value); -} - -void __VISetClosedCaption(u32 value) -{ - __VIWriteI2CRegister32(0x7a, value); -} - -void __VISetGamma(VIGamma gamma) -{ - u8 *data = (u8 *)&gamma_coeffs[gamma][0]; - __VIWriteI2CRegisterBuf(0x10, 0x21, data); -} - -/* User Configurable */ - -void VIDEO_SetGamma(VIGamma gamma) -{ - __VISetGamma(gamma); -} - -void VIDEO_SetTrapFilter(bool enable) -{ - if (enable) - __VISetTrapFilter(0); - else - __VISetTrapFilter(1); -} diff --git a/gx/vi_encoder.h b/gx/vi_encoder.h deleted file mode 100644 index f5290dc568..0000000000 --- a/gx/vi_encoder.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** - * vi_encoder.c - * - * Wii Audio/Video Encoder support - * - * Copyright (C) 2009 Eke-Eke, with some code from libogc (C) Hector Martin - * - * Redistribution and use of this code or any derivative works are permitted - * provided that the following conditions are met: - * - * - Redistributions may not be sold, nor may they be used in a commercial - * product or activity. - * - * - Redistributions that are modified from the original source must include the - * complete source code, including the source code for all components used by a - * binary built from the modified sources. However, as a special exception, the - * source code distributed need not include anything that is normally distributed - * (in either source or binary form) with the major components (compiler, kernel, - * and so on) of the operating system on which the executable runs, unless that - * component itself accompanies the executable. - * - * - Redistributions must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************************/ -#ifdef HW_RVL - -typedef enum -{ - VI_GM_0_1=1, - VI_GM_0_2, - VI_GM_0_3, - VI_GM_0_4, - VI_GM_0_5, - VI_GM_0_6, - VI_GM_0_7, - VI_GM_0_8, - VI_GM_0_9, - VI_GM_1_0, - VI_GM_1_1, - VI_GM_1_2, - VI_GM_1_3, - VI_GM_1_4, - VI_GM_1_5, - VI_GM_1_6, - VI_GM_1_7, - VI_GM_1_8, - VI_GM_1_9, - VI_GM_2_0, - VI_GM_2_1, - VI_GM_2_2, - VI_GM_2_3, - VI_GM_2_4, - VI_GM_2_5, - VI_GM_2_6, - VI_GM_2_7, - VI_GM_2_8, - VI_GM_2_9, - VI_GM_3_0 -} VIGamma; - -extern void VIDEO_SetGamma(VIGamma gamma); -extern void VIDEO_SetTrapFilter(bool enable); - - -#endif From 5de1373d236b178fd8e579b4a43d132c1d3d3241 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 8 Aug 2012 22:39:19 +0200 Subject: [PATCH 111/492] Revert "Revert "(GX) Add VI_Trap Filter (for Wii)" - noticeable audio pops" This reverts commit 827e69fabcac8673c12d0265ad36b5f5fcb5e256. --- console/griffin/griffin.c | 3 + console/rarch_console_settings.c | 12 +- console/rgui/rgui.c | 13 + console/rgui/rgui.h | 3 + general.h | 2 +- gx/gx_video.c | 4 + gx/vi_encoder.c | 561 +++++++++++++++++++++++++++++++ gx/vi_encoder.h | 79 +++++ 8 files changed, 672 insertions(+), 5 deletions(-) create mode 100644 gx/vi_encoder.c create mode 100644 gx/vi_encoder.h diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index 23cfd05181..b95be707ad 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -127,6 +127,9 @@ VIDEO DRIVER #if defined(HAVE_OPENGL) #include "../../gfx/gl.c" #elif defined(GEKKO) +#ifdef HW_RVL +#include "../../gx/vi_encoder.c" +#endif #include "../../gx/gx_video.c" #endif diff --git a/console/rarch_console_settings.c b/console/rarch_console_settings.c index 8101230fae..097833a9e4 100644 --- a/console/rarch_console_settings.c +++ b/console/rarch_console_settings.c @@ -312,6 +312,12 @@ void rarch_settings_create_menu_item_label(char * str, unsigned setting, size_t } } +#if defined(_XBOX360) +#define DEFAULT_GAMMA 1 +#elif defined(GEKKO) +#define DEFAULT_GAMMA 0 +#endif + void rarch_settings_set_default (const input_driver_t *input) { // g_settings @@ -385,13 +391,11 @@ void rarch_settings_set_default (const input_driver_t *input) #ifdef _XBOX360 g_console.color_format = 0; #endif -#if defined(_XBOX360) || defined(GEKKO) - g_console.gamma_correction = 1; -#endif + g_console.gamma_correction = DEFAULT_GAMMA; #ifdef _XBOX1 g_console.flicker_filter = 1; - g_console.soft_display_filter_enable = false; #endif + g_console.soft_display_filter_enable = true; #ifdef HAVE_ZLIB g_console.zip_extract_mode = 0; #endif diff --git a/console/rgui/rgui.c b/console/rgui/rgui.c index 18060985df..fdac3db0c6 100644 --- a/console/rgui/rgui.c +++ b/console/rgui/rgui.c @@ -319,6 +319,11 @@ static void render_text(rgui_handle_t *rgui) case RGUI_SETTINGS_VIDEO_FILTER: snprintf(type_str, sizeof(type_str), g_settings.video.smooth ? "Bilinear filtering" : "Point filtering"); break; +#ifdef HW_RVL + case RGUI_SETTINGS_VIDEO_SOFT_FILTER: + snprintf(type_str, sizeof(type_str), g_console.soft_display_filter_enable ? "ON" : "OFF"); + break; +#endif case RGUI_SETTINGS_VIDEO_GAMMA: snprintf(type_str, sizeof(type_str), "%d", g_console.gamma_correction); break; @@ -402,6 +407,11 @@ static void rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t else rarch_settings_change(S_HW_TEXTURE_FILTER); break; +#ifdef HW_RVL + case RGUI_SETTINGS_VIDEO_SOFT_FILTER: + g_console.soft_display_filter_enable = !g_console.soft_display_filter_enable; + break; +#endif case RGUI_SETTINGS_VIDEO_GAMMA: if (action == RGUI_ACTION_START) { @@ -542,6 +552,9 @@ static void rgui_settings_populate_entries(rgui_handle_t *rgui) rgui_list_clear(rgui->folder_buf); RGUI_MENU_ITEM("Hardware filtering", RGUI_SETTINGS_VIDEO_FILTER); +#ifdef HW_RVL + RGUI_MENU_ITEM("VI Trap filtering", RGUI_SETTINGS_VIDEO_SOFT_FILTER); +#endif RGUI_MENU_ITEM("Gamma", RGUI_SETTINGS_VIDEO_GAMMA); RGUI_MENU_ITEM("Rotation", RGUI_SETTINGS_VIDEO_ROTATION); RGUI_MENU_ITEM("Mute Audio", RGUI_SETTINGS_AUDIO_MUTE); diff --git a/console/rgui/rgui.h b/console/rgui/rgui.h index 7f79cca320..b629a18d37 100644 --- a/console/rgui/rgui.h +++ b/console/rgui/rgui.h @@ -34,6 +34,9 @@ typedef enum // settings options are done here too RGUI_SETTINGS_VIDEO_FILTER, +#ifdef HW_RVL + RGUI_SETTINGS_VIDEO_SOFT_FILTER, +#endif RGUI_SETTINGS_VIDEO_GAMMA, RGUI_SETTINGS_VIDEO_ROTATION, RGUI_SETTINGS_AUDIO_MUTE, diff --git a/general.h b/general.h index 654f859ed4..d4e359df5b 100644 --- a/general.h +++ b/general.h @@ -214,8 +214,8 @@ struct console_settings #endif #ifdef _XBOX1 unsigned flicker_filter; - bool soft_display_filter_enable; #endif + bool soft_display_filter_enable; bool initialize_rarch_enable; bool info_msg_enable; bool ingame_menu_enable; diff --git a/gx/gx_video.c b/gx/gx_video.c index 5112e56967..8b03be19a0 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -429,6 +429,10 @@ static bool wii_frame(void *data, const void *frame, if(!frame && !menu_render) return true; +#ifdef HW_RVL + VIDEO_SetTrapFilter(g_console.soft_display_filter_enable); +#endif + gx->frame_count++; if(should_resize) diff --git a/gx/vi_encoder.c b/gx/vi_encoder.c new file mode 100644 index 0000000000..24365bb0ca --- /dev/null +++ b/gx/vi_encoder.c @@ -0,0 +1,561 @@ +/**************************************************************************** + * vi_encoder.c + * + * Wii Audio/Video Encoder support + * + * Copyright (C) 2009 Eke-Eke, with some code from libogc (C) Hector Martin + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include +#include +#include +#include + +#include "vi_encoder.h" + +/**************************************************************************** + * I2C driver by Hector Martin (marcan) + * + ****************************************************************************/ + +#define _SHIFTL(v, s, w) \ + ((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s))) +#define _SHIFTR(v, s, w) \ + ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1))) + +extern void udelay(int us); + +static u32 i2cIdentFirst = 0; +static u32 i2cIdentFlag = 1; +static vu16* const _viReg = (u16*)0xCC002000; +static vu32* const _i2cReg = (u32*)0xCD800000; + +static inline void __viOpenI2C(u32 channel) +{ + u32 val = ((_i2cReg[49]&~0x8000)|0x4000); + val |= _SHIFTL(channel,15,1); + _i2cReg[49] = val; +} + +static inline u32 __viSetSCL(u32 channel) +{ + u32 val = (_i2cReg[48]&~0x4000); + val |= _SHIFTL(channel,14,1); + _i2cReg[48] = val; + return 1; +} +static inline u32 __viSetSDA(u32 channel) +{ + u32 val = (_i2cReg[48]&~0x8000); + val |= _SHIFTL(channel,15,1); + _i2cReg[48] = val; + return 1; +} + +static inline u32 __viGetSDA() +{ + return _SHIFTR(_i2cReg[50],15,1); +} + +static inline void __viCheckI2C() +{ + __viOpenI2C(0); + udelay(4); + + i2cIdentFlag = 0; + if(__viGetSDA()!=0) i2cIdentFlag = 1; +} + +static u32 __sendSlaveAddress(u8 addr) +{ + u32 i; + + __viSetSDA(i2cIdentFlag^1); + udelay(2); + + __viSetSCL(0); + for(i=0;i<8;i++) { + if(addr&0x80) __viSetSDA(i2cIdentFlag); + else __viSetSDA(i2cIdentFlag^1); + udelay(2); + + __viSetSCL(1); + udelay(2); + + __viSetSCL(0); + addr <<= 1; + } + + __viOpenI2C(0); + udelay(2); + + __viSetSCL(1); + udelay(2); + + if(i2cIdentFlag==1 && __viGetSDA()!=0) return 0; + + __viSetSDA(i2cIdentFlag^1); + __viOpenI2C(1); + __viSetSCL(0); + + return 1; +} + +static u32 __VISendI2CData(u8 addr,void *val,u32 len) +{ + u8 c; + s32 i,j; + u32 level,ret; + + if(i2cIdentFirst==0) { + __viCheckI2C(); + i2cIdentFirst = 1; + } + + _CPU_ISR_Disable(level); + + __viOpenI2C(1); + __viSetSCL(1); + + __viSetSDA(i2cIdentFlag); + udelay(4); + + ret = __sendSlaveAddress(addr); + if(ret==0) { + _CPU_ISR_Restore(level); + return 0; + } + + __viOpenI2C(1); + for(i=0;i> 8; + buf[2] = data & 0xFF; + __VISendI2CData(0xe0,buf,3); + udelay(2); +} + +static void __VIWriteI2CRegister32(u8 reg, u32 data) +{ + u8 buf[5]; + buf[0] = reg; + buf[1] = data >> 24; + buf[2] = (data >> 16) & 0xFF; + buf[3] = (data >> 8) & 0xFF; + buf[4] = data & 0xFF; + __VISendI2CData(0xe0,buf,5); + udelay(2); +} + +static void __VIWriteI2CRegisterBuf(u8 reg, int size, u8 *data) +{ + u8 buf[0x100]; + buf[0] = reg; + memcpy(&buf[1], data, size); + __VISendI2CData(0xe0,buf,size+1); + udelay(2); +} + +/**************************************************************************** + * A/V functions support (Eke-Eke) + * + ****************************************************************************/ +static const u8 gamma_coeffs[][33] = +{ + /* GM_0_0 */ + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + }, + + /* GM_0_1 */ + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x97, 0x3B, 0x49, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x80, 0x1B, 0x80, 0xEB, 0x00 + }, + + /* GM_0_2 */ + { + 0x00, 0x00, 0x00, 0x28, 0x00, 0x5A, 0x02, 0xDB, 0x0D, 0x8D, 0x30, 0x49, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x10, 0x00, 0x10, 0x40, 0x11, 0x00, 0x18, 0x80, 0x42, 0x00, 0xEB, 0x00 + }, + + /* GM_0_3 */ + { + 0x00, 0x00, 0x00, 0x7A, 0x02, 0x3C, 0x07, 0x6D, 0x12, 0x9C, 0x27, 0x24, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x10, 0x00, 0x10, 0xC0, 0x15, 0x80, 0x29, 0x00, 0x62, 0x00, 0xEB, 0x00 + }, + + /* GM_0_4 */ + { + 0x00, 0x4E, 0x01, 0x99, 0x05, 0x2D, 0x0B, 0x24, 0x14, 0x29, 0x20, 0xA4, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x00, 0x10, 0x10, 0x40, 0x12, 0xC0, 0x1D, 0xC0, 0x3B, 0x00, 0x78, 0xC0, 0xEB, 0x00 + }, + + /* GM_0_5 */ + { + 0x00, 0xEC, 0x03, 0xD7, 0x08, 0x00, 0x0D, 0x9E, 0x14, 0x3E, 0x1B, 0xDB, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x10, 0xC0, 0x16, 0xC0, 0x27, 0xC0, 0x4B, 0x80, 0x89, 0x80, 0xEB, 0x00 + }, + + /* GM_0_6 */ + { + 0x02, 0x76, 0x06, 0x66, 0x0A, 0x96, 0x0E, 0xF3, 0x13, 0xAC, 0x18, 0x49, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x12, 0x00, 0x1C, 0x00, 0x32, 0x80, 0x59, 0xC0, 0x96, 0x00, 0xEB, 0x00 + }, + + /* GM_0_7 */ + { + 0x04, 0xEC, 0x08, 0xF5, 0x0C, 0x96, 0x0F, 0xCF, 0x12, 0xC6, 0x15, 0x80, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x14, 0x00, 0x22, 0x00, 0x3C, 0xC0, 0x66, 0x40, 0x9F, 0xC0, 0xEB, 0x00 + }, + + /* GM_0_8 */ + { + 0x08, 0x00, 0x0B, 0xAE, 0x0E, 0x00, 0x10, 0x30, 0x11, 0xCB, 0x13, 0x49, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x16, 0x80, 0x28, 0xC0, 0x46, 0x80, 0x71, 0x00, 0xA7, 0x80, 0xEB, 0x00 + }, + + /* GM_0_9 */ + { + 0x0B, 0xB1, 0x0E, 0x14, 0x0F, 0x2D, 0x10, 0x18, 0x10, 0xE5, 0x11, 0x80, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x19, 0x80, 0x2F, 0x80, 0x4F, 0xC0, 0x7A, 0x00, 0xAD, 0xC0, 0xEB, 0x00 + }, + + /* GM_1_0 */ + { + 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, + 0x10, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xEB, + 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x60, 0x00, 0x80, 0x00, 0xA0, 0x00, 0xEB, 0x00 + }, + + /* GM_1_1 */ + { + 0x14, 0xEC, 0x11, 0xC2, 0x10, 0x78, 0x0F, 0xB6, 0x0F, 0x2F, 0x0E, 0xB6, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x21, 0x00, 0x3C, 0xC0, 0x5F, 0xC0, 0x89, 0x00, 0xB7, 0x80, 0xEB, 0x00 + }, + + /* GM_1_2 */ + { + 0x19, 0xD8, 0x13, 0x33, 0x10, 0xD2, 0x0F, 0x6D, 0x0E, 0x5E, 0x0D, 0xA4, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x25, 0x00, 0x43, 0x00, 0x66, 0xC0, 0x8F, 0x40, 0xBB, 0x40, 0xEB, 0x00 + }, + + /* GM_1_3 */ + { + 0x1E, 0xC4, 0x14, 0x7A, 0x11, 0x0F, 0xF, 0x0C, 0x0D, 0xA1, 0x0C, 0xB6, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x29, 0x00, 0x49, 0x00, 0x6D, 0x40, 0x94, 0xC0, 0xBE, 0x80, 0xEB, 0x00 + }, + + /* GM_1_4 */ + { + 0x24, 0x00, 0x15, 0x70, 0x11, 0x0F, 0x0E, 0xAA, 0x0D, 0x0F, 0x0B, 0xDB, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x2D, 0x40, 0x4E, 0xC0, 0x73, 0x00, 0x99, 0x80, 0xC1, 0x80, 0xEB, 0x00 + }, + + /* GM_1_5 */ + { + 0x29, 0x3B, 0x16, 0x3D, 0x11, 0x0F, 0x0E, 0x30, 0x0C, 0x7D, 0x0B, 0x24, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x31, 0x80, 0x54, 0x40, 0x78, 0x80, 0x9D, 0xC0, 0xC4, 0x00, 0xEB, 0x00 + }, + + /* GM_1_6 */ + { + 0x2E, 0x27, 0x17, 0x0A, 0x10, 0xD2, 0x0D, 0xE7, 0x0B, 0xEB, 0x0A, 0x80, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x35, 0x80, 0x59, 0x80, 0x7D, 0x40, 0xA1, 0xC0, 0xC6, 0x40, 0xEB, 0x00 + }, + + /* GM_1_7 */ + { + 0x33, 0x62, 0x17, 0x5C, 0x10, 0xD2, 0x0D, 0x6D, 0x0B, 0x6D, 0x09, 0xED, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x39, 0xC0, 0x5E, 0x40, 0x82, 0x00, 0xA5, 0x40, 0xC8, 0x40, 0xEB, 0x00 + }, + + /* GM_1_8 */ + { + 0x38, 0x4E, 0x17, 0xAE, 0x10, 0xB4, 0x0D, 0x0C, 0x0A, 0xF0, 0x09, 0x6D, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x3D, 0xC0, 0x62, 0xC0, 0x86, 0x40, 0xA8, 0x80, 0xCA, 0x00, 0xEB, 0x00 + }, + + /* GM_1_9 */ + { + 0x3D, 0x3B, 0x18, 0x00, 0x10, 0x5A, 0x0C, 0xC3, 0x0A, 0x72, 0x09, 0x00, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x41, 0xC0, 0x67, 0x40, 0x8A, 0x00, 0xAB, 0x80, 0xCB, 0x80, 0xEB, 0x00 + }, + + /* GM_2_0 */ + { + 0x41, 0xD8, 0x18, 0x28, 0x10, 0x3C, 0x0C, 0x49, 0x0A, 0x1F, 0x08, 0x92, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x45, 0x80, 0x6B, 0x40, 0x8D, 0xC0, 0xAE, 0x00, 0xCD, 0x00, 0xEB, 0x00 + }, + + /* GM_2_1 */ + { + 0x46, 0x76, 0x18, 0x51, 0x0F, 0xE1, 0x0C, 0x00, 0x09, 0xB6, 0x08, 0x36, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x49, 0x40, 0x6F, 0x40, 0x91, 0x00, 0xB0, 0x80, 0xCE, 0x40, 0xEB, 0x00 + }, + + /* GM_2_2 */ + { + 0x4A, 0xC4, 0x18, 0x7A, 0x0F, 0xA5, 0x0B, 0x9E, 0x09, 0x63, 0x07, 0xDB, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x4C, 0xC0, 0x73, 0x00, 0x94, 0x40, 0xB2, 0xC0, 0xCF, 0x80, 0xEB, 0x00 + }, + + /* GM_2_3 */ + { + 0x4F, 0x13, 0x18, 0x51, 0x0F, 0x69, 0x0B, 0x6D, 0x09, 0x0F, 0x07, 0x80, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x50, 0x40, 0x76, 0x40, 0x97, 0x00, 0xB5, 0x00, 0xD0, 0xC0, 0xEB, 0x00 + }, + + /* GM_2_4 */ + { + 0x53, 0x13, 0x18, 0x7A, 0x0F, 0x0F, 0x0B, 0x24, 0x08, 0xBC, 0x07, 0x36, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x53, 0x80, 0x79, 0xC0, 0x99, 0xC0, 0xB7, 0x00, 0xD1, 0xC0, 0xEB, 0x00 + }, + + /* GM_2_5 */ + { + 0x57, 0x13, 0x18, 0x51, 0x0E, 0xF0, 0x0A, 0xC3, 0x08, 0x7D, 0x06, 0xED, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x56, 0xC0, 0x7C, 0xC0, 0x9C, 0x80, 0xB8, 0xC0, 0xD2, 0xC0, 0xEB, 0x00 + }, + + /* GM_2_6 */ + { + 0x5B, 0x13, 0x18, 0x28, 0x0E, 0x96, 0x0A, 0x92, 0x08, 0x29, 0x06, 0xB6, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x5A, 0x00, 0x7F, 0xC0, 0x9E, 0xC0, 0xBA, 0x80, 0xD3, 0x80, 0xEB, 0x00 + }, + + /* GM_2_7 */ + { + 0x5E, 0xC4, 0x18, 0x00, 0x0E, 0x78, 0x0A, 0x30, 0x08, 0x00, 0x06, 0x6D, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x5D, 0x00, 0x82, 0x80, 0xA1, 0x40, 0xBC, 0x00, 0xD4, 0x80, 0xEB, 0x00 + }, + + /* GM_2_8 */ + { + 0x62, 0x76, 0x17, 0xD7, 0x0E, 0x1E, 0x0A, 0x00, 0x07, 0xC1, 0x06, 0x36, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x60, 0x00, 0x85, 0x40, 0xA3, 0x40, 0xBD, 0x80, 0xD5, 0x40, 0xEB, 0x00 + }, + + /* GM_2_9 */ + { + 0x65, 0xD8, 0x17, 0xAE, 0x0D, 0xE1, 0x09, 0xCF, 0x07, 0x82, 0x06, 0x00, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x62, 0xC0, 0x87, 0xC0, 0xA5, 0x40, 0xBF, 0x00, 0xD6, 0x00, 0xEB, 0x00 + }, + + /* GM_3_0 */ + { + 0x69, 0x3B, 0x17, 0x85, 0x0D, 0xA5, 0x09, 0x86, 0x07, 0x43, 0x05, 0xDB, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x65, 0x80, 0x8A, 0x40, 0xA7, 0x40, 0xC0, 0x40, 0xD6, 0x80, 0xEB, 0x00 + } +}; + +void __VISetTiming(u8 timing) +{ + __VIWriteI2CRegister8(0x00,timing); +} + +void __VISetYUVSEL(u8 dtvstatus) +{ + u8 vdacFlagRegion = 0; + u32 currTvMode = _SHIFTR(_viReg[1],8,2); + if(currTvMode==VI_PAL || currTvMode==VI_EURGB60) + vdacFlagRegion = 2; + else if(currTvMode==VI_MPAL) + vdacFlagRegion = 1; + + __VIWriteI2CRegister8(0x01, _SHIFTL(dtvstatus,5,3)|(vdacFlagRegion&0x1f)); +} + +void __VISetVBICtrl(u16 data) +{ + __VIWriteI2CRegister16(0x02, data); +} + +void __VISetTrapFilter(u8 disable) +{ + if (disable) + __VIWriteI2CRegister8(0x03, 0); + else + __VIWriteI2CRegister8(0x03, 1); +} + +void __VISet3in1Output(u8 enable) +{ + __VIWriteI2CRegister8(0x04,enable); +} + +void __VISetCGMS(u16 value) +{ + __VIWriteI2CRegister16(0x05, value); +} + +void __VISetWSS(u16 value) +{ + __VIWriteI2CRegister16(0x08, value); +} + +void __VISetRGBOverDrive(u8 value) +{ + u32 currTvMode = _SHIFTR(_viReg[1],8,2); + if (currTvMode == VI_DEBUG) + __VIWriteI2CRegister8(0x0A,(value<<1)|1); + else + __VIWriteI2CRegister8(0x0A,0); +} + +void __VISetOverSampling(void) +{ + __VIWriteI2CRegister8(0x65,1); +} + +void __VISetCCSEL(void) +{ + __VIWriteI2CRegister8(0x6a,1); +} + +void __VISetFilterEURGB60(u8 enable) +{ + __VIWriteI2CRegister8(0x6e, enable); +} + +void __VISetVolume(u16 value) +{ + __VIWriteI2CRegister16(0x71,value); +} + +void __VISetClosedCaption(u32 value) +{ + __VIWriteI2CRegister32(0x7a, value); +} + +void __VISetGamma(VIGamma gamma) +{ + u8 *data = (u8 *)&gamma_coeffs[gamma][0]; + __VIWriteI2CRegisterBuf(0x10, 0x21, data); +} + +/* User Configurable */ + +void VIDEO_SetGamma(VIGamma gamma) +{ + __VISetGamma(gamma); +} + +void VIDEO_SetTrapFilter(bool enable) +{ + if (enable) + __VISetTrapFilter(0); + else + __VISetTrapFilter(1); +} diff --git a/gx/vi_encoder.h b/gx/vi_encoder.h new file mode 100644 index 0000000000..f5290dc568 --- /dev/null +++ b/gx/vi_encoder.h @@ -0,0 +1,79 @@ +/**************************************************************************** + * vi_encoder.c + * + * Wii Audio/Video Encoder support + * + * Copyright (C) 2009 Eke-Eke, with some code from libogc (C) Hector Martin + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ +#ifdef HW_RVL + +typedef enum +{ + VI_GM_0_1=1, + VI_GM_0_2, + VI_GM_0_3, + VI_GM_0_4, + VI_GM_0_5, + VI_GM_0_6, + VI_GM_0_7, + VI_GM_0_8, + VI_GM_0_9, + VI_GM_1_0, + VI_GM_1_1, + VI_GM_1_2, + VI_GM_1_3, + VI_GM_1_4, + VI_GM_1_5, + VI_GM_1_6, + VI_GM_1_7, + VI_GM_1_8, + VI_GM_1_9, + VI_GM_2_0, + VI_GM_2_1, + VI_GM_2_2, + VI_GM_2_3, + VI_GM_2_4, + VI_GM_2_5, + VI_GM_2_6, + VI_GM_2_7, + VI_GM_2_8, + VI_GM_2_9, + VI_GM_3_0 +} VIGamma; + +extern void VIDEO_SetGamma(VIGamma gamma); +extern void VIDEO_SetTrapFilter(bool enable); + + +#endif From d7fd90883be253d996b72450b06c3b81b2755756 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 8 Aug 2012 23:18:31 +0200 Subject: [PATCH 112/492] (GX) Slim down vi_encoder.c --- gx/vi_encoder.c | 533 +++++++++--------------------------------------- gx/vi_encoder.h | 36 ---- 2 files changed, 91 insertions(+), 478 deletions(-) diff --git a/gx/vi_encoder.c b/gx/vi_encoder.c index 24365bb0ca..b9c050fdda 100644 --- a/gx/vi_encoder.c +++ b/gx/vi_encoder.c @@ -58,7 +58,6 @@ extern void udelay(int us); static u32 i2cIdentFirst = 0; static u32 i2cIdentFlag = 1; -static vu16* const _viReg = (u16*)0xCC002000; static vu32* const _i2cReg = (u32*)0xCD800000; static inline void __viOpenI2C(u32 channel) @@ -68,34 +67,20 @@ static inline void __viOpenI2C(u32 channel) _i2cReg[49] = val; } -static inline u32 __viSetSCL(u32 channel) +static inline void __viSetSCL(u32 channel) { u32 val = (_i2cReg[48]&~0x4000); val |= _SHIFTL(channel,14,1); _i2cReg[48] = val; - return 1; } -static inline u32 __viSetSDA(u32 channel) +static inline void __viSetSDA(u32 channel) { u32 val = (_i2cReg[48]&~0x8000); val |= _SHIFTL(channel,15,1); _i2cReg[48] = val; - return 1; } -static inline u32 __viGetSDA() -{ - return _SHIFTR(_i2cReg[50],15,1); -} - -static inline void __viCheckI2C() -{ - __viOpenI2C(0); - udelay(4); - - i2cIdentFlag = 0; - if(__viGetSDA()!=0) i2cIdentFlag = 1; -} +#define __viGetSDA() (_SHIFTR(_i2cReg[50],15,1)) static u32 __sendSlaveAddress(u8 addr) { @@ -132,430 +117,94 @@ static u32 __sendSlaveAddress(u8 addr) return 1; } -static u32 __VISendI2CData(u8 addr,void *val,u32 len) -{ - u8 c; - s32 i,j; - u32 level,ret; - - if(i2cIdentFirst==0) { - __viCheckI2C(); - i2cIdentFirst = 1; - } - - _CPU_ISR_Disable(level); - - __viOpenI2C(1); - __viSetSCL(1); - - __viSetSDA(i2cIdentFlag); - udelay(4); - - ret = __sendSlaveAddress(addr); - if(ret==0) { - _CPU_ISR_Restore(level); - return 0; - } - - __viOpenI2C(1); - for(i=0;i> 8; - buf[2] = data & 0xFF; - __VISendI2CData(0xe0,buf,3); - udelay(2); -} - -static void __VIWriteI2CRegister32(u8 reg, u32 data) -{ - u8 buf[5]; - buf[0] = reg; - buf[1] = data >> 24; - buf[2] = (data >> 16) & 0xFF; - buf[3] = (data >> 8) & 0xFF; - buf[4] = data & 0xFF; - __VISendI2CData(0xe0,buf,5); - udelay(2); -} - -static void __VIWriteI2CRegisterBuf(u8 reg, int size, u8 *data) -{ - u8 buf[0x100]; - buf[0] = reg; - memcpy(&buf[1], data, size); - __VISendI2CData(0xe0,buf,size+1); - udelay(2); -} - -/**************************************************************************** - * A/V functions support (Eke-Eke) - * - ****************************************************************************/ -static const u8 gamma_coeffs[][33] = -{ - /* GM_0_0 */ - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - - }, - - /* GM_0_1 */ - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x97, 0x3B, 0x49, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x80, 0x1B, 0x80, 0xEB, 0x00 - }, - - /* GM_0_2 */ - { - 0x00, 0x00, 0x00, 0x28, 0x00, 0x5A, 0x02, 0xDB, 0x0D, 0x8D, 0x30, 0x49, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x10, 0x00, 0x10, 0x40, 0x11, 0x00, 0x18, 0x80, 0x42, 0x00, 0xEB, 0x00 - }, - - /* GM_0_3 */ - { - 0x00, 0x00, 0x00, 0x7A, 0x02, 0x3C, 0x07, 0x6D, 0x12, 0x9C, 0x27, 0x24, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x10, 0x00, 0x10, 0xC0, 0x15, 0x80, 0x29, 0x00, 0x62, 0x00, 0xEB, 0x00 - }, - - /* GM_0_4 */ - { - 0x00, 0x4E, 0x01, 0x99, 0x05, 0x2D, 0x0B, 0x24, 0x14, 0x29, 0x20, 0xA4, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x00, 0x10, 0x10, 0x40, 0x12, 0xC0, 0x1D, 0xC0, 0x3B, 0x00, 0x78, 0xC0, 0xEB, 0x00 - }, - - /* GM_0_5 */ - { - 0x00, 0xEC, 0x03, 0xD7, 0x08, 0x00, 0x0D, 0x9E, 0x14, 0x3E, 0x1B, 0xDB, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x10, 0xC0, 0x16, 0xC0, 0x27, 0xC0, 0x4B, 0x80, 0x89, 0x80, 0xEB, 0x00 - }, - - /* GM_0_6 */ - { - 0x02, 0x76, 0x06, 0x66, 0x0A, 0x96, 0x0E, 0xF3, 0x13, 0xAC, 0x18, 0x49, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x12, 0x00, 0x1C, 0x00, 0x32, 0x80, 0x59, 0xC0, 0x96, 0x00, 0xEB, 0x00 - }, - - /* GM_0_7 */ - { - 0x04, 0xEC, 0x08, 0xF5, 0x0C, 0x96, 0x0F, 0xCF, 0x12, 0xC6, 0x15, 0x80, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x14, 0x00, 0x22, 0x00, 0x3C, 0xC0, 0x66, 0x40, 0x9F, 0xC0, 0xEB, 0x00 - }, - - /* GM_0_8 */ - { - 0x08, 0x00, 0x0B, 0xAE, 0x0E, 0x00, 0x10, 0x30, 0x11, 0xCB, 0x13, 0x49, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x16, 0x80, 0x28, 0xC0, 0x46, 0x80, 0x71, 0x00, 0xA7, 0x80, 0xEB, 0x00 - }, - - /* GM_0_9 */ - { - 0x0B, 0xB1, 0x0E, 0x14, 0x0F, 0x2D, 0x10, 0x18, 0x10, 0xE5, 0x11, 0x80, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x19, 0x80, 0x2F, 0x80, 0x4F, 0xC0, 0x7A, 0x00, 0xAD, 0xC0, 0xEB, 0x00 - }, - - /* GM_1_0 */ - { - 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, - 0x10, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xEB, - 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x60, 0x00, 0x80, 0x00, 0xA0, 0x00, 0xEB, 0x00 - }, - - /* GM_1_1 */ - { - 0x14, 0xEC, 0x11, 0xC2, 0x10, 0x78, 0x0F, 0xB6, 0x0F, 0x2F, 0x0E, 0xB6, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x21, 0x00, 0x3C, 0xC0, 0x5F, 0xC0, 0x89, 0x00, 0xB7, 0x80, 0xEB, 0x00 - }, - - /* GM_1_2 */ - { - 0x19, 0xD8, 0x13, 0x33, 0x10, 0xD2, 0x0F, 0x6D, 0x0E, 0x5E, 0x0D, 0xA4, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x25, 0x00, 0x43, 0x00, 0x66, 0xC0, 0x8F, 0x40, 0xBB, 0x40, 0xEB, 0x00 - }, - - /* GM_1_3 */ - { - 0x1E, 0xC4, 0x14, 0x7A, 0x11, 0x0F, 0xF, 0x0C, 0x0D, 0xA1, 0x0C, 0xB6, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x29, 0x00, 0x49, 0x00, 0x6D, 0x40, 0x94, 0xC0, 0xBE, 0x80, 0xEB, 0x00 - }, - - /* GM_1_4 */ - { - 0x24, 0x00, 0x15, 0x70, 0x11, 0x0F, 0x0E, 0xAA, 0x0D, 0x0F, 0x0B, 0xDB, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x2D, 0x40, 0x4E, 0xC0, 0x73, 0x00, 0x99, 0x80, 0xC1, 0x80, 0xEB, 0x00 - }, - - /* GM_1_5 */ - { - 0x29, 0x3B, 0x16, 0x3D, 0x11, 0x0F, 0x0E, 0x30, 0x0C, 0x7D, 0x0B, 0x24, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x31, 0x80, 0x54, 0x40, 0x78, 0x80, 0x9D, 0xC0, 0xC4, 0x00, 0xEB, 0x00 - }, - - /* GM_1_6 */ - { - 0x2E, 0x27, 0x17, 0x0A, 0x10, 0xD2, 0x0D, 0xE7, 0x0B, 0xEB, 0x0A, 0x80, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x35, 0x80, 0x59, 0x80, 0x7D, 0x40, 0xA1, 0xC0, 0xC6, 0x40, 0xEB, 0x00 - }, - - /* GM_1_7 */ - { - 0x33, 0x62, 0x17, 0x5C, 0x10, 0xD2, 0x0D, 0x6D, 0x0B, 0x6D, 0x09, 0xED, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x39, 0xC0, 0x5E, 0x40, 0x82, 0x00, 0xA5, 0x40, 0xC8, 0x40, 0xEB, 0x00 - }, - - /* GM_1_8 */ - { - 0x38, 0x4E, 0x17, 0xAE, 0x10, 0xB4, 0x0D, 0x0C, 0x0A, 0xF0, 0x09, 0x6D, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x3D, 0xC0, 0x62, 0xC0, 0x86, 0x40, 0xA8, 0x80, 0xCA, 0x00, 0xEB, 0x00 - }, - - /* GM_1_9 */ - { - 0x3D, 0x3B, 0x18, 0x00, 0x10, 0x5A, 0x0C, 0xC3, 0x0A, 0x72, 0x09, 0x00, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x41, 0xC0, 0x67, 0x40, 0x8A, 0x00, 0xAB, 0x80, 0xCB, 0x80, 0xEB, 0x00 - }, - - /* GM_2_0 */ - { - 0x41, 0xD8, 0x18, 0x28, 0x10, 0x3C, 0x0C, 0x49, 0x0A, 0x1F, 0x08, 0x92, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x45, 0x80, 0x6B, 0x40, 0x8D, 0xC0, 0xAE, 0x00, 0xCD, 0x00, 0xEB, 0x00 - }, - - /* GM_2_1 */ - { - 0x46, 0x76, 0x18, 0x51, 0x0F, 0xE1, 0x0C, 0x00, 0x09, 0xB6, 0x08, 0x36, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x49, 0x40, 0x6F, 0x40, 0x91, 0x00, 0xB0, 0x80, 0xCE, 0x40, 0xEB, 0x00 - }, - - /* GM_2_2 */ - { - 0x4A, 0xC4, 0x18, 0x7A, 0x0F, 0xA5, 0x0B, 0x9E, 0x09, 0x63, 0x07, 0xDB, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x4C, 0xC0, 0x73, 0x00, 0x94, 0x40, 0xB2, 0xC0, 0xCF, 0x80, 0xEB, 0x00 - }, - - /* GM_2_3 */ - { - 0x4F, 0x13, 0x18, 0x51, 0x0F, 0x69, 0x0B, 0x6D, 0x09, 0x0F, 0x07, 0x80, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x50, 0x40, 0x76, 0x40, 0x97, 0x00, 0xB5, 0x00, 0xD0, 0xC0, 0xEB, 0x00 - }, - - /* GM_2_4 */ - { - 0x53, 0x13, 0x18, 0x7A, 0x0F, 0x0F, 0x0B, 0x24, 0x08, 0xBC, 0x07, 0x36, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x53, 0x80, 0x79, 0xC0, 0x99, 0xC0, 0xB7, 0x00, 0xD1, 0xC0, 0xEB, 0x00 - }, - - /* GM_2_5 */ - { - 0x57, 0x13, 0x18, 0x51, 0x0E, 0xF0, 0x0A, 0xC3, 0x08, 0x7D, 0x06, 0xED, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x56, 0xC0, 0x7C, 0xC0, 0x9C, 0x80, 0xB8, 0xC0, 0xD2, 0xC0, 0xEB, 0x00 - }, - - /* GM_2_6 */ - { - 0x5B, 0x13, 0x18, 0x28, 0x0E, 0x96, 0x0A, 0x92, 0x08, 0x29, 0x06, 0xB6, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x5A, 0x00, 0x7F, 0xC0, 0x9E, 0xC0, 0xBA, 0x80, 0xD3, 0x80, 0xEB, 0x00 - }, - - /* GM_2_7 */ - { - 0x5E, 0xC4, 0x18, 0x00, 0x0E, 0x78, 0x0A, 0x30, 0x08, 0x00, 0x06, 0x6D, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x5D, 0x00, 0x82, 0x80, 0xA1, 0x40, 0xBC, 0x00, 0xD4, 0x80, 0xEB, 0x00 - }, - - /* GM_2_8 */ - { - 0x62, 0x76, 0x17, 0xD7, 0x0E, 0x1E, 0x0A, 0x00, 0x07, 0xC1, 0x06, 0x36, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x60, 0x00, 0x85, 0x40, 0xA3, 0x40, 0xBD, 0x80, 0xD5, 0x40, 0xEB, 0x00 - }, - - /* GM_2_9 */ - { - 0x65, 0xD8, 0x17, 0xAE, 0x0D, 0xE1, 0x09, 0xCF, 0x07, 0x82, 0x06, 0x00, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x62, 0xC0, 0x87, 0xC0, 0xA5, 0x40, 0xBF, 0x00, 0xD6, 0x00, 0xEB, 0x00 - }, - - /* GM_3_0 */ - { - 0x69, 0x3B, 0x17, 0x85, 0x0D, 0xA5, 0x09, 0x86, 0x07, 0x43, 0x05, 0xDB, - 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, - 0x10, 0x00, 0x65, 0x80, 0x8A, 0x40, 0xA7, 0x40, 0xC0, 0x40, 0xD6, 0x80, 0xEB, 0x00 - } -}; - -void __VISetTiming(u8 timing) -{ - __VIWriteI2CRegister8(0x00,timing); -} - -void __VISetYUVSEL(u8 dtvstatus) -{ - u8 vdacFlagRegion = 0; - u32 currTvMode = _SHIFTR(_viReg[1],8,2); - if(currTvMode==VI_PAL || currTvMode==VI_EURGB60) - vdacFlagRegion = 2; - else if(currTvMode==VI_MPAL) - vdacFlagRegion = 1; - - __VIWriteI2CRegister8(0x01, _SHIFTL(dtvstatus,5,3)|(vdacFlagRegion&0x1f)); -} - -void __VISetVBICtrl(u16 data) -{ - __VIWriteI2CRegister16(0x02, data); -} - -void __VISetTrapFilter(u8 disable) -{ - if (disable) - __VIWriteI2CRegister8(0x03, 0); - else - __VIWriteI2CRegister8(0x03, 1); -} - -void __VISet3in1Output(u8 enable) -{ - __VIWriteI2CRegister8(0x04,enable); -} - -void __VISetCGMS(u16 value) -{ - __VIWriteI2CRegister16(0x05, value); -} - -void __VISetWSS(u16 value) -{ - __VIWriteI2CRegister16(0x08, value); -} - -void __VISetRGBOverDrive(u8 value) -{ - u32 currTvMode = _SHIFTR(_viReg[1],8,2); - if (currTvMode == VI_DEBUG) - __VIWriteI2CRegister8(0x0A,(value<<1)|1); - else - __VIWriteI2CRegister8(0x0A,0); -} - -void __VISetOverSampling(void) -{ - __VIWriteI2CRegister8(0x65,1); -} - -void __VISetCCSEL(void) -{ - __VIWriteI2CRegister8(0x6a,1); -} - -void __VISetFilterEURGB60(u8 enable) -{ - __VIWriteI2CRegister8(0x6e, enable); -} - -void __VISetVolume(u16 value) -{ - __VIWriteI2CRegister16(0x71,value); -} - -void __VISetClosedCaption(u32 value) -{ - __VIWriteI2CRegister32(0x7a, value); -} - -void __VISetGamma(VIGamma gamma) -{ - u8 *data = (u8 *)&gamma_coeffs[gamma][0]; - __VIWriteI2CRegisterBuf(0x10, 0x21, data); -} - -/* User Configurable */ - -void VIDEO_SetGamma(VIGamma gamma) -{ - __VISetGamma(gamma); -} - void VIDEO_SetTrapFilter(bool enable) { - if (enable) - __VISetTrapFilter(0); - else - __VISetTrapFilter(1); + u8 disable; + u8 data; + u8 reg; + u8 buf[2]; + + disable = !enable; + data = !disable; + reg = 0x03; + + buf[0] = reg; + buf[1] = data; + + u8 addr = 0xe0; + void* val = buf; + u32 len = 2; + + u8 c; + s32 i,j; + u32 level,ret; + + if(i2cIdentFirst==0) + { + __viOpenI2C(0); + udelay(4); + + i2cIdentFlag = 0; + if(__viGetSDA()!=0) + i2cIdentFlag = 1; + i2cIdentFirst = 1; + } + + _CPU_ISR_Disable(level); + + __viOpenI2C(1); + __viSetSCL(1); + + __viSetSDA(i2cIdentFlag); + udelay(4); + + ret = __sendSlaveAddress(addr); + if(ret==0) { + _CPU_ISR_Restore(level); + goto end; + } + + __viOpenI2C(1); + for(i=0;i Date: Wed, 8 Aug 2012 23:25:41 +0200 Subject: [PATCH 113/492] (GX) VIDEO_SetTrapFilter not run every frame now --- console/rgui/rgui.c | 1 + gx/gx_video.c | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/console/rgui/rgui.c b/console/rgui/rgui.c index fdac3db0c6..cfb4c508e7 100644 --- a/console/rgui/rgui.c +++ b/console/rgui/rgui.c @@ -410,6 +410,7 @@ static void rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t #ifdef HW_RVL case RGUI_SETTINGS_VIDEO_SOFT_FILTER: g_console.soft_display_filter_enable = !g_console.soft_display_filter_enable; + gx->should_resize = true; break; #endif case RGUI_SETTINGS_VIDEO_GAMMA: diff --git a/gx/gx_video.c b/gx/gx_video.c index 8b03be19a0..0c6b8744b9 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -429,14 +429,13 @@ static bool wii_frame(void *data, const void *frame, if(!frame && !menu_render) return true; -#ifdef HW_RVL - VIDEO_SetTrapFilter(g_console.soft_display_filter_enable); -#endif - gx->frame_count++; if(should_resize) { +#ifdef HW_RVL + VIDEO_SetTrapFilter(g_console.soft_display_filter_enable); +#endif GX_SetDispCopyGamma(g_console.gamma_correction); gx->should_resize = false; } From 6598e71b9c2c009e5528f2d16a7968dd55a88bae Mon Sep 17 00:00:00 2001 From: Toad King Date: Wed, 8 Aug 2012 18:23:33 -0400 Subject: [PATCH 114/492] (GX) Change button combos for GC controller for Menu/Exit Stick Up + C-Stick Up + L + R for menu Start + Select + L + R for exit --- gx/gx_input.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gx/gx_input.c b/gx/gx_input.c index 24a75eaa57..a921d5f545 100644 --- a/gx/gx_input.c +++ b/gx/gx_input.c @@ -286,9 +286,6 @@ static void wii_input_poll(void *data) state |= (PAD_TriggerL(port) > 127) ? GX_GC_L_TRIGGER : 0; state |= (PAD_TriggerR(port) > 127) ? GX_GC_R_TRIGGER : 0; - if((down & PAD_BUTTON_A) && (PAD_TriggerL(port) > 127) && (PAD_TriggerR(port) > 127) && (down & PAD_TRIGGER_Z) && (down & PAD_BUTTON_START) && (down & PAD_BUTTON_A)) - quit_gc = true; - s8 x = PAD_StickX(port); s8 y = PAD_StickY(port); @@ -312,6 +309,9 @@ static void wii_input_poll(void *data) { state |= y > 0 ? GX_GC_RSTICK_UP : GX_GC_RSTICK_DOWN; } + + if ((state & (GX_GC_START | GX_GC_Z_TRIGGER | GX_GC_L_TRIGGER | GX_GC_R_TRIGGER)) == (GX_GC_START | GX_GC_Z_TRIGGER | GX_GC_L_TRIGGER | GX_GC_R_TRIGGER)) + quit_gc = true; } #ifdef HW_RVL @@ -414,7 +414,7 @@ static void wii_input_poll(void *data) } #endif - if ((state & (GX_GC_START | GX_GC_Z_TRIGGER | GX_GC_L_TRIGGER | GX_GC_R_TRIGGER)) == (GX_GC_START | GX_GC_Z_TRIGGER | GX_GC_L_TRIGGER | GX_GC_R_TRIGGER)) + if ((state & (GX_GC_LSTICK_UP | GX_GC_RSTICK_UP | GX_GC_L_TRIGGER | GX_GC_R_TRIGGER)) == (GX_GC_LSTICK_UP | GX_GC_RSTICK_UP | GX_GC_L_TRIGGER | GX_GC_R_TRIGGER)) { state |= GX_WIIMOTE_HOME; } From 4e8bb6580bc5a278a300dbaaa2cbeec991a239d9 Mon Sep 17 00:00:00 2001 From: Toad King Date: Wed, 8 Aug 2012 19:27:52 -0400 Subject: [PATCH 115/492] (GX) more GC button combo changes Exit is now Stick Down + C-Stick Down + L + R --- gx/gx_input.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gx/gx_input.c b/gx/gx_input.c index a921d5f545..707763391c 100644 --- a/gx/gx_input.c +++ b/gx/gx_input.c @@ -310,7 +310,7 @@ static void wii_input_poll(void *data) state |= y > 0 ? GX_GC_RSTICK_UP : GX_GC_RSTICK_DOWN; } - if ((state & (GX_GC_START | GX_GC_Z_TRIGGER | GX_GC_L_TRIGGER | GX_GC_R_TRIGGER)) == (GX_GC_START | GX_GC_Z_TRIGGER | GX_GC_L_TRIGGER | GX_GC_R_TRIGGER)) + if ((state & (GX_GC_LSTICK_DOWN | GX_GC_RSTICK_DOWN | GX_GC_L_TRIGGER | GX_GC_R_TRIGGER)) == (GX_GC_LSTICK_DOWN | GX_GC_RSTICK_DOWN | GX_GC_L_TRIGGER | GX_GC_R_TRIGGER)) quit_gc = true; } @@ -375,7 +375,7 @@ static void wii_input_poll(void *data) state |= (down & WPAD_CLASSIC_BUTTON_ZL) ? GX_CLASSIC_ZL_TRIGGER : 0; state |= (down & WPAD_CLASSIC_BUTTON_ZR) ? GX_CLASSIC_ZR_TRIGGER : 0; - if((down & WPAD_CLASSIC_BUTTON_HOME) && (down & WPAD_CLASSIC_BUTTON_ZL) && (down & WPAD_CLASSIC_BUTTON_ZR)) + if((down & WPAD_CLASSIC_BUTTON_HOME) && (down & WPAD_CLASSIC_BUTTON_ZL) && (down & WPAD_CLASSIC_BUTTON_ZR)) quit_classic = true; s8 x = wii_stick_x(exp.classic.ljs); From 0fd65fccc18943c68a87db68d247b7d24a2a57cd Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Thu, 9 Aug 2012 03:07:08 +0200 Subject: [PATCH 116/492] (GX) Dirty hack to get Classic analog sticks mapped as D-pad working properly (without messing up same controls in menu) --- gx/gx_input.c | 52 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/gx/gx_input.c b/gx/gx_input.c index 707763391c..5f46bf3de8 100644 --- a/gx/gx_input.c +++ b/gx/gx_input.c @@ -257,6 +257,8 @@ static void wii_input_post_init(void) static void wii_input_poll(void *data) { + //TODO: Hack, analog stick twitchiness needs to be properly fixed + gx_video_t *gx = (gx_video_t*)driver.video_data; (void)data; bool quit_gc = false; bool quit_classic = false; @@ -378,28 +380,44 @@ static void wii_input_poll(void *data) if((down & WPAD_CLASSIC_BUTTON_HOME) && (down & WPAD_CLASSIC_BUTTON_ZL) && (down & WPAD_CLASSIC_BUTTON_ZR)) quit_classic = true; - s8 x = wii_stick_x(exp.classic.ljs); - s8 y = wii_stick_y(exp.classic.ljs); + //TODO: Hack, analog stick twitchiness needs to be properly fixed + if(gx->menu_render) + { + s8 x = wii_stick_x(exp.classic.ljs); + s8 y = wii_stick_y(exp.classic.ljs); - if (abs(x) > JOYSTICK_THRESHOLD) - { - state |= x > 0 ? GX_CLASSIC_LSTICK_RIGHT : GX_CLASSIC_LSTICK_LEFT; - } - if (abs(y) > JOYSTICK_THRESHOLD) - { - state |= y > 0 ? GX_CLASSIC_LSTICK_UP : GX_CLASSIC_LSTICK_DOWN; - } + if (abs(x) > JOYSTICK_THRESHOLD) + state |= x > 0 ? GX_CLASSIC_LSTICK_RIGHT : GX_CLASSIC_LSTICK_LEFT; + if (abs(y) > JOYSTICK_THRESHOLD) + state |= y > 0 ? GX_CLASSIC_LSTICK_UP : GX_CLASSIC_LSTICK_DOWN; - x = wii_stick_x(exp.classic.rjs); - y = wii_stick_y(exp.classic.rjs); + x = wii_stick_x(exp.classic.rjs); + y = wii_stick_y(exp.classic.rjs); - if (abs(x) > JOYSTICK_THRESHOLD) - { - state |= x > 0 ? GX_CLASSIC_RSTICK_RIGHT : GX_CLASSIC_RSTICK_LEFT; + if (abs(x) > JOYSTICK_THRESHOLD) + state |= x > 0 ? GX_CLASSIC_RSTICK_RIGHT : GX_CLASSIC_RSTICK_LEFT; + if (abs(y) > JOYSTICK_THRESHOLD) + state |= y > 0 ? GX_CLASSIC_RSTICK_UP : GX_CLASSIC_RSTICK_DOWN; } - if (abs(y) > JOYSTICK_THRESHOLD) + else { - state |= y > 0 ? GX_CLASSIC_RSTICK_UP : GX_CLASSIC_RSTICK_DOWN; + if(exp.classic.ljs.pos.x > 40) + state |= GX_CLASSIC_LSTICK_RIGHT; + if(exp.classic.ljs.pos.x < 25) + state |= GX_CLASSIC_LSTICK_LEFT; + if(exp.classic.ljs.pos.y > 45) + state |= GX_CLASSIC_LSTICK_UP; + if(exp.classic.ljs.pos.y < 20) + state |= GX_CLASSIC_LSTICK_DOWN; + + if(exp.classic.rjs.pos.x > 40) + state |= GX_CLASSIC_RSTICK_RIGHT; + if(exp.classic.rjs.pos.x < 25) + state |= GX_CLASSIC_RSTICK_LEFT; + if(exp.classic.rjs.pos.y > 45) + state |= GX_CLASSIC_RSTICK_UP; + if(exp.classic.rjs.pos.y < 20) + state |= GX_CLASSIC_RSTICK_DOWN; } // do not return, fall through for wiimote d-pad } From e277828526334913dd334d51d6758e41c3797f0f Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Thu, 9 Aug 2012 03:13:08 +0200 Subject: [PATCH 117/492] (GX) Cleanup dirty hack a bit --- gx/gx_input.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/gx/gx_input.c b/gx/gx_input.c index 5f46bf3de8..8b609171d1 100644 --- a/gx/gx_input.c +++ b/gx/gx_input.c @@ -401,22 +401,27 @@ static void wii_input_poll(void *data) } else { - if(exp.classic.ljs.pos.x > 40) + u8 ls_x = exp.classic.ljs.pos.x; + u8 ls_y = exp.classic.ljs.pos.y; + u8 rs_x = exp.classic.rjs.pos.x; + u8 rs_y = exp.classic.rjs.pos.y; + + if(ls_x > 40) state |= GX_CLASSIC_LSTICK_RIGHT; - if(exp.classic.ljs.pos.x < 25) + if(ls_x < 25) state |= GX_CLASSIC_LSTICK_LEFT; - if(exp.classic.ljs.pos.y > 45) + if(ls_y > 45) state |= GX_CLASSIC_LSTICK_UP; - if(exp.classic.ljs.pos.y < 20) + if(ls_y < 20) state |= GX_CLASSIC_LSTICK_DOWN; - if(exp.classic.rjs.pos.x > 40) + if(rs_x > 40) state |= GX_CLASSIC_RSTICK_RIGHT; - if(exp.classic.rjs.pos.x < 25) + if(rs_x < 25) state |= GX_CLASSIC_RSTICK_LEFT; - if(exp.classic.rjs.pos.y > 45) + if(rs_y > 45) state |= GX_CLASSIC_RSTICK_UP; - if(exp.classic.rjs.pos.y < 20) + if(rs_y < 20) state |= GX_CLASSIC_RSTICK_DOWN; } // do not return, fall through for wiimote d-pad From 5e97b86e659c76498897e66653c19bf0ff371309 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Thu, 9 Aug 2012 03:54:27 +0200 Subject: [PATCH 118/492] (GX) Change wii_ naming conventions to gx_ --- console/griffin/hook.h | 26 ++++++++-------- console/rgui/rgui.c | 10 +++--- driver.c | 6 ++-- driver.h | 6 ++-- gx/frontend/main.c | 28 ++++++++--------- gx/gx_audio.c | 46 +++++++++++++-------------- gx/gx_input.c | 70 +++++++++++++++++++++++++----------------- gx/gx_input.h | 2 +- gx/gx_video.c | 34 ++++++++++---------- settings.c | 6 ++-- 10 files changed, 121 insertions(+), 113 deletions(-) diff --git a/console/griffin/hook.h b/console/griffin/hook.h index 045dff26e0..91fc3785a9 100644 --- a/console/griffin/hook.h +++ b/console/griffin/hook.h @@ -82,23 +82,23 @@ #elif defined(GEKKO) -#define video_init_func(video_info, input, input_data) wii_init(video_info, input, input_data) +#define video_init_func(video_info, input, input_data) gx_init(video_info, input, input_data) #define video_frame_func(data, width, height, pitch, msg) \ - wii_frame(driver.video_data, data, width, height, pitch, msg) -#define video_set_nonblock_state_func(state) wii_set_nonblock_state(driver.video_data, state) -#define video_alive_func() wii_alive(driver.video_data) -#define video_focus_func() wii_focus(driver.video_data) + gx_frame(driver.video_data, data, width, height, pitch, msg) +#define video_set_nonblock_state_func(state) gx_set_nonblock_state(driver.video_data, state) +#define video_alive_func() gx_alive(driver.video_data) +#define video_focus_func() gx_focus(driver.video_data) #define video_xml_shader_func(path) driver.video->xml_shader(driver.video_data, path) -#define video_free_func() wii_free(driver.video_data) -#define video_set_rotation_func(orientation) wii_set_rotation(driver.video_data, orientation) -#define video_set_aspect_ratio_func(aspectratio_idx) wii_set_aspect_ratio(driver.video_data, aspectratio_idx) +#define video_free_func() gx_free(driver.video_data) +#define video_set_rotation_func(orientation) gx_set_rotation(driver.video_data, orientation) +#define video_set_aspect_ratio_func(aspectratio_idx) gx_set_aspect_ratio(driver.video_data, aspectratio_idx) -#define input_init_func() wii_input_initialize() -#define input_poll_func() wii_input_poll(driver.input_data) +#define input_init_func() gx_input_initialize() +#define input_poll_func() gx_input_poll(driver.input_data) #define input_input_state_func(retro_keybinds, port, device, index, id) \ - wii_input_state(driver.input_data, retro_keybinds, port, device, index, id) -#define input_key_pressed_func(key) wii_key_pressed(driver.input_data, key) -#define input_free_func() wii_free_input(driver.input_data) + gx_input_state(driver.input_data, retro_keybinds, port, device, index, id) +#define input_key_pressed_func(key) gx_key_pressed(driver.input_data, key) +#define input_free_func() gx_free_input(driver.input_data) #define gfx_ctx_window_has_focus() (true) #else diff --git a/console/rgui/rgui.c b/console/rgui/rgui.c index cfb4c508e7..c4e0ad038e 100644 --- a/console/rgui/rgui.c +++ b/console/rgui/rgui.c @@ -447,21 +447,21 @@ static void rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t { rarch_settings_default(S_DEF_AUDIO_CONTROL_RATE); #ifdef GEKKO - video_wii.set_rotation(NULL, g_console.screen_orientation); + video_gx.set_rotation(NULL, g_console.screen_orientation); #endif } else if (action == RGUI_ACTION_LEFT) { rarch_settings_change(S_ROTATION_DECREMENT); #ifdef GEKKO - video_wii.set_rotation(NULL, g_console.screen_orientation); + video_gx.set_rotation(NULL, g_console.screen_orientation); #endif } else if (action == RGUI_ACTION_RIGHT) { rarch_settings_change(S_ROTATION_INCREMENT); #ifdef GEKKO - video_wii.set_rotation(NULL, g_console.screen_orientation); + video_gx.set_rotation(NULL, g_console.screen_orientation); #endif } break; @@ -507,9 +507,9 @@ static void rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t else if (action == RGUI_ACTION_RIGHT) g_settings.input.device[port]++; g_settings.input.device[port] %= RARCH_DEVICE_LAST; - input_wii.set_default_keybind_lut(g_settings.input.device[port], port); + input_gx.set_default_keybind_lut(g_settings.input.device[port], port); rarch_input_set_default_keybinds(port); - input_wii.set_analog_dpad_mapping(g_settings.input.device[port], g_settings.input.dpad_emulation[port], port); + input_gx.set_analog_dpad_mapping(g_settings.input.device[port], g_settings.input.dpad_emulation[port], port); break; case RGUI_SETTINGS_BIND_UP: case RGUI_SETTINGS_BIND_DOWN: diff --git a/driver.c b/driver.c index 6b5e9a175a..0131a62e5a 100644 --- a/driver.c +++ b/driver.c @@ -73,7 +73,7 @@ static const audio_driver_t *audio_drivers[] = { &audio_xdk360, #endif #ifdef GEKKO - &audio_wii, + &audio_gx, #endif &audio_null, }; @@ -98,7 +98,7 @@ static const video_driver_t *video_drivers[] = { &video_ext, #endif #ifdef GEKKO - &video_wii, + &video_gx, #endif #ifdef HAVE_RPI &video_rpi, @@ -123,7 +123,7 @@ static const input_driver_t *input_drivers[] = { &input_xinput, #endif #ifdef GEKKO - &input_wii, + &input_gx, #endif #ifdef IS_LINUX &input_linuxraw, diff --git a/driver.h b/driver.h index 917f25623e..02f3a4f582 100644 --- a/driver.h +++ b/driver.h @@ -237,10 +237,10 @@ extern const audio_driver_t audio_coreaudio; extern const audio_driver_t audio_xenon360; extern const audio_driver_t audio_xdk360; extern const audio_driver_t audio_ps3; -extern const audio_driver_t audio_wii; +extern const audio_driver_t audio_gx; extern const audio_driver_t audio_null; extern const video_driver_t video_gl; -extern const video_driver_t video_wii; +extern const video_driver_t video_gx; extern const video_driver_t video_xenon360; extern const video_driver_t video_xvideo; extern const video_driver_t video_xdk_d3d; @@ -252,7 +252,7 @@ extern const input_driver_t input_sdl; extern const input_driver_t input_x; extern const input_driver_t input_ps3; extern const input_driver_t input_xenon360; -extern const input_driver_t input_wii; +extern const input_driver_t input_gx; extern const input_driver_t input_xinput; extern const input_driver_t input_linuxraw; extern const input_driver_t input_null; diff --git a/gx/frontend/main.c b/gx/frontend/main.c index e6619de2ad..927cb710fb 100644 --- a/gx/frontend/main.c +++ b/gx/frontend/main.c @@ -50,7 +50,6 @@ uint32_t menu_framebuf[320 * 240]; rgui_handle_t *rgui; char app_dir[PATH_MAX]; -struct retro_system_info wii_core_info; static const struct retro_keybind _wii_nav_binds[] = { { 0, 0, 0, GX_GC_UP | GX_GC_LSTICK_UP | GX_GC_RSTICK_UP | GX_CLASSIC_UP | GX_CLASSIC_LSTICK_UP | GX_CLASSIC_RSTICK_UP | GX_WIIMOTE_UP | GX_NUNCHUK_UP, 0 }, @@ -151,11 +150,11 @@ static void menu_loop(void) { uint64_t input_state = 0; - input_wii.poll(NULL); + input_gx.poll(NULL); for (unsigned i = 0; i < GX_DEVICE_NAV_LAST; i++) { - input_state |= input_wii.input_state(NULL, wii_nav_binds, 0, + input_state |= input_gx.input_state(NULL, wii_nav_binds, 0, RETRO_DEVICE_JOYPAD, 0, i) ? (1 << i) : 0; } @@ -169,13 +168,13 @@ static void menu_loop(void) _quit_binds }; - input_state |= input_wii.input_state(NULL, quit_binds, false, + input_state |= input_gx.input_state(NULL, quit_binds, false, RETRO_DEVICE_JOYPAD, 0, 0) ? (GX_CLASSIC_HOME) : 0; - input_state |= input_wii.input_state(NULL, quit_binds, false, + input_state |= input_gx.input_state(NULL, quit_binds, false, RETRO_DEVICE_JOYPAD, 0, 1) ? (GX_WIIMOTE_HOME) : 0; - input_state |= input_wii.input_state(NULL, quit_binds, false, + input_state |= input_gx.input_state(NULL, quit_binds, false, RETRO_DEVICE_JOYPAD, 0, 2) ? (GX_QUIT_KEY) : 0; @@ -307,12 +306,9 @@ int main(void) #endif config_set_defaults(); - input_wii.init(); + input_gx.init(); - retro_get_system_info(&wii_core_info); - RARCH_LOG("Core: %s\n", wii_core_info.library_name); - - video_wii.start(); + video_gx.start(); gx_video_t *gx = (gx_video_t*)driver.video_data; gx->menu_data = menu_framebuf; @@ -328,11 +324,11 @@ int main(void) bool find_libretro_file = rarch_configure_libretro_core(full_path, path_prefix, path_prefix, default_paths.config_file, extension); - rarch_settings_set_default(&input_wii); + rarch_settings_set_default(&input_gx); rarch_config_load(default_paths.config_file, path_prefix, extension, find_libretro_file); init_libretro_sym(); - input_wii.post_init(); + input_gx.post_init(); menu_init(); @@ -341,7 +337,7 @@ begin_loop: { bool repeat = false; - input_wii.poll(NULL); + input_gx.poll(NULL); audio_start_func(); do{ @@ -366,8 +362,8 @@ begin_shutdown: if(g_console.emulator_initialized) rarch_main_deinit(); - input_wii.free(NULL); - video_wii.stop(); + input_gx.free(NULL); + video_gx.stop(); menu_free(); #ifdef HAVE_FILE_LOGGER diff --git a/gx/gx_audio.c b/gx/gx_audio.c index 7fcd511062..7f68425886 100644 --- a/gx/gx_audio.c +++ b/gx/gx_audio.c @@ -38,9 +38,9 @@ typedef struct lwpq_t cond; bool nonblock; -} wii_audio_t; +} gx_audio_t; -static wii_audio_t *g_audio; +static gx_audio_t *g_audio; static void dma_callback(void) { @@ -53,7 +53,7 @@ static void dma_callback(void) LWP_ThreadSignal(g_audio->cond); } -static void *wii_audio_init(const char *device, unsigned rate, unsigned latency) +static void *gx_audio_init(const char *device, unsigned rate, unsigned latency) { AUDIO_Init(NULL); AUDIO_RegisterDMACallback(dma_callback); @@ -91,9 +91,9 @@ static void *wii_audio_init(const char *device, unsigned rate, unsigned latency) return g_audio; } -static ssize_t wii_audio_write(void *data, const void *buf_, size_t size) +static ssize_t gx_audio_write(void *data, const void *buf_, size_t size) { - wii_audio_t *wa = data; + gx_audio_t *wa = data; size_t frames = size >> 2; const uint32_t *buf = buf_; @@ -122,27 +122,27 @@ static ssize_t wii_audio_write(void *data, const void *buf_, size_t size) return size; } -static bool wii_audio_stop(void *data) +static bool gx_audio_stop(void *data) { (void)data; AUDIO_StopDMA(); return true; } -static void wii_audio_set_nonblock_state(void *data, bool state) +static void gx_audio_set_nonblock_state(void *data, bool state) { - wii_audio_t *wa = data; + gx_audio_t *wa = data; wa->nonblock = state; } -static bool wii_audio_start(void *data) +static bool gx_audio_start(void *data) { (void)data; AUDIO_StartDMA(); return true; } -static void wii_audio_free(void *data) +static void gx_audio_free(void *data) { AUDIO_StopDMA(); AUDIO_RegisterDMACallback(NULL); @@ -156,27 +156,27 @@ static void wii_audio_free(void *data) g_audio = NULL; } -static size_t wii_audio_write_avail(void *data) +static size_t gx_audio_write_avail(void *data) { - wii_audio_t *wa = data; + gx_audio_t *wa = data; return ((wa->dma_busy - wa->dma_write + BLOCKS) & (BLOCKS - 1)) * CHUNK_SIZE; } -static size_t wii_audio_buffer_size(void *data) +static size_t gx_audio_buffer_size(void *data) { (void)data; return BLOCKS * CHUNK_SIZE; } -const audio_driver_t audio_wii = { - .init = wii_audio_init, - .write = wii_audio_write, - .stop = wii_audio_stop, - .start = wii_audio_start, - .set_nonblock_state = wii_audio_set_nonblock_state, - .free = wii_audio_free, - .ident = "wii", - .write_avail = wii_audio_write_avail, - .buffer_size = wii_audio_buffer_size, +const audio_driver_t audio_gx = { + .init = gx_audio_init, + .write = gx_audio_write, + .stop = gx_audio_stop, + .start = gx_audio_start, + .set_nonblock_state = gx_audio_set_nonblock_state, + .free = gx_audio_free, + .ident = "gx", + .write_avail = gx_audio_write_avail, + .buffer_size = gx_audio_buffer_size, }; diff --git a/gx/gx_input.c b/gx/gx_input.c index 8b609171d1..046b31233a 100644 --- a/gx/gx_input.c +++ b/gx/gx_input.c @@ -131,7 +131,7 @@ const struct platform_bind platform_keys[] = { const unsigned int platform_keys_size = sizeof(platform_keys); static bool g_quit; -static int16_t wii_input_state(void *data, const struct retro_keybind **binds, +static int16_t gx_input_state(void *data, const struct retro_keybind **binds, unsigned port, unsigned device, unsigned index, unsigned id) { @@ -144,7 +144,7 @@ static int16_t wii_input_state(void *data, const struct retro_keybind **binds, return (binds[port][id].joykey & pad_state[port]) ? 1 : 0; } -static void wii_free_input(void *data) +static void gx_free_input(void *data) { (void)data; } @@ -154,7 +154,7 @@ static void reset_callback(void) g_quit = true; } -static void wii_input_set_analog_dpad_mapping(unsigned device, unsigned map_dpad_enum, unsigned controller_id) +static void gx_input_set_analog_dpad_mapping(unsigned device, unsigned map_dpad_enum, unsigned controller_id) { switch (device) { @@ -233,7 +233,7 @@ static void wii_input_set_analog_dpad_mapping(unsigned device, unsigned map_dpad } } -static void *wii_input_initialize(void) +static void *gx_input_initialize(void) { PAD_Init(); #ifdef HW_RVL @@ -246,23 +246,25 @@ static void *wii_input_initialize(void) #define STUB_DEVICE 0 -static void wii_input_post_init(void) +static void gx_input_post_init(void) { for(unsigned i = 0; i < MAX_PADS; i++) - wii_input_set_analog_dpad_mapping(STUB_DEVICE, g_settings.input.dpad_emulation[i], i); + gx_input_set_analog_dpad_mapping(STUB_DEVICE, g_settings.input.dpad_emulation[i], i); } -#define wii_stick_x(x) ((s8)((sin((x).ang * M_PI / 180.0f)) * (x).mag * 128.0f)) -#define wii_stick_y(x) ((s8)((cos((x).ang * M_PI / 180.0f)) * (x).mag * 128.0f)) +#define gx_stick_x(x) ((s8)((sin((x).ang * M_PI / 180.0f)) * (x).mag * 128.0f)) +#define gx_stick_y(x) ((s8)((cos((x).ang * M_PI / 180.0f)) * (x).mag * 128.0f)) -static void wii_input_poll(void *data) +static void gx_input_poll(void *data) { //TODO: Hack, analog stick twitchiness needs to be properly fixed gx_video_t *gx = (gx_video_t*)driver.video_data; (void)data; bool quit_gc = false; +#ifdef HW_RVL bool quit_classic = false; bool quit_wiimote = false; +#endif PAD_ScanPads(); #ifdef HW_RVL @@ -346,8 +348,8 @@ static void wii_input_poll(void *data) state |= (down & WPAD_NUNCHUK_BUTTON_Z) ? GX_NUNCHUK_Z : 0; state |= (down & WPAD_NUNCHUK_BUTTON_C) ? GX_NUNCHUK_C : 0; - s8 x = wii_stick_x(exp.nunchuk.js); - s8 y = wii_stick_y(exp.nunchuk.js); + s8 x = gx_stick_x(exp.nunchuk.js); + s8 y = gx_stick_y(exp.nunchuk.js); if (abs(x) > JOYSTICK_THRESHOLD) { @@ -383,16 +385,16 @@ static void wii_input_poll(void *data) //TODO: Hack, analog stick twitchiness needs to be properly fixed if(gx->menu_render) { - s8 x = wii_stick_x(exp.classic.ljs); - s8 y = wii_stick_y(exp.classic.ljs); + s8 x = gx_stick_x(exp.classic.ljs); + s8 y = gx_stick_y(exp.classic.ljs); if (abs(x) > JOYSTICK_THRESHOLD) state |= x > 0 ? GX_CLASSIC_LSTICK_RIGHT : GX_CLASSIC_LSTICK_LEFT; if (abs(y) > JOYSTICK_THRESHOLD) state |= y > 0 ? GX_CLASSIC_LSTICK_UP : GX_CLASSIC_LSTICK_DOWN; - x = wii_stick_x(exp.classic.rjs); - y = wii_stick_y(exp.classic.rjs); + x = gx_stick_x(exp.classic.rjs); + y = gx_stick_y(exp.classic.rjs); if (abs(x) > JOYSTICK_THRESHOLD) state |= x > 0 ? GX_CLASSIC_RSTICK_RIGHT : GX_CLASSIC_RSTICK_LEFT; @@ -442,7 +444,11 @@ static void wii_input_poll(void *data) state |= GX_WIIMOTE_HOME; } - if (quit_gc || quit_wiimote || quit_classic) + if (quit_gc +#ifdef HW_RVL + || quit_wiimote || quit_classic +#endif + ) state |= GX_QUIT_KEY; pad_state[port] = state; @@ -455,7 +461,7 @@ static void wii_input_poll(void *data) } } -static bool wii_key_pressed(void *data, int key) +static bool gx_key_pressed(void *data, int key) { (void)data; @@ -466,11 +472,17 @@ static bool wii_key_pressed(void *data, int key) case RARCH_QUIT_KEY: if(IS_TIMER_EXPIRED(gx)) { +#ifdef HW_RVL uint64_t goto_menu_pressed_classic = pad_state[0] & GX_CLASSIC_HOME; uint64_t goto_menu_pressed_wiimote = pad_state[0] & GX_WIIMOTE_HOME; +#endif uint64_t quit_rarch = pad_state[0] & GX_QUIT_KEY; bool retval = false; - g_console.menu_enable = ((goto_menu_pressed_classic || goto_menu_pressed_wiimote || quit_rarch) && IS_TIMER_EXPIRED(gx)); + g_console.menu_enable = ((quit_rarch +#ifdef HW_RVL + || goto_menu_pressed_classic || goto_menu_pressed_wiimote) +#endif + && IS_TIMER_EXPIRED(gx)); if(g_console.menu_enable) { @@ -490,7 +502,7 @@ static bool wii_key_pressed(void *data, int key) } } -static void wii_set_default_keybind_lut(unsigned device, unsigned port) +static void gx_set_default_keybind_lut(unsigned device, unsigned port) { (void)port; @@ -575,15 +587,15 @@ static void wii_set_default_keybind_lut(unsigned device, unsigned port) } } -const input_driver_t input_wii = { - .init = wii_input_initialize, - .poll = wii_input_poll, - .input_state = wii_input_state, - .key_pressed = wii_key_pressed, - .free = wii_free_input, - .set_default_keybind_lut = wii_set_default_keybind_lut, - .set_analog_dpad_mapping = wii_input_set_analog_dpad_mapping, - .post_init = wii_input_post_init, +const input_driver_t input_gx = { + .init = gx_input_initialize, + .poll = gx_input_poll, + .input_state = gx_input_state, + .key_pressed = gx_key_pressed, + .free = gx_free_input, + .set_default_keybind_lut = gx_set_default_keybind_lut, + .set_analog_dpad_mapping = gx_input_set_analog_dpad_mapping, + .post_init = gx_input_post_init, .max_pads = MAX_PADS, - .ident = "wii", + .ident = "gx", }; diff --git a/gx/gx_input.h b/gx/gx_input.h index 41a3ef41a1..41db29b3a8 100644 --- a/gx/gx_input.h +++ b/gx/gx_input.h @@ -85,7 +85,7 @@ enum GX_QUIT_KEY = 1ULL << 60, }; -enum wii_device_id +enum gx_device_id { GX_DEVICE_GC_ID_JOYPAD_A = 0, GX_DEVICE_GC_ID_JOYPAD_B, diff --git a/gx/gx_video.c b/gx/gx_video.c index 0c6b8744b9..e2b0c1264c 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -193,7 +193,7 @@ static void gx_restart(void) { } -static void *wii_init(const video_info_t *video, +static void *gx_init(const video_info_t *video, const input_driver_t **input, void **input_data) { if (driver.video_data) @@ -218,7 +218,7 @@ static void gx_start(void) video_info.smooth = g_settings.video.smooth; video_info.input_scale = 2; - driver.video_data = wii_init(&video_info, NULL, NULL); + driver.video_data = gx_init(&video_info, NULL, NULL); //gx_video_t *gx = (gx_video_t*)driver.video_data; VIDEO_Init(); @@ -415,7 +415,7 @@ static void update_texture(const uint32_t *src, GX_InvalidateTexAll(); } -static bool wii_frame(void *data, const void *frame, +static bool gx_frame(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch, const char *msg) { @@ -469,30 +469,30 @@ static bool wii_frame(void *data, const void *frame, return true; } -static void wii_set_nonblock_state(void *data, bool state) +static void gx_set_nonblock_state(void *data, bool state) { (void)data; g_vsync = !state; } -static bool wii_alive(void *data) +static bool gx_alive(void *data) { (void)data; return true; } -static bool wii_focus(void *data) +static bool gx_focus(void *data) { (void)data; return true; } -static void wii_free(void *data) +static void gx_free(void *data) { (void)data; } -static void wii_set_rotation(void * data, uint32_t orientation) +static void gx_set_rotation(void * data, uint32_t orientation) { (void)data; (void)orientation; @@ -516,15 +516,15 @@ static void wii_set_rotation(void * data, uint32_t orientation) GX_SetArray(GX_VA_TEX0, vertex_ptr, 2 * sizeof(float)); } -const video_driver_t video_wii = { - .init = wii_init, - .frame = wii_frame, - .alive = wii_alive, - .set_nonblock_state = wii_set_nonblock_state, - .focus = wii_focus, - .free = wii_free, - .ident = "wii", - .set_rotation = wii_set_rotation, +const video_driver_t video_gx = { + .init = gx_init, + .frame = gx_frame, + .alive = gx_alive, + .set_nonblock_state = gx_set_nonblock_state, + .focus = gx_focus, + .free = gx_free, + .ident = "gx", + .set_rotation = gx_set_rotation, .start = gx_start, .stop = gx_stop, .restart = gx_restart, diff --git a/settings.c b/settings.c index 0eeda77e09..4e8342db47 100644 --- a/settings.c +++ b/settings.c @@ -66,7 +66,7 @@ const char *config_get_default_audio(void) case AUDIO_PS3: return "ps3"; case AUDIO_WII: - return "wii"; + return "gx"; case AUDIO_NULL: return "null"; default: @@ -81,7 +81,7 @@ const char *config_get_default_video(void) case VIDEO_GL: return "gl"; case VIDEO_WII: - return "wii"; + return "gx"; case VIDEO_XENON360: return "xenon360"; case VIDEO_XDK_D3D: @@ -116,7 +116,7 @@ const char *config_get_default_input(void) case INPUT_XINPUT: return "xinput"; case INPUT_WII: - return "wii"; + return "gx"; case INPUT_LINUXRAW: return "linuxraw"; case INPUT_NULL: From 0c6017caff0047aeedecdbb8a096de4a01d567f0 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Thu, 9 Aug 2012 05:27:06 +0200 Subject: [PATCH 119/492] (GX) Cleanups --- console/rgui/rgui.c | 2 -- gx/gx_input.c | 39 ++++++++------------------------------- gx/gx_video.c | 1 - 3 files changed, 8 insertions(+), 34 deletions(-) diff --git a/console/rgui/rgui.c b/console/rgui/rgui.c index c4e0ad038e..55470a42fb 100644 --- a/console/rgui/rgui.c +++ b/console/rgui/rgui.c @@ -680,9 +680,7 @@ const char *rgui_iterate(rgui_handle_t *rgui, rgui_action_t action) rgui_list_back(rgui->path_stack, &dir, &menu_type, &directory_ptr); if (menu_type == RGUI_SETTINGS || rgui_is_controller_menu(menu_type)) - { return rgui_settings_iterate(rgui, action); - } if (rgui->need_refresh) action = RGUI_ACTION_NOOP; diff --git a/gx/gx_input.c b/gx/gx_input.c index 046b31233a..889ff85a65 100644 --- a/gx/gx_input.c +++ b/gx/gx_input.c @@ -294,25 +294,17 @@ static void gx_input_poll(void *data) s8 y = PAD_StickY(port); if (abs(x) > JOYSTICK_THRESHOLD) - { state |= x > 0 ? GX_GC_LSTICK_RIGHT : GX_GC_LSTICK_LEFT; - } if (abs(y) > JOYSTICK_THRESHOLD) - { state |= y > 0 ? GX_GC_LSTICK_UP : GX_GC_LSTICK_DOWN; - } x = PAD_SubStickX(port); y = PAD_SubStickY(port); if (abs(x) > JOYSTICK_THRESHOLD) - { state |= x > 0 ? GX_GC_RSTICK_RIGHT : GX_GC_RSTICK_LEFT; - } if (abs(y) > JOYSTICK_THRESHOLD) - { state |= y > 0 ? GX_GC_RSTICK_UP : GX_GC_RSTICK_DOWN; - } if ((state & (GX_GC_LSTICK_DOWN | GX_GC_RSTICK_DOWN | GX_GC_L_TRIGGER | GX_GC_R_TRIGGER)) == (GX_GC_LSTICK_DOWN | GX_GC_RSTICK_DOWN | GX_GC_L_TRIGGER | GX_GC_R_TRIGGER)) quit_gc = true; @@ -352,13 +344,9 @@ static void gx_input_poll(void *data) s8 y = gx_stick_y(exp.nunchuk.js); if (abs(x) > JOYSTICK_THRESHOLD) - { state |= x > 0 ? GX_NUNCHUK_RIGHT : GX_NUNCHUK_LEFT; - } if (abs(y) > JOYSTICK_THRESHOLD) - { state |= y > 0 ? GX_NUNCHUK_UP : GX_NUNCHUK_DOWN; - } break; } case WPAD_EXP_CLASSIC: @@ -408,23 +396,14 @@ static void gx_input_poll(void *data) u8 rs_x = exp.classic.rjs.pos.x; u8 rs_y = exp.classic.rjs.pos.y; - if(ls_x > 40) - state |= GX_CLASSIC_LSTICK_RIGHT; - if(ls_x < 25) - state |= GX_CLASSIC_LSTICK_LEFT; - if(ls_y > 45) - state |= GX_CLASSIC_LSTICK_UP; - if(ls_y < 20) - state |= GX_CLASSIC_LSTICK_DOWN; - - if(rs_x > 40) - state |= GX_CLASSIC_RSTICK_RIGHT; - if(rs_x < 25) - state |= GX_CLASSIC_RSTICK_LEFT; - if(rs_y > 45) - state |= GX_CLASSIC_RSTICK_UP; - if(rs_y < 20) - state |= GX_CLASSIC_RSTICK_DOWN; + state |= (ls_x > 40) ? GX_CLASSIC_LSTICK_RIGHT : 0; + state |= (ls_x < 25) ? GX_CLASSIC_LSTICK_LEFT : 0; + state |= (ls_y > 45) ? GX_CLASSIC_LSTICK_UP : 0; + state |= (ls_y < 20) ? GX_CLASSIC_LSTICK_DOWN : 0; + state |= (rs_x > 40) ? GX_CLASSIC_RSTICK_RIGHT : 0; + state |= (rs_x < 25) ? GX_CLASSIC_RSTICK_LEFT: 0; + state |= (rs_y > 45) ? GX_CLASSIC_RSTICK_UP : 0; + state |= (rs_y < 20) ? GX_CLASSIC_RSTICK_DOWN : 0; } // do not return, fall through for wiimote d-pad } @@ -440,9 +419,7 @@ static void gx_input_poll(void *data) #endif if ((state & (GX_GC_LSTICK_UP | GX_GC_RSTICK_UP | GX_GC_L_TRIGGER | GX_GC_R_TRIGGER)) == (GX_GC_LSTICK_UP | GX_GC_RSTICK_UP | GX_GC_L_TRIGGER | GX_GC_R_TRIGGER)) - { state |= GX_WIIMOTE_HOME; - } if (quit_gc #ifdef HW_RVL diff --git a/gx/gx_video.c b/gx/gx_video.c index e2b0c1264c..90b260e323 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -220,7 +220,6 @@ static void gx_start(void) driver.video_data = gx_init(&video_info, NULL, NULL); - //gx_video_t *gx = (gx_video_t*)driver.video_data; VIDEO_Init(); GXRModeObj *mode = VIDEO_GetPreferredMode(NULL); setup_video_mode(mode); From 48480bc22f309d0b8936fc943c06a930c2663cc3 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Thu, 9 Aug 2012 06:29:33 +0200 Subject: [PATCH 120/492] (PS3/RGL) Cleanup --- console/rarch_console_settings.c | 2 +- console/rgl/ps3/rgl.cpp | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/console/rarch_console_settings.c b/console/rarch_console_settings.c index 097833a9e4..73130e563d 100644 --- a/console/rarch_console_settings.c +++ b/console/rarch_console_settings.c @@ -314,7 +314,7 @@ void rarch_settings_create_menu_item_label(char * str, unsigned setting, size_t #if defined(_XBOX360) #define DEFAULT_GAMMA 1 -#elif defined(GEKKO) +#else #define DEFAULT_GAMMA 0 #endif diff --git a/console/rgl/ps3/rgl.cpp b/console/rgl/ps3/rgl.cpp index 7fdffaba08..1c01020d31 100644 --- a/console/rgl/ps3/rgl.cpp +++ b/console/rgl/ps3/rgl.cpp @@ -1684,8 +1684,6 @@ GLAPI void APIENTRY glClear( GLbitfield mask ) if ( newmask ) { cellGcmSetScissorInline( &_RGLState.fifo, 0, 0, 4095, 4095); - cellGcmSetDepthTestEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); - cellGcmSetStencilTestEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); static float _RGLClearVertexBuffer[12] __attribute__((aligned(128))) = { @@ -4880,13 +4878,10 @@ void _RGLFifoGlSetRenderTarget( RGLRenderTargetEx const * const args ) grt->antialias = CELL_GCM_SURFACE_CENTER_1; - cellGcmSetAntiAliasingControlInline( &_RGLState.fifo, CELL_GCM_FALSE, CELL_GCM_FALSE, CELL_GCM_FALSE, 0xFFFF); - grt->type = CELL_GCM_SURFACE_PITCH; _RGLSetTarget( rt, args ); cellGcmSetSurfaceInline( &_RGLState.fifo, grt); - cellGcmSetDepthTestEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); } void _RGLSetError( GLenum error ) {} @@ -4973,7 +4968,6 @@ static GLuint _RGLValidateStates( void ) _RGLFifoWaitForFreeSpace( &_RGLState.fifo, 7 + 5 * conf.instructionCount ); cellGcmSetVertexProgramLoadInline( &_RGLState.fifo, &conf, vs->ucode); - cellGcmSetUserClipPlaneControlInline( &_RGLState.fifo, 0, 0, 0, 0, 0, 0 ); RGLInterpolantState *s = &_RGLState.state.interpolant; s->vertexProgramAttribMask = vs->header.vertexProgram.attributeOutputMask; From 90786687d414584e1990fd592d49d862df1d6b9f Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Thu, 9 Aug 2012 07:13:29 +0200 Subject: [PATCH 121/492] (RGL) Cleanup --- console/rgl/ps3/device_ctx.cpp | 21 --------------------- console/rgl/ps3/rgl.cpp | 2 -- 2 files changed, 23 deletions(-) diff --git a/console/rgl/ps3/device_ctx.cpp b/console/rgl/ps3/device_ctx.cpp index c70f21d4fa..1b3d2521a0 100644 --- a/console/rgl/ps3/device_ctx.cpp +++ b/console/rgl/ps3/device_ctx.cpp @@ -260,23 +260,7 @@ static GLboolean _RGLInitFromRM( RGLResource *rmResource ) cellGcmSetBlendEquationInline( &_RGLState.fifo, CELL_GCM_FUNC_ADD, CELL_GCM_FUNC_ADD ); cellGcmSetBlendFuncInline( &_RGLState.fifo, CELL_GCM_ONE, CELL_GCM_ZERO, CELL_GCM_ONE, CELL_GCM_ZERO ); cellGcmSetClearColorInline( &_RGLState.fifo, hwColor); - cellGcmSetAlphaTestEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); - cellGcmSetBlendEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); - cellGcmSetAlphaTestEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); - cellGcmSetBlendEnableMrtInline( &_RGLState.fifo, CELL_GCM_FALSE, CELL_GCM_FALSE, CELL_GCM_FALSE); - cellGcmSetLogicOpEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); - cellGcmSetCullFaceEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); - cellGcmSetCullFaceEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); - cellGcmSetDepthBoundsTestEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); - cellGcmSetDepthTestEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); - cellGcmSetPolygonOffsetFillEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); - cellGcmSetPolygonOffsetLineEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); - cellGcmSetRestartIndexEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); - cellGcmSetFragmentProgramGammaEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); cellGcmSetScissorInline( &_RGLState.fifo, 0, 0, 4095, 4095); - cellGcmSetStencilTestEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); - cellGcmSetTwoSidedStencilTestEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); - cellGcmSetTwoSideLightEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); cellGcmSetVertexAttribOutputMaskInline( &_RGLState.fifo, s->vertexProgramAttribMask & s->fragmentProgramAttribMask); cellGcmSetPointSpriteControlInline( &_RGLState.fifo, CELL_GCM_FALSE, 1, 0); @@ -1234,11 +1218,6 @@ GLAPI void psglSwap(void) cellGcmSetWaitFlip(); } - cellGcmSetPolySmoothEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); - cellGcmSetLineStippleEnableInline( &_RGLState.fifo, CELL_GCM_FALSE ); - cellGcmSetPolygonStippleEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); - cellGcmSetDepthBoundsTestEnable( &_RGLState.fifo, CELL_GCM_FALSE); - LContext->needValidate = PSGL_VALIDATE_ALL; for(int unit = 0; unit < MAX_TEXTURE_UNITS; unit++) diff --git a/console/rgl/ps3/rgl.cpp b/console/rgl/ps3/rgl.cpp index 1c01020d31..fe44fcc25a 100644 --- a/console/rgl/ps3/rgl.cpp +++ b/console/rgl/ps3/rgl.cpp @@ -1683,8 +1683,6 @@ GLAPI void APIENTRY glClear( GLbitfield mask ) if ( newmask ) { - cellGcmSetScissorInline( &_RGLState.fifo, 0, 0, 4095, 4095); - static float _RGLClearVertexBuffer[12] __attribute__((aligned(128))) = { -1.f, -1.f, 0.f, From ddf33463ece43efe17e7eb743f2b21db3e46292d Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Thu, 9 Aug 2012 07:29:56 +0200 Subject: [PATCH 122/492] (PSL1GHT) Add PSL1GHT ifdefs for input --- ps3/ps3_input.c | 27 +++++++++++++++++++++++++++ ps3/sdk_defines.h | 2 ++ 2 files changed, 29 insertions(+) diff --git a/ps3/ps3_input.c b/ps3/ps3_input.c index 6a59b79d19..a2b0a1159c 100644 --- a/ps3/ps3_input.c +++ b/ps3/ps3_input.c @@ -150,6 +150,32 @@ static void ps3_input_poll(void *data) if (state_tmp.len != 0) { state[i] = 0; +#ifdef __PSL1GHT__ + state[i] |= (state_tmp.BTN_LEFT) ? PS3_GAMEPAD_DPAD_LEFT : 0; + state[i] |= (state_tmp.BTN_DOWN) ? PS3_GAMEPAD_DPAD_DOWN : 0; + state[i] |= (state_tmp.BTN_RIGHT) ? PS3_GAMEPAD_DPAD_RIGHT : 0; + state[i] |= (state_tmp.BTN_UP) ? PS3_GAMEPAD_DPAD_UP : 0; + state[i] |= (state_tmp.BTN_START) ? PS3_GAMEPAD_START : 0; + state[i] |= (state_tmp.BTN_R3) ? PS3_GAMEPAD_R3 : 0; + state[i] |= (state_tmp.BTN_L3) ? PS3_GAMEPAD_L3 : 0; + state[i] |= (state_tmp.BTN_SELECT) ? PS3_GAMEPAD_SELECT : 0; + state[i] |= (state_tmp.BTN_TRIANGLE) ? PS3_GAMEPAD_TRIANGLE : 0; + state[i] |= (state_tmp.BTN_SQUARE) ? PS3_GAMEPAD_SQUARE : 0; + state[i] |= (state_tmp.BTN_CROSS) ? PS3_GAMEPAD_CROSS : 0; + state[i] |= (state_tmp.BTN_CIRCLE) ? PS3_GAMEPAD_CIRCLE : 0; + state[i] |= (state_tmp.BTN_R1) ? PS3_GAMEPAD_R1 : 0; + state[i] |= (state_tmp.BTN_L1) ? PS3_GAMEPAD_L1 : 0; + state[i] |= (state_tmp.BTN_R2) ? PS3_GAMEPAD_R2 : 0; + state[i] |= (state_tmp.BTN_L2) ? PS3_GAMEPAD_L2 : 0; + state[i] |= (state_tmp.ANA_L_H <= DEADZONE_LOW) ? PS3_GAMEPAD_LSTICK_LEFT_MASK : 0; + state[i] |= (state_tmp.ANA_L_H >= DEADZONE_HIGH) ? PS3_GAMEPAD_LSTICK_RIGHT_MASK : 0; + state[i] |= (state_tmp.ANA_L_V <= DEADZONE_LOW) ? PS3_GAMEPAD_LSTICK_UP_MASK : 0; + state[i] |= (state_tmp.ANA_L_V >= DEADZONE_HIGH) ? PS3_GAMEPAD_LSTICK_DOWN_MASK : 0; + state[i] |= (state_tmp.ANA_R_H <= DEADZONE_LOW) ? PS3_GAMEPAD_RSTICK_LEFT_MASK : 0; + state[i] |= (state_tmp.ANA_R_H >= DEADZONE_HIGH) ? PS3_GAMEPAD_RSTICK_RIGHT_MASK : 0; + state[i] |= (state_tmp.ANA_R_V <= DEADZONE_LOW) ? PS3_GAMEPAD_RSTICK_UP_MASK : 0; + state[i] |= (state_tmp.ANA_R_V >= DEADZONE_HIGH) ? PS3_GAMEPAD_RSTICK_DOWN_MASK : 0; +#else state[i] |= (state_tmp.button[CELL_PAD_BTN_OFFSET_DIGITAL1] & CELL_PAD_CTRL_LEFT) ? PS3_GAMEPAD_DPAD_LEFT : 0; state[i] |= (state_tmp.button[CELL_PAD_BTN_OFFSET_DIGITAL1] & CELL_PAD_CTRL_DOWN) ? PS3_GAMEPAD_DPAD_DOWN : 0; state[i] |= (state_tmp.button[CELL_PAD_BTN_OFFSET_DIGITAL1] & CELL_PAD_CTRL_RIGHT) ? PS3_GAMEPAD_DPAD_RIGHT : 0; @@ -174,6 +200,7 @@ static void ps3_input_poll(void *data) state[i] |= (state_tmp.button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X] >= DEADZONE_HIGH) ? PS3_GAMEPAD_RSTICK_RIGHT_MASK : 0; state[i] |= (state_tmp.button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y] <= DEADZONE_LOW) ? PS3_GAMEPAD_RSTICK_UP_MASK : 0; state[i] |= (state_tmp.button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y] >= DEADZONE_HIGH) ? PS3_GAMEPAD_RSTICK_DOWN_MASK : 0; +#endif } } diff --git a/ps3/sdk_defines.h b/ps3/sdk_defines.h index 72c5570d95..d258a327af 100644 --- a/ps3/sdk_defines.h +++ b/ps3/sdk_defines.h @@ -81,6 +81,8 @@ #define cellPadEnd ioPadEnd #define now_connect connected + +#define CELL_PAD_CTRL_LEFT BTN_LEFT #endif /*============================================================ From 9f2e1a816bc59c5cd7719237fda5ded24f1a2234 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Thu, 9 Aug 2012 07:30:42 +0200 Subject: [PATCH 123/492] (PSL1GHT) Minor cleanup --- ps3/sdk_defines.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/ps3/sdk_defines.h b/ps3/sdk_defines.h index d258a327af..72c5570d95 100644 --- a/ps3/sdk_defines.h +++ b/ps3/sdk_defines.h @@ -81,8 +81,6 @@ #define cellPadEnd ioPadEnd #define now_connect connected - -#define CELL_PAD_CTRL_LEFT BTN_LEFT #endif /*============================================================ From abebe492af107334002bc646068107798b4fcbca Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Thu, 9 Aug 2012 07:39:32 +0200 Subject: [PATCH 124/492] (PSL1GHT) Added some PSL1GHT GCM Defines --- ps3/sdk_defines.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ps3/sdk_defines.h b/ps3/sdk_defines.h index 72c5570d95..0b6d455519 100644 --- a/ps3/sdk_defines.h +++ b/ps3/sdk_defines.h @@ -363,6 +363,11 @@ #define CELL_GCM_FUNC_ADD GCM_FUNC_ADD +#define CELL_GCM_SMOOTH (0x1D01) +#define CELL_GCM_DEBUG_LEVEL2 2 + +#define CELL_GCM_COMPMODE_DISABLED 0 + #define CELL_RESC_720x480 RESC_720x480 #define CELL_RESC_720x576 RESC_720x576 #define CELL_RESC_1280x720 RESC_1280x720 From 80eb46a51c40215cb7fad0f18c51bc983a7bd8c1 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Thu, 9 Aug 2012 07:44:09 +0200 Subject: [PATCH 125/492] (Xbox 1) Remove Arial.ttf font --- xbox1/Media/arial.ttf | Bin 65692 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 xbox1/Media/arial.ttf diff --git a/xbox1/Media/arial.ttf b/xbox1/Media/arial.ttf deleted file mode 100644 index 25769bbf1b0751c727fcab04da0f84fa517ec61f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65692 zcmeFad3Y4n)-SyGuBx8rxjUUscZSXcWS$_9l1ZjOm{ps$D}@?b>^- zwb%NswJU@YLaZPnsU9$FXrJ$s=5HW`eS*Db1`W;1tuKGzE<%K6Y!4jKvwYNrEiGv{ zSwo0>*7zCYW(_@ja6cgt1AbFKe%_qmg1_HaLrC0wLZsU#&6+%8{8>#AA;Dj;ZJK=Z zf=Ts{mf>1q{C>xrDHCSQfBX5Bvj{o9h!Ce{%EWOKc8+>`C?Q`j!~F`UV23%Z7O;H~ z+sRXA%$fh<-12eQK7%^Vnm%#%Ey7H;i;(XsaQ{^|&m2Fl`vvc(git@0gEPj>pCvpj zR1@<3C-{BvmT@yC_G!MUGq!ns9+@?>cFqUgmu@BG;sZGUyIHd*&Ki2Y(^Nt()e)k` zbCbgM?*j5R-N;S|JH##G5s69Nq^;6tDvzp*s#0~Y+N++bF=_T_`)R+|tG=lA5IPL zO6{EbZdz5^!Sru324)=3e59kT;}4zAWF5-xmOUZ+TuxR_dCugVBeseR-ec{g`jh&&=Hv=ea(w_Pwd^!+l@rm)CDV zzm5Gn446EiZom@*S_b^H+)$oXUS2+_d}aAF<$o*xd>|R<8CW!M_`qcYe;!mc=(a)I z2E8)q^9papV}oxTeCyx`2LEG7)sV>0(xFcbiy!vE@ViFbKH{+v;7EKvQ&UQxQ>j#v z1fo)_`QNpVntxO@MKa)H^LO)0s=0of-)56G`V*F)*JJy?clqN@aFlWLoIKn$QpVgxlQ)J#k$TZkFd3VMauh!xaMY@iNe2X%s8 zCNAOtbrUD32lO}MC2o{`#EWtq@qzjk8c*U-4iJCzSCXL6Ac;pgL=r#~Nf0y%^cRv$ zLZB%m5i|_?Gf5>$plKu-G@XP&GZdOhQlpnh2a*QbQK6kk2Fh6^6EvH21kC~ciR6+_ zpm`(sP#!>ff|irs z(I3b_g$^Ruqg+AyfDR^oqu-Mu3LQ%Np*)QAkG7KGq#SgFLPwH;D32n8qTi89QUN*| zw3XaI2BSQN3`DMbDDkNe$={G8?px)PgQ0 zb3pGPbEE$tcanLa%M`kt+=}uFG9Pp$SrGk_tRf3R?;^K>t|p5>*O0}aYZZDoxgF(u z$P&23F=mQE}PnM&+fvk+4CJ&NTC_e;xnmkPI0^LYf zM^BMQ$QsZ`$y(6I6#6*12jxv<9q49K54r{PbMgea7xYPTALvu$e$c1M1JTdOGh}`A zQ}Qg?0J@bt2)a$7+sQ*HKSv%0eV#l5x>*D^KOuV+`XYG>25AC)lk5R~i|hq`o4g2m zlr)3BL-v6lQ|P;7Kg#csgP`w|m!ikXanSe42jp*{ACg0$ACZ>mdjxd>{e&C_JwaXp zJxPv$eyY&V$lp=^oV*Hpio6zmmz-AU8S+N-82N&{3Hl{@3-lifJxkt3`5ZY4dY-%k z`W1OM`VRS8q2G}AQ2v&@A3aL`Nsfblr_fgN0m|Q#kD_mrAIQg`7Zmz0@(IfSCMQ6D zBqu>HD)cAvS@bP(iF^+FGdTtN3+S8VS8^KkH*yB_GWi1ZibC7SKca7t2ssNHCFel@ z(&_*2>-2y9U#`>t`QO&*-~2Ch`ZxbYr+@wbiBA8=UpoE2t3`Yj|39(Q z|L@i5f7$8(eLMXxozCs_*I}*yWvBmzz5Io}{GY>K&i@zeS$-jWz+(-a-T{M{({*$l`wDq8{L` zOUQEJIDWMp2!0~a=n9~(chdpUxxjr-i+2Ls9sm!17Ojhpiry2wFZvXa#eKr-K=$=O z>Br-HH2S^t39!bF_{DnQm#67{+C4zGM?%W?36BB0-6&LvG&&jhy#T!aR@6ZRUVW6d zuuNQiBKeAX=pvy9uJUBGA$kO7`GGf20SdaG7SQWiNE#C@2Ri1$J?7)84+D?fi*GYf z#go(^U5Gvf1l$WGzb~GriM&Hwgh<=cNEzBqLMx>MmG6t^`WtzTyi1el%WS4(ka8ti zS_o{=0gQh*YWpmHd7l2vZpU|t@T%B5+8yzX<BQeT=+Jjd;=^t)+L+kLW*G z4>p!P!oCz95Vwi%tHAmz}dX&CPzh>95VQf14 zL6{=c2rr4<@f|AGig!vYq&2FqBcmcmBJV|hj^;*J0Qp}8bo*ZP$>VskeLzJ|;Cq^U zNhPYMCVYc5M2FMc@V%YhO`o7!={DMgySz)kq~Fkg)1T;NM(|a!I2K}w_$IO0>{j*w zdz2l+_g(fK`&DoYi9)7OAe0J~!c5d^rBILW9^nhoCms`{Xy;sMgR}_|)90ka(gl@4 zeFs8GZ(n(`Eu-yJghWl_T%uKhW_3Fj@wC&Qv=%0M>A+Q zIsh#*mQJHJbUs>g8Qn;qR_gu&J&0ENnErq|8<}6Jb0=27y0by}-pD4h8dlHlV@>QM z_M4y<^nzJ%3K_!nLX|L4m?JC@HV6&E+rsC#4f0Eh}%&r6<;B(;z2yyJGk=JdkdOUKmDm=`TW*2y7s@ zs7T;ZlIh3~XoVcFA`j9D;$)1xd2|s_?q?ts>C!E#43(3f`g_)#z#Vny+fK* z!&o!oQA92)>(;fjOXrf}qJsRq+??#JP8~aBW~8U3hEtN05<|g+K)gTB=k>TY-m-=o!3J6#?A6eF-jvn7s(W_qKzHeNJ(7A%)OGAYcIose>QQQNC(YVL z-QB2CVD4U>cQK+d;t?BsNj-Ztc$4r`Tt-OgHEu#f#o$rBdd7u9l^r`Y&>rKHZfYP& z-5boA$|Eu4f2y$uU;8!*gSaDAATDb;#a7w#5M3+meRX= zb#L5yEqbc|&>-%{mRF8ypv!T~Ab%46RI%rqnAD5!sh$>W&?a?HnzDLYHM+*Px`7N? z5ZdkY$@>tj^Ysd@9yTf|)KC_eR5`Avf0u)-9f0cLqs9kOlTk@{reaPe7L(QEi_ro2R8st^VFG$& zYJ;{%^=eCJz8{ZB8>AFVQgHQ81RRjm`rV)RjBDScO0oPz_(9Gm*I2EAj=NfJ$jofW z$lxrZ?twl<9lI&p1syxgYi3DFvn)ZZ(0rriT~; zJTZ2>|InoVgGY}F_F7%t&b9rA{b?(9oHr=i4aeF`4fYV93&Cv_|SIX-5pS3?mL+8x) zipHwl(B)6tf2y8gwa|YUR1WJuZ1n2Yx<4L6gF>ZoV+jc*0#TFhO^lvZshiouvYklc zS%K)(;#o?(8kKaG2?sFE9Bxouy*2loYEvQ=ycx zAhJ>3(&_X|Lt7s5WM<-KRi)*YR?FG5ZD-F~z9(g6<(9Vd{fCZflte<52p7ojfpAwQgied zIT%jQ*Q<1D2}v;o2|D`kwHl2eFrwC!>gu#q+Z=6?oknxM_7oMwQbuK?HJ^G7HP3o@ z{W5uLSlTkH&=hDCUZb{B5NfrRl<*}dn`UO(dF6yWh1TaD?f7}l(QKiSx-VRad=sO* zmd@x`Vx@E(*)Rz-Q@$fDzBrzZG{0zn(f^wLHUBU1D$1NhD+&&xl~h)OA<9CudbK4^ zXHZ)_Mzh-DHrZ5Gx5+Lz+$I-ux=mi@^ca228K?6LjyPSs;P4m&Dyzqspt8p4ba8Ph zMC%|#YxHoALrhDaLlgVh*>9i!y<8ix*&gpPiE!|8=SrS+` z;(5U6e!!SwlC33!Oq)#1G&iJsAWr)Lu8VftV=W0nh@07##^AOooP(+|ThCg~URz(} zO$CkuZEw6-6I$BPiq?`W(3MiB%*B=?D?54k%KRT6v~E?6+n!XAXAc#G?0EuT@|;OR z$Qcrn>>m%#eM@G=?krAwnPKTuQjdm36s_T$XltYT?Q90P5urRB4Xn3e1tEzCC zFg|OcaBHYG>$bv`p}MSl3e7pq(Niz#O9H`Qa(;*A=oz^~Fe!hUrZ~f8C zbGsc9$!MlUyQwZ0dz;daQ=@-BEyk%2?JlSdbEehVO0vUpxGpS&o7oWAoZ)i26B2^K z;^N%g^mP3Ce%VFPotc?AIeNWLmkn30j=T#gZe|8qD|M=!X<1@nmi_b|qN2sJxl9@) zEs@qqqU0@kZH>bIRpqT0Yg)OOa?Wr6LLmP5y@*b~*ha5k~ zE?H^nl)2KhSn1rHY)_8`a=%cK!JeFwl#-YtsBB@A*=S~}qENvgnwJLB!QN>Q$u@u# zrW6mNpAG zmRjU;yWG}rYB*ewUsPBGdF4CQ;c%+eW0Q?kByn<*>9ORYE_3}(@MU7Y1-5UlW&_g^{#RE9&fUaJiIpX-k#NZ z*424k_V$}wZmqD57-25I={f(j8e7}1iT0Ff_YFVrn|7}%&9bU$%%YSwm+{fsn{Lg5 z?z}bnrfL&3gC0J89J1W>89Z;?ojnZV049YNrH}odjZ{h6L)8KrDJ&0&%E82=6xjQTmS;meMMFeqmlN zEO%8>VwfiK?#avLy(7>(O8*zfZhd^i>OC*6SiXyv^r#%&y(bnS@xCix&~uMJhyyEe zpflgut8%nB`mxXcerW$2uhPHIdF1ZeIUDb({jFA|{q<*h&*Pu+1Fz8|a~@echaZ5J z7!^GwrJ|n_fEN_fF7m4jowHrD-3vP{%v#}kChK#e*%1Gvi`|uVXCb@OzbwR>T(sIf zF2rQlG{UwAPP$mFzc!xD_05iBbIENkw%UDX9NXr6!Nu+jtPZl(x;y>st>CMv?5OK- z9NX`E)xo9~?su`N?umJ9Vip~dH>QyF&KsS;%3a;#ShlYufraCegN$_S80gqZrz3GL zSG+Umas`9?bsZf#UB_^`h32ORIt%)^74b{s-e+aFII6yaQ0$r6;>#pC1qz@%UZc~o1nVY zrqY!rzOs}m1+KdP>xZ=ON>QOlQz46mMO-3doh;G9BDYG-#gZyAn56W$nm%jHvWY?%UX)TLZ+_0{C z%9e=`iqROnQx$t6EIWyWRNC(u5tasNJrZiCskm*xTZELwgoB$X+yGeBNg4KSKm8Q> z9#>fu8O*A|Ef!KD>r%~>SZr#I#nMdk8p$S;25Z@<-ekHlC{W>f>tkz`i?&_jVu;bQ z45k;YqG4v``YMlS6|0;UN>8tUr+oCmr3+HKCP7jngAdYQsOkHYZI|DzT)pAIOOb>K z7wi7Gcb0PRBH56}(kx7?vruBw^1JIc36$SmM>YvJnx41CZv7v3wkHv5ekv4ZY92JD z)56~7>NK%y>cXW5N0%Q%#_<{Y#ld|WR*!!Fa@)!8Bma(Qa9>#%&pyO`J>)j|I-S;F zGFy-vt*6Yx-ETD!1&!NgL`Jm49dgAVhdb^N)q;lVRFa+$OVB|bhg1^LKMezAy=;`8 zCbHF@PrTk)Xd-Ttm0xTF^Od$$mBNI;0E0g$DP_%9=niOm)LW&##!sm#bt+g*?zE|o zo!%=rCNJ-_WMS8t^E(gfS3GY{?ox5bJ;mvJdX8V8-{GDNQ^Bg?gI3+$Z}_@SUOdxm z;4+=Xz0l6Zass(U%YM}ew@7N0_7-vwV8z00u`(K|q3gEOb&;A@df!&Q-Ws_D_t_pfMehWrsv`sU=wQ4*hv%=5 z!;0lhb+nY|7&xVrsEXB{2LW%I3G`$$Mvu*UZcXF97tdO7Uzl2)!mN(z?wssAFek>h z)WX7|y+n~RML@%%76S}ifj;YMW@bP|`K%uFXAE4I}~MtP<0e!~?QvYx*Z ztx^jlGoEZ~QU$#hKisn2EU5n*AORN^8x}Lnx{)i{D*Y<+8zxb!)_Yhl`v7M@Z;!ZP z_A$;e-XU?*)zkIk?KeB8d#mFXuzC80=7-c9EN^&DvX4|B=|44ld;w8%1dK*^tyT^t zI&Zer_m^v(H=TdD+dMc0ZkW|uyyQVjrhDswL~Q`K`T)M zqi^bzs@wRp5E{g9eFjN}`vhkz_C(nd4FZs7l2^Z;9d?golk-Df3 zNQYDh)URpY@T>b8Dh0h+7IE&vBZwXjbe?wqF zjZW2It&LugeF2?Cqf));_c{E2pT_S4pJ{x4!5FZ>I&U0grPgNZ*<%dA5)U-91G1Si zgRa(n9QENnNe{54BuFeUoDJ4JWe5PwWJ{RH_OoQzU+Z?o`jgvKnVd1Xx+*PeZHrmN zinh8saB}+!5_Pqgi%Au&nw{bdg^SQ4SBF6^yfH%v!+=UHs;?9=cgm9+f7tr)ZFf9M z_t}4W@A#!Y&mMkaOkl^3>q^JB+q6;mV zNsh{ClF?=CWn5ttds#$IVQN~8W%WL7*{*)ihJ6qlY#>GZ}fVD(Il#A zlFOXiyfdmBx8hsVlX&G4|ip}Y>J%V4EQB6kZ!cqjt$NXvS6LMHmq=en1<^+ zdYWnRZtro*-5CO=(f=+69h&KV?JdWB3Pl!Rb|~V|24A8i3rdYQVNBnHe;^rPAzA~C z&t(CYA!MQGT2WDYTxPib}i`oI>8ziOp=%i;|?1;}i0A@B?8e$cah$>bg*Yy50=k*dl9%m#u2mZCyDErSW+pHT%XxU%kTSSpm*8jf)+#B1`7Xv>Y_uByu6>x|b85G(#E5)* zS)W%TBz7zj#Q6A9ZhBXuRdJ5&Fv$86LtRCQK@OJ~68%_rEa4|)Rss?#pm|n!<5s~+ z*@m`d?6Lb_eYGi4K*v5U?7hBtrc#QL`BU=^-$L((&l;Indkf8T=m)$tqb&)Q!x zd}R1EPNTJZOc_2wn=NJQ_d`epFr3A%bK30oH%(@T$?kxQ2(FXuCSAZOn>GW9Fqvg1 zbvpev2HotAJiqapY>HrcXWiIxw=OgpR zL@vGe+P%Ba@R6$=?dXL3#sjH%UQV6vr9IWMv!}ObaI|e$aJn!-JwY?gHX%4iGuOXd zv%>$8<^z{i4FPUS4JHLcT#~J60ohn#WJaSSjvgP&TMa_1l>%{6V!&aIW8E{|OWdNnnI$)7wvSt_?Xub~s)~qaRq-KAX%H@=YM7FI zoPtq?mast}(GtXJDZ-YEI(`>lm2kPy)1mM55!VgBiCuSaa#P!_?=Jfya`v&izTWY9 zThX9<2F`x!iQ5)#7l)drWtV4n`~I`>)sdgyU)_2;;%bZNwwJdazVdn1_R8kRAKJN- zj~?S7r7pzhjbxT=I%1?E{+LG8LISyB&t_EA8jQ671^ELHQdGIXd}d9p_Mc=B0+eH! zP=?h^x&%Y17xJbkDQ@Z2l$Kv?9mw?*$1x#s(DEf#Mc(l2-~-r5Dk7-VNrg6B(Kunx z+DL2vLi0Z1jvwz5f7`KkeZ&^I-2CYd`YnC!QI6OSMgMxyzi!Nd%O)q}q5>C9clCAk z4WBoBlPzhp5!+i#7m0H;HTv0xxyFU=HDoniE3VKi)h{!wFy8Hc+xn{AmWYnt?GO6+ zDj3Y-tBygSMrY(edeA@u9%6_KblTjBcCv*6Dk&{sGX`o8aWs@omi3vnW*Kl+wwaon z>Aib%J+%!mJaK4ua;@{~I3IM%PUfu7xn{X2{vnK)s|wpzQkB)(u6x=UA;t`|YhXV9 z?)6<$%mjX*{i=fx*H8E(Q_yL%Za#mg<=g2qR^A=CbmBzh(!DpWm_B9sU6UrS>fE<} z=+dn_?pX4y5SRYYw9O|^Z=UpEdWR#c4n~0@x2$`a4x6&<&avZHF1r#fuOIYG-5uMv zLYBBr;%yy(EH%sdoqYpba?%a1kx7$;n_V+}lam(u76;b))&w@Xw)qbFzIB}sUJBZ~ zx*m7!a0#8$C#YB|S5`@ARZl3W3Z?}HnZ|O>us#Uf!YyDNRx;6-Mxw@u$u8I|@;#Rma@O5Ja`Ker>um()#LY$MEh+)dd z!*<_!)(+RAaYGkZ6w<;2GxlDg>Q~pb-nQ^xPdtB;z4i2*`Mb9*TD*l0wJf}4z>-g9 z89XDVQ_Ux*sbyp2AMowIiZs4(NXUO=?~zB>a;aj-Lm+eoGG2I;p;!)z5>ctOOjRlh zrBo%t`p?4jNESpJY|*s)CpBC`V52L;k%FDux!a6o9~=Rp^61ek&%z;KF;7UjHu5&) ztXln@`up`y>M!Ww71FS-NY`68LN`&jNB5;pt=E~<{GRGk%&awu`sXlSR>(Te_8QY(&n; z%ZHl#E2W=i6t3B zZ3U5HPpo<_Ce7Y`S5biH(MhBR~0P+gr_q8hR}%g5q&F1O!Q1lnUp@y zw=jNo@^a5I-`e;!p_O5`$x>k=!caaO>ddLx`U*YMt6c|JAJT*LX9t>kbQW|8+|cSw zgPF53S>}FPPEy%{#;iWc2rk|!n=KXHNV09SIXT-hO9?7$L#*QQrn2IUWSp!eN$ha| z&IPo?*>UvS$l?z_r1$?sRrID&d-8sXZ2#A($X$_N zdJLPekiJaiU+9|IYo^Ih_P=4uCrdZcvduSCJ<>LA ztvN2WYXvo~dzL1?@M&c7w?9Q5-_~&Z)RRkQpIiUZrx!n`W*U6!jU8`APJQuaMyi(% zxa*-F%ifx_YQuH)?|`q7p+}@jX+LDyL<92pEK9a!vSy05+OkThx4a>}s%o)Zu;?{X zB{JG7EK~FimLCm28hrctTY29z~O-2&(mR2v-F!2}^F8XP!7 z8;~STKqVkPHA~hKjo}*^4hGv#^%zF=vds`A6V<|y3S@(w7KM7~(Pm0zeTAV#ecB+@ z8>oSATg>WXYPLjOr)KK=%^!WNKvOkd7)$u`pmTj*OKU6fl$H9>+0Zli`*Rdf86Ti@ zR$7i6F&#OwQi`o1TKyaJL;E)b5ch8q&4Na~AKpBoz1*&-q_bLOX#Bb2PR>i7bA`k4H zG$LtIQmuBGR+{RYE6vhk0Fv(1t5RKB!IPR1aK&r2c3U7LBR!q?;{#};gh0SbG@h_( zSW4L7>kuCZDyqCHv&$F-*MV6G-G*QqMi~wSV1W|>^#KIa%HzmX!7aHj3y|;+{;G*3 z(NJy-1_&oX0p}Je+>7!C7T)?+?WD=e*Nv=ud2Qr=+I4Ahzy7`Ncs%kcopEEh$LP+( z)~}81koH&Zn|R|hd8r5MChw}w5r$Y@lgj(fOuxKYZ781Jd&mN$p;0m^`js>fx-%YL z#qjZLT0BPXT;q6*Wpm=|$g=o)vQc_Yc-pv6XfnQLe3zV!|1sWbvc+5D!9=^WvmB2ACK&9=t2QFz$2(Z7{G#kN{MG}$zzba!V&Qt;Av`RE)C+3_@H$ z)LO#kek2@3c7QLz9S&-!#v2%qmQ%n~J__vJMq%OU{F! zBc2CU%T)oyyija9+%@vbxz@}6j< zyrsRb1HbomEI82K(K*?OcoqtAYK=-GX+({v@_Kw8rqb&SI-?GH%;j*|U4kl3aEGYP z1me;7L)4|Sh7b}1=AMBMLSdXS5V8dP=U`xqlu&LvJOsZg^f>+XxzV>*&Z!-^@ZO`# zBM5!n`*cpP@&|7oxFhnmwBH#&;HJp2BhN-6+s5VYD9q{g%`@kJ&Is_He*)akvy}DZ z2HB~S0ve54O$3p1wN4w*6Aiq_7TIsH<*SDY{errnk?DL!QQQ91hAub6`iUn>C_Q!Y zZ03J5InZ7O`sVO=$oYhreC2T=^U8<9GHL&gNZIod;|^XEm=fZ0)I>}A%Na^d)*%3O zwKAy4qd_3FjQRA}?ylo)&bj2;-4PgQmoCJtdHTxlcit*|e&rl%Xsh6N?YyIH67D$z ze7_HTpF-Y~xj^cfcgTOVUyrPEARM;eu+URx^Rku1lq< z@!_D3>b&9c?d?$BT5hSj#PeE^;s7C6xRwjMvdKjq3rGCG6+OkIIKR*D^$RLP*plK5 zCxkUANJC8V7~@04WwwWKvcn!!V=GZg2~ocu?BTG21hk$j?{5AivZ<+&R(!gN()+?YLpSZ6x%}|0 zq2iU4-Fy3mZmjHi+ID7k?LK$pw(^Gy{lt7i7~wfLJ&j%sHzS@My8Lk5oa+c&LvfbppgavPgEOc z8O1J@9tb)>EuMaZR^>ek-YP4FYl%G=5HbNkAwMb4ngqJ#F#GNB;Wm}DzwH?|`nTS! zv8^1nIt1ogidsR_@1aP5WE`t*Ebgjc){S}jv31An*g7pewoXzKh*}!s1F>z7Pg%=3 zMoWHBs+V@+^*TX}qU#WYX&_=2fcy#o=@*EESauM*>yc^kg!mC20qOu)+U`1xqE(eO zvk|zu+D#m!<1CtIJ#?6lOsH*9^ebT;YHKCsvSlKhteV5-s#Y0SSyfsFhtVg8#DH0= z4eNB8u)Zp2r$Iz=E9}*F(N4ppziqE_!&XaG%_Tmvg8f=?3pflhgtV{#H&d{eaF?Cx zS>yXoOFLZo@*OW9rJFrl7xk#UUHJDEZ}XeePH~CE$S4ir{YjV0IYMGliALKwRac-Y z)LpL|DXb7a7S!`}CxjC^Ax&Bs%yN)UjI zo@vCkrhP5)b$lov>y}2Fi|;=rclF{!1VAonptPrj4;GzsX=Oy&LE$qpN8+#XRB!tW=VrufX%uBkajSL zhpaMm*{awm@UUxOjw0U$;WGs9%0T!6;pO%T4{~GeQBYI_a!WO(utz+wN8(_Q>?30I zlj2IwlCcj*Pp#TSJV^&{iO844xDs&Qsl6@~T_r01pn6-0CecwM%8nBL;CoU~bjI-2 z*i|aIbkmyIRip+?!x@E!DE`#e4Tsq$RNeM4yCX{4E?of6r?ZdSUbylQJO6D&Z0|iW z1HC7aJlQ}QuW~=b5T4iHqlPOzb=uf5rES@cCP}CTPn1@gqR;Naz)#>#{qse3;8ZE1~ z)!CSBKidl6HfOgKMEE>M))}INyqqx^l6Ss)iM0>UV4O zCA>Q8GGa>~!Ce1HF-H407{D263TGIjzw9#UxQW^hyMM4ZRATB7QlR&}MJ1-(BBi*e zBlfn#>zS1>XVK}X}7871w%{O^1FR6HVF z`K`D3*5v~6%w^uO02CE%tR>&>vgx^sEr5#EaC={^f$(VHh6)-jUN5FqYeXRk{G=+V zr$Kms)%scbI=!UVV3=0|eg^zfVHO>4J}9(IMI+bnT(6i)R@^n%>>`rAcrU6WIROu0+r}OT{Hmd6ex9l4wjna;^47ZN8k9LpsjPQ+&TjPG1S-b&3um$v5 zXP9Tl`09``V-E9{@%sO0vBClXknx8wZjIf-T~ThlDMNCR1vnitEEo({GM=uYg>TW` z&oxE%9y%7;zx8z*|M90ZZoxPAz7zSFy-8=##|}rH{_J#Q^Pbn~=)XmNjvS-;G_H~A z?~k10*axgtu?@0mMCQdvxnQDox`Xw%^mp7~xxpdo4FSj+aeKH?M>Mvu#uxNa{P{e_ zb{*jTT?Y)b)KtM$xn@Vj2HJMdL`junp^z2EsFEeeZBLedU-`}VRem3NBeII#cJT44 z0XfSecS-wAwuyUZ9Eh~FJulF;OUB&kM92#{RQE{Vqy3#Ejf(Q}vEfZ&=JgagS%%cn zof+;TmAX5J2S@|leZy7K@T5`UnbK{-LTRnAR$7k*?$7mC!4xe|Usuly$gsw10H`h=h^Bk%?2KNzUov z+rszw?+JhE`7G=Orv1V0xDqh>2XfcA5+=CP1a(^2;{v7$U(zQrzConqK)@_8O>#i3 z^@Z*Im@k-7m%%bZVMvYMoBrqiM__>Wzv8j98-4B)V$HL>p@53;U;ry3aydJN=R2jU z{$QtZCc)mqcJ8opRw)Xnia)KKUGn&2PyYS2$ibZrwAUM)V{U0XzjelQV3ZS)FKOIo zQ^wpd@v*ARl_j^`&_c(YJV7Vye>w8>$vu(NcV|^SN=uMXdVl2O2u_Z?liJ0L{@^wn zoJ8675YafOw!Cq5N*xTFB@&Xe5@}tCZ^^CsQ$7sJ~iLczBae7ar~3U z_;Bnv&R33O&5z5qD5RMB`TGTj>c{wJ_-AY9n--Xt>sFZ`G;T9Do4+=FWww|MhM?8# zuv*Plvq5XaJT;$7rvi>`G)Nw;*5&qj1ISMfB`Q4Z@tDmfO(1M~R8p- z+IcyNkLOpN0$7dSvmSJXqRQJ{0}l9>WGQJwvGi0P!Gp@WW|w8gqMtgAY%VcdI$Ld> zF$`DI8byDbFmU_4B~~ag8y1u7FR@?{wFaNF!j0wyTp_P$!Sz#=yp1u4VEhx_OE&pM-Z)+uFV+fkL@_0`Kq&F|5c;YI#P>?*ncO>d zs8FdM6F)NTF1sns7*1x%LTXB(IX|gqO0TTZ!4XNrQ*PEzGfp>6a!m9r&@VJDG%vQy zO|DH@A*|NlWn68(+p;|Q&XoI%8_XM=fs|yEQ7?ty3&&v+73NUk<(tWg*aw#_uH!mr zl~&B}4AKf(O=lrvPJ-3iASZSV1YCj?=%|eg`}%3a>Au`h*ha&MT5{!?bIpC?@ZUA8 z1P(tB_+z=qGrQpY!+B~4OO)^j0{;O9M<%9=fcXLRQ!*vEP;o54>2SLM0P+L?E@I&^ zFB-?bzIf*Lp%r7gL~b5Db@J{1e&ESpS4jKKJGM1!DJiBWM%67`arv>=B0oM%KepU* z_sH(GJ$p?~a*xX_dUE2-mnTepd#P#7JxgyGl$SR>t;?QybC1=|`38@W4Gp{>a-=4M zkh8`DXc)Mxm}G{ST5Y3Zc2WAGDo9xt52jJNhbrb5KdRaLa118mo-8t_tIl(~Bc_3s z2^a_?B5}+fi5FK#;w0ma9l!lZaL+9m%Mx)<2dR;DVe=?)l;#bM=;A}Y3j=n(*hSM@ z?5CM$en$G*tTqs4#wfL>B%E?E1h*4%0 z_h{ix#0E4aEfMm8(0}_-rg#)e{MIT~AD$4o{J}es-)0@Ye#hdE_DcJ&?D{-%<;i=f z@f%^#mEDK-+;mvU;)0h?q~55zj{G3^$dYIVNfT0ZS%z#wwc#$!UD|p>i{XMnA2d`L z07Phm8p#3I5iV4aNe;#&EoIU-K^<(vi5fbQ!F)z4Nm@yThSq87HP{9eX=HL*$yi3$ zVdf=+T}WkXP^yqvHtfNA_y!m7iq>Yfs!?AJjlpfg8lI@c7Y`4%Kxz2AtpFL6bmY*xOOM>}EV!HdG|9O9sqcqEM`;Pg10PLIu?)drk46m3?6*&MW39Ttn#rZs3h zPRVSwfTJX*K@vO`Gh9-Q21$d=W3wTqqVc)iKFf7lI+z5B0n~{_M)+s&-e3?opV!+= z*X(N7(>`x`8_e%EpSR63u-C+%=dWq&tL8UX)ew9x{K^75vs|$=`Mip;5= zrnw!MGoT?AUQ_&d12POGCo_{5B%Yn#SscN?)@&<&V?7{W_OcqYH z`6A!_xTZ;X0cL5{+Tg_NFF(oUnaf09^tYW2mXo0!({1VYVp=2=Yl^kS#?Gb!TajI7 zvvYsi#)+xjiAD;K;#B|9xt3qY38Lb9b8;)aRnNj=x;jmtVG7#{#m<_}dVa+|nqgv< zW{iHcX_##?ohVMzOxI5}O|;Dw7i#!eaI5WB`wDTjdbMu7*sOWc_Nw@X=40^_%?Z;- zwy(smHD8;~+d6>Zv|7q%)Cziw#f~|)MryGbtw`X3N3LZ?yi0wA-8QU(+&9Y9_ zBwH#h$1DP}s>jN@An`h!heKSNGY4MeY*pns=WVTOtwKTJEbiWNri#&((x149=kVZT zHgm=))hPUPbrs_y#Ylkei#g|++{M|4cPGP<_m)s@3wYv6U<;jsHEEBnfNOlcHx6EY zTnV3Qw%gA=y%ssaUt)*dAYd_?T<%i4&E*E%fs!Di1aIw>+zDo5qOC-4h!1t8BtBHC z*YOhLC4=3KeRenY@e)JnYMo;1YgNQ13>R919N24W=PJKySy9CB71a$*%IQH$tDy;FNnYi4t>(-Q4pU`nluKjLEMiQMhnr4N}dz61CLdLDP*mJ{D33S|EG3&Iiyn=>lo0G z_4lr@vMz0JeMdtTy}I8>{a?1d$Yu!Tk=~0I)z;IUR~p;y=k1*i+oAz_!9dRMvO(xu zP9K z-J)Rr$bzat!n@@Pq$?KPLe`^XQ)*#h*FATWIeBWY)Z_+LOOo?bi`OiFkuAz4$t!S!x z@cLg*tmm!%dsg}YIhj(J_yo&CFhPLrZieeLPhiO81Y-hP<_YP@Mt>1W>GWzodMw-* zGar6WN0-p~bX#QPy>x3VA)S)c$W+>-JVn0j7o|+K$|B&ED%6Ho-c$C1D5R*#^V&!F zL@i}P!GAmf4HW?KC$# zWW@|5gzPPfL0E(QZhI{H`olgt?p`{6&(FAd=*np}9Bmo>B7(O_ME;3}@&SuPVvtY5 zw1OVjaXxBKI?2fv(BTQ6lNr&;9(U{^^?Dpm}*=)_{cvK@cIIJW) zUEcf(S|Ko5KspWA4J#SmvBQS$rYn%KR^7~6eZ@WStF~8IwC==%e)mmBW{%07F?Grl;rKg;_kM2qz@-Bn zCZjJoMR!Zbu9Y>Onl=69as4{Yzi@eZ*JAp4n%|OEp4F%NhCy9#Mc=JJ-|_eppV#rO z{0x;0=47cr>Lp2K2@MG>Apr>h{_g%+3H1r8&h}DQDN_Ch_^LGMPS=gTX_}jjx43Tc zwIrM{oOGY`erf;C{hjw8@n;gE3GSejWzKSBOJ!zR8ep!FCP^pbe-eMQ7%Wbci0STe ze%OCHr{ARaB)_XiRzx)bR6#!nU?j;CQW$HY@P#+i26};t3CLO+Lw#nq0wWwQJIn$5F1izW|JCBlgP6oSr(I3El6We#Uyavu(9kS+VR<@*}HDqStCdO z{nEkdEPwdD^PYct?!4y_7x-!2pmlH7Mt+EV^cdZ6X!x3=Z@v5KQOH+C^lPCNobDs9 z$UU?M+QZ(%J=8wbU2U&+Kf)dnHX5I@Jmu4Cj9%R|HdUA=%{9z2))}8M?9uMk?J*z# z@DIjJiDS((%}dOJ8Pfu`%RTul;|fxZ!~w1&&mbPAC1x|`b%{2=UhVOVdOy-ilTC?n zs6nzmGXc&(U%xZ?n3|RWP|b%9ifj5;y(kSB`&l_zrMVZ?w&6a1zf6c~5>?$3$a_G2htJC>1yg{KIrZ z97FvRq>0+`j%t5P!Uxia_RqcN?B^Umxc})rr*MoTAtBSpS**X0^BW?s$;M8u&aA-L zpY<~KcJ%d+)QvDsHl9;`<@$|YG+C%qFzJyO5r=lNVj@0d+mz?Yqa?*@PO(_twZeO? zw$>rpevU2q5OQoztD|bMOg#vBHr_yfMLQ!Qs|sn!a9`U>&%&%}MYt5p@4Uq2H-vwN zlK6Wz75GZYi)!a3p?KnvB_Gb6_Q9Ri8?qYPg3r&L_w?4==5JZ?_}a@)Zlc2K!PhYp zqN}#I-+cMilW!m4TC+bSF92S0qP;$oC*U7@IN5NaN~+Qh*H09tOEa|-^%@I8M;4Z9 zJ0bn%xa3pk*gAW2{MXsaeb@O1+c2HVKh8G8H_ks_HQ#xOUGiA)W;3(V?XGZfh(d7r z&GnYe$St#oaekc|N`AYnrR(irDYvW`)!NjI{02moeF=PsND1fjwH(KFU;<5W&_YQSP0X}F* z$!=E(H}3E7{l0JTG6KhEAL7MaSH9NmUOs+p+etRqP(0$UMce2I_mfRD0kUtPX^~Tr zUoF9%`=`+LD|$?MhL3r6G-e$}Y&Y2@`yE=E<<0hDQl9q_!=uJ+MzznFW^C}bcttON zvNT^pe!Rvg7|ebhb+Sx{T@+MAw+Ry{qjp(zr-(>4y^mYIXpWp>W#p7~{)GH`-04Y= z_aNO*LgW(FDMLGkLv8>oS)Z-&lej_5=PV)pQ%P2ESP+6%t28R6vH+kZR+Tx9B0oi$ zXAiEL&25l8KD!=D3g{aL-<*7Q$nH&>?7lna4Hy$woI9lFv17uBuAb?B|{9qN@nEHo^As(O5Ae0p_g+9q+X;h)wp>ok1{TD=$~h3@K%Ez7mLmRF%N#yPJM2VIg3|$Omtqurx$K{@9u*O zpPBgS=D&UW@H2}SZQZeO{?<{x!6~^DMi(`#p{1WcMCsax>aI-t<=Fh^gpBuE4!!-# ztFNHPS7L$z&-8JSo%=A!u|+mI-T5hE0bXUc-zX}xypmy8xiwaU)geffnEjI4fi$HQ zt(;ewAJx(pWIPR2;6-^ZFV)dqAtfjoMU zwqCng+n{aHp4MK_s);s1J4;)q-PFG8j5ey(5xiUtlO0vU?QnA?B(kg2DR_6xCULXa zAhw8SL{*D;L1aV>itl1e6bEXqJ{}S~6wJ1LRya4CI9wFV9fyux)zs7^{`1(e%T6(T z`6L8A`UGZCcUJ0WBM-{`Q=~3pp0q*|-5UJsC=prIlATbao&h1jd{w=gS4yu^`>p1B z$T$EJ%qL6H>FV_~L0_gH1bf44ckBr93Mq`JBq0s7a7e9&l$9&dD4u*2OR(f%T3+5t ziw4#(l95ari#e>Z=;El>q>e*c5pRAz%@>)a|-=brPO@1z>~?5Q1a_i*KlU;XOT z)%Q4uZ&D_GyY016(`g<<&CCBn$!zR3-KUzzn=iJ=7syvyx!0Wb30=T9yS>Gv8~A1q z-n{@u;ERm-LSKh(%nI}Y<_619Y~jq6){CrH%1f;u%6~SikC<7ZIj3f|CUc{u)zRjd zpiD4dq)xD0qbxVwV>x2}welPDaq}1IKh3AKfY%D(h^%lzkpM(uH9<|8HLxSVlVlA% zi52awXt0ec@D>6DaBSb$+@!d{p>@C1lNP$r=2wH8?%(NkzgY_(J*nk*W;@CYBW zD?u=k_jjem+s=%E41sSR84h9Z7V0N6v`QIaS>F|;w?FQ33vdbE#3#FW+i5crLm7k( zHa*JwvBETe5Kr^_Tf_m+I=L%MiT}1UW?T-y5>y%s1@Hvh)}L`!V-j9EsJMl0RJ5bKy2 zh_q%eTtxZ=0i0Qj9k$S_V;(f;u+|hxM-IRj_;>mMn*;OUapkz>PoYoKrVmUf(>$c5 z3oYST8d}N1WZWEx+c5B$xe(xG>(MORnBA7;S&TqucB60=p1e1l-56uB{cN%hvubT& zmK~MQO}0rq1xJ`R%t4W&?0$CD?z6)aGCz>-1c0C1A+(ba^J&$^(mRUm59l*Jz=BTb z@pFE=C&s*vK-ct0QVEqVK#MMP(l{7%q*#7?&X(J29+|c5?$oNce)`1j!b$xXY~FLx z^mDImR&sZZzI5tE2Y2l2DCQ5$xwQGNhdb`(yRN!w%)NJX{JwM5_zblbl-|*OCfV%c zkGc1||1AH-_l3My!SG7j$L(Rjq z@#YEI73OwLt8+Jdn}hY?!S0dXk-@>?Nv27b^WBrZlY{4n=bGkPrn~2Q=LV;TuVev> z+2oigk28(4PPEUFXP9PK=h&^GxT1Q{<^1rjKux)dvULKyh7Hm&>SXvXL}D$@okfz4 zpIgyXy`yyyX$hS36~tLUP;eslOBe|x_S2}hj5Uq5Of^llC>Yv4;e83OR3X#$lsN`H zeDmRtSn%qcFlWZ`if_`WttF2DJG0W%)mKy!+SdSduy3dHbDT9e(>Q)X0s{ z?_^LTUPy3n>)Y+_N_Ri^NVn3Oem2ch=~8=Pq9#z2I47|ny)msdhniy}LL*`mw2Agf zp-C~=9PI7xxuMyyL+SVYABR7VzLz}iKc4&~eI^|&RLb4ufqJFc4O^!BV)v)Ezb5i- zo5zVA0d2a?L2SAuXQb$;mFdbdQvO*dze6gJ&V00h3b>xMi+ z{YbduLyt?FZeQ2Xf&p20)D?T+me{@RzVYGaO*3ygI&0~%t1sTr%k#*xtDbyx$>N>) zcGHWuoOj->XSO_)|91Vk%^ly$55N1`+aJ9B)^AZ)!}9I&C#Wko7;+Eln{B+DmxcTC zk$kz`+!|<&jErndZcCaFzcbdF9ON4m!=^ko%{MJJCAlW~zWD?1XXY>LUxwYKyue-# zFjT#LI3Hran78xa+dm5bIrv57v)F0wf}g8DioK-M?8g>Ka)z9>673^hOm|Ijt-+3c ziRTCV$VBoxa;zc5o*=R2dvyaBPOvtJ4Y!c@A-R5M4_Q%m_XRKJzn=fzs>2H(?8rQI z)#68XEL-{z)U{gQ(X1C!x8>J9a{Ipr%1^)h?yIlA|C`rIYPcRk(Gk>)N4i$;TjgVJ zg%v7w%0N&fU#=`s%odMk(JT(1$KsGc7-JL7FIg=m8{slgkoGYjFYx>aDbzc(Q?Y>6 z0eXWIiwG%B%}wrYLLh>-AJLSNLSYfX?Tty**vSAf?YaKJ{_U+3FX?~IIejnjCzagx zg~OU3EgsrBWl_ibl>1ib40a;-)$C1uNi%}T4k{X7Fr#3l<#x-uqDOpBR=gtHETL#P zR6VldHz8AuU%}~ykj7ZK z{lPlnuaR_u5|Q>Vx-VQ8f#z|ST2zJ<&&8XLma(#E4NXuv z?8c|m9ID~1HEU{k4XBG)k(4fS6&&l9oqE%JMM#~6Kufv5S~OZr>$D3$QQoQQSqNQE zdHKRcLNm6As2}jZQyU4PRWGhg7GkfM^SHfkpIbH;IMOl6QliF~sS<~zA0IQ$!kAP5 z<_fJ8(rrnx#cD2Bz{2QG(5lcy9tRpZVX`PIzxG<%b}S@^qHah2;#@Hps6kgH7TTWZ z5^UrIe;fuwu638|=Brm;RiC}{$USWX8q4k&d(Dd%d!Dr~ZeKYo7_5q|d+F}+?MJTp z>It*>#r;Ku_DbEv@>7O25p81g^_B5 z*>Fe*5FvIb#6qLt*$(AD2@uh5qI^MgTlCrJnWz%QUX^|kTTly2TaH>jvB;LukuKp7 zD`ThRfLVab2wws*`o$I~s<@pFmxJ&VlQGk6$cTL(2P zEeK+JB)6{o;F5>h+_pV7&%E=_yS?w8`}Yi++g87rZ|c~6TkoOgjook)Z^Gseyg9TR zM@?ASr042QOe*j+0ZQ^mknc2EAUf4)bO4;>%iVa#Fcj~&;&-|wnW>XXaKNX}bqnNZ zDTo6;eW>p)=~XACaVV8a;3Lo^)mw*2L#^ZC8aP3_$Z|QmoVRQ3ma8P-0r+z5D$AAD z8(}iJLB3hNNxQ}JfV9POhxIAxLFT$@rG4gu&Nr~n{k`RL z<#X3xyeG{6w#2-$!2YNvn8r1rf2?l6Dfgcl3CNEZP@m!YG^@**e$}JGd&1-OmP5M( zJ%iI~w`UzrKcM!S$K@)wYOuR&1PJPEK)9)^UPW_x>`sT(V+E-VFdF10MlI?E5Ys7H z{U^y`XN^O4>}QVxh|y+c^R27N8qY7#Enric?^z9I1AKaJiivi20OPYq_p+0|lbCz3 z1Vl!im>h<H)gZK3AIV4HNs(U1~MmahKG{i6jC~>b|+S8>I`0bRJ-LtZ5}p3{VpcH2~f0{e9jh zsRDmc0POV9ZhV5Vo5kio0|1f$9{EB7eIyslY-IlVgO9f=wT~azTHkNqj{KhIA20na zI{AIaJ#X=O9b4XhmtX$vhkWJU)4xP-cVYJV2YS1kE!yLP)t$5rI^g&hyMChlM1$w1 z>yYV?`H=dy%i_|5O;Oor2{@wede&^amfddCs=OB}6VwT|i=20}E!Hiz=lFj68@9Kc z@3=pdKd}7D@sayetJe!#vH=V-!|NE(AQy1HKnA&74tF;!$Za)4fogRhk&alnyOXaN zz@Q^gwq$!^gUoJ$4YIa*nRmEjmA$~~y3A}@r33I0drmixF|QGx%L8?1T3*Eq+EB{j zo|T5scfy!RFps!D1sj*}a_I>J0!X2AA|X4yzySdTBoIKa8ArTPM}oe_XrevNaH2`T zbZiL_BZWYp6cV4Iivju>^t=I}cYtgF!iO{v^g;tdu7EZIP#j1NeHt1_r6L!@0eoHl zokfdT z?vMJz@um|0c-Iaqh}(2jWxAxg&P@mSdV7P8u(#M&Y%g~7vG;M*JMZz>O1ve$VZjOB z3BCz|c5l0{J+R!o%(2|F!oMPLz2g?ot=?OGH~Y6(AG5vSe%^D?|E2XW{{L}wxKH`d z#FH5Ab|3(~nBXIRpD*jR`tiYK$K;T;S^eM{2G-CHoQ@oixTLr{&a2`t#d&-`Z{6$i z>0aHxpO4dRtzO;BFZI3zm!AFXoP91wT_VHm^kc{uQV4kXv-G^)D>p&uS94NX?~y#aIc`Q88^-v+!J4T-e{OO3CX zmVRLb@5BURoq>BLq@>mUz7;LQKsju(<>$Wgad|;w^D&1|>d9%gJp*77ij-{M4;t=4M5kSRk zz04sw%AHoAt6Y1q8koQuFi|g))B?vgC)1r%oNJulI2Gp-$-0WM9TIB;VI{(kND-HN zNruK{mx|i3l|T_j?bQLHti}B)WY159&61iALle-eax@DD5fm9TmY~bn3z7?sb}B}t zXjDb`^vZKoIaEX9Lbh;%fMn5R{>NP|0W~t-K7S6FJS`aOM{D}75dHEm-5PA-P>S+s z@a(V!8p&K}ppp92W&$Pr;l&r_+vMpTFV9~-i~V(zteH1m*>TC$miy3pO<-PK2@75s z7*IzIb+HmJFe{u6YS`wi%fi8;E?69tO3TXZschPZNzQ}yG?jiP=JjMvk>*%7CpVj( zDJyQyJyTY8DLhHJ)Ly=z6TgJ6PXDomCFq&~1OiGPyQHrS1sGKh`0)C3FPH)v`qV;3 zhanF97Y5G~39IxKb~7C0*G;1?1D@K_dst&`d}C_nAe;BX$@8Wu+JH+_jZ-W1aS@)r zY!si)+iqc_>&IQ*&ux8RCo@|vKh5)#o^DYKYiNL?x6=L6^eIFSpCbtmtKe38J+2VQO0kE1}_pepBR~2e< zk*LXQi52wkyHSUwz*p0I4g+#GY7&Fs?|KtXLM0)olrcvdp$eQ?hcA;(I~~t>qs{Sb zvA@}yH5WIRJj0Y`^E1*Iwgz3fz2ZKQno=Il)+qHsbV8vsGisDk@2bCGMnAXhfst$f zJ#hZ@*@nHpeKj|*{sDJz=1=omZXSagxR6&W6 zwB>!f^u8Y)jr<}V)*yQn6&?vKG$>YxnFfTd#IJ(=HSK+3{=0yI^j1O?^` zXFb)jZpGlig#*_2(bt~eGWV-CeIc)W_o~9Wgm-k`_gnhJXEh*nnP4L^|B2_MA~d)v z-Ol=hJtw0BvF6vYee>I=4=V=}D|nD+&?3{X7lx$zdZ|0@iSD$o0|%o@5lVXotGZp9 zNhy=Ol+r8|X{5{Z6N#AuX>#IuZ?MghBo*k`^;V~=+p6WN>eba7su3MY8dlC&N)w4E zFRVwDwFdz^`CP3)TFj|<(rs)Un`?&O8}umqBz7jo=f`%$cw5Z)aA|B~jK`Gy`4!?`k)9QR+bvv3 zbzt}(iu$YRtiRV$e{tO@^BrlHmW|pgJe!evDv9v)5UCnFQ{9YI1>o>zmqLd_6(8}; zLlHQScPFJPL|TDpGrfW`3^Hm#`Uh$-raO66-&O>uilgE<>wAC~7)3Yo`TbM_r9X70 z+S>GW6K{%JDOFQz~s-%oW|f+M*U(5;*`;yJ~f_3utWwP9TUYIojl7uTnC;5Qev ztZDhCMQ({t75%BTJKf|SrFx<}4u0JeFHJV{8BjxDO2&P zICsa{*YPuPUL9Wz(Fa1}mVMN@;+}>y7?ezzVEJf6aEMFrNs1A}osXXC~^4 z=ZTg)0zpTTigvOR5~>P{>e@;m2f!CnWHi^Ec(P~_VNDYGJioIaoapKYiEp5BrHPHR z#MxA$cD|o#py>bT2f{ie`az5>fPu(J9y^=d=m+0Ve^~mYs~<#>1pOf0orGG$xSs07 z$mQ+gdejOgYy~q9ChoIcRn&@+f@;M`aYUr32GY2yytSOKEZ^JnAw1`30ofyTWe1AXfK+NKzzk_VZ zgL2}nJIRk-e^|_W5ulbyS?(#Mhx8a!J)S{zW9094ktU}HIddggTVi#B{}PVko@+$s zIa{wZ6Vzj!AD(|iNt(7uHt7<*mNTetSQ;i9U=mbSnFlU>&0j;6!d4Kx?to1^S5!)R|hQ>RYMTJD&B6y}~D+B?$2M;~_9r4ibVVm;v@c0+Dv7h8; zZTl8W1eeyxkMSoVc~Lx)TI@3UZM!UM0iL>Tm&~vsxowwutsQUB)gkjwg&$Zh)W@K6 zgXGjfB1VtM91T6pWosT9g}!C|1)!nD)!qCHk#_m_N?@u$iuz;hCAMT#MsN6E~MWp81S@?)p6Tuk@+RzY1N$ zA|n#R(=#J86En-qBP=7+?XKDB<*rAhpLrfHeZ1^5r*&}ha?^~YoY0_y2xmau6^S?{ zl163d$zovPi8{(MsaV)$hrd!W+#zsMrpl?LBxlUAaA73s!2kXH5*<;O{7z>C#1vjf zq&TXYomNLQ5(K5l6MB)^Y!64IOl@I2sD@R$O^#b_PN%s@jaC#FwL->;lz(=RRYU0> zzg|edqYP(P!@$-G zI*EovwHM-_|1lGvdADbG=AV!C?z3#c;>DYmezCkrUpQ~Uv{`{2(Pz`%^EV9D`^u|2 zxaIaW{sZqj^Gnn0_6EjY-gRb;#@43u*OcEeH@2W%p7_$Lb^9tXl%?32<4QAnT9foQ zec0TFW#u=N%fSq54i67=#BeN93d))!SvEC-wW6pfo6IpuDu&3N>{U~IY47>HdGEXq zQo+(*3|!d-bygCDpb)xicNLk*Ib6j2?xg2QXVPy2f8oXZlD3*l0DRxiHXve?ry45B zXkW&ER&WU|C8HWId8zD|WnY)cWs6d|Y;m&x4y>b*=Ep_!gAUQ>KaXeuqTkiQ7%#6 zL=_20JvJJI(ZwDP;<_q?^njn;%KGMy`^H|{Hel?`r}~Xp);wuOO<8&D-DFkOu!jZ? zo^pfdwRH(T(#D?^hc#2HS*t03y8iI({aQCK zxT5#brITOZ6T9k`4KwCr^qrSK4-C`qNsZD7AU>uRH7zwS@vKNJuUy{$>ej3Es|PF| zzIens^E%J^#LboK`>$_Zudg4lcG%kCYe#G@4V5}deMO}Oy_I1Dy>?~rIjv1utEr&5 zs#tDOhYdWZwYjOPIP0}r?Qzy8uH3-l#X!vX^vYBm`<7x@bX#Km%hgM2`nQy}K?;wa zTX0FBzl$M++~CqS=zt<4DfkL)9RH8i~8rk+`M$e zRqaEY-}u?{zYaVfXrC}?VNv71A7~glaCq5*F>TXdnETQvymrL!y85SX9(dm1UcI*8 zFeG|i`^+J=KC!eDIdj=jJ`?d^ZBmMM+GBO6#rzH-TDi2;eqmRH znyT;3#&hqQ*?!ku?KAJzBobiG3ippLh*sE5?<=WonYIBuT zSy7zL#bXIjOW3Tn5SDA=CW!4}TOY|<71tgPloer`uhe~k*qdA9EFP~fD4G&j5LgqC zu>$tf?NU7$l(T7MbW_8A*iH#@gP|`5`(%_Eyyvvr7F3T=LUy9KjNwoH5r18wA38OX zhJC^atW{TC7tDZ|CzlQtz;GD)o1_ zt@?S@eKpe?&YhDEOnjucBz8r5?!?(Q$$xq7@Pelo)y~=88cwIu119tt)xQ47jkAVL z9yW7GV@b6CqNb*n;xW%&RM7v@b$>XW!8V)}IHu3hsxB!d^^tV8TJLkOcXM!a^xou0 z-uHv=M?XqxFI60<FRK119mK%rCwE4 zecIA&etLEK>$IHSi~v|ucWE|IMNQo$$$jZ9H?Ha+pDOiY!F>uy*a0tp5g*fR1bi^# zeClo`dJZ(%Q}@~<1B?Lx-!j2kfp$kvfEEeNw#Lc;JvAwn&_~Fgj#1LlO+7+gp%+w| zq?TqFDtOMmcbWc%g3S!a%8#S7-FS#vI$?O)ipf`K9>Bc&MlAww3NMO2)%WLqnk z&*9Fngp5PL7S2d96AnWEN&VtGFX|k$1oa>zBKpiw7lm$3k(VfSAu1B!n&M`l^Mnei zs}OsMm_kYC#ZUg6&3fzg{5`L|mcQqXx7nVPufNV_zIvF=e)XD%^1picq5KDr zKFZ1;dYDx`^z9dNMdgCl3F|a(q`%?CN>6V_Z@Mpf zU-A+3o5vgns^3Si`Ut)1gWBKpaW2r(`}vc*GdC8Y-#ody8qD|4^C<{}(ujWHY%5~( zi&htX4HlWrS`FG&w``!@N%>~!yM2Q?-L78m;a*dBXKqsJsZ$j5>D`^8rL$A?{XwTV z+aGAMz#kl(1hWYom>{c-t8K`Zu~g{~TD`WcJ|#6|arm*OuPdoZu|By*gxdR&_BWdS zhwYCJ@V~XbPY5JkWGda#2Q8rgYrBuTI{E7QXa6w$z?IiOo4zu+v~BTSw=KB%rvHy7 z?{F7gbJy{=*1bAy_1wgWwukSz=Yg5DANdnsZ~iCNCly+j`}Ndh8*B2^dq;SNcomz+ z>vAHl7)|F29ALN~knQ$e7Jv!Rj8=!;YEdMI)9s|;>|%X)d7knfWPK$+4S5aRET&zi zpFwsMR*JYQZdt(N8a(tO6-*cdp& z%QrFw&Mi}R0n!04*u8MF{kL|9Ji1{y?s;dBoF_`Y9** zJkzTfU8*!pF9e7~Z2_bJ%>E`gMKB3G`deiY){E#Zw@D_r%oOd`7IezTqdHD@2%*=g zCIFa803Zi~TKx5U;lK;ZNf7-L!#@MF$wnb@_@r%mfs;5RKquk@$%ql<%jd$*3=NkA z;RvWjF*iS|*C1$dQeCZWfJ?e2$v&cj0!OXg=7QfkIAQH}FStsGrq&t_fC^#?C|M(r zO~RmFCbwmSaalAVTCbA}N>Gb_*7c)6mSIk&2^rrtsV&$w*OIt?mcUjfEvU{!(mg zvo09`ExFOv92=Y)UOc$ue9NTF`MGhu+MR2qHE7ZegfcuaI6bU*WaUI@qC6pfL3%=FV)6N<7gx?^?R-V`dVYO&eer{q6D;hNi%VQ? zH<#i$u(GhSl3Z3v#EYwyf~vFU6)E`CRRg|>D~RNMS46I$H=6~H;WntfDywp8G+o1L zJVXWVX1#S=K`sr74$wArvov>L{UhEuW7X>*5yvpLc8(BwQ{7G)Je_YCGO*$ukV;@? z^*6=gTMu>FANP83>J`Q}vX=vf*ASv5$RN(cDx?+*y9*IM2gR;PA_x|OMB<`aqSRCV z>#=Fij!%~C%RhJEmIdP%e`wyH;-Lh>RL=!L$!q+*J3% zxFc((th)bC`E7fOlNY=&?(kjjZT>HI*}kF2M)V=Jv?Ui0oXY=j`cP{m!|GV@D9uTu zA=CtwcOiefV4W$qa7~ux@hl<(x|~_N!{o5qwRvW1*2EkXA#fw#1`XK-ZnDe(YDY>M zq9Tx5tLVf{CK`N&D(R`Afz6S9+#M~DZJ?+N7~gk3N{j#-f{Y(bL!`@ zZ#$YcZ&;syp61zYKwLX#w1HKkr5qv(~J53|8vKCK)|ik>m$s$x+qcfdG)De zW5KC(hGp6}*0MFVhidth+6A>-uN?z~ec*FSR9seSYOlFZ^lXafK;?q>0j2^hm;iD? zT>^78nwnNjqktm#A8kfR-vs;w{tIeqBT5Dl2&jI8Kmb+H#UQ|oR@|^~UAncVP``6n zm_>*7Z5wU5*}mnrhX)O0rJMbp`t=vb;)D7RpW{{K3ua$ErFvMS$7T&W%|ogS2ecGS zxUygWE5GS?Lrn>*a0byPxzgs*O@129mHaq=5p_fw&w;zEBFy_DD#nb!*eQfqUa3bV zvtMF?Qn~%>2wMl7u?6^t3BGK6>Ux--f4An!9ExqHp z{TuGs|J)ttO`Fj+X8H`%dv83uNo7%(zd3HOD}0!VNy%<>VmrLxu${6bFzbmO;pA^$GgU6+tn+aGhEXPuXHcT z-RSmu^_Jb=*Q_Q=Sy7;ZE;WZF?U z5*7!VXjBR50T9oF9MYi>z!HotGLEPu8rfhQp$(}xcJ>4)XmX@;G{__{u?xVp7dn}Y zVEO|Su26+RMbo2en2*$avupKBqh@|^^;0iR+xf~*E@$m)FTASBwNA?LbRaP#tO!8ckyQM(6Ub@9`i~E+C@&)@c`fusqTzM<=q4c5r*8=4&=`DUr zk+*v8%{(DLnNe28mS>h1JXxsB%Cr}PzR|7B@mwCAn_DU=A*pY{U_Qd7Pih`!7 z@-ykR=2F<;NRWe7}&LQu-^^+Ow z%Z>xB@4RzvQyI-@Kh2L-+OWRKQh{`n-f(M*txVmT$673-kaEO;KMZd5im;3gAizb7!rxwXec}C) zf4=p*GZWTM=o8^e?%j9ucNci(QCOshr#8>}>BcRAxBu|vBbRMk(uS}|RO-+2bJ$@~ zYKzpiGcNL9h}^5P+4i>7tTdV|jdC;0BqnnU5jekXwOyO}{r>=rc5*Uu-EsW5`}lDz zSyk?i&w5vn9DC7j1s=nUWU~n(^FA!aKK9}-w>2EYqKgdOdHP@Z=hj`A_hwlimmm;>HmU=_ZZvv7|AHT zpo{MZuH=lgN5A9>Gh-Huq*~#L8i^;u5-W(uB37bg@cIg)P)=z;>3ZFPa3Ya4+u+k@ zON4D^C2CG+vMp>0#N8|wS2ds~$=^Aib`b+~v`~awDcH}p?gZo>yCnp92Kxh?#W8+5 z@Mri)iG|zHTpD6MEK?YMVgLe-4ZWt=ED6z`4zviuc?Mm)!B^N&OAyIEuyu&uud20b zA>_%zf?kC)YWp<1cfJ{ZGaL-17Ec~?W8oFG2zBgxC-Tlq(G?3W$S;-g^C2 zmHmh0?g=-vUvcZVFKk{&t$l+uOg<+64*O7>v}7mwY`?ABusJ-XsYoRtg~9Y&xYZCAVU_j^1@Au9KcggQN8+`wqjf*@52Cf$ojq zs^S#=MCyz`!3u%p^@$^}Me?Tn%dBrQ?R#C?- zIvB|iF4NjV@P9>-t=1L@|B+o#6X5MR1SfynPNNCgpntUd)4#7mHP}T%2LPfn@%Qz+ z?2qrVkAFehfOp^RLWT*XRuMYBDh*^;uvt=OCl^?1o6S=P?Et|b+&xiM!ouH)NF$7v zk@g514~!OKnF9;W&ZJpd4=3u<@NTP1v-9a5$?x0)&SiuJ61?yN>1E)ujd=@FPlJ&JA)s@Cah?&?k}mNv;4 zlHJd0cN%H8M!KNx6T%t#_gTUqV+rhB3lWyO-keDn!`)8G zq(k6qGxQ>if-bqei0g{Llj=*SAG{G1_3zzx6N|GtrrjjBb}Zu;c0As3aK@pjf7!PE z)4x3Z^!s0Z{w^EH&SATb9eFyhKb5yDH(!_k=STTpfyg|;hO-(5uPa$P|IFv=KuE%A zsTZW-PxYC(z=bwGC^!hr?jy?vRgSC~RCl52LTzl}rMXMX##SOUnsZ9goZOtUX_dZ7 zHRI~|`N4@1UK6Y>?3-&YtF7!`Q&R^+RtemmvyS@Os`y6#HV7Slxjb&Ijbr1hX2G-; zhxPax-JeX#wko|u_eb?u?J+-V1@8tVgE@ z(?clkC|?NgrG+FLive*~9yX+5?E1vyDvV`R+maFOuA9n=CQhIb#O}{96eEmX$dDd{ zsBAJMV)@tS9$E3H{8vlA-gL{mwfdVY{{Xh7)8ELuZlR-$c^(w^?>+MJ{Q1$J?QUnU9lUJS`>!8) zcj_U}-STpBC?H@~=ZPxd=~(pLDc@~_peef*eu z%*TJJ{?f-^QeX1%9qJAr->Po)@eS$*A77=e^6_uAZ~c6ZHpkB|)-LvQyJkld`!qFV z2N#*_I^~p4ai@bbdy7MAp_s>G^eW$cb+x(y!C{!M(cj{9*jwP+q=%w)&ZSIk)LOvv z*dogtpmdCcyR6WHVTI7x6y{wB5K=2?6tUYeW`$I%>Qz_Y+^-2oy<0Oohh&V>Ss5!j42%wnt0*aGt|^j`3pYU^rqOoex#2U zHT8}5jURwD5T|~ke&XXt)uTRsNIm4^&#KS*_=D<$KE6rauT(zw0_t{)GzadtT|#;H6{Fo>4zsBmXx$PxPu)dY`McTQ%;`Scl5~ zsD7>T7b$e%ed;qRzgV54a!o~NK{=uIY++g>1%TcF>Mp8)fQoyGBBD>EsZZDm2Gs>> z2d10~H<=xms9T_L&~J5ylckoY;`D6o0YBEpc)}d{3)WAx>=Hfqp898%?^It^`Tx<_ zo!WMdFV?Qp_yyVwI9I|09_`iHJW0_!BHLia>}(6s7~jbzIT9e7Mh4LeRQpm_C#7EM z>ru%of2?k4h91pYp$WYLXCx!c*{iikB9ipuxwu!HiuPq4Cl_`s zJh_k*Eyy3(Pc!2E?RVKK(vWuSeOJC0lKH2P<-;&GU~LyZQv%OP00UswrG3BvmhOV$ zizF*wc{OkVsnjpKbwZZ!iN=ychU`k_W1{0N=kWRf-|k zzSpGnLa(A9RQwCs)h^w2ol9}`FDP~PxAq4;cDo*nmqrm3jtDMpgMzq! zxWClDF*+>z%cu;+V}5UmN&P8$r_{;>bmsVR7^B_5${dHfu0u2K!+1w8=v1!+k~w=#g|H^4~^!v``O5y#FLBd+(}66 z6jhdT4{Mhpq!%*FUHQYT?_JneH?h~*oAk8Rc-kQGw8{h6tG%s<6zmJ={&e$Jd8^Fj zS?a=F#(h7-jXUovL}_+Y{-1ZT>ip5W;HPyYuji}jo`mTvFg*fBzb*QC(4=6;iLiHe zn@zh3nspH7Lwru7r@@(y-Q<%H0n6=~2aa^W1zj$$*9VGpkob3kJ>hp^=3GY^x!m91 zh4>UJOs8_4<`^-K4T;r?Nq)4d^RX{8!_smx)T5`-jc?*+k|Tm%-h%@q2g)& zIPfl?jbVtnEdLMIPx=++hegM{N1ye-|E;_^U#lV5R@co_=+xYfT zFYtQ-6xt^Z;rH%po>fC1v-nt!kEuB!`e?;RH@|nc(tg4C{p_pV8Pdm>p9BcG>kqn| zPSJuY302jW`Eq4Vm(kR9^`2MP(_@s)}(IH@i~^XdX%-h%3(gcASmtdtQo-ZpC5f;NdCh z+yOW=rTe5RVO#k^Ort=AFJ08nl_Q17kw%xjE&9=>L1Nx@RD+*frXDazQ53E_U{p`1u z1%2sTCtbV#&hK8^$80(EPvzRz_wIY;wbu_G-ZHDQ<-RSgRlQnIFB0D!IdJ&y*_Hk7 zy{CUwul}2V_|=bS1`f0Hpcx4377nXFZN>xNS#`16KL~qhPp>bai;x1ILCmfv({+-4 zhn-j1FNN`f@9#JxTr#|8H}t|g!q6%7&_~?XrH_CY2ja|lBX#grqo=!iKHcy*5YHEq zLJ1~H@{pSYNulLA&YXHUPC+{k>Hb8z&PmFfZQ%Ci+k}k}%bIhqkUo4pvjd+L(ocN9 zR0G+yC>8m#ZFTH$@cE9_h;{>?d6el}Q6@)^n+Pw8+mM^QC=)@i;SG0Y2k!8{dgXLE z#2LOZXFh>gGoi;_4xf1)cll3#HJyn&{c04Xtrs<8V6g^Ppj2IwiQNR<8i_6lyHHEgv+EOIIIvF_aYq| zPB8YE9wN@hG=6(XF=$+9M~sP>*l$6rGC=Wr^7sjZoe@g$&;EA0<2aTM!junOu2=Yj7AKPfS)TLD!5S$5 zq0}#jY9x!(Rs%+6UkwW~9IOrvoey*N_b|G?Tmy;Jq{?ZiC4G1?^f{_Iq_XCw3H@jH zEld}v*U59owO%nWRS*a=<<*(}`}YCy-=am0Md5H2?JyoxRwJz@18RlVv0UzV zbvI-#7{Bq3^ZVQMV0U^A9SUv?yl5O3%p(}yJFrue>(KLUzoyA&}i0F$x76obXv2Z={jPZ<*38K$?I^Q-5}sDRzrzz2^}{ z?nR07XC#%)!2WraUMNeJ?brqajc+n-Rd#?Jc$ryMN%OEBIK~e$NE0n8?px#L% z?70c(@uW}Eii&c@v794Xobjhkyh)mzBY2(rYhXpTg~(NI)2r_>mt+qu(_ksX>ssI_!8Vq` zI0*%T0{}ahxiE|Hqp&E|*8w#mRM0=&zMcL1iHlcFShD!`Bi9bykl)FgHa%QDc=V{1 zTOP>2!#3yV@cY*B`vQq`r{;h8+9&xJH>EsJ_o*KI`J+$$Vr6ySyAES%I6MzBrh`%( z!ssde$_BYPIbNO|M-=6v@MKA@q1d@B91cQP7m1i+F)4~YC!_bM631IO6fkpBqA=i1 zheKwrNRe1HqR3Db6`Hg}ENYVRRXU#bR)hFtLqvgAG@|BUAWsx&(XzrKSERI4aop_| zMhs=JrV?tRlMR-lh?2dn)AmiqHdRmv-zYr5u7N9Gp4#79c1mqnP=nMnT!s>oM zto}EZPcc3J_h)Tb{0RmInrK}){wx+iw5U9;PCuut{nmygYF%wN@! z|LB#~A0sAYJX|>ZyuPcin0xW*2M@jd_OD)f?U%HE3N4FR0Szt7ZEO_QqA;ypZgZ5@ zuJ0ItkiyXIyn?Z5=yqUX)5&JU$X6u}!mWQZ)~7a)GVk*)X}(CRozQ-v#rS*iIO$8#*fS0rKw! z$$f=gv1#<2O&4`X$(?j=@9QZ_ZvHn;AL8U5%y;B}!+v|~s)_3YFc=$*s_2V;SUzsm zTZW}CR4(#fuFUlQHEnK4fw?8%mwaItwAE5Ft|GDq6x+^Nku6%lWgn>6JL#!26k&vP zue4fPq&2Kf9w1QV+EW#BBv*Jec3`kxbQ-DcbUtypCb~u3Q<|c zpABRk4hA)>AQz{g<}5@UW8nLmF!DSw@?wRwfO%X|@%@Ae1~AIU7#t@75w`Xv9bYY~v()3fXPRUPX94>erelv;ttZ91 zhmE{^MgJ{TbNI)+?7Z~V{#pGx0MV8r_p*#+Z9HZJa0v>eN|l;Lml8&H;VX_@XR)ZD&8_b8VuXkx|H z`1J*3*@RM*vXpL5M2ats&X4j|ped*~(9=ZXL*PhYC(fGqu;4WWJEgMj0(QD60za48KizceW_i1-C72xDPy;j8Jl0a4t*dAb%^Ej*Ov89z zaK@m?x6H?2n0@ATGyF7g=74_Zm>z<^Sye@CrZqPxGcNN~$qOZaE1@-zv^*I@%TrPc zXFECOlw`)0igLh*Oqv=G$JEauVL!CXrhpJIrCV(FW`w7UjS9bnYJ*d)RKll9PN|en z)oo>EXl+ThIE!Nk`80Hm1f1_m3!34i-Cki*?2c0S!M}~&@u1!17Ye*3xnq!cLoj3L za!7_GI5Bj8s7TUs(wy9Z`t0n##(GH@6$9E&8euquLVGKp?bQFTUUXa;^}x5g`*e2u ze&(|N)Tagy7JX{t_0*@fjzgbnGTTp`kb`H3MTgSZbm7qyI$6J}b6g9IPPU|9;c|Gy zQElJeS=(VL#+aVI98@wU3P z9?zw)MEuvpr#Qr%-II{VT%Ct&9Gk#6b59Ed|DZO|F^qG8%-b|%wNmy zS}}9x#?OAF%J03JeV7l;xtE!lnm>h_&UDvwCH$KEvZ}pR{kpW3#YR8&20WrV`?X~4 zftuRptOvZFmfp=Z)!tDaPuK!?B7_@CE7cIZ@2~(I@PrNvYJK0nUIA$~{r zMe5)Pd3qTTpefy(0-pn`ud8bU#<{9*)AVY%knP;ntF}fAi^j%Yvb3R>4aAt$dLq#G zRPWx^e{XEAukCY3ZLiYC(fu$E3hbrTpby#4OLT`4D~%VJN|i_p(csbCD5esETEo`S z0zEhl47is`t<*g9K@0{ur{g34bytm0QeP zF@t3h{ka;_d9@^qSc3=I&FppoDea6mhRfpd#cp(e*OU zZ7=}9nxm=Q1mqqO4dbJVa0Qx*%>*LOh|6(AjBBpZ2iymDq!Zj4z$;vh8+5-w0)pr! z-7iY7;1bQIC^ky3n2=UnVbky}Bq>Ce!DkHsF2s7Ii*Om;1wSKilygNvJW%=`55fm4 z7_*_fLp*7ePga1g({PnZrSc&~=gT;^6XPeMxLQOkSDcDZstp%W`BbFFz7@$(9Ws53 zZ)8x`nqcdqTdS19Lf?xEMXDYT0ckZ-m~jn&s&={##T560aSe&>HWfc0E4U7&KyGcQ zE=|L;W!x7pgnhvawT;ABt8kTKwOUn_&*8L6NQ;zq3zbi!3n?GQ3yDxc4sjC=M8=4Q zWwW4akXwtzp<3upqI|eqluzv{pMvt?OO%hw272Vq@`?LW&Ws0$BbCpjf&#{&C=M$= zC?-^?Of7>)!=X{d50rwQN4Io}Thd)n44fO~vrzfy9~Hu8vr+jd4j;0J_}&gHsDjNF z2%S`>&X=MfwdNuT)oQU>WfdgCR_xsI$!eka-c&x&V$%!BkO$d8=cp$DB_L0N)E9Sv zi;>+*-*>(!XI4ySr?d z5>%@R@nPx4#tW5#4uIPkTirw0)2A8J8lN zI57^$H|}9|I1v89LxTa$i1Ja-qelbOfFG!;Z4}5EF`SI@;U*@uAIfJ;aW>6l$0Zm* zn4+9ckXJ~O&*wz>%qrlX4oqVzE;X5`a*UU8jtJpSV6$8fv(;g9fvp|E#$i17fkTtZ zXG0NC2(!(KJSc9Q;v3|Sa*8L}klKMns405UjqxoN8!zzfPWr}COo~;3K>-;= zX>G_U_Qxt}0({(Vr*TX41iKxn%;JO++MtEA+u^(Bas^a1;6{t6n$PYK*$4oG5b)da z1KJ8t$2@2@smKs&obG~RprtT- zC)M>rA~)o0_#peeo`6qtcwHf1z!UHzGKDAZ@p_Qf4nA!c3Zc4O==SCyrL|znbNEnb zj4L>8`MtgX{GjQD3+X!1v*?swAkoG>Jbr)7Vu_(-aMTQYJc!-qqDKc}5f^?y3a1y- zsY^3k5@;Q-7thuLfdGnV77MHwVPRZeT;#^U2!%o}czY(2L6py8b-SZJGX{r8!#s{M zb-pwWwc}3se7KD_6i{70cPId+DBLvQOZt5D45u5ZQJqMJ=2jz=)augQ4)iT2f--sN z+CV5^+!7bM>G>Apqd3}ew7R{4K*DNGgy8*cvqimL3p`Tk(V;}ljUUh#9X^!Yt(mR( z7BA|PC0KP_C1B=sZLmhZL@CQ{@w+hN$kH>~^n641o%BI;+H>i_H z2w&rc3q2kxA6@1F(g!aG{%jt9IGncG(h+>H+v9$}4Yb+xXh6li_yI%874Rabn3(Y` zl?ty&1ZJub&6+k_z^#S60bJz6hgdA;MTp%@L4?W&FZe_d<#YUK`3izTXt4d!u*Cz7 zdpH`5g6t(6EI3;}FS;to+dIogxux=X%OY$-!XLoIoC$?&!0ZRIkw_w27{CvhGCU#d zzXMjyj&JdzyCf0`v=kN&Ou-Q^MsLUy2?X&0*h9ZvlFG`{kg=VvP$(PMFpEd*m|oH1 zoi8Lp2PlunlgW5Ale7oop~7S)p24SNybKg}xRWpBMDGoS5H=T8V=bbjPC!vY31kq{ zbp)y7$xPC?B`yqwkgCT+LLPkO3Pn??GN-c)B@4S<*=W>BJ+CYt&y8uZ4n5IfN5 zov;5}+O>eURb1(FWhHhVwrt6kE$K@4UOi*kl4Z$}WJOABNhV4hJHc{-ZA^%<<;29; zS<4|5XsR@XkV42V-G)bLLQ)C|gjP;yng`Fm($ekYYw6M!+NK}n`(U>Vh228?eM`On zj1(uO>~_E1vCo+^XU;kExT8Bqx^rjB%h5Z=CP`8hNwh0iKVx(#cFB&EB6%f?h+BA# zQDej-BV&cpxNu?ZLMKzz)RtrMBdhizjS1S4Vpj?#A!ua1vbd1sSPNWf5Up0PM&q>` zjJWXiqF7-9+bc7F5xMgwyH7 zZujI5VAJ-BO06h1DhsQsbY?u{s^GoDQAGs?fEZ8|n2}ue3WFln+g*waDZAoFqtR1( zu}Tzik)XC1hsrHsidBXR(O|1H7;rAD8QO~7WiMETAVgVjUk*4MUeuZ-hr?f0<#(BI zmXNkl!cj+HqYRh7Nkj&287RG~3MZ#kfs4SbxLhtY5tA`K+lpbaT~r`sMgmXa#44g- zs2<-Ts&p2M&yE{JjjX|O0J!4CfW13p*%GqbVMcMgG$y;n<8s^GNV)7mn@vGa)mgL_ zi^*cqSj@QG z7OA@0hes_k*g?D99Sm5Iv3Rk?WV2|s7R_SqQnbl#XI9V*G*P3)B&)TXDqI#DswgAj z@pvp+qR6sFs;t!2$a0Ho5#|~zPL!%dn~I^b(rUHJ%Umv)v3cAYvrBGrdt4qg5Sz6- zoHk5Rb+S&D&9V%&@^VXgGgH->@wlyCG>N(jofXO3#b(o4!H&3Go=8YWMmbKoa>_cLjA^hHZ9=OM&Zt*>)9qMmZxi(NWBj&PU@P{QtNNsq_p^VGNabXJce+{(z~GT@wNC0Mj_~MpntW6B*!M;T6=wS zb3(6Av^X3tLtV7KUhe`s;qkO2RydHM(Kr;3L$7z}Gah`m-eaxu zIXn<@A%UkU4n0xlnlNGhHM!jhe+BNvjWvdv8uUmp)YLRKHoDjNaaNPx8wu7p{q9&W z;*SLVo}j<8x!H?bxYccNyPa+~)T*kSRV$b(76G~)OYIJa0dFQl+aHVs3nn25QG`O0 zV+*ixi8mDLG#EM~_3j4Il<<0M8^P}M`y-tz-N?W_$I8^}2#yQS{boMQ{u@g$xvQhzpey9{A<@y%;T4Gnuj{~*bfXdo^u)Bd7YB`!(HNKuMk9JB za9u1GkH^BPxX~L6bjDM$R6N!ik6pVw7KUzpKneuBfqUU0GFe#kmT3_EH{Uf$w5gPOa%f;#D6H4}^}Wyx zDSk2Byt28uSurXRXeUzLse(lahQpXtO@$=KOMq>`*y`0IiZaq23P&7{{#Z5*GCexCkg)?C$PH6HS<46(!*}ro!>&L^y&(I-L$F_yrVCC>Y#- z__?>Q*F^t727GBkIQqH^ucQ-w>G6RR?9A&jD#iLgJmqEbEFdmj{^xE=lu5HkXU{_G zQcfYC=(YJp7FM265%Q{6XrnqyHGoy6X4)}t1N8}eX+ZS^-OixIOl|5DGzIx5kZwnO zj_E>vJ>b`XC}0D?2w=P}zz`tK(vUsNbYWu~v%}*o4U|bVId8-4hbZshybCl6I0X8r z`gJ-szm;x6`cddTkDuH^Oa`_N&VPa)0RLg+4}*6IaUar0Ko3ICSELt|?k59y3jp)M zuZNwx0j$lgk{2nc&d&Y@ZRv;2)qp!u#yZ4T0XiY0LmUU}6)wA&e+BgH;Oz!&L_OF~y&8Z5SfV;XI1mL-JWo&)+J8-<-Dvv-+JZVBMO7KHa2V zgJ;~Y(}VNgpb`ccL#&^E1&Fcng#J!rO<_0s??d&&^oZ(x?2Gd|@?hK~p|=Zg2(oYT z>zpMo?A{5u2fFWEYBRfbNbkZm>VcjA1WnLM16HDsbAWMP2KtU)KlBCi1{uKCDzx(~ zlVS4Ebri?Y(aSL%h0K2R$wkC!Kn*MN67Vs?#tZ;?--aCnU_Rg|U@Kq=${oaYTfwf` zybEY6%H?$_)aek?d(p-tMR}&L%s)X}i=e2tvhgLnTliF}?!d=xOvquG#rt?FVxK(# z9GZOd>nkZlCx&uDvp`uCfIoz znAvIKcA6-{X=bMhtMFLvaYzOr`6{sH&wm82;@A$ErMzxSq5CT62*<3RAub={C5EUH z7DBw-5SdYWh%6j43nB7z`6TCD#c_(`H7GrVw~?9rdQNZPbRVY&xXnS}R+N$iW~E@I z7N^aSX+2=R^JnMY@!3pr1lZP|rtsiv^4&(50*HqG#Vl7BX%$td*qhRV8V}B>Pc>Gg)sT6yNY5j?>U%|cKIGpi(xvoG)rXv3 z$jZgNpV?W&$}Ramrx$bnFF9Qax}xMQPU}ExOFrOqHIw0`3u-f`YZ$*w&uN9xi@ANZ zhtu4qy0!Nc+cKj=!x{Ow+`A`Q;w7hO;T6W64UGmz|QLj8SF(PNi zvzZ-RAm*hBoN+cqH_;G{Q<|m`PtXYP6mTzn0-G~ru%Kgzh7rpc>@v7pINb$JrafJh zk}1J$ZR2w71>#^m^5ax$rK0HSG@E@ZaF+|2OSlGvT8{rjHewnx9gRp~c!N>bnx{Yq9 zPts1zPdVB}pQhcIo%UciqrG$&?W50Ne!7SD<1O{Sr+=W&qVMjfFJQIuBXk6Bfqju4 zrN?mVc!Hj!r|8S{70S~LoupIrG~rxe%x7ol9G$0U={b6yzK&(g-=uG0P4or&4tSh)zdhnIwlBuMk>?3}e2}C%NpJD^F*;gCZ8u77 z&crHzo6L|i5(5QvSU&7jwK)$yh$KVKd+!6qkn@gvKr!UJbr&dxoZ~lxV#qmiBPfQP z1J{FM$ho!`6wn#fq0@Gkw05f?w`){8$OmWxtOKZ3JJ=un3GT6^`us_^8=Kue)Yee% zmU8EW+%rP1N5~x&av34FQ^@TSa#10-QOGq2IZ?=2gj}1DJ1>Oc7374rr~e|^+Ey#% zUJ`Oo3AwD0a|$_!kh2RpS!g?>QckW4@Th}Fr`qFwmOK?(?$@A-3Osd%J_RVD=Yf9+ znB}Q92+7uhu))G&>nZn&LfRYgH?=D&E0nEtJ>XM-cL4Lak#}G~MU%kH@K?CGCg2r- zwJfEw;twZ`wc&u)%7)5R$pKN&ScJ8fS&NGF_$7_-uoAnxmY@Eh{Er`CquBNZs(V!j z@R^gak!>M9aPm)P>5TBeN#}W~y+*j7ENTHOJ6p*qI1q;^%hO9qEMxo@Y@7ciV*g2T z1JpDposH5t0h^Jkh11fX#NSG9;fz?2Z;I!oSL8El;iU9aaGpFZy)5pNzT0%B44h}2 zX9Ps&WG;GE3`Dtm@slT+bR4J88 z&84Q&>N0IvWf>kw9oE>uywd9Vl`LXkud(qBr?E3LXm*d4rsPKW#fBEWCOkKhG8y^4d=7?2YHc4V`Dos3#w4=**X{ zyS8se5bo^N>+OK0Id;rAWMv%hC*SvRrttqlfWJmM8oBJI@FkxE#sCyO6_>K?J!n3&~85gxlFcJzEb8T2V@*TkkRMpB`))lKF4J8%efi+ zAeo%806|1BlE_6w!N^5;&1bksQ&D8!oX9?25>8`bwc#=h!A$wZOETpbAv4#Je~ZY( zvGD%Xvi{-0j*P8ildU5I*p$Ef<}G#k+zqlkGu+QI9?VA~F%Op=OYg^V~8%p+{TDh(z^cQ9An=7kj-N%%*ju~rV zWv%3TA1N!uvRAUQLaeM1D{E!jN?sQ6QNFHkri|kK*b1D-r&Nm;V#IDTDgAMM<+kN~ z_%2iGcACzqNjOG}8v65#ZSj0LfQ@YYvfIwG@Tp>16<}+MS#>*?DW-GSld+Ih33in& zP8hq>+q2uLu462T|11K#4Aa{gMkZr?Y(RELzHKO(#TLDtc{h%ZUV)>dXG%-K-IVMH zFLH^uXi*1V_$@HKU`Ci=Ny(fb<3$;7!GfY73jV9WYXmOeCOxM*e@bYx2=K4_OY)Y^ zUKMTyy#wfk!GXSWbQrgP0a*o?s_@O2;5XqL9_}ti09GJ@m`*AhI`z`;6AIBq4-vNRY9w?>vlW6M{xwZ{|5j;mIt zR;}(_)78Cp-PJwm-t`-<>FXc3cJR85*KdNWG(3_S-MnS&#;xNwO-ye4yQ%E-_M3Oy z@`+n-yZw_pKb70{>D_nixpVJb`#y8`J^Sya1I+)S`##Gn_>Z5XgZDr1;6wCzqKCh5 zsO0b?M~;5+(Jwvr__5<~g-*~@U;YYFe&*zc*n)2vT7e+Cck=kx#_hX40fc#6y?JpixtES&n&@CcvfKH)R){6^^o?in6|xB3%!nBSlm z>FfC7@I!cm`{28d!F#<4{_6z%&PjN$+qnPAz7jJ3^#|}^Z-ozg8~oSX;e*}}A9g1( dFZM_DV|b*;;F+F;fBHE5(NDuO-Rn3<^j~~j6OsS` From db6c0ee85cd8445c454b12f7899b07606f1a0ec5 Mon Sep 17 00:00:00 2001 From: Themaister Date: Thu, 9 Aug 2012 08:56:35 +0200 Subject: [PATCH 126/492] Use custom matrix calculation routines. Aims for more compatibility with modern OpenGL. --- Makefile | 2 +- Makefile.win | 2 +- gfx/context/sdl_ctx.c | 22 ++++++-- gfx/math/matrix.c | 113 ++++++++++++++++++++++++++++++++++++++++++ gfx/math/matrix.h | 43 ++++++++++++++++ 5 files changed, 177 insertions(+), 5 deletions(-) create mode 100644 gfx/math/matrix.c create mode 100644 gfx/math/matrix.h diff --git a/Makefile b/Makefile index 392593d13f..c4905ede83 100644 --- a/Makefile +++ b/Makefile @@ -135,7 +135,7 @@ ifeq ($(HAVE_X11), 1) endif ifeq ($(HAVE_OPENGL), 1) - OBJ += gfx/gl.o gfx/fonts/freetype.o + OBJ += gfx/gl.o gfx/fonts/freetype.o gfx/math/matrix.o ifeq ($(OSX),1) LIBS += -framework OpenGL else diff --git a/Makefile.win b/Makefile.win index f02a6d15ca..b8fdd29db0 100644 --- a/Makefile.win +++ b/Makefile.win @@ -61,7 +61,7 @@ ifeq ($(TDM_GCC),) endif ifeq ($(HAVE_SDL), 1) - OBJ += gfx/sdl_gfx.o gfx/gl.o gfx/fonts/freetype.o gfx/context/sdl_ctx.o input/sdl_input.o audio/sdl_audio.o fifo_buffer.o + OBJ += gfx/sdl_gfx.o gfx/gl.o gfx/math/matrix.o gfx/fonts/freetype.o gfx/context/sdl_ctx.o input/sdl_input.o audio/sdl_audio.o fifo_buffer.o LIBS += -lSDL DEFINES += -ISDL -DHAVE_SDL endif diff --git a/gfx/context/sdl_ctx.c b/gfx/context/sdl_ctx.c index 51ba0e641e..a8466f7d39 100644 --- a/gfx/context/sdl_ctx.c +++ b/gfx/context/sdl_ctx.c @@ -26,6 +26,7 @@ #endif #include "sdl_ctx.h" +#include "../math/matrix.h" // SDL 1.2 is portable, sure, but you still need some platform specific workarounds ;) // Hopefully SDL 1.3 will solve this more cleanly :D @@ -441,13 +442,28 @@ void gfx_ctx_input_driver(const input_driver_t **input, void **input_data) #ifdef HAVE_OPENGL void gfx_ctx_set_projection(gl_t *gl, const struct gl_ortho *ortho, bool allow_rotate) { + // TODO: Explicitly setting matrix modes is not used for GLES 2.0. glMatrixMode(GL_PROJECTION); - glLoadIdentity(); + + // Calculate projection. + math_matrix proj; + matrix_ortho(&proj, ortho->left, ortho->right, + ortho->bottom, ortho->top, ortho->znear, ortho->zfar); if (allow_rotate) - glRotatef(gl->rotation, 0, 0, 1); + { + math_matrix rot; + matrix_rotate_z(&rot, M_PI * gl->rotation / 180.0f); + matrix_multiply(&proj, &rot, &proj); + } - glOrtho(ortho->left, ortho->right, ortho->bottom, ortho->top, ortho->znear, ortho->zfar); + // Load matrix directly into GL. + // TODO: For GLES 2.0 or similar, we should keep this matrix + // somewhere and pass it directly to the shader. + // It should probably be part of gl_t ... + glLoadMatrixf(proj.data); + + // TODO: Explicitly setting matrix modes is not used for GLES 2.0. glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } diff --git a/gfx/math/matrix.c b/gfx/math/matrix.c new file mode 100644 index 0000000000..d7e358fe91 --- /dev/null +++ b/gfx/math/matrix.c @@ -0,0 +1,113 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include "matrix.h" +#include +#include + +void matrix_identity(math_matrix *mat) +{ + memset(mat, 0, sizeof(*mat)); + for (unsigned i = 0; i < 4; i++) + MAT_ELEM(*mat, i, i) = 1.0f; +} + +void matrix_transpose(math_matrix *out, const math_matrix *in) +{ + math_matrix mat; + for (unsigned i = 0; i < 4; i++) + for (unsigned j = 0; j < 4; j++) + MAT_ELEM(mat, j, i) = MAT_ELEM(*in, i, j); + + *out = mat; +} + +void matrix_rotate_x(math_matrix *mat, float rad) +{ + float cosine = cosf(rad); + float sine = sinf(rad); + + matrix_identity(mat); + + MAT_ELEM(*mat, 1, 1) = cosine; + MAT_ELEM(*mat, 2, 2) = cosine; + MAT_ELEM(*mat, 1, 2) = -sine; + MAT_ELEM(*mat, 2, 1) = sine; +} + +void matrix_rotate_y(math_matrix *mat, float rad) +{ + float cosine = cosf(rad); + float sine = sinf(rad); + + matrix_identity(mat); + + MAT_ELEM(*mat, 0, 0) = cosine; + MAT_ELEM(*mat, 2, 2) = cosine; + MAT_ELEM(*mat, 0, 2) = -sine; + MAT_ELEM(*mat, 2, 0) = sine; +} + +void matrix_rotate_z(math_matrix *mat, float rad) +{ + float cosine = cosf(rad); + float sine = sinf(rad); + + matrix_identity(mat); + + MAT_ELEM(*mat, 0, 0) = cosine; + MAT_ELEM(*mat, 1, 1) = cosine; + MAT_ELEM(*mat, 0, 1) = -sine; + MAT_ELEM(*mat, 1, 0) = sine; +} + +void matrix_ortho(math_matrix *mat, + float left, float right, + float bottom, float top, + float znear, float zfar) +{ + matrix_identity(mat); + + float tx = -(right + left) / (right - left); + float ty = -(top + bottom) / (top - bottom); + float tz = -(zfar + znear) / (zfar - znear); + + MAT_ELEM(*mat, 0, 0) = 2.0f / (right - left); + MAT_ELEM(*mat, 1, 1) = 2.0f / (top - bottom); + MAT_ELEM(*mat, 2, 2) = -2.0f / (zfar - znear); + MAT_ELEM(*mat, 0, 3) = tx; + MAT_ELEM(*mat, 1, 3) = ty; + MAT_ELEM(*mat, 2, 3) = tz; +} + +void matrix_multiply(math_matrix *out, + const math_matrix *a, const math_matrix *b) +{ + math_matrix mat; + + for (unsigned r = 0; r < 4; r++) + { + for (unsigned c = 0; c < 4; c++) + { + float dot = 0.0f; + for (unsigned k = 0; k < 4; k++) + dot += MAT_ELEM(*a, r, k) * MAT_ELEM(*b, k, c); + MAT_ELEM(mat, r, c) = dot; + } + } + + *out = mat; +} + diff --git a/gfx/math/matrix.h b/gfx/math/matrix.h new file mode 100644 index 0000000000..9fc2624287 --- /dev/null +++ b/gfx/math/matrix.h @@ -0,0 +1,43 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef MATH_MATRIX_H__ +#define MATH_MATRIX_H__ + +// Colunm-major matrix (OpenGL-style). +// Reimplements functionality from FF OpenGL pipeline to be able to work on GLES 2.0 and modern GL variants. +typedef struct math_matrix +{ + float data[16]; +} math_matrix; + +#define MAT_ELEM(mat, r, c) ((mat).data[4 * (c) + (r)]) + +void matrix_load_identity(math_matrix *mat); +void matrix_transpose(math_matrix *out, const math_matrix *in); + +void matrix_rotate_x(math_matrix *mat, float rad); +void matrix_rotate_y(math_matrix *mat, float rad); +void matrix_rotate_z(math_matrix *mat, float rad); + +void matrix_ortho(math_matrix *mat, + float left, float right, + float bottom, float top, + float znear, float zfar); + +void matrix_multiply(math_matrix *out, const math_matrix *a, const math_matrix *b); + +#endif + From 749329f455c728aa7cffa226b4b231fc5deb6bf6 Mon Sep 17 00:00:00 2001 From: Themaister Date: Thu, 9 Aug 2012 10:36:42 +0200 Subject: [PATCH 127/492] Fix build if freetype isn't enabled. --- gfx/fonts/freetype.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/fonts/freetype.c b/gfx/fonts/freetype.c index 6c9f1cdb0a..546b5b9683 100644 --- a/gfx/fonts/freetype.c +++ b/gfx/fonts/freetype.c @@ -282,7 +282,7 @@ void gl_render_msg(void *data, const char *msg) struct gl_ortho ortho = {0, 1, 0, 1, -1, 1}; gl_set_projection(gl, &ortho, true); #else - (void)gl; + (void)data; (void)msg; #endif } From 84a6c4d5215c598c4f57ce926f880896ef244622 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Thu, 9 Aug 2012 18:58:08 +0200 Subject: [PATCH 128/492] (RGL) Remove TextureMatrixStack --- console/rgl/ps3/device_ctx.cpp | 3 - console/rgl/ps3/rgl.cpp | 297 +++++++++++++-------------------- console/rgl/ps3/rgl.h | 8 - 3 files changed, 119 insertions(+), 189 deletions(-) diff --git a/console/rgl/ps3/device_ctx.cpp b/console/rgl/ps3/device_ctx.cpp index 1b3d2521a0..ea6f69d375 100644 --- a/console/rgl/ps3/device_ctx.cpp +++ b/console/rgl/ps3/device_ctx.cpp @@ -1220,9 +1220,6 @@ GLAPI void psglSwap(void) LContext->needValidate = PSGL_VALIDATE_ALL; - for(int unit = 0; unit < MAX_TEXTURE_UNITS; unit++) - LContext->TextureCoordsUnits[unit].TextureMatrixStack.dirty = GL_TRUE; - LContext->ModelViewMatrixStack.dirty = GL_TRUE; LContext->ProjectionMatrixStack.dirty = GL_TRUE; LContext->attribs->DirtyMask = (1 << MAX_VERTEX_ATTRIBS) - 1; diff --git a/console/rgl/ps3/rgl.cpp b/console/rgl/ps3/rgl.cpp index fe44fcc25a..5d8239dabd 100644 --- a/console/rgl/ps3/rgl.cpp +++ b/console/rgl/ps3/rgl.cpp @@ -2799,69 +2799,53 @@ static inline void gmmLocalMemcpy( const uint32_t moveSize ) { - CellGcmContextData *thisContext = &_RGLState.fifo; - int32_t offset = 0; - int32_t sizeLeft = moveSize; - int32_t dimension = 4096; + CellGcmContextData *thisContext = &_RGLState.fifo; + int32_t offset = 0; + int32_t sizeLeft = moveSize; + int32_t dimension = 4096; - while (sizeLeft) - { - while(sizeLeft >= dimension*dimension*4) - { - cellGcmSetTransferImage(thisContext, - CELL_GCM_TRANSFER_LOCAL_TO_LOCAL, - dstOffset+offset, - dimension*4, - 0, - 0, - srcOffset+offset, - dimension*4, - 0, - 0, - dimension, - dimension, - 4); - - offset = offset + dimension*dimension*4; - sizeLeft = sizeLeft - (dimension*dimension*4); - } - - dimension = dimension >> 1; - - if (dimension == 32) - break; - } - - if (sizeLeft) - { - cellGcmSetTransferImage(thisContext, - CELL_GCM_TRANSFER_LOCAL_TO_LOCAL, - dstOffset+offset, - sizeLeft, - 0, - 0, - srcOffset+offset, - sizeLeft, - 0, - 0, - sizeLeft/4, - 1, - 4); - } -} - -static inline void gmmMemcpy(const uint32_t dstOffset, const uint32_t srcOffset, const uint32_t moveSize) -{ - if (dstOffset + moveSize <= srcOffset) - gmmLocalMemcpy(dstOffset, srcOffset, moveSize); - else + while (sizeLeft) { - uint32_t moveBlockSize = srcOffset-dstOffset; - uint32_t iterations = (moveSize+moveBlockSize-1)/moveBlockSize; + while(sizeLeft >= dimension*dimension*4) + { + cellGcmSetTransferImage(thisContext, + CELL_GCM_TRANSFER_LOCAL_TO_LOCAL, + dstOffset+offset, + dimension*4, + 0, + 0, + srcOffset+offset, + dimension*4, + 0, + 0, + dimension, + dimension, + 4); - for (uint32_t i = 0; i < iterations; i++) - gmmLocalMemcpy(dstOffset+(i*moveBlockSize), srcOffset+(i*moveBlockSize), moveBlockSize); + offset = offset + dimension*dimension*4; + sizeLeft = sizeLeft - (dimension*dimension*4); + } + + dimension = dimension >> 1; + + if (dimension == 32) + break; } + + if (sizeLeft) + cellGcmSetTransferImage(thisContext, + CELL_GCM_TRANSFER_LOCAL_TO_LOCAL, + dstOffset+offset, + sizeLeft, + 0, + 0, + srcOffset+offset, + sizeLeft, + 0, + 0, + sizeLeft/4, + 1, + 4); } static uint8_t gmmInternalSweep (void) @@ -2912,7 +2896,16 @@ static uint8_t gmmInternalSweep (void) totalMoveSize += moveSize; - gmmMemcpy(dstOffset, srcOffset, moveSize); + if (dstOffset + moveSize <= srcOffset) + gmmLocalMemcpy(dstOffset, srcOffset, moveSize); + else + { + uint32_t moveBlockSize = srcOffset-dstOffset; + uint32_t iterations = (moveSize+moveBlockSize-1)/moveBlockSize; + + for (uint32_t i = 0; i < iterations; i++) + gmmLocalMemcpy(dstOffset+(i*moveBlockSize), srcOffset+(i*moveBlockSize), moveBlockSize); + } pTempBlock = pSrcBlock; @@ -2949,13 +2942,23 @@ static uint8_t gmmInternalSweep (void) pAllocator->startAddress : pBlock->pPrev->base.address + pBlock->pPrev->base.size; uint32_t pinSrcAddress = pTempBlock->base.address; + uint32_t moveSize = pTempBlock->base.size; dstOffset = gmmAddressToOffset(pinDstAddress, 0); srcOffset = gmmAddressToOffset(pinSrcAddress, 0); - totalMoveSize += pTempBlock->base.size; + totalMoveSize += moveSize; - gmmMemcpy(dstOffset, srcOffset, pTempBlock->base.size); + if (dstOffset + moveSize <= srcOffset) + gmmLocalMemcpy(dstOffset, srcOffset, moveSize); + else + { + uint32_t moveBlockSize = srcOffset-dstOffset; + uint32_t iterations = (moveSize+moveBlockSize-1)/moveBlockSize; + + for (uint32_t i = 0; i < iterations; i++) + gmmLocalMemcpy(dstOffset+(i*moveBlockSize), srcOffset+(i*moveBlockSize), moveBlockSize); + } pTempBlock->base.address = pinDstAddress; @@ -3068,26 +3071,6 @@ static void gmmFreeAll (void) } } -static void gmmRemoveFree( - GmmAllocator *pAllocator, - GmmBlock *pBlock, - uint8_t freeIndex -) -{ - - if (pBlock == pAllocator->pFreeHead[freeIndex]) - pAllocator->pFreeHead[freeIndex] = pBlock->pNextFree; - - if (pBlock == pAllocator->pFreeTail[freeIndex]) - pAllocator->pFreeTail[freeIndex] = pBlock->pPrevFree; - - if (pBlock->pNextFree) - pBlock->pNextFree->pPrevFree = pBlock->pPrevFree; - - if (pBlock->pPrevFree) - pBlock->pPrevFree->pNextFree = pBlock->pNextFree; -} - static uint32_t gmmFindFreeBlock( GmmAllocator *pAllocator, uint32_t size @@ -3142,7 +3125,16 @@ static uint32_t gmmFindFreeBlock( gmmAddFree(pAllocator, pNewBlock); } pBlock->base.size = size; - gmmRemoveFree(pAllocator, pBlock, freeIndex); + + if (pBlock == pAllocator->pFreeHead[freeIndex]) + pAllocator->pFreeHead[freeIndex] = pBlock->pNextFree; + if (pBlock == pAllocator->pFreeTail[freeIndex]) + pAllocator->pFreeTail[freeIndex] = pBlock->pPrevFree; + if (pBlock->pNextFree) + pBlock->pNextFree->pPrevFree = pBlock->pPrevFree; + if (pBlock->pPrevFree) + pBlock->pPrevFree->pNextFree = pBlock->pNextFree; + retId = (uint32_t)pBlock; } @@ -3205,7 +3197,6 @@ uint32_t gmmAlloc(const uint8_t isTile, const uint32_t size) return retId; } - static int _RGLLoadFPShader( _CGprogram *program ) { unsigned int ucodeSize = program->header.instructionCount * 16; @@ -3229,16 +3220,6 @@ static int _RGLLoadFPShader( _CGprogram *program ) return GL_TRUE; } -static void _RGLUnloadFPShader( _CGprogram *program ) -{ - if ( program->loadProgramId != GMM_ERROR ) - { - gmmFree( program->loadProgramId ); - program->loadProgramId = GMM_ERROR; - program->loadProgramOffset = 0; - } -} - void _RGLPlatformSetVertexRegister4fv( unsigned int reg, const float * __restrict v ) {} void _RGLPlatformSetVertexRegisterBlock( unsigned int reg, unsigned int count, const float * __restrict v ) {} void _RGLPlatformSetFragmentRegister4fv( unsigned int reg, const float * __restrict v ) {} @@ -4238,7 +4219,14 @@ void _RGLPlatformProgramErase( void* platformProgram ) _CGprogram* program = ( _CGprogram* )platformProgram; if ( program->loadProgramId != GMM_ERROR ) - _RGLUnloadFPShader( program ); + { + if ( program->loadProgramId != GMM_ERROR ) + { + gmmFree( program->loadProgramId ); + program->loadProgramId = GMM_ERROR; + program->loadProgramOffset = 0; + } + } if ( program->runtimeParameters ) { @@ -4834,32 +4822,6 @@ static inline void _RGLSetColorDepthBuffers( RGLRenderTarget *rt, RGLRenderTarge } } -static inline void _RGLSetTarget( RGLRenderTarget *rt, RGLRenderTargetEx const * const args ) -{ - CellGcmSurface * grt = &rt->gcmRenderTarget; - - switch ( rt->colorBufferCount ) - { - case 0: - grt->colorTarget = CELL_GCM_SURFACE_TARGET_NONE; - break; - case 1: - grt->colorTarget = CELL_GCM_SURFACE_TARGET_1; - break; - case 2: - grt->colorTarget = CELL_GCM_SURFACE_TARGET_MRT1; - break; - case 3: - grt->colorTarget = CELL_GCM_SURFACE_TARGET_MRT2; - break; - case 4: - grt->colorTarget = CELL_GCM_SURFACE_TARGET_MRT3; - break; - default: - break; - } -} - void _RGLFifoGlSetRenderTarget( RGLRenderTargetEx const * const args ) { RGLRenderTarget *rt = &_RGLState.renderTarget; @@ -4877,14 +4839,37 @@ void _RGLFifoGlSetRenderTarget( RGLRenderTargetEx const * const args ) grt->antialias = CELL_GCM_SURFACE_CENTER_1; grt->type = CELL_GCM_SURFACE_PITCH; - _RGLSetTarget( rt, args ); + + switch ( rt->colorBufferCount ) + { + case 0: + grt->colorTarget = CELL_GCM_SURFACE_TARGET_NONE; + break; + case 1: + grt->colorTarget = CELL_GCM_SURFACE_TARGET_1; + break; + case 2: + grt->colorTarget = CELL_GCM_SURFACE_TARGET_MRT1; + break; + case 3: + grt->colorTarget = CELL_GCM_SURFACE_TARGET_MRT2; + break; + case 4: + grt->colorTarget = CELL_GCM_SURFACE_TARGET_MRT3; + break; + default: + break; + } cellGcmSetSurfaceInline( &_RGLState.fifo, grt); } -void _RGLSetError( GLenum error ) {} +void _RGLSetError( GLenum error ) +{ + RARCH_ERR("Error code: %d\n", error); +} -GLAPI GLenum APIENTRY glGetError() +GLAPI GLenum APIENTRY glGetError(void) { if ( !_CurrentContext ) return GL_INVALID_OPERATION; @@ -4897,17 +4882,13 @@ GLAPI GLenum APIENTRY glGetError() } } -static uint32_t * _RGLFifoWaitForFreeSpace( RGLFifo *fifo, GLuint spaceInWords ) -{ - if ( fifo->current + spaceInWords + 1024 > fifo->end ) - _RGLOutOfSpaceCallback( fifo, spaceInWords ); - - return _RGLState.fifo.current; -} - static inline void _RGLPushProgramPushBuffer( _CGprogram * cgprog ) { - _RGLFifoWaitForFreeSpace( &_RGLState.fifo, cgprog->constantPushBufferWordSize + 4 + 32); + RGLFifo *fifo = &_RGLState.fifo; + GLuint spaceInWords = cgprog->constantPushBufferWordSize + 4 + 32; + + if ( fifo->current + spaceInWords + 1024 > fifo->end ) + _RGLOutOfSpaceCallback( fifo, spaceInWords ); uint32_t padding_in_word = ( ( 0x10-(((uint32_t)_RGLState.fifo.current)&0xf))&0xf )>>2; uint32_t padded_size = ( ((cgprog->constantPushBufferWordSize)<<2) + 0xf )&~0xf; @@ -4963,7 +4944,11 @@ static GLuint _RGLValidateStates( void ) conf.registerCount = vs->header.vertexProgram.registerCount; conf.attributeInputMask = vs->header.attributeInputMask; - _RGLFifoWaitForFreeSpace( &_RGLState.fifo, 7 + 5 * conf.instructionCount ); + RGLFifo *fifo = &_RGLState.fifo; + GLuint spaceInWords = 7 + 5 * conf.instructionCount; + + if ( fifo->current + spaceInWords + 1024 > fifo->end ) + _RGLOutOfSpaceCallback( fifo, spaceInWords ); cellGcmSetVertexProgramLoadInline( &_RGLState.fifo, &conf, vs->ucode); @@ -5232,12 +5217,6 @@ static void _RGLResetContext( PSGLcontext *LContext ) LContext->BlendFactorSrcAlpha = GL_ONE; LContext->BlendFactorDestAlpha = GL_ZERO; - for ( int i = 0;i < MAX_TEXTURE_COORDS;++i ) - { - jsTextureCoordsUnit *tu = LContext->TextureCoordsUnits + i; - tu->revalidate = 0; - _RGLMatrixStackReset( &( tu->TextureMatrixStack ) ); - } for ( int i = 0;i < MAX_TEXTURE_IMAGE_UNITS;++i ) { jsTextureImageUnit *tu = LContext->TextureImageUnits + i; @@ -5258,7 +5237,6 @@ static void _RGLResetContext( PSGLcontext *LContext ) LContext->ActiveTexture = 0; LContext->CurrentImageUnit = LContext->TextureImageUnits; - LContext->CurrentCoordsUnit = LContext->TextureCoordsUnits; LContext->packAlignment = 4; LContext->unpackAlignment = 4; @@ -5368,16 +5346,6 @@ PSGLcontext* psglCreateContext (void) return NULL; } - for ( int i = 0; i < MAX_TEXTURE_COORDS; i++ ) - { - _RGLMatrixStackInit(&( LContext->TextureCoordsUnits[i].TextureMatrixStack), MAX_TEXTURE_STACK_DEPTH); - if ( !LContext->TextureCoordsUnits[i].TextureMatrixStack.MatrixStackf ) - { - psglDestroyContext( LContext ); - return NULL; - } - } - _RGLTexNameSpaceInit( &LContext->textureNameSpace, ( jsTexNameSpaceCreateFunction )_RGLAllocateTexture, ( jsTexNameSpaceDestroyFunction )_RGLFreeTexture ); for ( int i = 0;i < MAX_TEXTURE_IMAGE_UNITS;++i ) @@ -5486,9 +5454,6 @@ void psglDestroyContext( PSGLcontext* LContext ) _RGLMatrixStackClear( &( LContext->ModelViewMatrixStack ) ); _RGLMatrixStackClear( &( LContext->ProjectionMatrixStack ) ); - for ( int i = 0; i < MAX_TEXTURE_COORDS; i++ ) - _RGLMatrixStackClear( &( LContext->TextureCoordsUnits[i].TextureMatrixStack ) ); - for ( int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i ) { jsTextureImageUnit* tu = LContext->TextureImageUnits + i; @@ -5519,9 +5484,6 @@ void _RGLAttachContext( PSGLdevice *device, PSGLcontext* context ) } context->needValidate = PSGL_VALIDATE_ALL; - for (int unit = 0; unit < MAX_TEXTURE_UNITS; unit++) - context->TextureCoordsUnits[unit].TextureMatrixStack.dirty = GL_TRUE; - context->ModelViewMatrixStack.dirty = GL_TRUE; context->ProjectionMatrixStack.dirty = GL_TRUE; context->attribs->DirtyMask = ( 1 << MAX_VERTEX_ATTRIBS ) - 1; @@ -5545,14 +5507,6 @@ GLAPI void APIENTRY glGetFloatv( GLenum pname, GLfloat* params ) if (LMatrixStack) LMatrix = LMatrixStack->MatrixStackf + LMatrixStack->MatrixStackPtr * ELEMENTS_IN_MATRIX; break; - case GL_TEXTURE_MATRIX: - if ((LContext)->CurrentCoordsUnit) - LMatrixStack = &((LContext)->CurrentCoordsUnit->TextureMatrixStack); - else - LMatrixStack = NULL; - if (LMatrixStack) - LMatrix = LMatrixStack->MatrixStackf + LMatrixStack->MatrixStackPtr * ELEMENTS_IN_MATRIX; - break; case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: return; default: @@ -5811,12 +5765,6 @@ GLAPI void APIENTRY glLoadIdentity(void) case GL_PROJECTION: LMatrixStack = &((LContext)->ProjectionMatrixStack); break; - case GL_TEXTURE: - if ((LContext)->CurrentCoordsUnit) - LMatrixStack = &((LContext)->CurrentCoordsUnit->TextureMatrixStack); - else - LMatrixStack=NULL; - break; default: break; } @@ -5846,12 +5794,6 @@ GLAPI void APIENTRY glOrthof( GLfloat left, GLfloat right, GLfloat bottom, GLflo case GL_PROJECTION: LMatrixStack = &((LContext)->ProjectionMatrixStack); break; - case GL_TEXTURE: - if ((LContext)->CurrentCoordsUnit) - LMatrixStack = &((LContext)->CurrentCoordsUnit->TextureMatrixStack); - else - LMatrixStack=NULL; - break; default: break; } @@ -6451,7 +6393,6 @@ GLAPI void APIENTRY glActiveTexture(GLenum texture) int unit = texture - GL_TEXTURE0; LContext->ActiveTexture = unit; LContext->CurrentImageUnit = unit < MAX_TEXTURE_IMAGE_UNITS ? LContext->TextureImageUnits + unit : NULL; - LContext->CurrentCoordsUnit = unit < MAX_TEXTURE_COORDS ? LContext->TextureCoordsUnits + unit : NULL; } GLAPI void APIENTRY glClientActiveTexture(GLenum texture) diff --git a/console/rgl/ps3/rgl.h b/console/rgl/ps3/rgl.h index 0fb0a4d9e6..de9ee1b414 100644 --- a/console/rgl/ps3/rgl.h +++ b/console/rgl/ps3/rgl.h @@ -283,12 +283,6 @@ typedef struct jsTexture* currentTexture; } jsTextureImageUnit; -typedef struct -{ - GLuint revalidate; - jsMatrixStack TextureMatrixStack; -} jsTextureCoordsUnit; - enum { FRAMEBUFFER_ATTACHMENT_NONE, @@ -513,8 +507,6 @@ struct PSGLcontext GLuint CS_ActiveTexture; jsTextureImageUnit TextureImageUnits[MAX_TEXTURE_IMAGE_UNITS]; jsTextureImageUnit* CurrentImageUnit; - jsTextureCoordsUnit TextureCoordsUnits[MAX_TEXTURE_COORDS]; - jsTextureCoordsUnit* CurrentCoordsUnit; jsTexture *VertexTextureImages[MAX_VERTEX_TEXTURE_IMAGE_UNITS]; GLsizei packAlignment; GLsizei unpackAlignment; From 04a5a174091002bd7c742d2115ed7551bb9f036c Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Thu, 9 Aug 2012 19:17:07 +0200 Subject: [PATCH 129/492] (PSL1GHT) Add PSL1GHT semaphore redefinitions --- console/rgl/ps3/rgl.h | 2 +- ps3/sdk_defines.h | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/console/rgl/ps3/rgl.h b/console/rgl/ps3/rgl.h index de9ee1b414..5016752d1a 100644 --- a/console/rgl/ps3/rgl.h +++ b/console/rgl/ps3/rgl.h @@ -774,7 +774,7 @@ struct RGLResource RGLSemaphoreMemory *semaphores; }; -typedef volatile struct +typedef struct { GLuint Ignored00[0x010]; GLuint Put; diff --git a/ps3/sdk_defines.h b/ps3/sdk_defines.h index 0b6d455519..398b6050e0 100644 --- a/ps3/sdk_defines.h +++ b/ps3/sdk_defines.h @@ -310,6 +310,20 @@ #define SYS_PPU_THREAD_CREATE_JOINABLE 0 /* FIXME - not sure if this is correct */ #endif +/*============================================================ + SEMAPHORE PROTOTYPES +============================================================ */ + +#ifdef __PSL1GHT__ +#include +#define sys_semaphore_attribute_t sys_sem_attr_t +#define sys_semaphore_value_t s32 + +#define sys_semaphore_create sysSemCreate +#define sys_semaphore_destroy sysSemDestroy +#define sys_semaphore_post sysSemPost +#endif + /*============================================================ MEMORY PROTOTYPES ============================================================ */ From 450b59262b8af314a2313fdc44b6f9df944c2d90 Mon Sep 17 00:00:00 2001 From: Themaister Date: Thu, 9 Aug 2012 22:06:31 +0200 Subject: [PATCH 130/492] Avoid redundant FF GL calls. --- gfx/gl.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/gfx/gl.c b/gfx/gl.c index 0c836d7bf5..36f83c299b 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -1106,9 +1106,6 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo glDisable(GL_DITHER); glClearColor(0, 0, 0, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_COLOR_ARRAY); From c45c49c5c2016a4b67af5e6f091a85cdc46fc7ec Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Thu, 9 Aug 2012 22:15:30 +0200 Subject: [PATCH 131/492] (RGL) Include cgGLSetMatrixParameterfc --- console/rgl/ps3/cg.h | 2 ++ console/rgl/ps3/rgl.cpp | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/console/rgl/ps3/cg.h b/console/rgl/ps3/cg.h index 7e615b58a6..ddb6cad2c7 100644 --- a/console/rgl/ps3/cg.h +++ b/console/rgl/ps3/cg.h @@ -453,6 +453,8 @@ inline int _RGLGetProgramProfileIndex( CGprofile profile ) return -1; } +CGGL_API void cgGLSetMatrixParameterfc( CGparameter param, const float *matrix ); + #ifdef __cplusplus } #endif diff --git a/console/rgl/ps3/rgl.cpp b/console/rgl/ps3/rgl.cpp index 5d8239dabd..845cdd25c8 100644 --- a/console/rgl/ps3/rgl.cpp +++ b/console/rgl/ps3/rgl.cpp @@ -8413,3 +8413,9 @@ unsigned int _RGLGetTypeColCount( CGtype parameterType ) int typeIndex = parameterType - 1 - CG_TYPE_START_ENUM; return _typesColCount[typeIndex]; } + +CGGL_API void cgGLSetMatrixParameterfc( CGparameter param, const float *matrix ) +{ + CgRuntimeParameter* ptr = _cgGetParamPtr( param ); + ptr->settercIndex( ptr, matrix, CG_GETINDEX( param ) ); +} From 77b2ed5514a8558b6d6c4d6f07f1768cb06d6d54 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Thu, 9 Aug 2012 23:06:39 +0200 Subject: [PATCH 132/492] Revert "(PSL1GHT) Add PSL1GHT semaphore redefinitions" This reverts commit 04a5a174091002bd7c742d2115ed7551bb9f036c. --- console/rgl/ps3/rgl.h | 2 +- ps3/sdk_defines.h | 14 -------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/console/rgl/ps3/rgl.h b/console/rgl/ps3/rgl.h index 5016752d1a..de9ee1b414 100644 --- a/console/rgl/ps3/rgl.h +++ b/console/rgl/ps3/rgl.h @@ -774,7 +774,7 @@ struct RGLResource RGLSemaphoreMemory *semaphores; }; -typedef struct +typedef volatile struct { GLuint Ignored00[0x010]; GLuint Put; diff --git a/ps3/sdk_defines.h b/ps3/sdk_defines.h index 398b6050e0..0b6d455519 100644 --- a/ps3/sdk_defines.h +++ b/ps3/sdk_defines.h @@ -310,20 +310,6 @@ #define SYS_PPU_THREAD_CREATE_JOINABLE 0 /* FIXME - not sure if this is correct */ #endif -/*============================================================ - SEMAPHORE PROTOTYPES -============================================================ */ - -#ifdef __PSL1GHT__ -#include -#define sys_semaphore_attribute_t sys_sem_attr_t -#define sys_semaphore_value_t s32 - -#define sys_semaphore_create sysSemCreate -#define sys_semaphore_destroy sysSemDestroy -#define sys_semaphore_post sysSemPost -#endif - /*============================================================ MEMORY PROTOTYPES ============================================================ */ From a283a54bee5198b622af41827cd5c6a1e30df7c2 Mon Sep 17 00:00:00 2001 From: Themaister Date: Thu, 9 Aug 2012 22:33:32 +0200 Subject: [PATCH 133/492] Use calculated MVP directly in shader params. --- gfx/context/ps3_ctx.c | 31 ++++++++----------------------- gfx/context/sdl_ctx.c | 2 ++ gfx/gl.c | 8 ++++---- gfx/gl_common.h | 2 ++ gfx/shader_cg.c | 4 ++-- gfx/shader_cg.h | 3 ++- gfx/shader_glsl.c | 8 ++++++-- gfx/shader_glsl.h | 3 ++- 8 files changed, 28 insertions(+), 33 deletions(-) diff --git a/gfx/context/ps3_ctx.c b/gfx/context/ps3_ctx.c index 41e341e7e7..57d1d78fb7 100644 --- a/gfx/context/ps3_ctx.c +++ b/gfx/context/ps3_ctx.c @@ -356,34 +356,19 @@ const char *ps3_get_resolution_label(uint32_t resolution) void gfx_ctx_set_projection(gl_t *gl, const struct gl_ortho *ortho, bool allow_rotate) { - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); + // Calculate projection. + math_matrix proj; + matrix_ortho(&proj, ortho->left, ortho->right, + ortho->bottom, ortho->top, ortho->znear, ortho->zfar); if (allow_rotate) { - switch (gl->rotation) - { - case 90: - vertex_ptr = vertexes_90; - break; - case 180: - vertex_ptr = vertexes_180; - break; - case 270: - vertex_ptr = vertexes_270; - break; - case 0: - default: - vertex_ptr = default_vertex_ptr; - break; - } + math_matrix rot; + matrix_rotate_z(&rot, M_PI * gl->rotation / 180.0f); + matrix_multiply(&proj, &rot, &proj); } - glVertexPointer(2, GL_FLOAT, 0, vertex_ptr); - - glOrtho(ortho->left, ortho->right, ortho->bottom, ortho->top, ortho->znear, ortho->zfar); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + gl->mvp = proj; } void gfx_ctx_set_aspect_ratio(void *data, unsigned aspectratio_index) diff --git a/gfx/context/sdl_ctx.c b/gfx/context/sdl_ctx.c index a8466f7d39..7b0fe608c4 100644 --- a/gfx/context/sdl_ctx.c +++ b/gfx/context/sdl_ctx.c @@ -466,6 +466,8 @@ void gfx_ctx_set_projection(gl_t *gl, const struct gl_ortho *ortho, bool allow_r // TODO: Explicitly setting matrix modes is not used for GLES 2.0. glMatrixMode(GL_MODELVIEW); glLoadIdentity(); + + gl->mvp = proj; } #endif diff --git a/gfx/gl.c b/gfx/gl.c index 36f83c299b..50467d3664 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -203,14 +203,14 @@ static inline void gl_shader_deinit(void) #endif } -static inline void gl_shader_set_proj_matrix(void) +static inline void gl_shader_set_proj_matrix(const math_matrix *mat) { #ifdef HAVE_CG - gl_cg_set_proj_matrix(); + gl_cg_set_proj_matrix(mat); #endif #ifdef HAVE_XML - gl_glsl_set_proj_matrix(); + gl_glsl_set_proj_matrix(mat); #endif } @@ -440,7 +440,7 @@ void gl_set_projection(gl_t *gl, struct gl_ortho *ortho, bool allow_rotate) #endif gfx_ctx_set_projection(gl, ortho, allow_rotate); - gl_shader_set_proj_matrix(); + gl_shader_set_proj_matrix(&gl->mvp); } void gl_set_viewport(gl_t *gl, unsigned width, unsigned height, bool force_full, bool allow_rotate) diff --git a/gfx/gl_common.h b/gfx/gl_common.h index 906f27adda..277ee37a4b 100644 --- a/gfx/gl_common.h +++ b/gfx/gl_common.h @@ -18,6 +18,7 @@ #include "../general.h" #include "fonts/fonts.h" +#include "math/matrix.h" #ifdef HAVE_CONFIG_H #include "../config.h" @@ -179,6 +180,7 @@ typedef struct gl unsigned last_height[TEXTURES]; unsigned tex_w, tex_h; GLfloat tex_coords[8]; + math_matrix mvp; #ifdef __CELLOS_LV2__ GLuint pbo; diff --git a/gfx/shader_cg.c b/gfx/shader_cg.c index e41bf117a9..825db7ad2f 100644 --- a/gfx/shader_cg.c +++ b/gfx/shader_cg.c @@ -149,10 +149,10 @@ static void gl_cg_reset_attrib(void) cg_attrib_index = 0; } -void gl_cg_set_proj_matrix(void) +void gl_cg_set_proj_matrix(const math_matrix *mat) { if (cg_active && prg[active_index].mvp) - cgGLSetStateMatrixParameter(prg[active_index].mvp, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY); + cgGLSetMatrixParameterfc(prg[active_index].mvp, mat->data); } #define set_param_2f(param, x, y) \ diff --git a/gfx/shader_cg.h b/gfx/shader_cg.h index 3af257e990..162013b9a7 100644 --- a/gfx/shader_cg.h +++ b/gfx/shader_cg.h @@ -19,6 +19,7 @@ #include "../boolean.h" #include "gl_common.h" +#include "math/matrix.h" #include bool gl_cg_init(const char *path); @@ -26,7 +27,7 @@ bool gl_cg_reinit(const char *path); void gl_cg_deinit(void); -void gl_cg_set_proj_matrix(void); +void gl_cg_set_proj_matrix(const math_matrix *mat); void gl_cg_set_params(unsigned width, unsigned height, unsigned tex_width, unsigned tex_height, diff --git a/gfx/shader_glsl.c b/gfx/shader_glsl.c index 9956d5d05c..b96db992fa 100644 --- a/gfx/shader_glsl.c +++ b/gfx/shader_glsl.c @@ -1225,8 +1225,12 @@ void gl_glsl_set_params(unsigned width, unsigned height, } } -void gl_glsl_set_proj_matrix(void) -{} +void gl_glsl_set_proj_matrix(const math_matrix *mat) +{ + // If we're using FF-based GL, this matrix + // will be implicitly passed to the shader. + (void)mat; +} void gl_glsl_use(unsigned index) { diff --git a/gfx/shader_glsl.h b/gfx/shader_glsl.h index f834e0e0cd..b0dba1b8bd 100644 --- a/gfx/shader_glsl.h +++ b/gfx/shader_glsl.h @@ -19,12 +19,13 @@ #include "../boolean.h" #include "gl_common.h" +#include "math/matrix.h" bool gl_glsl_init(const char *path); void gl_glsl_deinit(void); -void gl_glsl_set_proj_matrix(void); +void gl_glsl_set_proj_matrix(const math_matrix *mat); void gl_glsl_set_params(unsigned width, unsigned height, unsigned tex_width, unsigned tex_height, From c369aa97dfce7017ce7dd246b5a07b9f3b2275ab Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Thu, 9 Aug 2012 23:20:39 +0200 Subject: [PATCH 134/492] (RGL) Uses custom matrix code --- console/griffin/griffin.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index b95be707ad..a4f814d4fe 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -124,6 +124,10 @@ VIDEO IMAGE VIDEO DRIVER ============================================================ */ +#if defined(__CELLOS_LV2__) +#include "../../gfx/math/matrix.c" +#endif + #if defined(HAVE_OPENGL) #include "../../gfx/gl.c" #elif defined(GEKKO) From f4ecdf2bceef7f1793f6af4e62c89ebd56320e0f Mon Sep 17 00:00:00 2001 From: Themaister Date: Thu, 9 Aug 2012 23:53:15 +0200 Subject: [PATCH 135/492] Remove use of cgGLSetStateMatrixParameter. --- gfx/shader_cg.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/gfx/shader_cg.c b/gfx/shader_cg.c index 825db7ad2f..36ba6d68e3 100644 --- a/gfx/shader_cg.c +++ b/gfx/shader_cg.c @@ -1021,8 +1021,6 @@ static void set_program_attributes(unsigned i) prg[i].frame_cnt_v = cgGetNamedParameter(prg[i].vprg, "IN.frame_count"); prg[i].frame_dir_v = cgGetNamedParameter(prg[i].vprg, "IN.frame_direction"); prg[i].mvp = cgGetNamedParameter(prg[i].vprg, "modelViewProj"); - if (prg[i].mvp) - cgGLSetStateMatrixParameter(prg[i].mvp, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY); if (i == RARCH_CG_MENU_SHADER_INDEX) return; @@ -1133,8 +1131,6 @@ bool gl_cg_init(const char *path) return false; prg[0].mvp = cgGetNamedParameter(prg[0].vprg, "modelViewProj"); - if (prg[0].mvp) - cgGLSetStateMatrixParameter(prg[0].mvp, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY); for (unsigned i = 1; i <= cg_shader_num; i++) set_program_attributes(i); From 92d18ec2f1a44ff8b001b843bf02b1c38948e0c3 Mon Sep 17 00:00:00 2001 From: Themaister Date: Fri, 10 Aug 2012 00:03:14 +0200 Subject: [PATCH 136/492] Add small test for RETRO_KEYBOARD to libretro-test. --- libretro-test/libretro-test.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libretro-test/libretro-test.c b/libretro-test/libretro-test.c index c4f92179f9..f2a9abc931 100644 --- a/libretro-test/libretro-test.c +++ b/libretro-test/libretro-test.c @@ -3,6 +3,7 @@ #include #include #include +#include static uint16_t *frame_buf; @@ -115,6 +116,9 @@ static void update_input(void) if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT)) dir_x++; + if (input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_RETURN)) + fprintf(stderr, "Return key is pressed!\n"); + dir_x += input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X) / 2000; dir_y += input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y) / 2000; //dir_x += input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X) / 2000; From e2c96f9a09710e4293e63ecae35389292110f2d9 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 10 Aug 2012 00:00:06 +0200 Subject: [PATCH 137/492] (RGL) Big cleanup --- console/rgl/ps3/device_ctx.cpp | 2 - console/rgl/ps3/gl.h | 4 - console/rgl/ps3/rgl.cpp | 236 --------------------------------- console/rgl/ps3/rgl.h | 10 -- 4 files changed, 252 deletions(-) diff --git a/console/rgl/ps3/device_ctx.cpp b/console/rgl/ps3/device_ctx.cpp index ea6f69d375..205c189ff2 100644 --- a/console/rgl/ps3/device_ctx.cpp +++ b/console/rgl/ps3/device_ctx.cpp @@ -1220,8 +1220,6 @@ GLAPI void psglSwap(void) LContext->needValidate = PSGL_VALIDATE_ALL; - LContext->ModelViewMatrixStack.dirty = GL_TRUE; - LContext->ProjectionMatrixStack.dirty = GL_TRUE; LContext->attribs->DirtyMask = (1 << MAX_VERTEX_ATTRIBS) - 1; cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo); diff --git a/console/rgl/ps3/gl.h b/console/rgl/ps3/gl.h index bfba05e1ca..5730f7959a 100644 --- a/console/rgl/ps3/gl.h +++ b/console/rgl/ps3/gl.h @@ -310,10 +310,6 @@ GLAPI void APIENTRY glFlush( void ); GLAPI void APIENTRY glGenTextures( GLsizei n, GLuint *textures ); GLAPI GLenum APIENTRY glGetError( void ); GLAPI const GLubyte * APIENTRY glGetString( GLenum name ); -GLAPI void APIENTRY glLoadIdentity( void ); -GLAPI void APIENTRY glMatrixMode( GLenum mode ); -GLAPI void APIENTRY glOrthof( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar ); -GLAPI void APIENTRY glRotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z ); GLAPI void APIENTRY glPixelStorei( GLenum pname, GLint param ); GLAPI void APIENTRY glTexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer ); GLAPI void APIENTRY glTexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels ); diff --git a/console/rgl/ps3/rgl.cpp b/console/rgl/ps3/rgl.cpp index 845cdd25c8..b53fea2d51 100644 --- a/console/rgl/ps3/rgl.cpp +++ b/console/rgl/ps3/rgl.cpp @@ -5166,25 +5166,8 @@ PSGLcontext *psglGetCurrentContext() return _CurrentContext; } -const GLfloat _RGLIdentityMatrixf[ELEMENTS_IN_MATRIX] = -{ - 1.f, 0.f, 0.f, 0.f, - 0.f, 1.f, 0.f, 0.f, - 0.f, 0.f, 1.f, 0.f, - 0.f, 0.f, 0.f, 1.f -}; - -static void _RGLMatrixStackReset( jsMatrixStack* LMatrixStack ) -{ - LMatrixStack->MatrixStackPtr = 0; - memcpy( LMatrixStack->MatrixStackf, _RGLIdentityMatrixf, sizeof(GLfloat)*ELEMENTS_IN_MATRIX ); - LMatrixStack->dirty = GL_TRUE; -} - static void _RGLResetContext( PSGLcontext *LContext ) { - _RGLMatrixStackReset( &( LContext->ModelViewMatrixStack ) ); - _RGLMatrixStackReset( &( LContext->ProjectionMatrixStack ) ); _RGLTexNameSpaceResetNames( &LContext->textureNameSpace ); _RGLTexNameSpaceResetNames( &LContext->bufferObjectNameSpace ); _RGLTexNameSpaceResetNames( &LContext->framebufferNameSpace ); @@ -5265,16 +5248,6 @@ static void _RGLResetContext( PSGLcontext *LContext ) LContext->AllowTXPDemotion = GL_FALSE; } -static void _RGLMatrixStackInit( jsMatrixStack* LMatrixStack, GLuint depth ) -{ - LMatrixStack->MatrixStackf = (GLfloat *)malloc( sizeof(GLfloat)*ELEMENTS_IN_MATRIX * depth ); - - if (!LMatrixStack->MatrixStackf) - return; - - _RGLMatrixStackReset(LMatrixStack); -} - static jsTexture *_RGLAllocateTexture (void) { GLuint size = sizeof( jsTexture ) + sizeof( RGLTexture); @@ -5331,21 +5304,6 @@ PSGLcontext* psglCreateContext (void) memset( LContext, 0, sizeof( PSGLcontext ) ); LContext->error = GL_NO_ERROR; - LContext->MatrixMode = GL_MODELVIEW; - - _RGLMatrixStackInit( &( LContext->ModelViewMatrixStack ), _RGL_MAX_MODELVIEW_STACK_DEPTH ); - if ( !LContext->ModelViewMatrixStack.MatrixStackf ) - { - psglDestroyContext( LContext ); - return NULL; - } - _RGLMatrixStackInit( &( LContext->ProjectionMatrixStack ), _RGL_MAX_PROJECTION_STACK_DEPTH ); - if ( !LContext->ProjectionMatrixStack.MatrixStackf ) - { - psglDestroyContext( LContext ); - return NULL; - } - _RGLTexNameSpaceInit( &LContext->textureNameSpace, ( jsTexNameSpaceCreateFunction )_RGLAllocateTexture, ( jsTexNameSpaceDestroyFunction )_RGLFreeTexture ); for ( int i = 0;i < MAX_TEXTURE_IMAGE_UNITS;++i ) @@ -5399,15 +5357,6 @@ void psglResetCurrentContext (void) context->needValidate |= PSGL_VALIDATE_ALL; } -static void _RGLMatrixStackClear( jsMatrixStack* LMatrixStack ) -{ - if(LMatrixStack->MatrixStackf) - free( LMatrixStack->MatrixStackf ); - LMatrixStack->MatrixStackf = NULL; - LMatrixStack->MatrixStackPtr = 0; - LMatrixStack->dirty = GL_FALSE; -} - static bool context_shutdown = false; void psglDestroyContext( PSGLcontext* LContext ) @@ -5451,9 +5400,6 @@ void psglDestroyContext( PSGLcontext* LContext ) if ( _RGLContextDestroyHook ) _RGLContextDestroyHook( LContext ); - _RGLMatrixStackClear( &( LContext->ModelViewMatrixStack ) ); - _RGLMatrixStackClear( &( LContext->ProjectionMatrixStack ) ); - for ( int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i ) { jsTextureImageUnit* tu = LContext->TextureImageUnits + i; @@ -5484,38 +5430,9 @@ void _RGLAttachContext( PSGLdevice *device, PSGLcontext* context ) } context->needValidate = PSGL_VALIDATE_ALL; - context->ModelViewMatrixStack.dirty = GL_TRUE; - context->ProjectionMatrixStack.dirty = GL_TRUE; context->attribs->DirtyMask = ( 1 << MAX_VERTEX_ATTRIBS ) - 1; } -GLAPI void APIENTRY glGetFloatv( GLenum pname, GLfloat* params ) -{ - PSGLcontext* LContext = _CurrentContext; - jsMatrixStack* LMatrixStack = NULL; - GLfloat *LMatrix = NULL; - - switch (pname) - { - case GL_MODELVIEW_MATRIX: - LMatrixStack = &((LContext)->ModelViewMatrixStack); - if (LMatrixStack) - LMatrix = LMatrixStack->MatrixStackf + LMatrixStack->MatrixStackPtr * ELEMENTS_IN_MATRIX; - break; - case GL_PROJECTION_MATRIX: - LMatrixStack = &((LContext)->ProjectionMatrixStack); - if (LMatrixStack) - LMatrix = LMatrixStack->MatrixStackf + LMatrixStack->MatrixStackPtr * ELEMENTS_IN_MATRIX; - break; - case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: - return; - default: - _RGLSetError( GL_INVALID_ENUM ); - return; - } - memcpy(params, LMatrixStack->MatrixStackf + LMatrixStack->MatrixStackPtr * ELEMENTS_IN_MATRIX, sizeof(GLfloat) * ELEMENTS_IN_MATRIX); -} - GLAPI void APIENTRY glEnable( GLenum cap ) { PSGLcontext* LContext = _CurrentContext; @@ -5752,104 +5669,6 @@ void psglExit (void) #undef __STRICT_ANSI__ -GLAPI void APIENTRY glLoadIdentity(void) -{ - PSGLcontext* LContext = _CurrentContext; - jsMatrixStack* LMatrixStack = NULL; - - switch(LContext->MatrixMode) - { - case GL_MODELVIEW: - LMatrixStack = &((LContext)->ModelViewMatrixStack); - break; - case GL_PROJECTION: - LMatrixStack = &((LContext)->ProjectionMatrixStack); - break; - default: - break; - } - - memcpy( LMatrixStack->MatrixStackf + LMatrixStack->MatrixStackPtr * ELEMENTS_IN_MATRIX, _RGLIdentityMatrixf, sizeof(GLfloat)*ELEMENTS_IN_MATRIX ); - - LMatrixStack->dirty = GL_TRUE; -} - -GLAPI void APIENTRY glMatrixMode( GLenum mode ) -{ - PSGLcontext* LContext = _CurrentContext; - LContext->MatrixMode = mode; -} - -GLAPI void APIENTRY glOrthof( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar ) -{ - PSGLcontext* LContext = _CurrentContext; - jsMatrixStack* LMatrixStack = NULL; - GLfloat *LMatrix = NULL; - - switch(LContext->MatrixMode) - { - case GL_MODELVIEW: - LMatrixStack = &((LContext)->ModelViewMatrixStack); - break; - case GL_PROJECTION: - LMatrixStack = &((LContext)->ProjectionMatrixStack); - break; - default: - break; - } - - if (LMatrixStack) - LMatrix = LMatrixStack->MatrixStackf + LMatrixStack->MatrixStackPtr * ELEMENTS_IN_MATRIX; - - GLfloat L00, L01, L02, L03, L10, L11, L12, L13, L20, L21, L22, L23, L30, L31, L32, L33; - - GLfloat m00 = 2.f / ( right - left ); - GLfloat m03 = -( right + left ) / ( right - left ); - GLfloat m11 = 2.f / ( top - bottom ); - GLfloat m13 = -( top + bottom ) / ( top - bottom ); - GLfloat m22 = -2.f / ( zFar - zNear ); - GLfloat m23 = -( zFar + zNear ) / ( zFar - zNear ); - - L00 = LMatrix[0]; - L01 = LMatrix[4]; - L02 = LMatrix[8]; - L03 = LMatrix[12]; - L10 = LMatrix[1]; - L11 = LMatrix[5]; - L12 = LMatrix[9]; - L13 = LMatrix[13]; - L20 = LMatrix[2]; - L21 = LMatrix[6]; - L22 = LMatrix[10]; - L23 = LMatrix[14]; - L30 = LMatrix[3]; - L31 = LMatrix[7]; - L32 = LMatrix[11]; - L33 = LMatrix[15]; - - LMatrix[0] *= m00; - LMatrix[4] *= m11; - LMatrix[8] *= m22; - LMatrix[12] = L00 * m03 + L01 * m13 + L02 * m23 + L03; - - LMatrix[1] *= m00; - LMatrix[5] *= m11; - LMatrix[9] *= m22; - LMatrix[13] = L10 * m03 + L11 * m13 + L12 * m23 + L13; - - LMatrix[2] *= m00; - LMatrix[6] *= m11; - LMatrix[10] *= m22; - LMatrix[14] = L20 * m03 + L21 * m13 + L22 * m23 + L23; - - LMatrix[3] *= m00; - LMatrix[7] *= m11; - LMatrix[11] *= m22; - LMatrix[15] = L30 * m03 + L31 * m13 + L32 * m23 + L33; - - LMatrixStack->dirty = GL_TRUE; -} - GLAPI void APIENTRY glVertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid* pointer ) { _RGLVertexAttribPointerNV( _RGL_ATTRIB_POSITION_INDEX, size, type, GL_FALSE, stride, pointer ); @@ -7967,61 +7786,6 @@ CGGL_API void cgGLDisableClientState( CGparameter param ) _RGLDisableVertexAttribArrayNV( index ); } -CGGL_API void cgGLSetStateMatrixParameter( CGparameter param, - CGGLenum matrix, - CGGLenum transform ) -{ - float m[4][4]; - switch ( matrix ) - { - case CG_GL_MODELVIEW_MATRIX: - glGetFloatv( GL_MODELVIEW_MATRIX, ( float* )m ); - break; - case CG_GL_PROJECTION_MATRIX: - glGetFloatv( GL_PROJECTION_MATRIX, ( float* )m ); - break; - case CG_GL_TEXTURE_MATRIX: - glGetFloatv( GL_TEXTURE_MATRIX, ( float* )m ); - break; - case CG_GL_MODELVIEW_PROJECTION_MATRIX: - { - float mv[4][4], p[4][4]; - glGetFloatv( GL_MODELVIEW_MATRIX, ( float* )mv ); - glGetFloatv( GL_PROJECTION_MATRIX, ( float* )p ); - -#define M(I,J) \ - m[I][J] = mv[I][0]*p[0][J] + mv[I][1]*p[1][J] + mv[I][2]*p[2][J] + mv[I][3]*p[3][J] - M( 0, 0 ); M( 0, 1 ); M( 0, 2 ); M( 0, 3 ); - M( 1, 0 ); M( 1, 1 ); M( 1, 2 ); M( 1, 3 ); - M( 2, 0 ); M( 2, 1 ); M( 2, 2 ); M( 2, 3 ); - M( 3, 0 ); M( 3, 1 ); M( 3, 2 ); M( 3, 3 ); -#undef M - } - break; - default: - _RGLCgRaiseError( CG_INVALID_ENUMERANT_ERROR ); - return; - } - - CgRuntimeParameter* ptr = _cgGetParamPtr( param ); - - CGtype parameterType = _RGLGetParameterCGtype( ptr->program, ptr->parameterEntry ); - if ( RGL_LIKELY( parameterType == CG_FLOAT4x4 ) ) - { - ptr->settercIndex( ptr, m, CG_GETINDEX( param ) ); - } - else - { - float packedmatrix[16]; - unsigned int rows = _RGLGetTypeRowCount( parameterType ); - unsigned int cols = _RGLGetTypeColCount( parameterType ); - for ( GLuint row = 0; row < rows; ++row ) - for ( GLuint j = 0; j < cols; ++j ) - packedmatrix[row*cols + j] = m[j][row]; - ptr->setterrIndex( ptr, packedmatrix, CG_GETINDEX( param ) ); - } -} - CGGL_API void cgGLSetTextureParameter( CGparameter param, GLuint texobj ) { CgRuntimeParameter* ptr = _cgGetParamPtr(param); diff --git a/console/rgl/ps3/rgl.h b/console/rgl/ps3/rgl.h index de9ee1b414..7783a7c382 100644 --- a/console/rgl/ps3/rgl.h +++ b/console/rgl/ps3/rgl.h @@ -180,13 +180,6 @@ typedef struct GLfloat R, G, B, A; } jsColorRGBAf; -typedef struct -{ - GLfloat * MatrixStackf; - int MatrixStackPtr; - GLboolean dirty; -} jsMatrixStack; - typedef struct { int X, Y, XSize, YSize; @@ -482,9 +475,6 @@ jsTexNameSpace; struct PSGLcontext { GLenum error; - int MatrixMode; - jsMatrixStack ModelViewMatrixStack; - jsMatrixStack ProjectionMatrixStack; jsViewPort ViewPort; jsAttributeState defaultAttribs0; jsAttributeState *attribs; From 44209a4318bb90cda8cefc6cf18d58801fdfb481 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 10 Aug 2012 00:28:43 +0200 Subject: [PATCH 138/492] (PS3) Remove hardcoded tex coord matrices --- gfx/context/ps3_ctx.c | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/gfx/context/ps3_ctx.c b/gfx/context/ps3_ctx.c index 57d1d78fb7..c94db989b1 100644 --- a/gfx/context/ps3_ctx.c +++ b/gfx/context/ps3_ctx.c @@ -37,32 +37,6 @@ static struct texture_image menu_texture; static PSGLdevice* gl_device; static PSGLcontext* gl_context; -// Other vertex orientations -static const GLfloat vertexes_90[] = { - 0, 1, - 1, 1, - 1, 0, - 0, 0 -}; - -static const GLfloat vertexes_180[] = { - 1, 1, - 1, 0, - 0, 0, - 0, 1 -}; - -static const GLfloat vertexes_270[] = { - 1, 0, - 0, 0, - 0, 1, - 1, 1 -}; - -//forward decls -extern const GLfloat *vertex_ptr; -extern const GLfloat *default_vertex_ptr; - void gfx_ctx_set_swap_interval(unsigned interval, bool inited) { (void)inited; From 7ee8e1e524be04bbce9f692de5d05bc89204c719 Mon Sep 17 00:00:00 2001 From: Toad King Date: Thu, 9 Aug 2012 19:01:08 -0400 Subject: [PATCH 139/492] (GX) implement core changing in RGUI fix core management picking salamander, resulting in hard-lock change tabs->spaces --- console/rarch_console_libretro_mgmt.c | 40 ++++++++++++++----------- console/rgui/rgui.c | 42 ++++++++++++--------------- console/rgui/rgui.h | 1 + gx/frontend/main.c | 8 ++--- 4 files changed, 46 insertions(+), 45 deletions(-) diff --git a/console/rarch_console_libretro_mgmt.c b/console/rarch_console_libretro_mgmt.c index 253f6459ff..37268a480b 100644 --- a/console/rarch_console_libretro_mgmt.c +++ b/console/rarch_console_libretro_mgmt.c @@ -75,15 +75,15 @@ bool rarch_configure_libretro_core(const char *full_path, const char *tmp_path, if (path_file_exists(tmp_pathnewfile)) { // if libretro core already exists, this means we are - // upgrading the libretro core - so delete pre-existing - // file first. + // upgrading the libretro core - so delete pre-existing + // file first. RARCH_LOG("Upgrading emulator core...\n"); - ret = remove(tmp_pathnewfile); + ret = remove(tmp_pathnewfile); - if (ret == 0) + if (ret == 0) RARCH_LOG("Succeeded in removing pre-existing libretro core: [%s].\n", tmp_pathnewfile); - else + else RARCH_ERR("Failed to remove pre-existing libretro core: [%s].\n", tmp_pathnewfile); } @@ -93,14 +93,14 @@ bool rarch_configure_libretro_core(const char *full_path, const char *tmp_path, if (ret == 0) { RARCH_LOG("libretro core [%s] renamed to: [%s].\n", full_path, tmp_pathnewfile); - strlcpy(libretro_core_installed, tmp_pathnewfile, sizeof_libretro_core); - ret = 1; + strlcpy(libretro_core_installed, tmp_pathnewfile, sizeof_libretro_core); + ret = 1; } else { RARCH_ERR("Failed to rename CORE executable.\n"); - RARCH_WARN("CORE executable was not found, or some other errors occurred. Will attempt to load libretro core path from config file.\n"); - ret = 0; + RARCH_WARN("CORE executable was not found, or some other errors occurred. Will attempt to load libretro core path from config file.\n"); + ret = 0; } } @@ -151,22 +151,28 @@ void rarch_manage_libretro_set_first_file(char *first_file, size_t size_of_first if(first_exe) { -#ifdef _XBOX +#if defined(_XBOX) || defined(GEKKO) char fname_tmp[PATH_MAX]; fill_pathname_base(fname_tmp, first_exe, sizeof(fname_tmp)); +#ifdef _XBOX if(strcmp(fname_tmp, "RetroArch-Salamander.xex") == 0) +#elif defined(GEKKO) + if(strcmp(fname_tmp, "boot.dol") == 0) +#else +#error This case not handled +#endif { RARCH_WARN("First entry is RetroArch Salamander itself, increment entry by one and check if it exists.\n"); - first_exe = dir_list->elems[1].data; - fill_pathname_base(fname_tmp, first_exe, sizeof(fname_tmp)); + first_exe = dir_list->elems[1].data; + fill_pathname_base(fname_tmp, first_exe, sizeof(fname_tmp)); - if(!first_exe) - { + if(!first_exe) + { RARCH_ERR("Unlikely error happened - no second entry - no choice but to set it to RetroArch Salamander\n"); - first_exe = dir_list->elems[0].data; - fill_pathname_base(fname_tmp, first_exe, sizeof(fname_tmp)); - } + first_exe = dir_list->elems[0].data; + fill_pathname_base(fname_tmp, first_exe, sizeof(fname_tmp)); + } } strlcpy(first_file, fname_tmp, size_of_first_file); diff --git a/console/rgui/rgui.c b/console/rgui/rgui.c index 55470a42fb..9ae8a274d9 100644 --- a/console/rgui/rgui.c +++ b/console/rgui/rgui.c @@ -331,7 +331,7 @@ static void render_text(rgui_handle_t *rgui) { char rotate_msg[64]; rarch_settings_create_menu_item_label(rotate_msg, S_LBL_ROTATION, sizeof(rotate_msg)); - snprintf(type_str, sizeof(type_str), rotate_msg); + snprintf(type_str, sizeof(type_str), rotate_msg); } break; case RGUI_SETTINGS_AUDIO_MUTE: @@ -410,7 +410,7 @@ static void rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t #ifdef HW_RVL case RGUI_SETTINGS_VIDEO_SOFT_FILTER: g_console.soft_display_filter_enable = !g_console.soft_display_filter_enable; - gx->should_resize = true; + gx->should_resize = true; break; #endif case RGUI_SETTINGS_VIDEO_GAMMA: @@ -447,21 +447,21 @@ static void rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t { rarch_settings_default(S_DEF_AUDIO_CONTROL_RATE); #ifdef GEKKO - video_gx.set_rotation(NULL, g_console.screen_orientation); + video_gx.set_rotation(NULL, g_console.screen_orientation); #endif } else if (action == RGUI_ACTION_LEFT) { rarch_settings_change(S_ROTATION_DECREMENT); #ifdef GEKKO - video_gx.set_rotation(NULL, g_console.screen_orientation); + video_gx.set_rotation(NULL, g_console.screen_orientation); #endif } else if (action == RGUI_ACTION_RIGHT) { - rarch_settings_change(S_ROTATION_INCREMENT); + rarch_settings_change(S_ROTATION_INCREMENT); #ifdef GEKKO - video_gx.set_rotation(NULL, g_console.screen_orientation); + video_gx.set_rotation(NULL, g_console.screen_orientation); #endif } break; @@ -479,24 +479,17 @@ static void rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t else if (action == RGUI_ACTION_RIGHT) rarch_settings_change(S_AUDIO_CONTROL_RATE_INCREMENT); break; - - /*case RGUI_SETTINGS_CORE: - { - // !!JUST FOR TESTING!! - char boot_dol[PATH_MAX]; - char temp_dol[PATH_MAX]; - char temp2_dol[PATH_MAX]; - - snprintf(boot_dol, sizeof(boot_dol), "%s%s", app_dir, "boot.dol"); - snprintf(temp_dol, sizeof(temp_dol), "%s%s", app_dir, "temp.dol"); - snprintf(temp2_dol, sizeof(temp2_dol), "%s%s", app_dir, "temp2.dol"); - - rename(boot_dol, temp2_dol); - rename(temp_dol, boot_dol); - rename(temp2_dol, temp_dol); + case RGUI_SETTINGS_RESTART: + if (action == RGUI_ACTION_OK) + { +#ifdef GEKKO + snprintf(g_console.launch_app_on_exit, sizeof(g_console.launch_app_on_exit), "boot.dol"); +#endif + g_console.return_to_launcher = true; + g_console.mode_switch = MODE_EXIT; + g_console.menu_enable = false; + } break; - }*/ - // controllers case RGUI_SETTINGS_BIND_DEVICE: g_settings.input.device[port] += RARCH_DEVICE_LAST; @@ -565,6 +558,7 @@ static void rgui_settings_populate_entries(rgui_handle_t *rgui) RGUI_MENU_ITEM("Controller #2 Config", RGUI_SETTINGS_CONTROLLER_2); RGUI_MENU_ITEM("Controller #3 Config", RGUI_SETTINGS_CONTROLLER_3); RGUI_MENU_ITEM("Controller #4 Config", RGUI_SETTINGS_CONTROLLER_4); + RGUI_MENU_ITEM("Restart RetroArch", RGUI_SETTINGS_RESTART); } static void rgui_settings_controller_populate_entries(rgui_handle_t *rgui) @@ -760,7 +754,7 @@ const char *rgui_iterate(rgui_handle_t *rgui, rgui_action_t action) { if (menu_type == RGUI_SETTINGS_CORE) { - // CORE SWITCHING CODE GOES HERE + strlcpy(g_settings.libretro, path, sizeof(g_settings.libretro)); rgui->directory_ptr = directory_ptr; rgui->need_refresh = true; rgui_list_pop(rgui->path_stack); diff --git a/console/rgui/rgui.h b/console/rgui/rgui.h index b629a18d37..b210cc6911 100644 --- a/console/rgui/rgui.h +++ b/console/rgui/rgui.h @@ -46,6 +46,7 @@ typedef enum RGUI_SETTINGS_CONTROLLER_2, RGUI_SETTINGS_CONTROLLER_3, RGUI_SETTINGS_CONTROLLER_4, + RGUI_SETTINGS_RESTART, RGUI_SETTINGS_BIND_DEVICE, RGUI_SETTINGS_BIND_UP, diff --git a/gx/frontend/main.c b/gx/frontend/main.c index 927cb710fb..62b02bb38b 100644 --- a/gx/frontend/main.c +++ b/gx/frontend/main.c @@ -159,13 +159,13 @@ static void menu_loop(void) } static const struct retro_keybind _quit_binds[] = { - { 0, 0, (enum retro_key)0, (GX_CLASSIC_HOME), 0 }, - { 0, 0, (enum retro_key)0, (GX_WIIMOTE_HOME), 0 }, - { 0, 0, (enum retro_key)0, (GX_QUIT_KEY), 0 }, + { 0, 0, (enum retro_key)0, (GX_CLASSIC_HOME), 0 }, + { 0, 0, (enum retro_key)0, (GX_WIIMOTE_HOME), 0 }, + { 0, 0, (enum retro_key)0, (GX_QUIT_KEY), 0 }, }; const struct retro_keybind *quit_binds[] = { - _quit_binds + _quit_binds }; input_state |= input_gx.input_state(NULL, quit_binds, false, From f04e079d770d7b2ff4a88d59b48d28b05d9a508d Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 10 Aug 2012 01:37:17 +0200 Subject: [PATCH 140/492] (RGL) Cleanups --- console/rgl/ps3/cg.h | 14 --------- console/rgl/ps3/cgnv2rt.cpp | 59 +++++++++++++++++++++++++++++++++++-- console/rgl/ps3/cgnv2rt.h | 55 ---------------------------------- console/rgl/ps3/rgl.h | 6 ---- 4 files changed, 56 insertions(+), 78 deletions(-) diff --git a/console/rgl/ps3/cg.h b/console/rgl/ps3/cg.h index ddb6cad2c7..1521ab2c2d 100644 --- a/console/rgl/ps3/cg.h +++ b/console/rgl/ps3/cg.h @@ -419,20 +419,6 @@ static inline const CgParameterResource *_RGLGetParameterResource( const _CGprog return ( CgParameterResource * )( program->parameterResources + entry->typeIndex ); } -static inline CGtype _RGLGetParameterCGtype( const _CGprogram *program, const CgParameterEntry *entry ) -{ - if ( entry->flags & CGP_RTCREATED ) - return ( CGtype )entry->typeIndex; - else - { - const CgParameterResource *parameterResource = _RGLGetParameterResource( program, entry ); - if ( parameterResource ) - return ( CGtype )parameterResource->type; - } - - return CG_UNKNOWN_TYPE; -} - static inline const CgParameterArray *_RGLGetParameterArray( const _CGprogram *program, const CgParameterEntry *entry ) { return ( CgParameterArray* )( program->parameterResources + entry->typeIndex ); diff --git a/console/rgl/ps3/cgnv2rt.cpp b/console/rgl/ps3/cgnv2rt.cpp index 840f70d2dd..a8138e3c43 100644 --- a/console/rgl/ps3/cgnv2rt.cpp +++ b/console/rgl/ps3/cgnv2rt.cpp @@ -104,9 +104,62 @@ static bool bIsVertexProgram = true; static int getStride(CgBaseType *type); static int getSizeofSubArray(_CGNVCONTAINERS &containers, int dimensionIndex, int dimensionCount, int endianness); -static unsigned int stringTableFind( std::vector &stringTable, const char* str); -static unsigned int stringTableAdd( std::vector &stringTable, const char* str ); -static unsigned int stringTableAddUnique( std::vector &stringTable, const char* str ); + +static unsigned int stringTableFind( std::vector &stringTable, const char* str ) +{ + const char* data = &stringTable[0]; + size_t size = stringTable.size(); + const char *end = data + size; + + size_t length = strlen(str); + + if (length+1 > size) + return 0; + + data += length; + + const char *p = (char*)memchr(data,'\0',end-data); + while (p && (end-data)>0) + { + if (!memcmp(p - length, str, length)) + return (unsigned int)(p - length - &stringTable[0]); + + data = p+1; + p = (char*)memchr(data,'\0',end-data); + } + return 0; +} + +static unsigned int stringTableAdd( std::vector &stringTable, const char* str ) +{ + unsigned int ret = (unsigned int)stringTable.size(); + + if ( ret == 0 ) + { + stringTable.push_back('\0'); + ret = 1; + } + + size_t stringLength = strlen(str) + 1; + stringTable.resize(ret + stringLength); + memcpy(&stringTable[0] + ret,str,stringLength); + + return ret; +} + +static unsigned int stringTableAddUnique( std::vector &stringTable, const char* str ) +{ + if ( stringTable.size() == 0 ) + stringTable.push_back('\0'); + + unsigned int ret = stringTableFind(stringTable, str); + + if (ret == 0 && str[0] != '\0') + ret = stringTableAdd(stringTable, str); + + return ret; +} + template static size_t array_size(std::vector &array); template static void array_push(char* ¶meterOffset, std::vector &array); inline static unsigned int swap16(const unsigned int v); diff --git a/console/rgl/ps3/cgnv2rt.h b/console/rgl/ps3/cgnv2rt.h index 3fcac63705..cc222c1f2d 100644 --- a/console/rgl/ps3/cgnv2rt.h +++ b/console/rgl/ps3/cgnv2rt.h @@ -14,61 +14,6 @@ #define CNV2END(val) convert_endianness((val), elfEndianness) #define ENDSWAP(val) convert_endianness((val), (host_endianness() == 1) ? 2 : 1) -static unsigned int stringTableAdd( std::vector &stringTable, const char* str ) -{ - unsigned int ret = (unsigned int)stringTable.size(); - - if ( ret == 0 ) - { - stringTable.push_back('\0'); - ret = 1; - } - - size_t stringLength = strlen(str) + 1; - stringTable.resize(ret + stringLength); - memcpy(&stringTable[0] + ret,str,stringLength); - - return ret; -} - -static unsigned int stringTableFind( std::vector &stringTable, const char* str ) -{ - const char* data = &stringTable[0]; - size_t size = stringTable.size(); - const char *end = data + size; - - size_t length = strlen(str); - - if (length+1 > size) - return 0; - - data += length; - - const char *p = (char*)memchr(data,'\0',end-data); - while (p && (end-data)>0) - { - if (!memcmp(p - length, str, length)) - return (unsigned int)(p - length - &stringTable[0]); - - data = p+1; - p = (char*)memchr(data,'\0',end-data); - } - return 0; -} - -static unsigned int stringTableAddUnique( std::vector &stringTable, const char* str ) -{ - if ( stringTable.size() == 0 ) - stringTable.push_back('\0'); - - unsigned int ret = stringTableFind(stringTable, str); - - if (ret == 0 && str[0] != '\0') - ret = stringTableAdd(stringTable, str); - - return ret; -} - int convertNvToElfFromFile(const char *sourceFile, int endianness, int constTableOffset, void **binaryShader, int *size, std::vector &stringTable, std::vector &defaultValues); int convertNvToElfFromMemory(const void *sourceData, size_t size, int endianness, int constTableOffset, void **binaryShader, int *binarySize, std::vector &stringTable, std::vector &defaultValues); diff --git a/console/rgl/ps3/rgl.h b/console/rgl/ps3/rgl.h index 7783a7c382..1cb6b8ed27 100644 --- a/console/rgl/ps3/rgl.h +++ b/console/rgl/ps3/rgl.h @@ -260,10 +260,6 @@ jsTexture; #define MAX_TEXTURE_UNITS 4 -#define _RGL_MAX_MODELVIEW_STACK_DEPTH 16 -#define _RGL_MAX_PROJECTION_STACK_DEPTH 2 -#define MAX_TEXTURE_STACK_DEPTH 2 - #define MAX_VERTEX_ATTRIBS 16 typedef struct @@ -451,8 +447,6 @@ struct jsBufferObject void *platformBufferObject[]; }; -#define ELEMENTS_IN_MATRIX 16 - typedef struct jsNameSpace { void** data; From dfd5571f1275abb201eb695779b7a32478e161a6 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 10 Aug 2012 02:31:39 +0200 Subject: [PATCH 141/492] (RGL) Move some stuff around --- console/rgl/ps3/device_ctx.cpp | 72 ++++++++++++++++++++++++---------- console/rgl/ps3/rgl.cpp | 53 +++++-------------------- console/rgl/ps3/rgl.h | 10 ++++- 3 files changed, 70 insertions(+), 65 deletions(-) diff --git a/console/rgl/ps3/device_ctx.cpp b/console/rgl/ps3/device_ctx.cpp index 205c189ff2..c011dde301 100644 --- a/console/rgl/ps3/device_ctx.cpp +++ b/console/rgl/ps3/device_ctx.cpp @@ -35,15 +35,6 @@ using namespace cell::Gcm; extern void _RGLFifoGlSetRenderTarget( RGLRenderTargetEx const * const args ); -typedef struct -{ - int id; - GLuint offset; - GLuint size; - GLuint pitch; - GLuint bank; -} jsTiledRegion; - typedef struct { jsTiledRegion region[MAX_TILED_REGIONS]; @@ -60,6 +51,9 @@ static const uint32_t WaitLabelIndex = 111; extern GLuint nvFenceCounter; RGLState _RGLState; +extern GmmAllocator *pGmmLocalAllocator; +extern GmmAllocator *pGmmMainAllocator; + typedef struct { int width; @@ -1161,7 +1155,54 @@ PSGLdevice *psglGetCurrentDevice(void) return _CurrentDevice; } -extern void gmmUpdateFreeList (const uint8_t location); +static void gmmRemovePendingFree(GmmAllocator *pAllocator, GmmBlock *pBlock) +{ + if (pBlock == pAllocator->pPendingFreeHead) + pAllocator->pPendingFreeHead = pBlock->pNextFree; + + if (pBlock == pAllocator->pPendingFreeTail) + pAllocator->pPendingFreeTail = pBlock->pPrevFree; + + if (pBlock->pNextFree) + pBlock->pNextFree->pPrevFree = pBlock->pPrevFree; + + if (pBlock->pPrevFree) + pBlock->pPrevFree->pNextFree = pBlock->pNextFree; +} + +extern void gmmAddFree(GmmAllocator *pAllocator, GmmBlock *pBlock); + +static void gmmUpdateFreeLists (void) +{ + for(int i = 0; i < 2; i++) + { + uint8_t location = i == 0 ? CELL_GCM_LOCATION_LOCAL : CELL_GCM_LOCATION_MAIN; + GmmAllocator *pAllocator; + const uint32_t fence = _RGLState.semaphores->userSemaphores[SEMA_FENCE].val; + GmmBlock *pBlock = NULL; + GmmBlock *pTemp = NULL; + + pAllocator = (location == CELL_GCM_LOCATION_LOCAL) ? + pGmmLocalAllocator : + pGmmMainAllocator; + + pBlock = pAllocator->pPendingFreeHead; + + while (pBlock) + { + pTemp = pBlock->pNextFree; + + if ( !(( fence - pBlock->fence ) & 0x80000000 ) ) + { + gmmRemovePendingFree(pAllocator, pBlock); + gmmAddFree(pAllocator, pBlock); + } + + pBlock = pTemp; + } + } + +} GLAPI void psglSwap(void) { @@ -1169,8 +1210,7 @@ GLAPI void psglSwap(void) PSGLdevice *device = _CurrentDevice; RGLFifo *fifo = &_RGLState.fifo; - gmmUpdateFreeList(CELL_GCM_LOCATION_LOCAL); - gmmUpdateFreeList(CELL_GCM_LOCATION_MAIN); + gmmUpdateFreeLists(); RGLDevice *gcmDevice = ( RGLDevice * )device->platformDevice; @@ -1300,11 +1340,3 @@ GLboolean _RGLTryResizeTileRegion(GLuint address, GLuint size, void* data) return GL_TRUE; } - -void _RGLGetTileRegionInfo(void* data, GLuint *address, GLuint *size) -{ - jsTiledRegion* region = ( jsTiledRegion* )data; - - *address = region->offset; - *size = region->size; -} diff --git a/console/rgl/ps3/rgl.cpp b/console/rgl/ps3/rgl.cpp index b53fea2d51..395fd398b1 100644 --- a/console/rgl/ps3/rgl.cpp +++ b/console/rgl/ps3/rgl.cpp @@ -2080,21 +2080,6 @@ static uint32_t gmmInitFixedAllocator (void) return CELL_OK; } -static void gmmRemovePendingFree(GmmAllocator *pAllocator, GmmBlock *pBlock) -{ - if (pBlock == pAllocator->pPendingFreeHead) - pAllocator->pPendingFreeHead = pBlock->pNextFree; - - if (pBlock == pAllocator->pPendingFreeTail) - pAllocator->pPendingFreeTail = pBlock->pPrevFree; - - if (pBlock->pNextFree) - pBlock->pNextFree->pPrevFree = pBlock->pPrevFree; - - if (pBlock->pPrevFree) - pBlock->pPrevFree->pNextFree = pBlock->pNextFree; -} - static uint8_t gmmSizeToFreeIndex(uint32_t size) { if (size >= GMM_FREE_BIN_0 && size < GMM_FREE_BIN_1) @@ -2143,7 +2128,7 @@ static uint8_t gmmSizeToFreeIndex(uint32_t size) return 21; } -static void gmmAddFree(GmmAllocator *pAllocator, GmmBlock *pBlock) +void gmmAddFree(GmmAllocator *pAllocator, GmmBlock *pBlock) { uint8_t freeIndex = gmmSizeToFreeIndex(pBlock->base.size); @@ -2187,34 +2172,6 @@ static void gmmAddFree(GmmAllocator *pAllocator, GmmBlock *pBlock) } } -void gmmUpdateFreeList (const uint8_t location) -{ - GmmAllocator *pAllocator; - const uint32_t fence = _RGLState.semaphores->userSemaphores[SEMA_FENCE].val; - GmmBlock *pBlock = NULL; - GmmBlock *pTemp = NULL; - - pAllocator = (location == CELL_GCM_LOCATION_LOCAL) ? - pGmmLocalAllocator : - pGmmMainAllocator; - - - pBlock = pAllocator->pPendingFreeHead; - - while (pBlock) - { - pTemp = pBlock->pNextFree; - - if ( !(( fence - pBlock->fence ) & 0x80000000 ) ) - { - gmmRemovePendingFree(pAllocator, pBlock); - gmmAddFree(pAllocator, pBlock); - } - - pBlock = pTemp; - } - -} static void *gmmAllocFixed(uint8_t isTile) { @@ -2382,6 +2339,14 @@ char *gmmIdToAddress(const uint32_t id) return (char *)pBaseBlock->address; } +static void _RGLGetTileRegionInfo(void* data, GLuint *address, GLuint *size) +{ + jsTiledRegion* region = ( jsTiledRegion* )data; + + *address = region->offset; + *size = region->size; +} + static GmmBlock *gmmAllocBlock(GmmAllocator *pAllocator, uint32_t size) { uint32_t address; diff --git a/console/rgl/ps3/rgl.h b/console/rgl/ps3/rgl.h index 1cb6b8ed27..c194065d1d 100644 --- a/console/rgl/ps3/rgl.h +++ b/console/rgl/ps3/rgl.h @@ -185,6 +185,15 @@ typedef struct int X, Y, XSize, YSize; } jsViewPort; +typedef struct +{ + int id; + GLuint offset; + GLuint size; + GLuint pitch; + GLuint bank; +} jsTiledRegion; + enum { IMAGE_DATASTATE_UNSET = 0x0, @@ -860,7 +869,6 @@ void _RGLSetNativeCgVertexProgram( const void *header ); void _RGLSetNativeCgFragmentProgram( const void *header ); GLboolean _RGLTryResizeTileRegion( GLuint address, GLuint size, void* data ); -void _RGLGetTileRegionInfo( void* data, GLuint *address, GLuint *size ); static inline GLuint _RGLPlatformGetBitsPerPixel( GLenum internalFormat ) { From 9d356c716da3bf9771481d13a5d139b5cb11b9a7 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 10 Aug 2012 03:37:12 +0200 Subject: [PATCH 142/492] (Salamander) Remove console/salamander - Salamander is platform-independent per port now --- console/salamander/main.c | 326 -------------------------------------- 1 file changed, 326 deletions(-) delete mode 100644 console/salamander/main.c diff --git a/console/salamander/main.c b/console/salamander/main.c deleted file mode 100644 index be23b1573f..0000000000 --- a/console/salamander/main.c +++ /dev/null @@ -1,326 +0,0 @@ -/* RetroArch - A frontend for libretro. - * RetroArch Salamander - A frontend for managing some pre-launch tasks. - * Copyright (C) 2010-2012 - Hans-Kristian Arntzen - * Copyright (C) 2011-2012 - Daniel De Matteis - * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . - */ - -#include -#include - -#if defined(__CELLOS_LV2__) -#include -#include -#include -#include -#include -#include -#include -#include -#elif defined(_XBOX) -#include -#endif - -#include "../../compat/strl.h" -#include "../../conf/config_file.h" - -#if defined(_XBOX) -#include "../../msvc/msvc_compat.h" -#elif defined(__CELLOS_LV2__) -#define NP_POOL_SIZE (128*1024) -#endif - -#ifndef PATH_MAX -#define PATH_MAX 512 -#endif - -#include "../rarch_console_libretro_mgmt.h" -#include "../rarch_console_exec.h" - -#include "../../retroarch_logger.h" -#include "../../file.h" - -#if defined(__CELLOS_LV2__) -static uint8_t np_pool[NP_POOL_SIZE]; -char usrDirPath[PATH_MAX]; -SYS_PROCESS_PARAM(1001, 0x100000) -#elif defined(_XBOX) -DWORD volume_device_type; -#endif - -char LIBRETRO_DIR_PATH[PATH_MAX]; -char SYS_CONFIG_FILE[PATH_MAX]; -char libretro_path[PATH_MAX]; - -static void find_and_set_first_file(void) -{ - //Last fallback - we'll need to start the first executable file - // we can find in the RetroArch cores directory - - char first_file[PATH_MAX]; - rarch_manage_libretro_set_first_file(first_file, sizeof(first_file), -#if defined(_XBOX360) - "game:\\", "xex" -#elif defined(_XBOX1) - "D:\\", "xbe" -#elif defined(__CELLOS_LV2__) - LIBRETRO_DIR_PATH, "SELF" -#endif -); - - if(first_file) - strlcpy(libretro_path, first_file, sizeof(libretro_path)); - else - RARCH_ERR("Failed last fallback - RetroArch Salamander will exit.\n"); -} - -static void init_settings(void) -{ - char tmp_str[PATH_MAX]; - bool config_file_exists; - - if(!path_file_exists(SYS_CONFIG_FILE)) - { - FILE * f; - config_file_exists = false; - RARCH_ERR("Config file \"%s\" doesn't exist. Creating...\n", SYS_CONFIG_FILE); - f = fopen(SYS_CONFIG_FILE, "w"); - fclose(f); - } - else - config_file_exists = true; - - //try to find CORE executable - char core_executable[1024]; -#if defined(_XBOX360) - snprintf(core_executable, sizeof(core_executable), "game:\\CORE.xex"); -#elif defined(_XBOX1) - snprintf(core_executable, sizeof(core_executable), "D:\\CORE.xbe"); -#elif defined(__CELLOS_LV2__) - snprintf(core_executable, sizeof(core_executable), "%s/CORE.SELF", LIBRETRO_DIR_PATH); -#endif - - if(path_file_exists(core_executable)) - { - //Start CORE executable - snprintf(libretro_path, sizeof(libretro_path), core_executable); - RARCH_LOG("Start [%s].\n", libretro_path); - } - else - { - if(config_file_exists) - { - config_file_t * conf = config_file_new(SYS_CONFIG_FILE); - config_get_array(conf, "libretro_path", tmp_str, sizeof(tmp_str)); - snprintf(libretro_path, sizeof(libretro_path), tmp_str); - } - - if(!config_file_exists || !strcmp(libretro_path, "")) - find_and_set_first_file(); - else - { - RARCH_LOG("Start [%s] found in retroarch.cfg.\n", libretro_path); - } - } -} - -static void get_environment_settings (void) -{ -#if defined(_XBOX360) - //for devkits only, we will need to mount all partitions for retail - //in a different way - //DmMapDevkitDrive(); - - int result_filecache = XSetFileCacheSize(0x100000); - - if(result_filecache != TRUE) - { - RARCH_ERR("Couldn't change number of bytes reserved for file system cache.\n"); - } - unsigned long result = XMountUtilityDriveEx(XMOUNTUTILITYDRIVE_FORMAT0,8192, 0); - - if(result != ERROR_SUCCESS) - { - RARCH_ERR("Couldn't mount/format utility drive.\n"); - } - - // detect install environment - unsigned long license_mask; - - if (XContentGetLicenseMask(&license_mask, NULL) != ERROR_SUCCESS) - { - RARCH_LOG("RetroArch was launched as a standalone DVD, or using DVD emulation, or from the development area of the HDD.\n"); - } - else - { - XContentQueryVolumeDeviceType("GAME",&volume_device_type, NULL); - - switch(volume_device_type) - { - case XCONTENTDEVICETYPE_HDD: - RARCH_LOG("RetroArch was launched from a content package on HDD.\n"); - break; - case XCONTENTDEVICETYPE_MU: - RARCH_LOG("RetroArch was launched from a content package on USB or Memory Unit.\n"); - break; - case XCONTENTDEVICETYPE_ODD: - RARCH_LOG("RetroArch was launched from a content package on Optical Disc Drive.\n"); - break; - default: - RARCH_LOG("RetroArch was launched from a content package on an unknown device type.\n"); - break; - } - } -#elif defined(_XBOX1) - strlcpy(SYS_CONFIG_FILE, "D:\\retroarch.cfg", sizeof(SYS_CONFIG_FILE)); -#elif defined(__CELLOS_LV2__) - unsigned int get_type; - unsigned int get_attributes; - CellGameContentSize size; - char dirName[CELL_GAME_DIRNAME_SIZE]; - char contentInfoPath[PATH_MAX]; - - memset(&size, 0x00, sizeof(CellGameContentSize)); - - int ret = cellGameBootCheck(&get_type, &get_attributes, &size, dirName); - if(ret < 0) - { - RARCH_ERR("cellGameBootCheck() Error: 0x%x.\n", ret); - } - else - { - RARCH_LOG("cellGameBootCheck() OK.\n"); - RARCH_LOG("Directory name: [%s].\n", dirName); - RARCH_LOG(" HDD Free Size (in KB) = [%d] Size (in KB) = [%d] System Size (in KB) = [%d].\n", size.hddFreeSizeKB, size.sizeKB, size.sysSizeKB); - - switch(get_type) - { - case CELL_GAME_GAMETYPE_DISC: - RARCH_LOG("RetroArch was launched on Optical Disc Drive.\n"); - break; - case CELL_GAME_GAMETYPE_HDD: - RARCH_LOG("RetroArch was launched on HDD.\n"); - break; - } - - if((get_attributes & CELL_GAME_ATTRIBUTE_APP_HOME) == CELL_GAME_ATTRIBUTE_APP_HOME) - RARCH_LOG("RetroArch was launched from host machine (APP_HOME).\n"); - - ret = cellGameContentPermit(contentInfoPath, usrDirPath); - - if(ret < 0) - { - RARCH_ERR("cellGameContentPermit() Error: 0x%x\n", ret); - } - else - { - RARCH_LOG("cellGameContentPermit() OK.\n"); - RARCH_LOG("contentInfoPath : [%s].\n", contentInfoPath); - RARCH_LOG("usrDirPath : [%s].\n", usrDirPath); - } - - /* now we fill in all the variables */ - snprintf(SYS_CONFIG_FILE, sizeof(SYS_CONFIG_FILE), "%s/retroarch.cfg", usrDirPath); - snprintf(LIBRETRO_DIR_PATH, sizeof(LIBRETRO_DIR_PATH), "%s/cores", usrDirPath); - } -#endif -} - -#ifdef __CELLOS_LV2__ -//dummy - just to avoid the emitted warnings -static void callback_sysutil_exit(uint64_t status, uint64_t param, void *userdata) -{ - (void) param; - (void) userdata; - (void) status; -} -#endif - -int main(int argc, char *argv[]) -{ -#if defined(_XBOX) - XINPUT_STATE state; //C4101 - - get_environment_settings(); - - //WIP - no Xbox 1 controller input yet -#ifdef _XBOX360 - XInputGetState(0, &state); - - if(state.Gamepad.wButtons & XINPUT_GAMEPAD_Y) - { - //override path, boot first executable in cores directory - RARCH_LOG("Fallback - Will boot first executable in RetroArch cores directory.\n"); - find_and_set_first_file(); - } - else -#endif - { - //normal executable loading path - init_settings(); - } -#elif defined(__CELLOS_LV2__) - CellPadData pad_data; - - cellSysutilRegisterCallback(0, callback_sysutil_exit, NULL); - - cellSysmoduleLoadModule(CELL_SYSMODULE_IO); - cellSysmoduleLoadModule(CELL_SYSMODULE_FS); - cellSysmoduleLoadModule(CELL_SYSMODULE_SYSUTIL_GAME); - cellSysmoduleLoadModule(CELL_SYSMODULE_NET); - - cellSysmoduleLoadModule(CELL_SYSMODULE_SYSUTIL_NP); - - sys_net_initialize_network(); - -#ifdef HAVE_LOGGER - logger_init(); -#endif - - sceNpInit(NP_POOL_SIZE, np_pool); - - get_environment_settings(); - - cellPadInit(7); - - cellPadGetData(0, &pad_data); - - if(pad_data.button[CELL_PAD_BTN_OFFSET_DIGITAL2] & CELL_PAD_CTRL_TRIANGLE) - { - //override path, boot first executable in cores directory - RARCH_LOG("Fallback - Will boot first executable in RetroArch cores/ directory.\n"); - find_and_set_first_file(); - } - else - { - //normal executable loading path - init_settings(); - } - - cellPadEnd(); - -#ifdef HAVE_LOGGER - logger_shutdown(); -#endif -#endif - - rarch_console_exec(libretro_path); - -#ifdef __CELLOS_LV2__ - cellSysmoduleUnloadModule(CELL_SYSMODULE_SYSUTIL_GAME); - cellSysmoduleLoadModule(CELL_SYSMODULE_FS); - cellSysmoduleLoadModule(CELL_SYSMODULE_IO); -#endif - - return 1; -} From 7491de4c95d8e1372fd0e8b7ec0b2bf2ff37f708 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 10 Aug 2012 03:48:54 +0200 Subject: [PATCH 143/492] (RARCH_CONSOLE) Add Salamander default path --- console/rarch_console.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/console/rarch_console.h b/console/rarch_console.h index 6291be438a..9c00667690 100644 --- a/console/rarch_console.h +++ b/console/rarch_console.h @@ -97,6 +97,9 @@ typedef struct char savestate_dir[MAXIMUM_PATH]; #if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) char menu_shader_file[MAXIMUM_PATH]; +#ifdef IS_SALAMANDER + char salamander_file[MAXIMUM_PATH]; +#endif char shader_file[MAXIMUM_PATH]; char shader_dir[MAXIMUM_PATH]; #endif From 552180f276eb3c2e840e04b3f76b26fbdde0ff7e Mon Sep 17 00:00:00 2001 From: Toad King Date: Thu, 9 Aug 2012 22:58:38 -0400 Subject: [PATCH 144/492] (SALAMANDER) fix rarch_manage_libretro_set_first_file so it doesn't select the salamander executable --- console/rarch_console.h | 6 +++--- console/rarch_console_libretro_mgmt.c | 11 +++-------- gx/salamander/main.c | 3 +++ ps3/salamander/main.c | 3 +++ xdk/salamander/main.c | 5 +++++ 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/console/rarch_console.h b/console/rarch_console.h index 9c00667690..6cdcc65c8d 100644 --- a/console/rarch_console.h +++ b/console/rarch_console.h @@ -97,11 +97,11 @@ typedef struct char savestate_dir[MAXIMUM_PATH]; #if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) char menu_shader_file[MAXIMUM_PATH]; -#ifdef IS_SALAMANDER - char salamander_file[MAXIMUM_PATH]; -#endif char shader_file[MAXIMUM_PATH]; char shader_dir[MAXIMUM_PATH]; +#endif +#ifdef IS_SALAMANDER + char salamander_file[MAXIMUM_PATH]; #endif char sram_dir[MAXIMUM_PATH]; char system_dir[MAXIMUM_PATH]; diff --git a/console/rarch_console_libretro_mgmt.c b/console/rarch_console_libretro_mgmt.c index 37268a480b..ba97ffefe8 100644 --- a/console/rarch_console_libretro_mgmt.c +++ b/console/rarch_console_libretro_mgmt.c @@ -17,6 +17,7 @@ #include #include "../boolean.h" #include "../file.h" +#include "rarch_console.h" #include "rarch_console_libretro_mgmt.h" @@ -151,17 +152,11 @@ void rarch_manage_libretro_set_first_file(char *first_file, size_t size_of_first if(first_exe) { -#if defined(_XBOX) || defined(GEKKO) +#ifdef IS_SALAMANDER char fname_tmp[PATH_MAX]; fill_pathname_base(fname_tmp, first_exe, sizeof(fname_tmp)); -#ifdef _XBOX - if(strcmp(fname_tmp, "RetroArch-Salamander.xex") == 0) -#elif defined(GEKKO) - if(strcmp(fname_tmp, "boot.dol") == 0) -#else -#error This case not handled -#endif + if(strncmp(fname_tmp, default_paths.salamander_file, sizeof(fname_tmp)) == 0) { RARCH_WARN("First entry is RetroArch Salamander itself, increment entry by one and check if it exists.\n"); first_exe = dir_list->elems[1].data; diff --git a/gx/salamander/main.c b/gx/salamander/main.c index 262904199b..1c945953f1 100644 --- a/gx/salamander/main.c +++ b/gx/salamander/main.c @@ -43,6 +43,8 @@ char libretro_path[512]; char PORT_DIR[512]; char app_dir[512]; +default_paths_t default_paths; + static void find_and_set_first_file(void) { //Last fallback - we'll need to start the first executable file @@ -107,6 +109,7 @@ static void get_environment_settings(void) getcwd(PORT_DIR, MAXPATHLEN); snprintf(SYS_CONFIG_FILE, sizeof(SYS_CONFIG_FILE), "%sretroarch.cfg", PORT_DIR); snprintf(LIBRETRO_DIR_PATH, sizeof(LIBRETRO_DIR_PATH), PORT_DIR); + snprintf(default_paths.salamander_file, sizeof(default_paths.salamander_file), "boot.dol"); } int main(int argc, char *argv[]) diff --git a/ps3/salamander/main.c b/ps3/salamander/main.c index 31c80fb774..864b03d17b 100644 --- a/ps3/salamander/main.c +++ b/ps3/salamander/main.c @@ -50,6 +50,8 @@ char LIBRETRO_DIR_PATH[PATH_MAX]; char SYS_CONFIG_FILE[PATH_MAX]; char libretro_path[PATH_MAX]; +default_paths_t default_paths; + static void find_and_set_first_file(void) { //Last fallback - we'll need to start the first executable file @@ -160,6 +162,7 @@ static void get_environment_settings (void) snprintf(SYS_CONFIG_FILE, sizeof(SYS_CONFIG_FILE), "%s/retroarch.cfg", usrDirPath); snprintf(LIBRETRO_DIR_PATH, sizeof(LIBRETRO_DIR_PATH), "%s/cores", usrDirPath); } + snprintf(default_paths.salamander_file, sizeof(default_paths.salamander_file), ""); } //dummy - just to avoid the emitted warnings diff --git a/xdk/salamander/main.c b/xdk/salamander/main.c index e41b5e668b..031ab02a96 100644 --- a/xdk/salamander/main.c +++ b/xdk/salamander/main.c @@ -41,6 +41,8 @@ char LIBRETRO_DIR_PATH[PATH_MAX]; char SYS_CONFIG_FILE[PATH_MAX]; char libretro_path[PATH_MAX]; +default_paths_t default_paths; + static void find_and_set_first_file(void) { //Last fallback - we'll need to start the first executable file @@ -156,8 +158,11 @@ static void get_environment_settings (void) break; } } + + strlcpy(default_paths.salamander_file, "RetroArch-Salamander.xex", sizeof(default_paths.salamander_file)); #elif defined(_XBOX1) strlcpy(SYS_CONFIG_FILE, "D:\\retroarch.cfg", sizeof(SYS_CONFIG_FILE)); + strlcpy(default_paths.salamander_file, "RetroArch-Salamander.xbe", sizeof(default_paths.salamander_file)); #endif } From fcebaca85e7fde38645108bf173413c8201bb97d Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 10 Aug 2012 04:47:58 +0200 Subject: [PATCH 145/492] (PS3) Rewrite resolution context code --- console/rmenu/rmenu.c | 11 +++++----- gfx/context/ps3_ctx.c | 47 +++++++++++++++++++------------------------ gfx/context/ps3_ctx.h | 3 ++- 3 files changed, 29 insertions(+), 32 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index cd3657496c..62d42e1c12 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -136,8 +136,12 @@ static void set_setting_label(menu * current_menu, item *items, unsigned current { #ifdef __CELLOS_LV2__ case SETTING_CHANGE_RESOLUTION: - set_setting_label_color(items,g_console.initial_resolution_id == g_console.supported_resolutions[g_console.current_resolution_index], currentsetting); - snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), ps3_get_resolution_label(g_console.supported_resolutions[g_console.current_resolution_index])); + { + unsigned width = gfx_ctx_get_resolution_width(g_console.supported_resolutions[g_console.current_resolution_index]); + unsigned height = gfx_ctx_get_resolution_height(g_console.supported_resolutions[g_console.current_resolution_index]); + set_setting_label_color(items,g_console.initial_resolution_id == g_console.supported_resolutions[g_console.current_resolution_index], currentsetting); + snprintf(items[currentsetting].setting_text, sizeof(items[currentsetting].setting_text), "%dx%d", width, height); + } break; #endif #if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) @@ -604,9 +608,6 @@ static void menu_stack_push(item *items, unsigned menu_id) menu_stack_refresh(items, current_menu); } -//forward decls -extern const char *ps3_get_resolution_label(unsigned resolution); - static void display_menubar(menu *current_menu) { DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; diff --git a/gfx/context/ps3_ctx.c b/gfx/context/ps3_ctx.c index c94db989b1..59eb60dca7 100644 --- a/gfx/context/ps3_ctx.c +++ b/gfx/context/ps3_ctx.c @@ -257,10 +257,14 @@ void gfx_ctx_get_available_resolutions (void) defaultresolution = true; uint32_t videomode[] = { - CELL_VIDEO_OUT_RESOLUTION_480, CELL_VIDEO_OUT_RESOLUTION_576, - CELL_VIDEO_OUT_RESOLUTION_960x1080, CELL_VIDEO_OUT_RESOLUTION_720, - CELL_VIDEO_OUT_RESOLUTION_1280x1080, CELL_VIDEO_OUT_RESOLUTION_1440x1080, - CELL_VIDEO_OUT_RESOLUTION_1600x1080, CELL_VIDEO_OUT_RESOLUTION_1080 + CELL_VIDEO_OUT_RESOLUTION_480, + CELL_VIDEO_OUT_RESOLUTION_576, + CELL_VIDEO_OUT_RESOLUTION_960x1080, + CELL_VIDEO_OUT_RESOLUTION_720, + CELL_VIDEO_OUT_RESOLUTION_1280x1080, + CELL_VIDEO_OUT_RESOLUTION_1440x1080, + CELL_VIDEO_OUT_RESOLUTION_1600x1080, + CELL_VIDEO_OUT_RESOLUTION_1080 }; num_videomodes = sizeof(videomode) / sizeof(uint32_t); @@ -303,29 +307,20 @@ int gfx_ctx_check_resolution(unsigned resolution_id) return cellVideoOutGetResolutionAvailability(CELL_VIDEO_OUT_PRIMARY, resolution_id, CELL_VIDEO_OUT_ASPECT_AUTO, 0); } -const char *ps3_get_resolution_label(uint32_t resolution) +unsigned gfx_ctx_get_resolution_width(unsigned resolution_id) { - switch (resolution) - { - case CELL_VIDEO_OUT_RESOLUTION_480: - return "720x480"; - case CELL_VIDEO_OUT_RESOLUTION_576: - return "720x576"; - case CELL_VIDEO_OUT_RESOLUTION_720: - return "1280x720"; - case CELL_VIDEO_OUT_RESOLUTION_960x1080: - return "960x1080"; - case CELL_VIDEO_OUT_RESOLUTION_1280x1080: - return "1280x1080"; - case CELL_VIDEO_OUT_RESOLUTION_1440x1080: - return "1440x1080"; - case CELL_VIDEO_OUT_RESOLUTION_1600x1080: - return "1600x1080"; - case CELL_VIDEO_OUT_RESOLUTION_1080: - return "1920x1080"; - default: - return "Unknown"; - } + CellVideoOutResolution resolution; + cellVideoOutGetResolution(resolution_id, &resolution); + + return resolution.width; +} + +unsigned gfx_ctx_get_resolution_height(unsigned resolution_id) +{ + CellVideoOutResolution resolution; + cellVideoOutGetResolution(resolution_id, &resolution); + + return resolution.height; } void gfx_ctx_set_projection(gl_t *gl, const struct gl_ortho *ortho, bool allow_rotate) diff --git a/gfx/context/ps3_ctx.h b/gfx/context/ps3_ctx.h index 074122bfc7..0635dc1554 100644 --- a/gfx/context/ps3_ctx.h +++ b/gfx/context/ps3_ctx.h @@ -19,7 +19,8 @@ void gfx_ctx_get_available_resolutions (void); int gfx_ctx_check_resolution(unsigned resolution_id); -const char *ps3_get_resolution_label(uint32_t resolution); +unsigned gfx_ctx_get_resolution_width(unsigned resolution_id); +unsigned gfx_ctx_get_resolution_height(unsigned resolution_id); void gfx_ctx_set_projection(gl_t *gl, const struct gl_ortho *ortho, bool allow_rotate); void gfx_ctx_set_aspect_ratio(void *data, unsigned aspectratio_index); void gfx_ctx_set_overscan(void); From 6929349c4f8673abe47c5c21736e32ab498c67d7 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 10 Aug 2012 05:00:19 +0200 Subject: [PATCH 146/492] (GX) Salamander path refactor --- gx/salamander/main.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/gx/salamander/main.c b/gx/salamander/main.c index 1c945953f1..c299cd583f 100644 --- a/gx/salamander/main.c +++ b/gx/salamander/main.c @@ -23,8 +23,6 @@ #include #include -#include "../gx_input.h" - #include "../../console/rarch_console.h" #include "../../console/rarch_console_exec.h" #include "../../console/rarch_console_libretro_mgmt.h" @@ -37,11 +35,7 @@ #include "../../general.h" #include "../../file.h" -char LIBRETRO_DIR_PATH[512]; -char SYS_CONFIG_FILE[512]; char libretro_path[512]; -char PORT_DIR[512]; -char app_dir[512]; default_paths_t default_paths; @@ -52,7 +46,7 @@ static void find_and_set_first_file(void) char first_file[512] = {0}; rarch_manage_libretro_set_first_file(first_file, sizeof(first_file), - LIBRETRO_DIR_PATH, "dol"); + default_paths.core_dir, "dol"); if(first_file[0]) strlcpy(libretro_path, first_file, sizeof(libretro_path)); @@ -65,12 +59,12 @@ static void init_settings(void) char tmp_str[512]; bool config_file_exists; - if(!path_file_exists(SYS_CONFIG_FILE)) + if(!path_file_exists(default_paths.config_file)) { FILE * f; config_file_exists = false; - RARCH_ERR("Config file \"%s\" doesn't exist. Creating...\n", SYS_CONFIG_FILE); - f = fopen(SYS_CONFIG_FILE, "w"); + RARCH_ERR("Config file \"%s\" doesn't exist. Creating...\n", default_paths.config_file); + f = fopen(default_paths.config_file, "w"); fclose(f); } else @@ -78,7 +72,7 @@ static void init_settings(void) //try to find CORE executable char core_executable[1024]; - snprintf(core_executable, sizeof(core_executable), "%s/CORE.dol", LIBRETRO_DIR_PATH); + snprintf(core_executable, sizeof(core_executable), "%s/CORE.dol", default_paths.core_dir); if(path_file_exists(core_executable)) { @@ -90,7 +84,7 @@ static void init_settings(void) { if(config_file_exists) { - config_file_t * conf = config_file_new(SYS_CONFIG_FILE); + config_file_t * conf = config_file_new(default_paths.config_file); config_get_array(conf, "libretro_path", tmp_str, sizeof(tmp_str)); snprintf(libretro_path, sizeof(libretro_path), tmp_str); } @@ -106,9 +100,16 @@ static void init_settings(void) static void get_environment_settings(void) { - getcwd(PORT_DIR, MAXPATHLEN); - snprintf(SYS_CONFIG_FILE, sizeof(SYS_CONFIG_FILE), "%sretroarch.cfg", PORT_DIR); - snprintf(LIBRETRO_DIR_PATH, sizeof(LIBRETRO_DIR_PATH), PORT_DIR); + getcwd(default_paths.port_dir, MAXPATHLEN); + snprintf(default_paths.core_dir, sizeof(default_paths.core_dir), default_paths.port_dir); + snprintf(default_paths.config_file, sizeof(default_paths.config_file), "%sretroarch.cfg", default_paths.port_dir); + snprintf(default_paths.system_dir, sizeof(default_paths.system_dir), "%s/system", default_paths.core_dir); + snprintf(default_paths.savestate_dir, sizeof(default_paths.savestate_dir), "%s/savestates", default_paths.core_dir); + snprintf(default_paths.filesystem_root_dir, sizeof(default_paths.filesystem_root_dir), "/"); + snprintf(default_paths.filebrowser_startup_dir, sizeof(default_paths.filebrowser_startup_dir), default_paths.filesystem_root_dir); + snprintf(default_paths.sram_dir, sizeof(default_paths.sram_dir), "%s/sram", default_paths.core_dir); + snprintf(default_paths.input_presets_dir, sizeof(default_paths.input_presets_dir), "%s/presets/input", default_paths.core_dir); + strlcpy(default_paths.executable_extension, ".dol", sizeof(default_paths.executable_extension)); snprintf(default_paths.salamander_file, sizeof(default_paths.salamander_file), "boot.dol"); } @@ -123,7 +124,6 @@ int main(int argc, char *argv[]) #endif fatInitDefault(); - getcwd(app_dir, sizeof(app_dir)); get_environment_settings(); From 6d87a1ab9f5c298fd5ec944b2e76bcb13f22f544 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 10 Aug 2012 05:18:32 +0200 Subject: [PATCH 147/492] (PS3 Salamander) Build fix --- ps3/salamander/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ps3/salamander/main.c b/ps3/salamander/main.c index 864b03d17b..640e2c8208 100644 --- a/ps3/salamander/main.c +++ b/ps3/salamander/main.c @@ -36,8 +36,9 @@ #define PATH_MAX 512 #endif -#include "../../console/rarch_console_libretro_mgmt.h" +#include "../../console/rarch_console.h" #include "../../console/rarch_console_exec.h" +#include "../../console/rarch_console_libretro_mgmt.h" #include "../../retroarch_logger.h" #include "../../file.h" From 82b3edfe86a20f8731bcfc90730b1eb6ef71589c Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 10 Aug 2012 05:28:11 +0200 Subject: [PATCH 148/492] (Xbox 1 Salamander) Fixed Salamander pathname --- xdk/salamander/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xdk/salamander/main.c b/xdk/salamander/main.c index 031ab02a96..4d3db291a3 100644 --- a/xdk/salamander/main.c +++ b/xdk/salamander/main.c @@ -162,7 +162,7 @@ static void get_environment_settings (void) strlcpy(default_paths.salamander_file, "RetroArch-Salamander.xex", sizeof(default_paths.salamander_file)); #elif defined(_XBOX1) strlcpy(SYS_CONFIG_FILE, "D:\\retroarch.cfg", sizeof(SYS_CONFIG_FILE)); - strlcpy(default_paths.salamander_file, "RetroArch-Salamander.xbe", sizeof(default_paths.salamander_file)); + strlcpy(default_paths.salamander_file, "default.xbe", sizeof(default_paths.salamander_file)); #endif } From da0d300d547bc5c9dd0fbed5cbcbb589701fa590 Mon Sep 17 00:00:00 2001 From: Toad King Date: Thu, 9 Aug 2012 23:49:29 -0400 Subject: [PATCH 149/492] (GX) fix exiting after failing to load a ROM --- gx/frontend/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gx/frontend/main.c b/gx/frontend/main.c index 62b02bb38b..e63ddc659b 100644 --- a/gx/frontend/main.c +++ b/gx/frontend/main.c @@ -349,7 +349,9 @@ begin_loop: else if(g_console.mode_switch == MODE_MENU) { menu_loop(); - rarch_startup(default_paths.config_file); + + if (g_console.mode_switch != MODE_EXIT) + rarch_startup(default_paths.config_file); } else goto begin_shutdown; From 49922e730e12af0a6441ad387b11c26a9bd3b92d Mon Sep 17 00:00:00 2001 From: Toad King Date: Thu, 9 Aug 2012 23:52:51 -0400 Subject: [PATCH 150/492] (CONSOLE) port failed rom fix to other platforms --- ps3/frontend/main.c | 4 +++- xdk/frontend/main.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ps3/frontend/main.c b/ps3/frontend/main.c index 157f17393d..8e3959379b 100644 --- a/ps3/frontend/main.c +++ b/ps3/frontend/main.c @@ -334,7 +334,9 @@ begin_loop: else if(g_console.mode_switch == MODE_MENU) { menu_loop(); - rarch_startup(default_paths.config_file); + + if (g_console.mode_switch != MODE_EXIT) + rarch_startup(default_paths.config_file); } else goto begin_shutdown; diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index c78af2302a..18e618d652 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -196,7 +196,9 @@ begin_loop: else if(g_console.mode_switch == MODE_MENU) { menu_loop(); - rarch_startup(default_paths.config_file); + + if (g_console.mode_switch != MODE_EXIT) + rarch_startup(default_paths.config_file); } else goto begin_shutdown; From 28eb3604f9fa0db1a0b638cbb0025402544c5306 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 10 Aug 2012 06:50:41 +0200 Subject: [PATCH 151/492] (PS3/Gl) refactored stuff --- gfx/context/ps3_ctx.c | 168 ++++++++++++++++++++---------------------- gfx/context/xdk_ctx.c | 2 + gfx/gl.c | 110 ++++++++++++++------------- 3 files changed, 136 insertions(+), 144 deletions(-) diff --git a/gfx/context/ps3_ctx.c b/gfx/context/ps3_ctx.c index 59eb60dca7..6b38196807 100644 --- a/gfx/context/ps3_ctx.c +++ b/gfx/context/ps3_ctx.c @@ -37,6 +37,84 @@ static struct texture_image menu_texture; static PSGLdevice* gl_device; static PSGLcontext* gl_context; +int gfx_ctx_check_resolution(unsigned resolution_id) +{ + return cellVideoOutGetResolutionAvailability(CELL_VIDEO_OUT_PRIMARY, resolution_id, CELL_VIDEO_OUT_ASPECT_AUTO, 0); +} + +unsigned gfx_ctx_get_resolution_width(unsigned resolution_id) +{ + CellVideoOutResolution resolution; + cellVideoOutGetResolution(resolution_id, &resolution); + + return resolution.width; +} + +unsigned gfx_ctx_get_resolution_height(unsigned resolution_id) +{ + CellVideoOutResolution resolution; + cellVideoOutGetResolution(resolution_id, &resolution); + + return resolution.height; +} + +void gfx_ctx_get_available_resolutions (void) +{ + bool defaultresolution; + uint32_t resolution_count; + uint16_t num_videomodes; + + if (g_console.check_available_resolutions) + return; + + defaultresolution = true; + + uint32_t videomode[] = { + CELL_VIDEO_OUT_RESOLUTION_480, + CELL_VIDEO_OUT_RESOLUTION_576, + CELL_VIDEO_OUT_RESOLUTION_960x1080, + CELL_VIDEO_OUT_RESOLUTION_720, + CELL_VIDEO_OUT_RESOLUTION_1280x1080, + CELL_VIDEO_OUT_RESOLUTION_1440x1080, + CELL_VIDEO_OUT_RESOLUTION_1600x1080, + CELL_VIDEO_OUT_RESOLUTION_1080 + }; + + num_videomodes = sizeof(videomode) / sizeof(uint32_t); + + resolution_count = 0; + for (unsigned i = 0; i < num_videomodes; i++) + { + if(gfx_ctx_check_resolution(videomode[i])) + resolution_count++; + } + + g_console.supported_resolutions = malloc(resolution_count * sizeof(uint32_t)); + g_console.supported_resolutions_count = 0; + + for (unsigned i = 0; i < num_videomodes; i++) + { + if(gfx_ctx_check_resolution(videomode[i])) + { + g_console.supported_resolutions[g_console.supported_resolutions_count++] = videomode[i]; + g_console.initial_resolution_id = videomode[i]; + + if (g_console.current_resolution_id == videomode[i]) + { + defaultresolution = false; + g_console.current_resolution_index = g_console.supported_resolutions_count-1; + } + } + } + + /* In case we didn't specify a resolution - make the last resolution + that was added to the list (the highest resolution) the default resolution */ + if (g_console.current_resolution_id > num_videomodes || defaultresolution) + g_console.current_resolution_index = g_console.supported_resolutions_count - 1; + + g_console.check_available_resolutions = true; +} + void gfx_ctx_set_swap_interval(unsigned interval, bool inited) { (void)inited; @@ -172,12 +250,9 @@ bool gfx_ctx_init(void) if (g_console.current_resolution_id) { - CellVideoOutResolution resolution; - cellVideoOutGetResolution(g_console.current_resolution_id, &resolution); - params.enable |= PSGL_DEVICE_PARAMETERS_WIDTH_HEIGHT; - params.width = resolution.width; - params.height = resolution.height; + params.width = gfx_ctx_get_resolution_width(g_console.current_resolution_id); + params.height = gfx_ctx_get_resolution_height(g_console.current_resolution_id); } gl_device = psglCreateDeviceExtended(¶ms); @@ -240,89 +315,6 @@ void gfx_ctx_set_fbo(bool enable) gl->render_to_tex = enable; } -/*============================================================ - MISC - TODO: Refactor -============================================================ */ - -void gfx_ctx_get_available_resolutions (void) -{ - bool defaultresolution; - uint32_t resolution_count; - uint16_t num_videomodes; - - if (g_console.check_available_resolutions) - return; - - defaultresolution = true; - - uint32_t videomode[] = { - CELL_VIDEO_OUT_RESOLUTION_480, - CELL_VIDEO_OUT_RESOLUTION_576, - CELL_VIDEO_OUT_RESOLUTION_960x1080, - CELL_VIDEO_OUT_RESOLUTION_720, - CELL_VIDEO_OUT_RESOLUTION_1280x1080, - CELL_VIDEO_OUT_RESOLUTION_1440x1080, - CELL_VIDEO_OUT_RESOLUTION_1600x1080, - CELL_VIDEO_OUT_RESOLUTION_1080 - }; - - num_videomodes = sizeof(videomode) / sizeof(uint32_t); - - resolution_count = 0; - for (unsigned i = 0; i < num_videomodes; i++) - { - if (cellVideoOutGetResolutionAvailability(CELL_VIDEO_OUT_PRIMARY, videomode[i], CELL_VIDEO_OUT_ASPECT_AUTO, 0)) - resolution_count++; - } - - g_console.supported_resolutions = malloc(resolution_count * sizeof(uint32_t)); - g_console.supported_resolutions_count = 0; - - for (unsigned i = 0; i < num_videomodes; i++) - { - if (cellVideoOutGetResolutionAvailability(CELL_VIDEO_OUT_PRIMARY, videomode[i], CELL_VIDEO_OUT_ASPECT_AUTO, 0)) - { - g_console.supported_resolutions[g_console.supported_resolutions_count++] = videomode[i]; - g_console.initial_resolution_id = videomode[i]; - - if (g_console.current_resolution_id == videomode[i]) - { - defaultresolution = false; - g_console.current_resolution_index = g_console.supported_resolutions_count-1; - } - } - } - - /* In case we didn't specify a resolution - make the last resolution - that was added to the list (the highest resolution) the default resolution */ - if (g_console.current_resolution_id > num_videomodes || defaultresolution) - g_console.current_resolution_index = g_console.supported_resolutions_count - 1; - - g_console.check_available_resolutions = true; -} - -int gfx_ctx_check_resolution(unsigned resolution_id) -{ - return cellVideoOutGetResolutionAvailability(CELL_VIDEO_OUT_PRIMARY, resolution_id, CELL_VIDEO_OUT_ASPECT_AUTO, 0); -} - -unsigned gfx_ctx_get_resolution_width(unsigned resolution_id) -{ - CellVideoOutResolution resolution; - cellVideoOutGetResolution(resolution_id, &resolution); - - return resolution.width; -} - -unsigned gfx_ctx_get_resolution_height(unsigned resolution_id) -{ - CellVideoOutResolution resolution; - cellVideoOutGetResolution(resolution_id, &resolution); - - return resolution.height; -} - void gfx_ctx_set_projection(gl_t *gl, const struct gl_ortho *ortho, bool allow_rotate) { // Calculate projection. diff --git a/gfx/context/xdk_ctx.c b/gfx/context/xdk_ctx.c index fc28810283..31c9a1154b 100644 --- a/gfx/context/xdk_ctx.c +++ b/gfx/context/xdk_ctx.c @@ -83,8 +83,10 @@ void gfx_ctx_swap_buffers(void) void gfx_ctx_clear(void) { xdk_d3d_video_t *device_ptr = (xdk_d3d_video_t*)driver.video_data; +#ifdef _XBOX1 unsigned flicker_filter = g_console.flicker_filter; bool soft_filter_enable = g_console.soft_display_filter_enable; +#endif device_ptr->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0); diff --git a/gfx/gl.c b/gfx/gl.c index 50467d3664..249966e7a6 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -292,7 +292,59 @@ static void gl_shader_scale(unsigned index, struct gl_fbo_scale *scale) #ifdef HAVE_FBO static void gl_compute_fbo_geometry(gl_t *gl, unsigned width, unsigned height, - unsigned vp_width, unsigned vp_height); + unsigned vp_width, unsigned vp_height) +{ + unsigned last_width = width; + unsigned last_height = height; + unsigned last_max_width = gl->tex_w; + unsigned last_max_height = gl->tex_h; + // Calculate viewports for FBOs. + for (int i = 0; i < gl->fbo_pass; i++) + { + switch (gl->fbo_scale[i].type_x) + { + case RARCH_SCALE_INPUT: + gl->fbo_rect[i].img_width = last_width * gl->fbo_scale[i].scale_x; + gl->fbo_rect[i].max_img_width = last_max_width * gl->fbo_scale[i].scale_x; + break; + + case RARCH_SCALE_ABSOLUTE: + gl->fbo_rect[i].img_width = gl->fbo_rect[i].max_img_width = gl->fbo_scale[i].abs_x; + break; + + case RARCH_SCALE_VIEWPORT: + gl->fbo_rect[i].img_width = gl->fbo_rect[i].max_img_width = gl->fbo_scale[i].scale_x * vp_width; + break; + + default: + break; + } + + switch (gl->fbo_scale[i].type_y) + { + case RARCH_SCALE_INPUT: + gl->fbo_rect[i].img_height = last_height * gl->fbo_scale[i].scale_y; + gl->fbo_rect[i].max_img_height = last_max_height * gl->fbo_scale[i].scale_y; + break; + + case RARCH_SCALE_ABSOLUTE: + gl->fbo_rect[i].img_height = gl->fbo_rect[i].max_img_height = gl->fbo_scale[i].abs_y; + break; + + case RARCH_SCALE_VIEWPORT: + gl->fbo_rect[i].img_height = gl->fbo_rect[i].max_img_height = gl->fbo_scale[i].scale_y * vp_height; + break; + + default: + break; + } + + last_width = gl->fbo_rect[i].img_width; + last_height = gl->fbo_rect[i].img_height; + last_max_width = gl->fbo_rect[i].max_img_width; + last_max_height = gl->fbo_rect[i].max_img_height; + } +} static void gl_create_fbo_textures(gl_t *gl) { @@ -533,60 +585,6 @@ static inline void set_texture_coords(GLfloat *coords, GLfloat xamt, GLfloat yam } #ifdef HAVE_FBO -static void gl_compute_fbo_geometry(gl_t *gl, unsigned width, unsigned height, - unsigned vp_width, unsigned vp_height) -{ - unsigned last_width = width; - unsigned last_height = height; - unsigned last_max_width = gl->tex_w; - unsigned last_max_height = gl->tex_h; - // Calculate viewports for FBOs. - for (int i = 0; i < gl->fbo_pass; i++) - { - switch (gl->fbo_scale[i].type_x) - { - case RARCH_SCALE_INPUT: - gl->fbo_rect[i].img_width = last_width * gl->fbo_scale[i].scale_x; - gl->fbo_rect[i].max_img_width = last_max_width * gl->fbo_scale[i].scale_x; - break; - - case RARCH_SCALE_ABSOLUTE: - gl->fbo_rect[i].img_width = gl->fbo_rect[i].max_img_width = gl->fbo_scale[i].abs_x; - break; - - case RARCH_SCALE_VIEWPORT: - gl->fbo_rect[i].img_width = gl->fbo_rect[i].max_img_width = gl->fbo_scale[i].scale_x * vp_width; - break; - - default: - break; - } - - switch (gl->fbo_scale[i].type_y) - { - case RARCH_SCALE_INPUT: - gl->fbo_rect[i].img_height = last_height * gl->fbo_scale[i].scale_y; - gl->fbo_rect[i].max_img_height = last_max_height * gl->fbo_scale[i].scale_y; - break; - - case RARCH_SCALE_ABSOLUTE: - gl->fbo_rect[i].img_height = gl->fbo_rect[i].max_img_height = gl->fbo_scale[i].abs_y; - break; - - case RARCH_SCALE_VIEWPORT: - gl->fbo_rect[i].img_height = gl->fbo_rect[i].max_img_height = gl->fbo_scale[i].scale_y * vp_height; - break; - - default: - break; - } - - last_width = gl->fbo_rect[i].img_width; - last_height = gl->fbo_rect[i].img_height; - last_max_width = gl->fbo_rect[i].max_img_width; - last_max_height = gl->fbo_rect[i].max_img_height; - } -} static inline void gl_start_frame_fbo(gl_t *gl) { @@ -1062,7 +1060,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo RARCH_LOG("GL: Using resolution %ux%u\n", gl->win_width, gl->win_height); -#if defined(HAVE_CG_MENU) && defined(RARCH_CONSOLE) +#if defined(HAVE_CG_MENU) RARCH_LOG("Initializing menu shader ...\n"); gl_cg_set_menu_shader(default_paths.menu_shader_file); #endif From e3e3e1f3bc09d75105f526d225875b671f634f78 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 10 Aug 2012 07:20:49 +0200 Subject: [PATCH 152/492] (PS3) Create gfx_ctx_get_aspect_ratio --- console/rgl/ps3/device_ctx.cpp | 16 ---------------- console/rgl/ps3/rgl.h | 1 - gfx/context/ps3_ctx.c | 16 ++++++++++++++++ gfx/context/ps3_ctx.h | 1 + 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/console/rgl/ps3/device_ctx.cpp b/console/rgl/ps3/device_ctx.cpp index c011dde301..06a7f24924 100644 --- a/console/rgl/ps3/device_ctx.cpp +++ b/console/rgl/ps3/device_ctx.cpp @@ -1050,22 +1050,6 @@ PSGLdevice* psglCreateDeviceExtended(const PSGLdeviceParameters *parameters ) return device; } -GLfloat psglGetDeviceAspectRatio(const PSGLdevice * device) -{ - CellVideoOutState videoState; - cellVideoOutGetState(CELL_VIDEO_OUT_PRIMARY, 0, &videoState); - - switch (videoState.displayMode.aspect) - { - case CELL_VIDEO_OUT_ASPECT_4_3: - return 4.0f/3.0f; - case CELL_VIDEO_OUT_ASPECT_16_9: - return 16.0f/9.0f; - } - - return 16.0f/9.0f; -} - void psglGetDeviceDimensions(const PSGLdevice * device, GLuint *width, GLuint *height) { *width = device->deviceParameters.width; diff --git a/console/rgl/ps3/rgl.h b/console/rgl/ps3/rgl.h index c194065d1d..f9a63b0729 100644 --- a/console/rgl/ps3/rgl.h +++ b/console/rgl/ps3/rgl.h @@ -1005,7 +1005,6 @@ extern void psglExit(); PSGLdevice *psglCreateDeviceAuto( GLenum colorFormat, GLenum depthFormat, GLenum multisamplingMode ); PSGLdevice *psglCreateDeviceExtended( const PSGLdeviceParameters *parameters ); -GLfloat psglGetDeviceAspectRatio(const PSGLdevice *device ); void psglGetDeviceDimensions(const PSGLdevice *device, GLuint *width, GLuint *height ); void psglDestroyDevice( PSGLdevice* device ); diff --git a/gfx/context/ps3_ctx.c b/gfx/context/ps3_ctx.c index 6b38196807..9057c2fae6 100644 --- a/gfx/context/ps3_ctx.c +++ b/gfx/context/ps3_ctx.c @@ -58,6 +58,22 @@ unsigned gfx_ctx_get_resolution_height(unsigned resolution_id) return resolution.height; } +float gfx_ctx_get_aspect_ratio(void) +{ + CellVideoOutState videoState; + cellVideoOutGetState(CELL_VIDEO_OUT_PRIMARY, 0, &videoState); + + switch (videoState.displayMode.aspect) + { + case CELL_VIDEO_OUT_ASPECT_4_3: + return 4.0f/3.0f; + case CELL_VIDEO_OUT_ASPECT_16_9: + return 16.0f/9.0f; + } + + return 16.0f/9.0f; +} + void gfx_ctx_get_available_resolutions (void) { bool defaultresolution; diff --git a/gfx/context/ps3_ctx.h b/gfx/context/ps3_ctx.h index 0635dc1554..f53a61d29f 100644 --- a/gfx/context/ps3_ctx.h +++ b/gfx/context/ps3_ctx.h @@ -19,6 +19,7 @@ void gfx_ctx_get_available_resolutions (void); int gfx_ctx_check_resolution(unsigned resolution_id); +float gfx_ctx_get_aspect_ratio(void); unsigned gfx_ctx_get_resolution_width(unsigned resolution_id); unsigned gfx_ctx_get_resolution_height(unsigned resolution_id); void gfx_ctx_set_projection(gl_t *gl, const struct gl_ortho *ortho, bool allow_rotate); From 545b530a5012f7be06fcafa7b67460537fd9e4f5 Mon Sep 17 00:00:00 2001 From: Toad King Date: Fri, 10 Aug 2012 14:48:56 -0400 Subject: [PATCH 153/492] (GX) fix asm blitter in optimized builds --- gx/gx_video.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gx/gx_video.c b/gx/gx_video.c index 90b260e323..b874ce22d7 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -235,10 +235,11 @@ static void gx_start(void) g_vsync = true; } -#if 0 -// TODO: Fix +#define ASM_BLITTER -static void update_texture_asm(const uint32_t *src, +#ifdef ASM_BLITTER + +static __attribute__ ((noinline)) void update_texture_asm(const uint32_t *src, unsigned width, unsigned height, unsigned pitch) { register uint32_t tmp0, tmp1, tmp2, tmp3, line2, line2b, line3, line3b, line4, line4b, line5; @@ -357,8 +358,8 @@ static void update_texture(const uint32_t *src, unsigned width, unsigned height, unsigned pitch) { gx_video_t *gx = (gx_video_t*)driver.video_data; -#if 0 - if (!(width & 3) && !(height & 3)) +#ifdef ASM_BLITTER + if (width && height && !(width & 3) && !(height & 3)) { update_texture_asm(src, width, height, pitch); } @@ -382,7 +383,6 @@ static void update_texture(const uint32_t *src, } } - // TODO: only convert when menu is visible if(gx->menu_render) { uint16_t *block = (uint16_t *) menu_tex.data; From ce0ff54693b5ee654d70a83c87f08754da7fe589 Mon Sep 17 00:00:00 2001 From: Toad King Date: Fri, 10 Aug 2012 22:49:12 -0400 Subject: [PATCH 154/492] (GX) add devoptabs for logging stdout/stderr, useful for logging core messages --- gx/frontend/main.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/gx/frontend/main.c b/gx/frontend/main.c index e63ddc659b..d0b428bedb 100644 --- a/gx/frontend/main.c +++ b/gx/frontend/main.c @@ -51,6 +51,52 @@ rgui_handle_t *rgui; char app_dir[PATH_MAX]; +static devoptab_t dotab_stdout = { + "stdout", // device name + 0, // size of file structure + NULL, // device open + NULL, // device close + NULL, // device write + NULL, // device read + NULL, // device seek + NULL, // device fstat + NULL, // device stat + NULL, // device link + NULL, // device unlink + NULL, // device chdir + NULL, // device rename + NULL, // device mkdir + 0, // dirStateSize + NULL, // device diropen_r + NULL, // device dirreset_r + NULL, // device dirnext_r + NULL, // device dirclose_r + NULL, // device statvfs_r + NULL, // device ftrunctate_r + NULL, // device fsync_r + NULL, // deviceData; +}; + +#ifdef HAVE_LOGGER +int gx_logger_net(struct _reent *r, int fd, const char *ptr, size_t len) +{ + static char temp[4000]; + size_t l = len >= 4000 ? 3999 : len; + memcpy(temp, ptr, l); + temp[l] = 0; + logger_send("%s", temp); + return len; +} +#endif + +#ifdef HAVE_FILE_LOGGER +int gx_logger_file(struct _reent *r, int fd, const char *ptr, size_t len) +{ + fwrite(ptr, 1, len, log_fp); + return len; +} +#endif + static const struct retro_keybind _wii_nav_binds[] = { { 0, 0, 0, GX_GC_UP | GX_GC_LSTICK_UP | GX_GC_RSTICK_UP | GX_CLASSIC_UP | GX_CLASSIC_LSTICK_UP | GX_CLASSIC_RSTICK_UP | GX_WIIMOTE_UP | GX_NUNCHUK_UP, 0 }, { 0, 0, 0, GX_GC_DOWN | GX_GC_LSTICK_DOWN | GX_GC_RSTICK_DOWN | GX_CLASSIC_DOWN | GX_CLASSIC_LSTICK_DOWN | GX_CLASSIC_RSTICK_DOWN | GX_WIIMOTE_DOWN | GX_NUNCHUK_DOWN, 0 }, @@ -299,10 +345,16 @@ int main(void) #ifdef HAVE_LOGGER g_extern.verbose = true; logger_init(); + devoptab_list[STD_OUT] = &dotab_stdout; + devoptab_list[STD_ERR] = &dotab_stdout; + dotab_stdout.write_r = gx_logger_net; #endif #ifdef HAVE_FILE_LOGGER g_extern.verbose = true; log_fp = fopen("/retroarch-log.txt", "w"); + devoptab_list[STD_OUT] = &dotab_stdout; + devoptab_list[STD_ERR] = &dotab_stdout; + dotab_stdout.write_r = gx_logger_file; #endif config_set_defaults(); From 28c14e794665b8e8188ec012ed83cdda15f1320e Mon Sep 17 00:00:00 2001 From: Toad King Date: Fri, 10 Aug 2012 23:42:24 -0400 Subject: [PATCH 155/492] (GX) silence warning --- gx/frontend/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gx/frontend/main.c b/gx/frontend/main.c index d0b428bedb..5041e6ff58 100644 --- a/gx/frontend/main.c +++ b/gx/frontend/main.c @@ -51,6 +51,7 @@ rgui_handle_t *rgui; char app_dir[PATH_MAX]; +#if defined(HAVE_LOGGER) || defined(HAVE_FILE_LOGGER) static devoptab_t dotab_stdout = { "stdout", // device name 0, // size of file structure @@ -76,6 +77,7 @@ static devoptab_t dotab_stdout = { NULL, // device fsync_r NULL, // deviceData; }; +#endif #ifdef HAVE_LOGGER int gx_logger_net(struct _reent *r, int fd, const char *ptr, size_t len) From c9a22392c857d3c71d2e0b25279c8c4b31b16f64 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 11 Aug 2012 09:18:39 +0200 Subject: [PATCH 156/492] Update to 0.9.7-rc1. --- Makefile.ps3 | 2 +- Makefile.ps3.retroarch | 2 +- Makefile.psl1ght | 2 +- Makefile.wii | 2 +- Makefile.wii.salamander | 2 +- Makefile.win | 6 +++--- Makefile.xenon | 2 +- android/jni/Android.mk | 2 +- configure | 2 +- gx/pkg/meta.xml | 2 +- msvc/RetroArch-360/RetroArch-360.vcxproj | 12 ++++++------ msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj | 10 +++++----- 12 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Makefile.ps3 b/Makefile.ps3 index 32dfcaeb49..ccb518d951 100644 --- a/Makefile.ps3 +++ b/Makefile.ps3 @@ -1,4 +1,4 @@ -RARCH_VERSION = "0.9.6" +RARCH_VERSION = "0.9.7-rc1" #which compiler to build with - GCC or SNC #set to GCC for debug builds for use with debugger diff --git a/Makefile.ps3.retroarch b/Makefile.ps3.retroarch index 183cfc874f..eb42aaa0d3 100644 --- a/Makefile.ps3.retroarch +++ b/Makefile.ps3.retroarch @@ -1,4 +1,4 @@ -RARCH_VERSION = "0.9.6" +RARCH_VERSION = "0.9.7-rc1" #which compiler to build with - GCC or SNC #set to GCC for debug builds for use with debugger diff --git a/Makefile.psl1ght b/Makefile.psl1ght index 0d8c29b044..d510d71125 100644 --- a/Makefile.psl1ght +++ b/Makefile.psl1ght @@ -40,7 +40,7 @@ endif RSXGL_DEFINES = -D__RSX__ -DGL3_PROTOTYPES -SHARED_FLAGS := -DHAVE_FILEBROWSER $(RSXGL_DEFINES) -DHAVE_OSKUTIL -DHAVE_MOUSE -DHAVE_DEFAULT_RETROPAD_INPUT -DRARCH_CONSOLE -DHAVE_CONFIGFILE=1 -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"0.9.6\" -Dmain=rarch_main -Wno-char-subscripts +SHARED_FLAGS := -DHAVE_FILEBROWSER $(RSXGL_DEFINES) -DHAVE_OSKUTIL -DHAVE_MOUSE -DHAVE_DEFAULT_RETROPAD_INPUT -DRARCH_CONSOLE -DHAVE_CONFIGFILE=1 -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"0.9.7-rc1\" -Dmain=rarch_main -Wno-char-subscripts CFLAGS += -std=gnu99 $(SHARED_FLAGS) CXXFLAGS += $(SHARED_FLAGS) diff --git a/Makefile.wii b/Makefile.wii index 5286a768a4..f961a0afb7 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -39,7 +39,7 @@ CFLAGS += -DHAVE_FILE_LOGGER CFLAGS += -Iconsole/logger endif -CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_RGUI -DRARCH_CONSOLE -DHAVE_LIBRETRO_MANAGEMENT -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"0.9.6\" -Dmain=rarch_main -Wno-char-subscripts +CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_RGUI -DRARCH_CONSOLE -DHAVE_LIBRETRO_MANAGEMENT -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"0.9.7-rc1\" -Dmain=rarch_main -Wno-char-subscripts ifeq ($(DEBUG), 1) CFLAGS += -O0 -g diff --git a/Makefile.wii.salamander b/Makefile.wii.salamander index 8f51129ba3..660be31137 100644 --- a/Makefile.wii.salamander +++ b/Makefile.wii.salamander @@ -39,7 +39,7 @@ CFLAGS += -DHAVE_FILE_LOGGER CFLAGS += -Iconsole/logger endif -CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DIS_SALAMANDER -DRARCH_CONSOLE -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DPACKAGE_VERSION=\"0.9.6\" -Wno-char-subscripts +CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DIS_SALAMANDER -DRARCH_CONSOLE -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DPACKAGE_VERSION=\"0.9.7-rc1\" -Wno-char-subscripts ifeq ($(DEBUG), 1) CFLAGS += -O0 -g diff --git a/Makefile.win b/Makefile.win index b8fdd29db0..68aa7c95ed 100644 --- a/Makefile.win +++ b/Makefile.win @@ -53,7 +53,7 @@ endif libretro ?= -lretro LIBS = -lm -DEFINES = -I. -DHAVE_CONFIGFILE -DHAVE_SDL -DHAVE_SCREENSHOTS -DHAVE_BSV_MOVIE -DPACKAGE_VERSION=\"0.9.6\" +DEFINES = -I. -DHAVE_CONFIGFILE -DHAVE_SDL -DHAVE_SCREENSHOTS -DHAVE_BSV_MOVIE -DPACKAGE_VERSION=\"0.9.7-rc1\" LDFLAGS = -L. -static-libgcc ifeq ($(TDM_GCC),) @@ -229,10 +229,10 @@ clean: rm -f tools/*.o dist_x86: all - zip -r retroarch-win32-0.9.6.zip $(TARGET) $(JTARGET) retroarch.cfg SDL.dll + zip -r retroarch-win32-0.9.7-rc1.zip $(TARGET) $(JTARGET) retroarch.cfg SDL.dll dist_x86_64: all - zip -r retroarch-win64-0.9.6.zip $(TARGET) $(JTARGET) retroarch.cfg SDL.dll + zip -r retroarch-win64-0.9.7-rc1.zip $(TARGET) $(JTARGET) retroarch.cfg SDL.dll libs_x86: wget https://github.com/downloads/Themaister/RetroArch/RetroArch-win32-libs.zip --no-check-certificate diff --git a/Makefile.xenon b/Makefile.xenon index b28b211132..ad8651c6db 100644 --- a/Makefile.xenon +++ b/Makefile.xenon @@ -21,7 +21,7 @@ INCDIRS = -I. -I$(DEVKITXENON)/usr/include OBJ = fifo_buffer.o retroarch.o driver.o file.o file_path.o settings.o message.o rewind.o movie.o gfx/gfx_common.o patch.o compat/compat.o screenshot.o audio/hermite.o dynamic.o audio/utils.o conf/config_file.o 360/frontend-xenon/main.o 360/xenon360_audio.o 360/xenon360_input.o 360/xenon360_video.o LIBS = -lretro_xenon360 -lxenon -lm -lc -DEFINES = -std=gnu99 -DHAVE_CONFIGFILE=1 -DPACKAGE_VERSION=\"0.9.6\" -DRARCH_CONSOLE -DHAVE_GETOPT_LONG=1 -Dmain=rarch_main +DEFINES = -std=gnu99 -DHAVE_CONFIGFILE=1 -DPACKAGE_VERSION=\"0.9.7-rc1\" -DRARCH_CONSOLE -DHAVE_GETOPT_LONG=1 -Dmain=rarch_main DEFINES += -maltivec -mhard-float -m32 -mpowerpc64 -mcpu=cell -mtune=cell -fno-pic -g -Wall -DXENON $(INCDIRS) DEFINES += -u read -u _start -u exc_base diff --git a/android/jni/Android.mk b/android/jni/Android.mk index a6894688cc..0cf9518461 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -1,4 +1,4 @@ -RARCH_VERSION = "0.9.6" +RARCH_VERSION = "0.9.7-rc1" LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) diff --git a/configure b/configure index fc410d94ea..3e084a275c 100755 --- a/configure +++ b/configure @@ -1,7 +1,7 @@ #!/bin/sh PACKAGE_NAME=retroarch -PACKAGE_VERSION=0.9.6 +PACKAGE_VERSION=0.9.7-rc1 . qb/qb.params.sh diff --git a/gx/pkg/meta.xml b/gx/pkg/meta.xml index eb8c620a49..321e7bc7b6 100644 --- a/gx/pkg/meta.xml +++ b/gx/pkg/meta.xml @@ -2,7 +2,7 @@ RetroArch GX Maister, Squarepusher, ToadKing - 0.9.6 + 0.9.7-rc1 2012 Multi-system emulator A port of RetroArch to the GameCube/Wii. diff --git a/msvc/RetroArch-360/RetroArch-360.vcxproj b/msvc/RetroArch-360/RetroArch-360.vcxproj index a2160a9ac7..bebbed986b 100644 --- a/msvc/RetroArch-360/RetroArch-360.vcxproj +++ b/msvc/RetroArch-360/RetroArch-360.vcxproj @@ -113,7 +113,7 @@ true false MultiThreadedDebug - _DEBUG;_XBOX;HAVE_XINPUT2;PACKAGE_VERSION="0.9.6";%(PreprocessorDefinitions);HAVE_DEFAULT_RETROPAD_INPUT;_CRT_SECURE_NO_WARNINGS;main=rarch_main;RARCH_CONSOLE;HAVE_CONFIGFILE;HAVE_FILEBROWSER;HAVE_HDD_CACHE_PARTITION;HAVE_NETPLAY;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO + _DEBUG;_XBOX;HAVE_XINPUT2;PACKAGE_VERSION="0.9.7-rc1";%(PreprocessorDefinitions);HAVE_DEFAULT_RETROPAD_INPUT;_CRT_SECURE_NO_WARNINGS;main=rarch_main;RARCH_CONSOLE;HAVE_CONFIGFILE;HAVE_FILEBROWSER;HAVE_HDD_CACHE_PARTITION;HAVE_NETPLAY;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO Callcap @@ -151,7 +151,7 @@ AnalyzeOnly false MultiThreadedDebug - _DEBUG;_XBOX;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.6";HAVE_DEFAULT_RETROPAD_INPUT;_CRT_SECURE_NO_WARNINGS;main=rarch_main;HAVE_CONFIGFILE;HAVE_FILEBROWSER;HAVE_HDD_CACHE_PARTITION;RARCH_CONSOLE;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO + _DEBUG;_XBOX;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.7-rc1";HAVE_DEFAULT_RETROPAD_INPUT;_CRT_SECURE_NO_WARNINGS;main=rarch_main;HAVE_CONFIGFILE;HAVE_FILEBROWSER;HAVE_HDD_CACHE_PARTITION;RARCH_CONSOLE;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO Callcap @@ -190,7 +190,7 @@ Size false MultiThreaded - NDEBUG;_XBOX;PROFILE;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.6";HAVE_DEFAULT_RETROPAD_INPUT;_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE;main=rarch_main;HAVE_CONFIGFILE;HAVE_FILEBROWSER;HAVE_HDD_CACHE_PARTITION;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO + NDEBUG;_XBOX;PROFILE;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.7-rc1";HAVE_DEFAULT_RETROPAD_INPUT;_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE;main=rarch_main;HAVE_CONFIGFILE;HAVE_FILEBROWSER;HAVE_HDD_CACHE_PARTITION;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO Callcap @@ -234,7 +234,7 @@ Size false MultiThreaded - NDEBUG;_XBOX;PROFILE;FASTCAP;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.6";HAVE_DEFAULT_RETROPAD_INPUT;_CRT_SECURE_NO_WARNINGS;main=rarch_main;HAVE_CONFIGFILE;HAVE_FILEBROWSER;HAVE_HDD_CACHE_PARTITION;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO + NDEBUG;_XBOX;PROFILE;FASTCAP;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.7-rc1";HAVE_DEFAULT_RETROPAD_INPUT;_CRT_SECURE_NO_WARNINGS;main=rarch_main;HAVE_CONFIGFILE;HAVE_FILEBROWSER;HAVE_HDD_CACHE_PARTITION;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO true @@ -275,7 +275,7 @@ false false MultiThreaded - NDEBUG;_XBOX;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.6";_CRT_SECURE_NO_WARNINGS;HAVE_DEFAULT_RETROPAD_INPUT;main=rarch_main;RARCH_CONSOLE=1;HAVE_CONFIGFILE;HAVE_FILEBROWSER;HAVE_HDD_CACHE_PARTITION;HAVE_NETPLAY;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO + NDEBUG;_XBOX;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.7-rc1";_CRT_SECURE_NO_WARNINGS;HAVE_DEFAULT_RETROPAD_INPUT;main=rarch_main;RARCH_CONSOLE=1;HAVE_CONFIGFILE;HAVE_FILEBROWSER;HAVE_HDD_CACHE_PARTITION;HAVE_NETPLAY;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO true @@ -316,7 +316,7 @@ false false MultiThreaded - NDEBUG;_XBOX;LTCG;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.6";_CRT_SECURE_NO_WARNINGS;HAVE_DEFAULT_RETROPAD_INPUT;RARCH_CONSOLE;main=rarch_main;HAVE_CONFIGFILE;HAVE_FILEBROWSER;HAVE_HDD_CACHE_PARTITION;HAVE_NETPLAY;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO + NDEBUG;_XBOX;LTCG;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.7-rc1";_CRT_SECURE_NO_WARNINGS;HAVE_DEFAULT_RETROPAD_INPUT;RARCH_CONSOLE;main=rarch_main;HAVE_CONFIGFILE;HAVE_FILEBROWSER;HAVE_HDD_CACHE_PARTITION;HAVE_NETPLAY;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO true diff --git a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj index 8f8a6d3591..3b0346f99d 100644 --- a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj +++ b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj @@ -22,7 +22,7 @@ Optimization="3" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\msvc-stdint";"$(SolutionDir)\msvc-71"" - PreprocessorDefinitions="_DEBUG;_XBOX;_XBOX1;HAVE_RMENU;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.6\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" + PreprocessorDefinitions="_DEBUG;_XBOX;_XBOX1;HAVE_RMENU;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.7-rc1\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" MinimalRebuild="TRUE" BasicRuntimeChecks="0" RuntimeLibrary="1" @@ -72,7 +72,7 @@ OmitFramePointers="TRUE" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\msvc-stdint";"$(SolutionDir)\msvc-71"" - PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.6\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;PROFILE;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" + PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.7-rc1\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;PROFILE;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="TRUE" @@ -126,7 +126,7 @@ OmitFramePointers="TRUE" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\msvc-stdint";"$(SolutionDir)\msvc-71"" - PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.6\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;PROFILE;FASTCAP;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" + PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.7-rc1\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;PROFILE;FASTCAP;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="TRUE" @@ -187,7 +187,7 @@ EnableFiberSafeOptimizations="TRUE" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\msvc-stdint";"$(SolutionDir)\msvc-71"" - PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.6\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;HAVE_GRIFFIN;inline=_inline;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" + PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.7-rc1\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;HAVE_GRIFFIN;inline=_inline;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="TRUE" @@ -240,7 +240,7 @@ OmitFramePointers="TRUE" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\msvc-stdint";"$(SolutionDir)\msvc-71"" - PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.6\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;LTCG;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" + PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.7-rc1\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;LTCG;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_CONFIGFILE;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="TRUE" From e57a0836979d9a2cae2013e71882f74218f641b4 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sat, 11 Aug 2012 13:33:32 +0200 Subject: [PATCH 157/492] (GX) Compile in HAVE_THREAD - provide pthread wrapper for GX --- Makefile.wii | 2 +- gx/gx_pthread.h | 79 +++++++++++++++++++++++++++++++++++++++++++++++++ thread.c | 2 ++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 gx/gx_pthread.h diff --git a/Makefile.wii b/Makefile.wii index f961a0afb7..c0da196745 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -39,7 +39,7 @@ CFLAGS += -DHAVE_FILE_LOGGER CFLAGS += -Iconsole/logger endif -CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_RGUI -DRARCH_CONSOLE -DHAVE_LIBRETRO_MANAGEMENT -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"0.9.7-rc1\" -Dmain=rarch_main -Wno-char-subscripts +CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_RGUI -DHAVE_THREAD -DRARCH_CONSOLE -DHAVE_LIBRETRO_MANAGEMENT -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"0.9.7-rc1\" -Dmain=rarch_main -Wno-char-subscripts ifeq ($(DEBUG), 1) CFLAGS += -O0 -g diff --git a/gx/gx_pthread.h b/gx/gx_pthread.h new file mode 100644 index 0000000000..739759a990 --- /dev/null +++ b/gx/gx_pthread.h @@ -0,0 +1,79 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * Copyright (C) 2011-2012 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef _GX_PTHREAD_WRAP_GX_ +#define _GX_PTHREAD_WRAP_GX_ + +#include +#include +#include + +#define STACKSIZE 8*1024 + +typedef lwp_t pthread_t; +typedef mutex_t pthread_mutex_t; +typedef void* pthread_mutexattr_t; +typedef int pthread_attr_t; +typedef cond_t pthread_cond_t; +typedef cond_t pthread_condattr_t; + +static inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg) +{ + *thread = 0; + return LWP_CreateThread(thread, start_routine, arg, 0, STACKSIZE, 64); +} + +static inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) +{ + return LWP_MutexInit(mutex, 0); +} + +static inline int pthread_mutex_destroy(pthread_mutex_t *mutex){ return LWP_MutexDestroy(*mutex);} + +static inline int pthread_mutex_lock(pthread_mutex_t *mutex) { return LWP_MutexLock(*mutex); } + +static inline int pthread_mutex_unlock(pthread_mutex_t *mutex) { return LWP_MutexUnlock(*mutex); } + +static inline int pthread_join(pthread_t thread, void**retval) { return LWP_JoinThread(thread, NULL); } + +static inline int pthread_mutex_trylock(pthread_mutex_t *mutex){ return LWP_MutexTryLock(*mutex);} + +static inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) +{ + return LWP_CondWait(*(cond), *(mutex)); +} + +static inline int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) +{ + return LWP_CondWait(*(cond), *(mutex)); +} + +static inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) +{ + return LWP_CondInit(cond); +} + +static inline int pthread_cond_signal(pthread_cond_t *cond) +{ + return LWP_CondSignal(*(cond)); +} + +static inline int pthread_cond_destroy(pthread_cond_t *cond) +{ + return LWP_CondDestroy(*(cond)); +} + +#endif diff --git a/thread.c b/thread.c index 0a068e829f..93d93a168e 100644 --- a/thread.c +++ b/thread.c @@ -21,6 +21,8 @@ #include #elif defined(_XBOX) #include +#elif defined(GEKKO) +#include "gx/gx_pthread.h" #else #include #include From 4d7d35f0efa3eeb67a4ec82fbe76e466ab40ef10 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sat, 11 Aug 2012 14:27:12 +0200 Subject: [PATCH 158/492] Move platform-specific thread code into common thread/ folder --- Makefile.xenon | 2 +- thread.c | 2 +- {gx => thread}/gx_pthread.h | 0 360/frontend-xenon/cond.c => thread/xenon_sdl_threads.c | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename {gx => thread}/gx_pthread.h (100%) rename 360/frontend-xenon/cond.c => thread/xenon_sdl_threads.c (100%) diff --git a/Makefile.xenon b/Makefile.xenon index ad8651c6db..9e259a9884 100644 --- a/Makefile.xenon +++ b/Makefile.xenon @@ -18,7 +18,7 @@ PPU_TARGET_ADJUSTED := retroarch-libxenon.elf32 LDDIRS = -L. -L$(DEVKITXENON)/usr/lib -L$(DEVKITXENON)/xenon/lib/32 INCDIRS = -I. -I$(DEVKITXENON)/usr/include -OBJ = fifo_buffer.o retroarch.o driver.o file.o file_path.o settings.o message.o rewind.o movie.o gfx/gfx_common.o patch.o compat/compat.o screenshot.o audio/hermite.o dynamic.o audio/utils.o conf/config_file.o 360/frontend-xenon/main.o 360/xenon360_audio.o 360/xenon360_input.o 360/xenon360_video.o +OBJ = fifo_buffer.o retroarch.o driver.o file.o file_path.o settings.o message.o rewind.o movie.o gfx/gfx_common.o patch.o compat/compat.o screenshot.o audio/hermite.o dynamic.o audio/utils.o conf/config_file.o 360/frontend-xenon/main.o 360/xenon360_audio.o 360/xenon360_input.o 360/xenon360_video.o thread/xenon_sdl_threads.o LIBS = -lretro_xenon360 -lxenon -lm -lc DEFINES = -std=gnu99 -DHAVE_CONFIGFILE=1 -DPACKAGE_VERSION=\"0.9.7-rc1\" -DRARCH_CONSOLE -DHAVE_GETOPT_LONG=1 -Dmain=rarch_main diff --git a/thread.c b/thread.c index 93d93a168e..dd9a412545 100644 --- a/thread.c +++ b/thread.c @@ -22,7 +22,7 @@ #elif defined(_XBOX) #include #elif defined(GEKKO) -#include "gx/gx_pthread.h" +#include "thread/gx_pthread.h" #else #include #include diff --git a/gx/gx_pthread.h b/thread/gx_pthread.h similarity index 100% rename from gx/gx_pthread.h rename to thread/gx_pthread.h diff --git a/360/frontend-xenon/cond.c b/thread/xenon_sdl_threads.c similarity index 100% rename from 360/frontend-xenon/cond.c rename to thread/xenon_sdl_threads.c From 5a34de395a4d40b74015853e225d49448a9880b5 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 11 Aug 2012 19:43:55 +0200 Subject: [PATCH 159/492] Minor stylistic cleanups. --- thread/gx_pthread.h | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/thread/gx_pthread.h b/thread/gx_pthread.h index 739759a990..c014b6291e 100644 --- a/thread/gx_pthread.h +++ b/thread/gx_pthread.h @@ -21,7 +21,7 @@ #include #include -#define STACKSIZE 8*1024 +#define STACKSIZE (8 * 1024) typedef lwp_t pthread_t; typedef mutex_t pthread_mutex_t; @@ -41,24 +41,41 @@ static inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex return LWP_MutexInit(mutex, 0); } -static inline int pthread_mutex_destroy(pthread_mutex_t *mutex){ return LWP_MutexDestroy(*mutex);} +static inline int pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + return LWP_MutexDestroy(*mutex); +} -static inline int pthread_mutex_lock(pthread_mutex_t *mutex) { return LWP_MutexLock(*mutex); } +static inline int pthread_mutex_lock(pthread_mutex_t *mutex) +{ + return LWP_MutexLock(*mutex); +} -static inline int pthread_mutex_unlock(pthread_mutex_t *mutex) { return LWP_MutexUnlock(*mutex); } +static inline int pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + return LWP_MutexUnlock(*mutex); +} -static inline int pthread_join(pthread_t thread, void**retval) { return LWP_JoinThread(thread, NULL); } +static inline int pthread_join(pthread_t thread, void **retval) +{ + // FIXME: Shouldn't the second arg to LWP_JoinThread take retval? + (void)retval; + return LWP_JoinThread(thread, NULL); +} -static inline int pthread_mutex_trylock(pthread_mutex_t *mutex){ return LWP_MutexTryLock(*mutex);} +static inline int pthread_mutex_trylock(pthread_mutex_t *mutex) +{ + return LWP_MutexTryLock(*mutex); +} static inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { - return LWP_CondWait(*(cond), *(mutex)); + return LWP_CondWait(*cond, *mutex); } static inline int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) { - return LWP_CondWait(*(cond), *(mutex)); + return LWP_CondWait(*cond, *mutex); } static inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) @@ -68,12 +85,12 @@ static inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr static inline int pthread_cond_signal(pthread_cond_t *cond) { - return LWP_CondSignal(*(cond)); + return LWP_CondSignal(*cond); } static inline int pthread_cond_destroy(pthread_cond_t *cond) { - return LWP_CondDestroy(*(cond)); + return LWP_CondDestroy(*cond); } #endif From 9f452def9c96d8f5457706e1cc96458982adbc6a Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 11 Aug 2012 20:36:52 +0200 Subject: [PATCH 160/492] Actually update rarch_video.h. --- gfx/ext/rarch_video.h | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/gfx/ext/rarch_video.h b/gfx/ext/rarch_video.h index 9f8f2a269c..04b8e057c5 100644 --- a/gfx/ext/rarch_video.h +++ b/gfx/ext/rarch_video.h @@ -24,7 +24,7 @@ extern "C" { #define RARCH_API_CALLTYPE #endif -#define RARCH_GRAPHICS_API_VERSION 3 +#define RARCH_GRAPHICS_API_VERSION 4 // Since we don't want to rely on C++ or C99 for a proper boolean type, // make sure return semantics are perfectly clear ... ;) @@ -170,17 +170,6 @@ typedef struct rarch_video_info // If any one of these are pressed, return 1 in state callback. struct rarch_keybind { - // If analog_x is true, we request an analog device to be polled - // rather than normal keys. - // The returned value should be the delta of - // last frame and current frame in the X-axis. - int analog_x; - // If analog_y is true, we request an analog device to be polled - // rather than normal keys. - // The returned value should be the delta of - // last frame and current frame in the Y-axis. - int analog_y; - // Keyboard key. The key values use the SDL 1.2 keysyms, // which probably need to be transformed to the native format. // The actual keysyms RetroArch uses are found in libretro.h. @@ -210,10 +199,18 @@ typedef struct rarch_input_driver void (*poll)(void *data); // Queries input state for a certain key on a certain player. - // Players are 1 - 5. + // Players are 1 - 8. // For digital inputs, pressed key is 1, not pressed key is 0. // Analog values have same range as a signed 16-bit integer. - int (*input_state)(void *data, const struct rarch_keybind *bind, + short (*input_state)(void *data, const struct rarch_keybind *bind, + unsigned player); + + // Queries analog input state for a certain key on a certain player in the range of [-0x8000, 0x7fff]. + // Only the direction of the bind should be returned. + // + // E.g. if the bind has bind for negative axis 5, and the axis is pressed to the positive + // axis, the returned value should be 0. + short (*input_state_analog)(void *data, unsigned joyaxis, unsigned player); // Frees the input struct. From e14a679f831bc067f7bb89fd81f3654e931a988b Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 12 Aug 2012 00:40:21 +0200 Subject: [PATCH 161/492] Forcefully disable VSync if game FPS >> monitor FPS. --- driver.c | 51 +++++++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/driver.c b/driver.c index 0131a62e5a..973c08c0a9 100644 --- a/driver.c +++ b/driver.c @@ -192,8 +192,37 @@ void init_drivers_pre(void) find_input_driver(); } +static void adjust_system_rates(void) +{ + const struct retro_system_timing *info = &g_extern.system.av_info.timing; + + float timing_skew = fabs(1.0f - info->fps / g_settings.video.refresh_rate); + if (timing_skew > 0.05f) // We don't want to adjust pitch too much. If we have extreme cases, just don't readjust at all. + { + RARCH_LOG("Timings deviate too much. Will not adjust. (Display = %.2f Hz, Game = %.2f Hz)\n", + g_settings.video.refresh_rate, + (float)info->fps); + + // We won't be able to do VSync reliably as game FPS > monitor FPS. + if (info->fps > g_settings.video.refresh_rate) + { + g_settings.video.vsync = false; + RARCH_LOG("Game FPS > Monitor FPS. Cannot rely on VSync.\n"); + } + + g_settings.video.refresh_rate = info->fps; + } + + g_settings.audio.in_rate = info->sample_rate * + (g_settings.video.refresh_rate / info->fps); + + RARCH_LOG("Set audio input rate to: %.2f Hz.\n", g_settings.audio.in_rate); +} + void init_drivers(void) { + adjust_system_rates(); + init_video_input(); init_audio(); } @@ -278,26 +307,6 @@ static void deinit_dsp_plugin(void) } #endif -static void adjust_audio_input_rate(void) -{ - const struct retro_system_timing *info = &g_extern.system.av_info.timing; - - float timing_skew = fabs(1.0f - info->fps / g_settings.video.refresh_rate); - if (timing_skew > 0.05f) // We don't want to adjust pitch too much. If we have extreme cases, just don't readjust at all. - { - RARCH_LOG("Timings deviate too much. Will not adjust. (Display = %.2f Hz, Game = %.2f Hz)\n", - g_settings.video.refresh_rate, - (float)info->fps); - - g_settings.video.refresh_rate = info->fps; - } - - g_settings.audio.in_rate = info->sample_rate * - (g_settings.video.refresh_rate / info->fps); - - RARCH_LOG("Set audio input rate to: %.2f Hz.\n", g_settings.audio.in_rate); -} - void init_audio(void) { // Accomodate rewind since at some point we might have two full buffers. @@ -321,8 +330,6 @@ void init_audio(void) return; } - adjust_audio_input_rate(); - driver.audio_data = audio_init_func(*g_settings.audio.device ? g_settings.audio.device : NULL, g_settings.audio.out_rate, g_settings.audio.latency); From 3634136a3a3085c5bcddf8d9d4747b0b4482c3a7 Mon Sep 17 00:00:00 2001 From: Toad King Date: Sun, 12 Aug 2012 01:32:22 -0400 Subject: [PATCH 162/492] (RGUI) display core name in menu --- console/rgui/rgui.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/console/rgui/rgui.c b/console/rgui/rgui.c index 9ae8a274d9..a7594b6484 100644 --- a/console/rgui/rgui.c +++ b/console/rgui/rgui.c @@ -29,7 +29,7 @@ #define TERM_START_X 15 #define TERM_START_Y 27 #define TERM_WIDTH (((RGUI_WIDTH - TERM_START_X - 15) / (FONT_WIDTH_STRIDE))) -#define TERM_HEIGHT (((RGUI_HEIGHT - TERM_START_Y - 15) / (FONT_HEIGHT_STRIDE))) +#define TERM_HEIGHT (((RGUI_HEIGHT - TERM_START_Y - 15) / (FONT_HEIGHT_STRIDE)) - 1) extern char app_dir[PATH_MAX]; @@ -290,6 +290,11 @@ static void render_text(rgui_handle_t *rgui) } blit_line(rgui, TERM_START_X + 15, 15, title, true); + struct retro_system_info info; + retro_get_system_info(&info); + snprintf(title, sizeof(title), "CORE: %s %s", info.library_name, info.library_version); + blit_line(rgui, TERM_START_X + 15, (TERM_HEIGHT * FONT_HEIGHT_STRIDE) + TERM_START_Y + 2, title, true); + unsigned x = TERM_START_X; unsigned y = TERM_START_Y; From 1af593f910b586b00b2cf21a69fa21107b9313fd Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sun, 12 Aug 2012 09:19:06 +0200 Subject: [PATCH 163/492] (RARCH_CONSOLE) Run set_nonblock_state if an emu runs at more than 60fps/60Hz - to forcibly set vsync off --- driver.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/driver.c b/driver.c index 973c08c0a9..03974700d6 100644 --- a/driver.c +++ b/driver.c @@ -208,6 +208,9 @@ static void adjust_system_rates(void) { g_settings.video.vsync = false; RARCH_LOG("Game FPS > Monitor FPS. Cannot rely on VSync.\n"); +#ifdef RARCH_CONSOLE + video_set_nonblock_state_func(false); +#endif } g_settings.video.refresh_rate = info->fps; From 1794aa6dff4903f3005ef1440c573340218fbb35 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 12 Aug 2012 09:36:15 +0200 Subject: [PATCH 164/492] Do not call set_nonblock_state for FF buttons if vsync isn't activated. --- gfx/gl.c | 10 ++++------ retroarch.c | 4 +++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gfx/gl.c b/gfx/gl.c index 249966e7a6..48b13c7fdd 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -983,12 +983,10 @@ static void gl_free(void *data) static void gl_set_nonblock_state(void *data, bool state) { - gl_t *gl = (gl_t*)data; - if (gl->vsync) - { - RARCH_LOG("GL VSync => %s\n", state ? "off" : "on"); - gfx_ctx_set_swap_interval(state ? 0 : 1, true); - } + (void)data; + + RARCH_LOG("GL VSync => %s\n", state ? "off" : "on"); + gfx_ctx_set_swap_interval(state ? 0 : 1, true); } static void *gl_init(const video_info_t *video, const input_driver_t **input, void **input_data) diff --git a/retroarch.c b/retroarch.c index 35703a2869..3db08f4da5 100644 --- a/retroarch.c +++ b/retroarch.c @@ -72,8 +72,10 @@ static void set_fast_forward_button(bool new_button_state, bool new_hold_button_ if (update_sync) { - if (g_extern.video_active) + // Only apply non-block-state for video if we're using vsync. + if (g_extern.video_active && g_settings.video.vsync) video_set_nonblock_state_func(syncing_state); + if (g_extern.audio_active) audio_set_nonblock_state_func(g_settings.audio.sync ? syncing_state : true); From 1b6b313787cd3c6e029472c09d77a5bbd4724a18 Mon Sep 17 00:00:00 2001 From: Toad King Date: Sun, 12 Aug 2012 03:38:23 -0400 Subject: [PATCH 165/492] (RGUI) add savestate support --- console/rgui/rgui.c | 32 +++++++++++++++++++++++++++++--- console/rgui/rgui.h | 3 +++ gx/gx_input.c | 6 +++--- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/console/rgui/rgui.c b/console/rgui/rgui.c index a7594b6484..315f4fe9b4 100644 --- a/console/rgui/rgui.c +++ b/console/rgui/rgui.c @@ -321,6 +321,9 @@ static void render_text(rgui_handle_t *rgui) snprintf(type_str, sizeof(type_str), "(DEV)"); w = 5; break; + case RGUI_SETTINGS_SAVESTATE_SLOT: + snprintf(type_str, sizeof(type_str), "%d", g_extern.state_slot); + break; case RGUI_SETTINGS_VIDEO_FILTER: snprintf(type_str, sizeof(type_str), g_settings.video.smooth ? "Bilinear filtering" : "Point filtering"); break; @@ -406,6 +409,25 @@ static void rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t switch (setting) { + case RGUI_SETTINGS_SAVESTATE_SLOT: + if (action == RGUI_ACTION_START) + rarch_settings_default(S_DEF_SAVE_STATE); + else if (action == RGUI_ACTION_LEFT) + rarch_settings_change(S_SAVESTATE_DECREMENT); + else if (action == RGUI_ACTION_RIGHT) + rarch_settings_change(S_SAVESTATE_INCREMENT); + break; + case RGUI_SETTINGS_SAVESTATE_SAVE: + case RGUI_SETTINGS_SAVESTATE_LOAD: + if (action == RGUI_ACTION_OK) + { + if (setting == RGUI_SETTINGS_SAVESTATE_SAVE) + rarch_save_state(); + else + rarch_load_state(); + rarch_settings_change(S_RETURN_TO_GAME); + } + break; case RGUI_SETTINGS_VIDEO_FILTER: if (action == RGUI_ACTION_START) rarch_settings_default(S_DEF_HW_TEXTURE_FILTER); @@ -490,9 +512,7 @@ static void rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t #ifdef GEKKO snprintf(g_console.launch_app_on_exit, sizeof(g_console.launch_app_on_exit), "boot.dol"); #endif - g_console.return_to_launcher = true; - g_console.mode_switch = MODE_EXIT; - g_console.menu_enable = false; + rarch_settings_change(S_RETURN_TO_LAUNCHER); } break; // controllers @@ -550,6 +570,12 @@ static void rgui_settings_populate_entries(rgui_handle_t *rgui) { rgui_list_clear(rgui->folder_buf); + if (g_console.ingame_menu_enable) + { + RGUI_MENU_ITEM("Savestate Slot", RGUI_SETTINGS_SAVESTATE_SLOT); + RGUI_MENU_ITEM("Save State", RGUI_SETTINGS_SAVESTATE_SAVE); + RGUI_MENU_ITEM("Load State", RGUI_SETTINGS_SAVESTATE_LOAD); + } RGUI_MENU_ITEM("Hardware filtering", RGUI_SETTINGS_VIDEO_FILTER); #ifdef HW_RVL RGUI_MENU_ITEM("VI Trap filtering", RGUI_SETTINGS_VIDEO_SOFT_FILTER); diff --git a/console/rgui/rgui.h b/console/rgui/rgui.h index b210cc6911..ddf97874a4 100644 --- a/console/rgui/rgui.h +++ b/console/rgui/rgui.h @@ -33,6 +33,9 @@ typedef enum RGUI_SETTINGS, // settings options are done here too + RGUI_SETTINGS_SAVESTATE_SLOT, + RGUI_SETTINGS_SAVESTATE_SAVE, + RGUI_SETTINGS_SAVESTATE_LOAD, RGUI_SETTINGS_VIDEO_FILTER, #ifdef HW_RVL RGUI_SETTINGS_VIDEO_SOFT_FILTER, diff --git a/gx/gx_input.c b/gx/gx_input.c index 889ff85a65..d4d8b20a10 100644 --- a/gx/gx_input.c +++ b/gx/gx_input.c @@ -464,14 +464,14 @@ static bool gx_key_pressed(void *data, int key) if(g_console.menu_enable) { g_console.mode_switch = MODE_MENU; - SET_TIMER_EXPIRATION(gx, 30); - retval = g_console.menu_enable; + g_console.ingame_menu_enable = true; + SET_TIMER_EXPIRATION(gx, 30); } if(quit_rarch) g_console.mode_switch = MODE_EXIT; - retval = g_console.menu_enable; + retval = g_console.menu_enable; return retval; } default: From 45579376f0c3f8915ce2daddf2726502ace92435 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 12 Aug 2012 10:01:35 +0200 Subject: [PATCH 166/492] Add exception for RETRO_DEVICE_KEYBOARD in input_state callback. --- libretro-test/libretro-test.c | 3 +++ retroarch.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libretro-test/libretro-test.c b/libretro-test/libretro-test.c index f2a9abc931..ff6eef5a54 100644 --- a/libretro-test/libretro-test.c +++ b/libretro-test/libretro-test.c @@ -119,6 +119,9 @@ static void update_input(void) if (input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_RETURN)) fprintf(stderr, "Return key is pressed!\n"); + if (input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_x)) + fprintf(stderr, "x key is pressed!\n"); + dir_x += input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X) / 2000; dir_y += input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y) / 2000; //dir_x += input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X) / 2000; diff --git a/retroarch.c b/retroarch.c index 3db08f4da5..78f67b615d 100644 --- a/retroarch.c +++ b/retroarch.c @@ -459,7 +459,7 @@ static int16_t input_state(unsigned port, unsigned device, unsigned index, unsig }; int16_t res = 0; - if (id < RARCH_FIRST_META_KEY) + if (id < RARCH_FIRST_META_KEY || device == RETRO_DEVICE_KEYBOARD) res = input_input_state_func(binds, port, device, index, id); #ifdef HAVE_BSV_MOVIE From 0e5528796d220c3e487176ed8b1a7d0241585d6b Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sun, 12 Aug 2012 11:55:12 +0200 Subject: [PATCH 167/492] Set nonblock_state_func argument for >60Hz emu ports/games to true --- driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver.c b/driver.c index 03974700d6..654b5c4541 100644 --- a/driver.c +++ b/driver.c @@ -209,7 +209,7 @@ static void adjust_system_rates(void) g_settings.video.vsync = false; RARCH_LOG("Game FPS > Monitor FPS. Cannot rely on VSync.\n"); #ifdef RARCH_CONSOLE - video_set_nonblock_state_func(false); + video_set_nonblock_state_func(true); #endif } From d0c4fdbc23bc641cd69bf8a53ccb54f91778b0a8 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 12 Aug 2012 20:25:57 +0200 Subject: [PATCH 168/492] Only build in libpng if it's 1.5+. libpng fails to build on 1.2 apparently. It might build on 1.3 or 1.4, but 1.5+ is known to work. --- qb/config.libs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qb/config.libs.sh b/qb/config.libs.sh index 2ef1bf1b45..d222f5eb48 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -100,7 +100,7 @@ fi check_pkgconf XML libxml-2.0 check_pkgconf SDL_IMAGE SDL_image -check_pkgconf LIBPNG libpng +check_pkgconf LIBPNG libpng 1.5 if [ "$HAVE_THREADS" != 'no' ]; then if [ "$HAVE_FFMPEG" != 'no' ]; then From 447412c6df586105e6714fbe5f63f1457d120e78 Mon Sep 17 00:00:00 2001 From: Themaister Date: Tue, 14 Aug 2012 23:32:55 +0200 Subject: [PATCH 169/492] Abstract all use of *Pointer() functions to one point. --- gfx/fonts/freetype.c | 20 +++++++++------ gfx/gl.c | 59 ++++++++++++++++++++++++++++++++------------ gfx/gl_common.h | 10 ++++++++ 3 files changed, 65 insertions(+), 24 deletions(-) diff --git a/gfx/fonts/freetype.c b/gfx/fonts/freetype.c index 546b5b9683..3ad538c239 100644 --- a/gfx/fonts/freetype.c +++ b/gfx/fonts/freetype.c @@ -241,7 +241,8 @@ void gl_render_msg(void *data, const char *msg) GLfloat font_tex_coords[8]; glBindTexture(GL_TEXTURE_2D, gl->font_tex); - glTexCoordPointer(2, GL_FLOAT, 0, font_tex_coords); + + gl->coords.tex_coord = font_tex_coords; struct font_output_list out; @@ -264,17 +265,20 @@ void gl_render_msg(void *data, const char *msg) } calculate_font_coords(gl, font_vertex, font_vertex_dark, font_tex_coords); - glVertexPointer(2, GL_FLOAT, 0, font_vertex_dark); - glColorPointer(4, GL_FLOAT, 0, gl->font_color_dark); + gl->coords.vertex = font_vertex_dark; + gl->coords.color = gl->font_color_dark; + gl_set_coords(&gl->coords, 0); glDrawArrays(GL_QUADS, 0, 4); - glVertexPointer(2, GL_FLOAT, 0, font_vertex); - glColorPointer(4, GL_FLOAT, 0, gl->font_color); + + gl->coords.vertex = font_vertex; + gl->coords.color = gl->font_color; + gl_set_coords(&gl->coords, 0); glDrawArrays(GL_QUADS, 0, 4); // Post - Go back to old rendering path. - glTexCoordPointer(2, GL_FLOAT, 0, gl->tex_coords); - glVertexPointer(2, GL_FLOAT, 0, vertexes_flipped); - glColorPointer(4, GL_FLOAT, 0, white_color); + gl->coords.vertex = vertexes_flipped; + gl->coords.tex_coord = gl->tex_coords; + gl->coords.color = white_color; glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); glDisable(GL_BLEND); diff --git a/gfx/gl.c b/gfx/gl.c index 48b13c7fdd..a85b9b6f01 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -480,6 +480,31 @@ void gl_init_fbo(gl_t *gl, unsigned width, unsigned height) //////////// +void gl_set_coords(const struct gl_coords *coords, unsigned unit) +{ + pglClientActiveTexture(GL_TEXTURE0 + unit); + + if (coords->vertex) + { + glVertexPointer(2, GL_FLOAT, 0, coords->vertex); + glEnableClientState(GL_VERTEX_ARRAY); + } + + if (coords->color) + { + glColorPointer(4, GL_FLOAT, 0, coords->color); + glEnableClientState(GL_COLOR_ARRAY); + } + + if (coords->tex_coord) + { + glTexCoordPointer(2, GL_FLOAT, 0, coords->tex_coord); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + + pglClientActiveTexture(GL_TEXTURE0); +} + void gl_set_projection(gl_t *gl, struct gl_ortho *ortho, bool allow_rotate) { #ifdef RARCH_CONSOLE @@ -567,10 +592,9 @@ static inline void set_lut_texture_coords(const GLfloat *coords) { #if defined(HAVE_XML) || defined(HAVE_CG) // For texture images. - pglClientActiveTexture(GL_TEXTURE1); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, coords); - pglClientActiveTexture(GL_TEXTURE0); + struct gl_coords co = {0}; + co.tex_coord = coords; + gl_set_coords(&co, 1); #else (void)coords; #endif @@ -597,7 +621,7 @@ static inline void gl_start_frame_fbo(gl_t *gl) // consistent texture coordinates. // We will "flip" it in place on last pass. if (gl->render_to_tex) - glVertexPointer(2, GL_FLOAT, 0, vertexes); + gl->coords.vertex = vertexes; } static void gl_check_fbo_dimensions(gl_t *gl) @@ -638,7 +662,7 @@ static void gl_frame_fbo(gl_t *gl, const struct gl_tex_info *tex_info) GLfloat fbo_tex_coords[8] = {0.0f}; // Render the rest of our passes. - glTexCoordPointer(2, GL_FLOAT, 0, fbo_tex_coords); + gl->coords.tex_coord = fbo_tex_coords; // It's kinda handy ... :) const struct gl_fbo_rect *prev_rect; @@ -680,6 +704,7 @@ static void gl_frame_fbo(gl_t *gl, const struct gl_tex_info *tex_info) gl->vp_width, gl->vp_height, gl->frame_count, tex_info, gl->prev_info, fbo_tex_info, fbo_tex_info_cnt); + gl_set_coords(&gl->coords, 0); glDrawArrays(GL_QUADS, 0, 4); fbo_tex_info_cnt++; @@ -706,10 +731,12 @@ static void gl_frame_fbo(gl_t *gl, const struct gl_tex_info *tex_info) gl->vp_width, gl->vp_height, gl->frame_count, tex_info, gl->prev_info, fbo_tex_info, fbo_tex_info_cnt); - glVertexPointer(2, GL_FLOAT, 0, vertex_ptr); + gl->coords.vertex = vertex_ptr; + + gl_set_coords(&gl->coords, 0); glDrawArrays(GL_QUADS, 0, 4); - glTexCoordPointer(2, GL_FLOAT, 0, gl->tex_coords); + gl->coords.tex_coord = gl->tex_coords; } #endif @@ -862,7 +889,9 @@ static void gl_render_menu(gl_t *gl) glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, gl->menu_texture_id); - glVertexPointer(2, GL_FLOAT, 0, default_vertex_ptr); + gl->coords.vertex = default_vertex_ptr; + + gl_set_coords(&gl->coords, 0); glDrawArrays(GL_QUADS, 0, 4); glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); } @@ -919,6 +948,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei gl->frame_count, &tex_info, gl->prev_info, NULL, 0); + gl_set_coords(&gl->coords, 0); glDrawArrays(GL_QUADS, 0, 4); #ifdef HAVE_FBO @@ -1102,14 +1132,11 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo glDisable(GL_DITHER); glClearColor(0, 0, 0, 1); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, vertex_ptr); - memcpy(gl->tex_coords, tex_coords, sizeof(tex_coords)); - glTexCoordPointer(2, GL_FLOAT, 0, gl->tex_coords); - glColorPointer(4, GL_FLOAT, 0, white_color); + gl->coords.vertex = vertex_ptr; + gl->coords.tex_coord = gl->tex_coords; + gl->coords.color = white_color; + gl_set_coords(&gl->coords, 0); set_lut_texture_coords(tex_coords); diff --git a/gfx/gl_common.h b/gfx/gl_common.h index 277ee37a4b..43f913186d 100644 --- a/gfx/gl_common.h +++ b/gfx/gl_common.h @@ -125,6 +125,13 @@ struct gl_tex_info GLfloat coord[8]; }; +struct gl_coords +{ + const GLfloat *vertex; + const GLfloat *color; + const GLfloat *tex_coord; +}; + #define MAX_SHADERS 16 #if defined(HAVE_XML) || defined(HAVE_CG) @@ -182,6 +189,8 @@ typedef struct gl GLfloat tex_coords[8]; math_matrix mvp; + struct gl_coords coords; + #ifdef __CELLOS_LV2__ GLuint pbo; #endif @@ -225,6 +234,7 @@ extern PFNGLACTIVETEXTUREPROC pglActiveTexture; void gl_shader_use(unsigned index); void gl_set_projection(gl_t *gl, struct gl_ortho *ortho, bool allow_rotate); void gl_set_viewport(gl_t *gl, unsigned width, unsigned height, bool force_full, bool allow_rotate); +void gl_set_coords(const struct gl_coords *coords, unsigned unit); void gl_init_fbo(gl_t *gl, unsigned width, unsigned height); void gl_deinit_fbo(gl_t *gl); From 211381bb89cebe20c3304fbe9df2e19006e6afc1 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 15 Aug 2012 09:44:17 +0200 Subject: [PATCH 170/492] (Libretro) Add nonblock_state --- driver.c | 6 +++++- libretro.h | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/driver.c b/driver.c index 654b5c4541..6e40f87e25 100644 --- a/driver.c +++ b/driver.c @@ -209,7 +209,11 @@ static void adjust_system_rates(void) g_settings.video.vsync = false; RARCH_LOG("Game FPS > Monitor FPS. Cannot rely on VSync.\n"); #ifdef RARCH_CONSOLE - video_set_nonblock_state_func(true); + struct retro_system_info info; + retro_get_system_info(&info); + + if(info.nonblock_state) + video_set_nonblock_state_func(true); #endif } diff --git a/libretro.h b/libretro.h index 301f78e9e0..00697f5bcc 100755 --- a/libretro.h +++ b/libretro.h @@ -383,6 +383,8 @@ struct retro_system_info // If false, ::data and ::size are guaranteed to be valid, but ::path might not be valid. // This is typically set to true for libretro implementations that must load from file. // Implementations should strive for setting this to false, as it allows the frontend to perform patching, etc. + bool nonblock_state; // If true, this indicates that the game's fps is above 60 and that vsync should + // be deactivated before startup bool block_extract; // If true, the frontend is not allowed to extract any archives before loading the real ROM. // Necessary for certain libretro implementations that load games from zipped archives. From 84de4f23e69c3cb6f73e4aca3a4e99229e82e9fe Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 15 Aug 2012 10:03:00 +0200 Subject: [PATCH 171/492] (Libretro) Correction to RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL description - level 0 and 1 were described incorrectly --- libretro.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libretro.h b/libretro.h index 00697f5bcc..9ca36ffc65 100755 --- a/libretro.h +++ b/libretro.h @@ -332,8 +332,9 @@ enum retro_key // about too demanding implementations. // // The levels are "floating", but roughly defined as: - // 1: Low-powered devices such as Raspberry Pi, smart phones, tablets, etc. - // 2: Medium-spec consoles, such as PS3/360, with sub-par CPUs. + // 0: Low-powered embedded devices such as Raspberry Pi + // 1: 6th generation consoles, such as Wii/Xbox 1, and phones, tablets, etc. + // 2: 7th generation consoles, such as PS3/360, with sub-par CPUs. // 3: Modern desktop/laptops with reasonably powerful CPUs. // 4: High-end desktops with very powerful CPUs. // From 44ff5ec1c3ab37d69e23edd1f962bdc3f7493a31 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 15 Aug 2012 10:49:39 +0200 Subject: [PATCH 172/492] (RGL) Clean up RGLTransferDataVidToVid --- console/rgl/ps3/readelf.h | 6 -- console/rgl/ps3/rgl.cpp | 142 +++++++++++++++++++++++++++----------- console/rgl/ps3/rgl.h | 41 ++++++++--- 3 files changed, 134 insertions(+), 55 deletions(-) diff --git a/console/rgl/ps3/readelf.h b/console/rgl/ps3/readelf.h index 21c65c72d8..2f4001087a 100644 --- a/console/rgl/ps3/readelf.h +++ b/console/rgl/ps3/readelf.h @@ -58,12 +58,6 @@ typedef struct ELF_section_t *findSection(const ELF_t *elf, const char *name); int lookupSymbol(const ELF_t *elf, const char *name); -const Elf32_Sym *getSymbolByIndex(const ELF_t *elf, int idx); - -const char *findSectionInPlace(const char* memory,unsigned int size,const char *name,size_t *sectionSize); -const char *findSymbolSectionInPlace(const char *memory, unsigned int size, size_t *symbolSize, size_t *symbolCount, const char **symbolstrtab); -int lookupSymbolValueInPlace(const char *symbolSection, size_t symbolSize, size_t symbolCount, const char *symbolstrtab, const char *name); -const char *getSymbolByIndexInPlace(const char *symbolSection, size_t symbolSize, size_t symbolCount, const char *symbolstrtab, int index); #ifdef __cplusplus } diff --git a/console/rgl/ps3/rgl.cpp b/console/rgl/ps3/rgl.cpp index 395fd398b1..5382b3d2bb 100644 --- a/console/rgl/ps3/rgl.cpp +++ b/console/rgl/ps3/rgl.cpp @@ -31,8 +31,6 @@ #define pad(x, pad) (((x) + (pad) - 1 ) / (pad) * (pad)) -#define gmmAddressToOffset(address, isMain) ((isMain) ? (address)-pGmmMainAllocator->memoryBase : (address)-pGmmLocalAllocator->memoryBase) - #define GL_UNSIGNED_SHORT_8_8 GL_UNSIGNED_SHORT_8_8_SCE #define GL_UNSIGNED_SHORT_8_8_REV GL_UNSIGNED_SHORT_8_8_REV_SCE #define GL_UNSIGNED_INT_16_16 GL_UNSIGNED_INT_16_16_SCE @@ -126,7 +124,7 @@ static inline float _RGLFloatFrom_GL_FLOAT(type_GL_FLOAT v) typedef GLhalfARB type_GL_HALF_FLOAT_ARB; -const char *findSectionInPlace(const char* memory,unsigned int /*size*/,const char *name, size_t *sectionSize) +static const char *findSectionInPlace(const char* memory,unsigned int /*size*/,const char *name, size_t *sectionSize) { const Elf32_Ehdr *ehdr = (const Elf32_Ehdr*)memory; @@ -149,7 +147,7 @@ const char *findSectionInPlace(const char* memory,unsigned int /*size*/,const ch return NULL; } -const char *findSymbolSectionInPlace(const char *memory, unsigned int /*size*/, size_t *symbolSize, size_t *symbolCount, const char **symbolstrtab) +static const char *findSymbolSectionInPlace(const char *memory, unsigned int /*size*/, size_t *symbolSize, size_t *symbolCount, const char **symbolstrtab) { const Elf32_Ehdr *ehdr = (const Elf32_Ehdr*)memory; @@ -172,7 +170,7 @@ const char *findSymbolSectionInPlace(const char *memory, unsigned int /*size*/, return NULL; } -int lookupSymbolValueInPlace(const char* symbolSection, size_t symbolSize, size_t symbolCount, const char *symbolstrtab, const char *name) +static int lookupSymbolValueInPlace(const char* symbolSection, size_t symbolSize, size_t symbolCount, const char *symbolstrtab, const char *name) { for (size_t i = 0; i < symbolCount; i++) { @@ -186,7 +184,7 @@ int lookupSymbolValueInPlace(const char* symbolSection, size_t symbolSize, size_ return -1; } -const char *getSymbolByIndexInPlace(const char* symbolSection, size_t symbolSize, size_t symbolCount, const char *symbolstrtab, int index) +static const char *getSymbolByIndexInPlace(const char* symbolSection, size_t symbolSize, size_t symbolCount, const char *symbolstrtab, int index) { Elf32_Sym* elf_sym = (Elf32_Sym*)symbolSection + index; return symbolstrtab + elf_sym->st_name; @@ -562,17 +560,25 @@ static void _RGLMemcpy( const GLuint dstId, unsigned dstOffset, unsigned int pit { const GLuint firstBytes = MIN( pitch - dstOffsetAlign, size ); - _RGLTransferDataVidToVid( - dstId, - 0, - pitch, - dstOffsetAlign / 2, dstOffset / pitch, - srcId, - srcOffset, - pitch, - 0, 0, - firstBytes / 2, 1, - 2 ); + transfer_params_t transfer_params; + + transfer_params.dst_id = dstId; + transfer_params.dst_id_offset = 0; + transfer_params.dst_pitch = pitch; + transfer_params.dst_x = dstOffsetAlign / 2; + transfer_params.dst_y = dstOffset / pitch; + transfer_params.src_id = srcId; + transfer_params.src_id_offset = srcOffset; + transfer_params.src_pitch = pitch; + transfer_params.src_x = 0; + transfer_params.src_y = 0; + transfer_params.width = firstBytes / 2; + transfer_params.height = 1; + transfer_params.bpp = 2; + transfer_params.fifo_ptr = &_RGLState.fifo; + + TransferDataVidToVid(&transfer_params); + dstOffset += firstBytes; srcOffset += firstBytes; size -= firstBytes; @@ -580,30 +586,50 @@ static void _RGLMemcpy( const GLuint dstId, unsigned dstOffset, unsigned int pit const GLuint fullLines = size / pitch; const GLuint extraBytes = size % pitch; + if ( fullLines ) - _RGLTransferDataVidToVid( - dstId, - 0, - pitch, - 0, dstOffset / pitch, - srcId, - srcOffset, - pitch, - 0, 0, - pitch / 2, fullLines, - 2 ); + { + transfer_params_t transfer_params; + + transfer_params.dst_id = dstId; + transfer_params.dst_id_offset = 0; + transfer_params.dst_pitch = pitch; + transfer_params.dst_x = 0; + transfer_params.dst_y = dstOffset / pitch; + transfer_params.src_id = srcId; + transfer_params.src_id_offset = srcOffset; + transfer_params.src_pitch = pitch; + transfer_params.src_x = 0; + transfer_params.src_y = 0; + transfer_params.width = pitch / 2; + transfer_params.height = fullLines; + transfer_params.bpp = 2; + transfer_params.fifo_ptr = &_RGLState.fifo; + + TransferDataVidToVid(&transfer_params); + } + if ( extraBytes ) - _RGLTransferDataVidToVid( - dstId, - 0, - pitch, - 0, fullLines + dstOffset / pitch, - srcId, - srcOffset, - pitch, - 0, fullLines, - extraBytes / 2, 1, - 2 ); + { + transfer_params_t transfer_params; + + transfer_params.dst_id = dstId; + transfer_params.dst_id_offset = 0; + transfer_params.dst_pitch = pitch; + transfer_params.dst_x = 0; + transfer_params.dst_y = fullLines + dstOffset / pitch; + transfer_params.src_id = srcId; + transfer_params.src_id_offset = srcOffset; + transfer_params.src_pitch = pitch; + transfer_params.src_x = 0; + transfer_params.src_y = fullLines; + transfer_params.width = extraBytes / 2; + transfer_params.height = 1; + transfer_params.bpp = 2; + transfer_params.fifo_ptr = &_RGLState.fifo; + + TransferDataVidToVid(&transfer_params); + } } static void _RGLPlatformBufferObjectSetData( jsBufferObject* bufferObject, GLintptr offset, GLsizeiptr size, const GLvoid *data, GLboolean tryImmediateCopy ) @@ -1491,7 +1517,24 @@ static void _RGLPlatformValidateTextureResources( jsTexture *texture ) dst.dataId = gcmTexture->gpuAddressId; dst.dataIdOffset = gcmTexture->gpuAddressIdOffset; - _RGLTransferDataVidToVid( dst.dataId, dst.dataIdOffset, dst.pitch ? dst.pitch : (dst.bpp * dst.width), 0, 0, src.dataId, src.dataIdOffset, src.pitch ? src.pitch : (src.bpp * src.width), 0, 0, src.width, src.height, src.bpp ); + transfer_params_t transfer_params; + + transfer_params.dst_id = dst.dataId; + transfer_params.dst_id_offset = dst.dataIdOffset; + transfer_params.dst_pitch = dst.pitch ? dst.pitch : (dst.bpp * dst.width); + transfer_params.dst_x = 0; + transfer_params.dst_y = 0; + transfer_params.src_id = src.dataId; + transfer_params.src_id_offset = src.dataIdOffset; + transfer_params.src_pitch = src.pitch ? src.pitch : (src.bpp * src.width); + transfer_params.src_x = 0; + transfer_params.src_y = 0; + transfer_params.width = src.width; + transfer_params.height = src.height; + transfer_params.bpp = src.bpp; + transfer_params.fifo_ptr = &_RGLState.fifo; + + TransferDataVidToVid(&transfer_params); _RGLImageFreeCPUStorage( image ); image->dataState |= IMAGE_DATASTATE_GPU; @@ -4691,7 +4734,24 @@ static GLboolean _RGLPlatformTexturePBOImage( dataIdOffset: gcmTexture->gpuAddressIdOffset, }; - _RGLTransferDataVidToVid( dst.dataId, dst.dataIdOffset, dst.pitch ? dst.pitch : (dst.bpp * dst.width), 0, 0, src.dataId, src.dataIdOffset, src.pitch ? src.pitch : (src.bpp * src.width), 0, 0, width, height, src.bpp ); + transfer_params_t transfer_params; + + transfer_params.dst_id = dst.dataId; + transfer_params.dst_id_offset = dst.dataIdOffset; + transfer_params.dst_pitch = dst.pitch ? dst.pitch : (dst.bpp * dst.width); + transfer_params.dst_x = 0; + transfer_params.dst_y = 0; + transfer_params.src_id = src.dataId; + transfer_params.src_id_offset = src.dataIdOffset; + transfer_params.src_pitch = src.pitch ? src.pitch : (src.bpp * src.width); + transfer_params.src_x = 0; + transfer_params.src_y = 0; + transfer_params.width = width; + transfer_params.height = height; + transfer_params.bpp = src.bpp; + transfer_params.fifo_ptr = &_RGLState.fifo; + + TransferDataVidToVid(&transfer_params); } _RGLImageFreeCPUStorage( image ); diff --git a/console/rgl/ps3/rgl.h b/console/rgl/ps3/rgl.h index f9a63b0729..785ba283aa 100644 --- a/console/rgl/ps3/rgl.h +++ b/console/rgl/ps3/rgl.h @@ -22,6 +22,8 @@ typedef struct _CGcontext *CGcontext; #define SUBPIXEL_ADJUST (0.5/(1<<12)) #define gmmIdIsMain(id) (((GmmBaseBlock *)id)->isMain) +#define gmmAddressToOffset(address, isMain) ((isMain) ? (address)-pGmmMainAllocator->memoryBase : (address)-pGmmLocalAllocator->memoryBase) + #ifdef __cplusplus extern "C" @@ -678,6 +680,9 @@ typedef struct GmmAllocator uint32_t totalSize; } GmmAllocator; +extern GmmAllocator *pGmmLocalAllocator; +extern GmmAllocator *pGmmMainAllocator; + uint32_t gmmInit( const void *localMemoryBase, const void *localStartAddress, @@ -711,14 +716,23 @@ void gmmSetTileAttrib(const uint32_t id, const uint32_t tag, void *pData); COMMAND_BUFFER = (typeof(COMMAND_BUFFER))gcmContext.current; \ } -#define _RGLTransferDataVidToVid(dstId, dstIdOffset, dstPitch, dstX, dstY, srcId, srcIdOffset, srcPitch, srcX, srcY, width, height, bytesPerPixel) \ -{ \ - GmmBaseBlock *pBaseBlock_dst = (GmmBaseBlock *)dstId; \ - GmmBaseBlock *pBaseBlock_src = (GmmBaseBlock *)srcId; \ - GLuint dstOffset_tmp = gmmAddressToOffset(pBaseBlock_dst->address, pBaseBlock_dst->isMain) + dstIdOffset; \ - GLuint srcOffset_tmp = gmmAddressToOffset(pBaseBlock_src->address, pBaseBlock_src->isMain) + srcIdOffset; \ - cellGcmSetTransferImageInline( &_RGLState.fifo, CELL_GCM_TRANSFER_LOCAL_TO_LOCAL, dstOffset_tmp, (dstPitch), (dstX), (dstY), (srcOffset_tmp), (srcPitch), (srcX), (srcY), (width), (height), (bytesPerPixel) ); \ -} +typedef struct +{ + unsigned dst_id; + unsigned dst_id_offset; + unsigned dst_pitch; + unsigned dst_x; + unsigned dst_y; + unsigned src_id; + unsigned src_id_offset; + unsigned src_pitch; + unsigned src_x; + unsigned src_y; + unsigned width; + unsigned height; + unsigned bpp; + void *fifo_ptr; +} transfer_params_t; #define HOST_BUFFER_ALIGNMENT 128 @@ -801,6 +815,17 @@ struct RGLFifo: public CellGcmContextData int spuid; }; +static inline void TransferDataVidToVid(transfer_params_t *params) +{ + GmmBaseBlock *pBaseBlock_dst = (GmmBaseBlock *)params->dst_id; + GmmBaseBlock *pBaseBlock_src = (GmmBaseBlock *)params->src_id; + + GLuint dstOffset_tmp = gmmAddressToOffset(pBaseBlock_dst->address, pBaseBlock_dst->isMain) + params->dst_id_offset; + GLuint srcOffset_tmp = gmmAddressToOffset(pBaseBlock_src->address, pBaseBlock_src->isMain) + params->src_id_offset; + + cellGcmSetTransferImageInline( (RGLFifo*)params->fifo_ptr, CELL_GCM_TRANSFER_LOCAL_TO_LOCAL, dstOffset_tmp, params->dst_pitch, params->dst_x, params->dst_y, srcOffset_tmp, params->src_pitch, params->src_x, params->src_y, params->width, params->height, params->bpp); +} + typedef struct RGLRenderTarget RGLRenderTarget; typedef struct RGLCachedState RGLCachedState; typedef struct RGLBlendState RGLBlendState; From 83a361cd826137bc34dc7b8557bb266196ee19c3 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 15 Aug 2012 11:01:09 +0200 Subject: [PATCH 173/492] (RGL) Replace messy initializers --- console/rgl/ps3/rgl.cpp | 97 ++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 50 deletions(-) diff --git a/console/rgl/ps3/rgl.cpp b/console/rgl/ps3/rgl.cpp index 5382b3d2bb..dbc32234c5 100644 --- a/console/rgl/ps3/rgl.cpp +++ b/console/rgl/ps3/rgl.cpp @@ -1464,34 +1464,34 @@ static void _RGLPlatformValidateTextureResources( jsTexture *texture ) const GLuint pixelBytes = layout->pixelBits / 8; - RGLSurface src = { - source: SURFACE_SOURCE_TEMPORARY, - width: 0, - height: 0, - bpp: pixelBytes, - pitch: 0, - format: layout->internalFormat, - pool: SURFACE_POOL_LINEAR, - ppuData: NULL, - dataId: GMM_ERROR, - dataIdOffset:0, - }; + RGLSurface src; + src.source = SURFACE_SOURCE_TEMPORARY; + src.width = 0; + src.height = 0; + src.bpp = pixelBytes; + src.pitch = 0; + src.format = layout->internalFormat; + src.pool = SURFACE_POOL_LINEAR; + src.ppuData = NULL; + src.dataId = GMM_ERROR; + src.dataIdOffset = 0; - RGLSurface dst = { - source: SURFACE_SOURCE_TEXTURE, - width: 0, - height: 0, - bpp: pixelBytes, - pitch: layout->pitch, - format: layout->internalFormat, - pool: SURFACE_POOL_SYSTEM, - ppuData: NULL, - dataId: GMM_ERROR, - dataIdOffset:0, - }; + RGLSurface dst; + dst.source = SURFACE_SOURCE_TEXTURE; + dst.width = 0; + dst.height = 0; + dst.bpp = pixelBytes; + dst.pitch = layout->pitch; + dst.format = layout->internalFormat; + dst.pool = SURFACE_POOL_SYSTEM; + dst.ppuData = NULL; + dst.dataId = GMM_ERROR; + dst.dataIdOffset = 0; GLuint bounceBufferId = GMM_ERROR; + jsImage *image = texture->image; + if(image->dataState == IMAGE_DATASTATE_HOST) { src.ppuData = image->data; @@ -4703,36 +4703,33 @@ static GLboolean _RGLPlatformTexturePBOImage( else { const GLuint bytesPerPixel = newLayout.pixelBits / 8; - RGLSurface src = - { - source: SURFACE_SOURCE_PBO, - width: image->width, - height: image->height, - bpp: bytesPerPixel, - pitch: pboPitch, - format: newLayout.internalFormat, - pool: SURFACE_POOL_LINEAR, - ppuData: NULL, - dataId: gpuId, - dataIdOffset: gpuIdOffset, - }; + + RGLSurface src; + src.source = SURFACE_SOURCE_PBO; + src.width = image->width; + src.height = image->height; + src.bpp = bytesPerPixel; + src.pitch = pboPitch; + src.format = newLayout.internalFormat; + src.pool = SURFACE_POOL_LINEAR; + src.ppuData = NULL; + src.dataId = gpuId; + src.dataIdOffset = gpuIdOffset; texture->revalidate |= TEXTURE_REVALIDATE_LAYOUT; _RGLPlatformValidateTextureResources( texture ); - RGLSurface dst = - { - source: SURFACE_SOURCE_TEXTURE, - width: image->width, - height: image->height, - bpp: bytesPerPixel, - pitch: gcmTexture->gpuLayout.pitch, - format: gcmTexture->gpuLayout.internalFormat, - pool: gcmTexture->pool, - ppuData: NULL, - dataId: gcmTexture->gpuAddressId, - dataIdOffset: gcmTexture->gpuAddressIdOffset, - }; + RGLSurface dst; + dst.source = SURFACE_SOURCE_TEXTURE; + dst.width = image->width; + dst.height = image->height; + dst.bpp = bytesPerPixel; + dst.pitch = gcmTexture->gpuLayout.pitch; + dst.format = gcmTexture->gpuLayout.internalFormat; + dst.pool = gcmTexture->pool; + dst.ppuData = NULL; + dst.dataId = gcmTexture->gpuAddressId; + dst.dataIdOffset = gcmTexture->gpuAddressIdOffset; transfer_params_t transfer_params; From 408a0c34bcbdca9ca014b4a0b81b1260d19408a2 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 15 Aug 2012 11:41:04 +0200 Subject: [PATCH 174/492] (RGL) Remove rglFifoGlVertexAttribPointer --- console/rgl/ps3/rgl.cpp | 106 +++++++++++++++------------------------- 1 file changed, 40 insertions(+), 66 deletions(-) diff --git a/console/rgl/ps3/rgl.cpp b/console/rgl/ps3/rgl.cpp index dbc32234c5..7ea367b336 100644 --- a/console/rgl/ps3/rgl.cpp +++ b/console/rgl/ps3/rgl.cpp @@ -243,64 +243,6 @@ DECLARE_PACKED_TYPE(GL_##REALTYPE,PACKED_TYPE(REALTYPE,N,S1,S2,S3,S4,REV),N,S1,S #define GET_BITS(to,from,first,count) if ((count)>0) to=((GLfloat)(((from)>>(first))&((1<<(count))-1)))/(GLfloat)((1<<((count==0)?1:count))-1) #define PUT_BITS(from,to,first,count) if ((count)>0) to|=((unsigned int)((from)*((GLfloat)((1<<((count==0)?1:count))-1))))<<(first); -static inline void _RGLFifoGlVertexAttribPointer -( - GLuint index, - GLint size, - RGLEnum type, - GLboolean normalized, - GLsizei stride, - GLushort frequency, - GLuint offset -) -{ - - switch(size) - { - case 0: - stride = 0; - normalized = 0; - type = RGL_FLOAT; - offset = 0; - break; - case 1: - case 2: - case 3: - case 4: - break; - default: - break; - } - - uint8_t gcmType = 0; - switch ( type ) - { - case RGL_UNSIGNED_BYTE: - if (normalized) - gcmType = CELL_GCM_VERTEX_UB; - else - gcmType = CELL_GCM_VERTEX_UB256; - break; - case RGL_SHORT: - gcmType = normalized ? CELL_GCM_VERTEX_S1 : CELL_GCM_VERTEX_S32K; - break; - case RGL_FLOAT: - gcmType = CELL_GCM_VERTEX_F; - break; - case RGL_HALF_FLOAT: - gcmType = CELL_GCM_VERTEX_SF; - break; - case RGL_CMP: - size = 1; - gcmType = CELL_GCM_VERTEX_CMP; - break; - default: - break; - } - - cellGcmSetVertexDataArrayInline( &_RGLState.fifo, index, frequency, stride, size, gcmType, CELL_GCM_LOCATION_LOCAL, offset ); -} - static void _RGLResetAttributeState( jsAttributeState* as ) { for(int i = 0; i < MAX_VERTEX_ATTRIBS; ++i) @@ -1742,12 +1684,14 @@ GLAPI void APIENTRY glClear( GLbitfield mask ) GLuint bufferId = gmmAlloc(0, sizeof(_RGLClearVertexBuffer)); memcpy( gmmIdToAddress(bufferId), _RGLClearVertexBuffer, sizeof( _RGLClearVertexBuffer ) ); GmmBaseBlock *pBaseBlock = (GmmBaseBlock *)bufferId; - _RGLFifoGlVertexAttribPointer( 0, 3, RGL_FLOAT, CELL_GCM_FALSE, 3*sizeof( GLfloat ), 1, gmmAddressToOffset(pBaseBlock->address, pBaseBlock->isMain)); + + cellGcmSetVertexDataArrayInline( &_RGLState.fifo, 0 /* index */, 1/* frequency */, 3 * sizeof(GLfloat)/*stride */, 3 /* size */, CELL_GCM_VERTEX_F /* gcmType */, CELL_GCM_LOCATION_LOCAL, gmmAddressToOffset(pBaseBlock->address, pBaseBlock->isMain)/* offset */); + RGLBIT_TRUE( LContext->attribs->DirtyMask, 0 ); for(int i = 1; i < MAX_VERTEX_ATTRIBS; ++i) { - _RGLFifoGlVertexAttribPointer( i, 0, RGL_FLOAT, 0, 0, 0, 0 ); + cellGcmSetVertexDataArrayInline( &_RGLState.fifo, i/* index */, 0/* frequency */, 0/*stride */, 0/* size */, CELL_GCM_VERTEX_F /*gcmType */, CELL_GCM_LOCATION_LOCAL, 0/* offset */ ); RGLBIT_TRUE( LContext->attribs->DirtyMask, i ); } cellGcmSetVertexData4fInline( &_RGLState.fifo, _RGL_ATTRIB_PRIMARY_COLOR_INDEX, (GLfloat*)&LContext->ClearColor); @@ -5891,9 +5835,10 @@ static GLuint _RGLValidateAttributesSlow( jsDrawParams *dparams) continue; jsAttribute* attrib = as->attrib + i; + if ( RGLBIT_GET( as->EnabledMask, i ) ) { - const GLsizei stride = attrib->clientStride; + GLsizei stride = attrib->clientStride; const GLuint freq = attrib->frequency; if ( RGL_UNLIKELY( dparams->attribXferSize[i] ) ) @@ -5921,12 +5866,43 @@ static GLuint _RGLValidateAttributesSlow( jsDrawParams *dparams) gpuOffset = gmmAddressToOffset(pBaseBlock->address, pBaseBlock->isMain) + (( const GLubyte* )attrib->clientData - ( const GLubyte* )NULL ); } - _RGLFifoGlVertexAttribPointer( i, attrib->clientSize, - ( RGLEnum )attrib->clientType, attrib->normalized, stride, freq, gpuOffset ); + if(attrib->clientSize == 0) + { + stride = 0; + attrib->normalized = 0; + attrib->clientType = RGL_FLOAT; + gpuOffset = 0; + } + + uint8_t gcmType = 0; + + switch ( (RGLEnum)attrib->clientType ) + { + case RGL_UNSIGNED_BYTE: + gcmType = attrib->normalized ? CELL_GCM_VERTEX_UB : CELL_GCM_VERTEX_UB256; + break; + case RGL_SHORT: + gcmType = attrib->normalized ? CELL_GCM_VERTEX_S1 : CELL_GCM_VERTEX_S32K; + break; + case RGL_FLOAT: + gcmType = CELL_GCM_VERTEX_F; + break; + case RGL_HALF_FLOAT: + gcmType = CELL_GCM_VERTEX_SF; + break; + case RGL_CMP: + attrib->clientSize = 1; + gcmType = CELL_GCM_VERTEX_CMP; + break; + default: + break; + } + + cellGcmSetVertexDataArrayInline( &_RGLState.fifo, i, freq, stride, attrib->clientSize, gcmType, CELL_GCM_LOCATION_LOCAL, gpuOffset ); } else { - _RGLFifoGlVertexAttribPointer( i, 0, RGL_FLOAT, 0, 0, 0, 0 ); + cellGcmSetVertexDataArrayInline( &_RGLState.fifo, i, 0, 0, 0, CELL_GCM_VERTEX_F, CELL_GCM_LOCATION_LOCAL, 0); cellGcmSetVertexData4fInline( &_RGLState.fifo, i,attrib->value); } } @@ -7520,9 +7496,7 @@ static _CGparameter *_cgGetNamedParameter( _CGprogram* progPtr, const char* name break; case CGP_STRUCTURE: if ( done ) - { itemIndex = ( int )( currentEntry - program->parametersEntries ); - } else { const CgParameterStructure *parameterStructure = _RGLGetParameterStructure( program, currentEntry ); From 82fed93971ed87d393dd7fe8fd159a1a34d07cac Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 15 Aug 2012 12:06:04 +0200 Subject: [PATCH 175/492] (PSL1GHT RGL) Add some GCM macro definitions for PSL1GHT --- console/rgl/ps3/rgl.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/console/rgl/ps3/rgl.cpp b/console/rgl/ps3/rgl.cpp index 7ea367b336..31b29b13a4 100644 --- a/console/rgl/ps3/rgl.cpp +++ b/console/rgl/ps3/rgl.cpp @@ -4329,7 +4329,13 @@ static void _RGLPlatformDestroyTexture( jsTexture* texture ) _RGLTextureTouchFBOs( texture ); } +#ifdef __PSL1GHT__ +#define CELL_GCM_METHOD_HEADER_TEXTURE_OFFSET(unit, val) (((val) << (18)) | ((0x00001a00) + (unit) * 0x20)) +#define CELL_GCM_METHOD_DATA_TEXTURE_OFFSET(val) (val) +#define CELL_GCM_METHOD_DATA_TEXTURE_CONTROL3(pitch, depth) ((pitch) | ((depth) << 20)) +#else #include +#endif static void _RGLPlatformValidateTextureStage( int unit, jsTexture* texture ) { @@ -4379,7 +4385,7 @@ static void _RGLPlatformValidateTextureStage( int unit, jsTexture* texture ) current[7] = CELL_GCM_METHOD_DATA_TEXTURE_IMAGE_RECT( platformTexture->gcmTexture.height, platformTexture->gcmTexture.width); - current[8] = CELL_GCM_METHOD_DATA_TEXTURE_BORDER_COLOR(0); + current[8] = 0; current[9] = CELL_GCM_METHOD_HEADER_TEXTURE_CONTROL3(unit,1); current[10] = CELL_GCM_METHOD_DATA_TEXTURE_CONTROL3( platformTexture->gcmTexture.pitch, From a48376efd96a01ae51cb93e6ff01cf923219dbf5 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 15 Aug 2012 12:30:08 +0200 Subject: [PATCH 176/492] (PSL1GHT) Move GCM macro method defines to sdk_defines.h --- console/rgl/ps3/rgl.cpp | 6 +----- ps3/sdk_defines.h | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/console/rgl/ps3/rgl.cpp b/console/rgl/ps3/rgl.cpp index 31b29b13a4..e4f786f1a7 100644 --- a/console/rgl/ps3/rgl.cpp +++ b/console/rgl/ps3/rgl.cpp @@ -4329,11 +4329,7 @@ static void _RGLPlatformDestroyTexture( jsTexture* texture ) _RGLTextureTouchFBOs( texture ); } -#ifdef __PSL1GHT__ -#define CELL_GCM_METHOD_HEADER_TEXTURE_OFFSET(unit, val) (((val) << (18)) | ((0x00001a00) + (unit) * 0x20)) -#define CELL_GCM_METHOD_DATA_TEXTURE_OFFSET(val) (val) -#define CELL_GCM_METHOD_DATA_TEXTURE_CONTROL3(pitch, depth) ((pitch) | ((depth) << 20)) -#else +#ifndef __PSL1GHT__ #include #endif diff --git a/ps3/sdk_defines.h b/ps3/sdk_defines.h index 0b6d455519..5ef54d72e1 100644 --- a/ps3/sdk_defines.h +++ b/ps3/sdk_defines.h @@ -484,4 +484,18 @@ #define cellGcmSetShadeModeInline rxSetShadeModel #endif +/*============================================================ + GCM PROTOTYPES +============================================================ */ + +#ifdef __PSL1GHT__ +#define CELL_GCM_METHOD_HEADER_TEXTURE_OFFSET(unit, val) (((val) << (18)) | ((0x00001a00) + (unit) * 0x20)) +#define CELL_GCM_METHOD_DATA_TEXTURE_OFFSET(val) (val) +#define CELL_GCM_METHOD_DATA_TEXTURE_CONTROL3(pitch, depth) ((pitch) | ((depth) << 20)) +#define CELL_GCM_METHOD_DATA_TEXTURE_IMAGE_RECT(height, width) ((height) | ((width) << 16)) +#define CELL_GCM_METHOD_DATA_TEXTURE_FILTER(bias, min, mag, filter) (((bias)) | ((filter) << 13) | ((min) << 16) | ((mag) << 24)) +#define CELL_GCM_METHOD_DATA_TEXTURE_CONTROL0(val0, minlod, maxlod, filter) (((minlod << 2) | (filter) << 4) | (maxlod << 7) | (minlod << 19) | (val0 << 31)) +#define CELL_GCM_METHOD_DATA_TEXTURE_ADDRESS(wraps, wrapt, wrapr, unsignedremap, zfunc, gamma) ((wraps) | ((0) << 4) | ((wrapt) << 8) | (unsignedremap << 12) | ((wrapr) << 16) | (gamma << 20) | (zfunc << 28)) +#endif + #endif From 8c7e235e327ad41cdfc88fc25da61a05fc4d8b6b Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 15 Aug 2012 13:15:12 +0200 Subject: [PATCH 177/492] (PSL1GHT/Rgl) Compatibility changes --- console/rgl/ps3/device_ctx.cpp | 38 +++++++++++++++----------------- console/rgl/ps3/rgl.cpp | 20 ++++++++--------- console/rgl/ps3/rgl.h | 2 +- ps3/sdk_defines.h | 40 +++++++++++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 32 deletions(-) diff --git a/console/rgl/ps3/device_ctx.cpp b/console/rgl/ps3/device_ctx.cpp index 06a7f24924..b00d38f315 100644 --- a/console/rgl/ps3/device_ctx.cpp +++ b/console/rgl/ps3/device_ctx.cpp @@ -248,26 +248,24 @@ static GLboolean _RGLInitFromRM( RGLResource *rmResource ) ref = RGL_CLAMPF_01(ref); - cellGcmSetAlphaFuncInline( &_RGLState.fifo, CELL_GCM_ALWAYS, RGL_QUICK_FLOAT2UINT( ref * 255.0f )); + cellGcmSetBlendColor( &_RGLState.fifo, hwColor, hwColor); + cellGcmSetBlendEquation( &_RGLState.fifo, CELL_GCM_FUNC_ADD, CELL_GCM_FUNC_ADD ); + cellGcmSetBlendFunc( &_RGLState.fifo, CELL_GCM_ONE, CELL_GCM_ZERO, CELL_GCM_ONE, CELL_GCM_ZERO ); + cellGcmSetClearColor( &_RGLState.fifo, hwColor); + cellGcmSetScissor( &_RGLState.fifo, 0, 0, 4095, 4095); + cellGcmSetVertexAttribOutputMask( &_RGLState.fifo, s->vertexProgramAttribMask & s->fragmentProgramAttribMask); - cellGcmSetBlendColorInline( &_RGLState.fifo, hwColor, hwColor); - cellGcmSetBlendEquationInline( &_RGLState.fifo, CELL_GCM_FUNC_ADD, CELL_GCM_FUNC_ADD ); - cellGcmSetBlendFuncInline( &_RGLState.fifo, CELL_GCM_ONE, CELL_GCM_ZERO, CELL_GCM_ONE, CELL_GCM_ZERO ); - cellGcmSetClearColorInline( &_RGLState.fifo, hwColor); - cellGcmSetScissorInline( &_RGLState.fifo, 0, 0, 4095, 4095); - cellGcmSetVertexAttribOutputMaskInline( &_RGLState.fifo, s->vertexProgramAttribMask & s->fragmentProgramAttribMask); + cellGcmSetPointSpriteControl( &_RGLState.fifo, CELL_GCM_FALSE, 1, 0); + cellGcmSetFrequencyDividerOperation( &_RGLState.fifo, 0); - cellGcmSetPointSpriteControlInline( &_RGLState.fifo, CELL_GCM_FALSE, 1, 0); - cellGcmSetFrequencyDividerOperationInline( &_RGLState.fifo, 0); - - cellGcmSetRestartIndexInline( &_RGLState.fifo, 0); - cellGcmSetShadeModeInline( &_RGLState.fifo, CELL_GCM_SMOOTH); + cellGcmSetRestartIndex( &_RGLState.fifo, 0); + cellGcmSetShadeMode( &_RGLState.fifo, CELL_GCM_SMOOTH); for (i = 0; i < CELL_GCM_MAX_TEXIMAGE_COUNT; i++) { - cellGcmSetTextureAddressInline( &_RGLState.fifo, i, CELL_GCM_TEXTURE_WRAP, CELL_GCM_TEXTURE_WRAP, CELL_GCM_TEXTURE_CLAMP_TO_EDGE, CELL_GCM_TEXTURE_UNSIGNED_REMAP_NORMAL, CELL_GCM_TEXTURE_ZFUNC_NEVER, 0 ); - cellGcmSetTextureFilterInline( &_RGLState.fifo, i, 0, CELL_GCM_TEXTURE_NEAREST_LINEAR, CELL_GCM_TEXTURE_LINEAR, CELL_GCM_TEXTURE_CONVOLUTION_QUINCUNX ); - cellGcmSetTextureControlInline( &_RGLState.fifo, i, CELL_GCM_TRUE, 0, 12 << 8, CELL_GCM_TEXTURE_MAX_ANISO_1 ); + cellGcmSetTextureAddress( &_RGLState.fifo, i, CELL_GCM_TEXTURE_WRAP, CELL_GCM_TEXTURE_WRAP, CELL_GCM_TEXTURE_CLAMP_TO_EDGE, CELL_GCM_TEXTURE_UNSIGNED_REMAP_NORMAL, CELL_GCM_TEXTURE_ZFUNC_NEVER, 0 ); + cellGcmSetTextureFilter( &_RGLState.fifo, i, 0, CELL_GCM_TEXTURE_NEAREST_LINEAR, CELL_GCM_TEXTURE_LINEAR, CELL_GCM_TEXTURE_CONVOLUTION_QUINCUNX ); + cellGcmSetTextureControl( &_RGLState.fifo, i, CELL_GCM_TRUE, 0, 12 << 8, CELL_GCM_TEXTURE_MAX_ANISO_1 ); } _RGLFifoGlViewport( 0, 0, CELL_GCM_MAX_RT_DIMENSION, CELL_GCM_MAX_RT_DIMENSION, 0.0f, 1.0f ); @@ -948,7 +946,7 @@ static int _RGLPlatformCreateDevice( PSGLdevice* device ) _RGLSetDisplayMode(vm, gcmDevice->color[0].bpp*8, gcmDevice->color[0].pitch); cellGcmSetFlipMode(gcmDevice->vsync ? CELL_GCM_DISPLAY_VSYNC : CELL_GCM_DISPLAY_HSYNC); - cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo); + cellGcmSetInvalidateVertexCache( &_RGLState.fifo); _RGLFifoFinish( &_RGLState.fifo ); for (int i = 0; i < params->bufferingMode; ++i) @@ -1066,7 +1064,7 @@ void psglDestroyDevice(PSGLdevice *device) RGLDevice *gcmDevice = ( RGLDevice * )device->platformDevice; PSGLdeviceParameters* params = &device->deviceParameters; - cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo); + cellGcmSetInvalidateVertexCache( &_RGLState.fifo); _RGLFifoFinish( &_RGLState.fifo ); if ( rescIsEnabled( params ) ) @@ -1106,7 +1104,7 @@ static void *_RGLPlatformRasterInit (void) { RGLDriver *driver = (RGLDriver*)malloc(sizeof(RGLDriver)); - cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo); + cellGcmSetInvalidateVertexCache( &_RGLState.fifo); _RGLFifoFinish( &_RGLState.fifo ); memset( driver, 0, sizeof( RGLDriver ) ); driver->rt.yInverted = CELL_GCM_TRUE; @@ -1246,13 +1244,13 @@ GLAPI void psglSwap(void) LContext->attribs->DirtyMask = (1 << MAX_VERTEX_ATTRIBS) - 1; - cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo); + cellGcmSetInvalidateVertexCache( &_RGLState.fifo); _RGLFifoFlush(fifo); while(sys_semaphore_wait(FlipSem, 1000) != CELL_OK); - cellGcmSetInvalidateVertexCacheInline(&_RGLState.fifo); + cellGcmSetInvalidateVertexCache(&_RGLState.fifo); _RGLFifoFlush(fifo); if (device->deviceParameters.bufferingMode == PSGL_BUFFERING_MODE_DOUBLE) diff --git a/console/rgl/ps3/rgl.cpp b/console/rgl/ps3/rgl.cpp index e4f786f1a7..04291de004 100644 --- a/console/rgl/ps3/rgl.cpp +++ b/console/rgl/ps3/rgl.cpp @@ -624,7 +624,7 @@ static void _RGLPlatformBufferObjectSetData( jsBufferObject* bufferObject, GLint } break; default: - cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo); + cellGcmSetInvalidateVertexCache( &_RGLState.fifo); _RGLFifoFinish( &_RGLState.fifo ); memcpy( gmmIdToAddress( dstId ) + offset, src, size ); break; @@ -732,7 +732,7 @@ static GLvoid _RGLPlatformBufferObjectCopyData( jsBufferObject* bufferObjectDst, _RGLMemcpy( dst->bufferId, 0, dst->pitch, src->bufferId, src->bufferSize ); break; case SURFACE_POOL_SYSTEM: - cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo); + cellGcmSetInvalidateVertexCache( &_RGLState.fifo); _RGLFifoFinish( &_RGLState.fifo ); memcpy( gmmIdToAddress( dst->bufferId ), gmmIdToAddress( src->bufferId ), src->bufferSize ); @@ -1149,7 +1149,7 @@ static void _RGLPlatformCopyGPUTexture( jsTexture* texture ) { _RGLImageAllocCPUStorage( image ); - cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo); + cellGcmSetInvalidateVertexCache( &_RGLState.fifo); _RGLFifoFinish( &_RGLState.fifo ); char* gpuData = gmmIdToAddress(gcmTexture->gpuAddressId) + gcmTexture->gpuAddressIdOffset; @@ -1701,7 +1701,7 @@ GLAPI void APIENTRY glClear( GLbitfield mask ) gmmFree( bufferId ); } - cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo); + cellGcmSetInvalidateVertexCache( &_RGLState.fifo); _RGLFifoFlush( fifo ); } @@ -4273,7 +4273,7 @@ static char *_RGLPlatformBufferObjectMap( jsBufferObject* bufferObject, GLenum a } else { - cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo); + cellGcmSetInvalidateVertexCache( &_RGLState.fifo); _RGLFifoFinish( &_RGLState.fifo ); } @@ -5333,7 +5333,7 @@ void psglDestroyContext( PSGLcontext* LContext ) if ( _CurrentContext == LContext ) { - cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo); + cellGcmSetInvalidateVertexCache( &_RGLState.fifo); _RGLFifoFinish( &_RGLState.fifo ); } @@ -5569,7 +5569,7 @@ GLAPI void APIENTRY glFlush(void) if ( RGL_UNLIKELY( LContext->needValidate ) ) _RGLValidateStates(); - cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo); + cellGcmSetInvalidateVertexCache( &_RGLState.fifo); _RGLFifoFlush( fifo ); } @@ -5577,7 +5577,7 @@ GLAPI void APIENTRY glFlush(void) GLAPI void APIENTRY glFinish(void) { glFlush(); - cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo); + cellGcmSetInvalidateVertexCache( &_RGLState.fifo); _RGLFifoFinish( &_RGLState.fifo ); } @@ -5623,7 +5623,7 @@ void psglExit (void) if ( LContext ) { glFlush(); - cellGcmSetInvalidateVertexCacheInline ( &_RGLState.fifo); + cellGcmSetInvalidateVertexCache ( &_RGLState.fifo); _RGLFifoFinish( &_RGLState.fifo ); psglMakeCurrent( NULL, NULL ); @@ -5990,7 +5990,7 @@ GLAPI void APIENTRY glDrawArrays( GLenum mode, GLint first, GLsizei count ) if(driver->invalidateVertexCache) { driver->invalidateVertexCache = GL_FALSE; - cellGcmSetInvalidateVertexCacheInline ( &_RGLState.fifo); + cellGcmSetInvalidateVertexCache ( &_RGLState.fifo); } GmmBaseBlock *pBaseBlock = (GmmBaseBlock *)driver->fpLoadProgramId; diff --git a/console/rgl/ps3/rgl.h b/console/rgl/ps3/rgl.h index 785ba283aa..34977ff6eb 100644 --- a/console/rgl/ps3/rgl.h +++ b/console/rgl/ps3/rgl.h @@ -823,7 +823,7 @@ static inline void TransferDataVidToVid(transfer_params_t *params) GLuint dstOffset_tmp = gmmAddressToOffset(pBaseBlock_dst->address, pBaseBlock_dst->isMain) + params->dst_id_offset; GLuint srcOffset_tmp = gmmAddressToOffset(pBaseBlock_src->address, pBaseBlock_src->isMain) + params->src_id_offset; - cellGcmSetTransferImageInline( (RGLFifo*)params->fifo_ptr, CELL_GCM_TRANSFER_LOCAL_TO_LOCAL, dstOffset_tmp, params->dst_pitch, params->dst_x, params->dst_y, srcOffset_tmp, params->src_pitch, params->src_x, params->src_y, params->width, params->height, params->bpp); + cellGcmSetTransferImage( (RGLFifo*)params->fifo_ptr, CELL_GCM_TRANSFER_LOCAL_TO_LOCAL, dstOffset_tmp, params->dst_pitch, params->dst_x, params->dst_y, srcOffset_tmp, params->src_pitch, params->src_x, params->src_y, params->width, params->height, params->bpp); } typedef struct RGLRenderTarget RGLRenderTarget; diff --git a/ps3/sdk_defines.h b/ps3/sdk_defines.h index 5ef54d72e1..adf395b041 100644 --- a/ps3/sdk_defines.h +++ b/ps3/sdk_defines.h @@ -368,6 +368,31 @@ #define CELL_GCM_COMPMODE_DISABLED 0 +#define CELL_GCM_TRANSFER_LOCAL_TO_LOCAL 0 + +#define CELL_GCM_TEXTURE_REMAP_ORDER_XYXY (0) +#define CELL_GCM_TEXTURE_REMAP_ORDER_XXXY (1) + +#define CELL_GCM_TEXTURE_UNSIGNED_REMAP_NORMAL (0) + +#define CELL_GCM_TEXTURE_REMAP_FROM_A (0) +#define CELL_GCM_TEXTURE_REMAP_FROM_R (1) +#define CELL_GCM_TEXTURE_REMAP_FROM_G (2) +#define CELL_GCM_TEXTURE_REMAP_FROM_B (3) + +#define CELL_GCM_TEXTURE_REMAP_ZERO (0) +#define CELL_GCM_TEXTURE_REMAP_ONE (1) +#define CELL_GCM_TEXTURE_REMAP_REMAP (2) + +#define CELL_GCM_MAX_TEXIMAGE_COUNT (16) + +#define CELL_GCM_TEXTURE_WRAP (1) + +#define CELL_GCM_TEXTURE_NR (0x00) +#define CELL_GCM_TEXTURE_LN (0x20) + +#define CELL_GCM_TEXTURE_B8 (0x81) + #define CELL_RESC_720x480 RESC_720x480 #define CELL_RESC_720x576 RESC_720x576 #define CELL_RESC_1280x720 RESC_1280x720 @@ -481,7 +506,17 @@ #define cellGcmSetTextureFilterInline rsxTextureFilter #define cellGcmSetTextureControlInline rsxTextureControl #define cellGcmSetCullFaceEnableInline rsxSetCullFaceEnable -#define cellGcmSetShadeModeInline rxSetShadeModel +#define cellGcmSetShadeModeInline rsxSetShadeModel +#define cellGcmSetTransferImage rsxSetTransferImage +#define cellGcmSetBlendColor rsxSetBlendColor +#define cellGcmSetBlendEquation rsxSetBlendEquation +#define cellGcmSetBlendFunc rsxSetBlendFunc +#define cellGcmSetClearColor rsxSetClearColor +#define cellGcmSetScissor rsxSetScissor +#define celGcmSetInvalidateVertexCache(fifo) rsxInvalidateTextureCache(fifo, GCM_INVALIDATE_VERTEX_TEXTURE) +#else +#define cellGcmSetTransferImage cellGcmSetTransferImageInline +#define celGcmSetInvalidateVertexCache cellGcmSetInvalidateVertexCacheInline #endif /*============================================================ @@ -498,4 +533,7 @@ #define CELL_GCM_METHOD_DATA_TEXTURE_ADDRESS(wraps, wrapt, wrapr, unsignedremap, zfunc, gamma) ((wraps) | ((0) << 4) | ((wrapt) << 8) | (unsignedremap << 12) | ((wrapr) << 16) | (gamma << 20) | (zfunc << 28)) #endif +#define CELL_GCM_REMAP_MODE(order, inputA, inputR, inputG, inputB, outputA, outputR, outputG, outputB) \ + (((order)<<16)|((inputA))|((inputR)<<2)|((inputG)<<4)|((inputB)<<6)|((outputA)<<8)|((outputR)<<10)|((outputG)<<12)|((outputB)<<14)) + #endif From 0890fced4be2909508cca0ae1e0f7f3add05c3e3 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 15 Aug 2012 13:54:17 +0200 Subject: [PATCH 178/492] (RGL) Add back cellGcmSetAlphaFunc --- console/rgl/ps3/device_ctx.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/console/rgl/ps3/device_ctx.cpp b/console/rgl/ps3/device_ctx.cpp index b00d38f315..b7144f08f5 100644 --- a/console/rgl/ps3/device_ctx.cpp +++ b/console/rgl/ps3/device_ctx.cpp @@ -248,6 +248,7 @@ static GLboolean _RGLInitFromRM( RGLResource *rmResource ) ref = RGL_CLAMPF_01(ref); + cellGcmSetAlphaFunc( &_RGLState.fifo, CELL_GCM_ALWAYS, RGL_QUICK_FLOAT2UINT( ref * 255.0f )); cellGcmSetBlendColor( &_RGLState.fifo, hwColor, hwColor); cellGcmSetBlendEquation( &_RGLState.fifo, CELL_GCM_FUNC_ADD, CELL_GCM_FUNC_ADD ); cellGcmSetBlendFunc( &_RGLState.fifo, CELL_GCM_ONE, CELL_GCM_ZERO, CELL_GCM_ONE, CELL_GCM_ZERO ); From 7372509befa6d37124582e58e3a4ee99eacd66e0 Mon Sep 17 00:00:00 2001 From: Themaister Date: Wed, 15 Aug 2012 19:52:48 +0200 Subject: [PATCH 179/492] Revert "(Libretro) Add nonblock_state" This reverts commit 211381bb89cebe20c3304fbe9df2e19006e6afc1. --- driver.c | 6 +----- libretro.h | 2 -- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/driver.c b/driver.c index 6e40f87e25..654b5c4541 100644 --- a/driver.c +++ b/driver.c @@ -209,11 +209,7 @@ static void adjust_system_rates(void) g_settings.video.vsync = false; RARCH_LOG("Game FPS > Monitor FPS. Cannot rely on VSync.\n"); #ifdef RARCH_CONSOLE - struct retro_system_info info; - retro_get_system_info(&info); - - if(info.nonblock_state) - video_set_nonblock_state_func(true); + video_set_nonblock_state_func(true); #endif } diff --git a/libretro.h b/libretro.h index 9ca36ffc65..1ec1a89c96 100755 --- a/libretro.h +++ b/libretro.h @@ -384,8 +384,6 @@ struct retro_system_info // If false, ::data and ::size are guaranteed to be valid, but ::path might not be valid. // This is typically set to true for libretro implementations that must load from file. // Implementations should strive for setting this to false, as it allows the frontend to perform patching, etc. - bool nonblock_state; // If true, this indicates that the game's fps is above 60 and that vsync should - // be deactivated before startup bool block_extract; // If true, the frontend is not allowed to extract any archives before loading the real ROM. // Necessary for certain libretro implementations that load games from zipped archives. From 3ac159845d6ed7c9037856a74d3bd67b59672481 Mon Sep 17 00:00:00 2001 From: Themaister Date: Wed, 15 Aug 2012 19:59:22 +0200 Subject: [PATCH 180/492] Set refresh_rate in console. --- console/rarch_console_settings.c | 1 + 1 file changed, 1 insertion(+) diff --git a/console/rarch_console_settings.c b/console/rarch_console_settings.c index 73130e563d..b2e6f8f163 100644 --- a/console/rarch_console_settings.c +++ b/console/rarch_console_settings.c @@ -345,6 +345,7 @@ void rarch_settings_set_default (const input_driver_t *input) g_settings.video.render_to_texture = true; g_settings.video.smooth = true; g_settings.video.vsync = true; + g_settings.video.refresh_rate = 59.92; strlcpy(g_settings.system_directory, default_paths.system_dir, sizeof(g_settings.system_directory)); From 405a901d187fe3e2a1614f42f890959b1309e9a5 Mon Sep 17 00:00:00 2001 From: Themaister Date: Wed, 15 Aug 2012 20:43:26 +0200 Subject: [PATCH 181/492] Be more careful about overwriting global settings in driver init. --- driver.c | 20 +++++++++++--------- general.h | 2 ++ retroarch.c | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/driver.c b/driver.c index 654b5c4541..e9c3fa58aa 100644 --- a/driver.c +++ b/driver.c @@ -194,6 +194,7 @@ void init_drivers_pre(void) static void adjust_system_rates(void) { + g_extern.system.force_nonblock = false; const struct retro_system_timing *info = &g_extern.system.av_info.timing; float timing_skew = fabs(1.0f - info->fps / g_settings.video.refresh_rate); @@ -206,20 +207,21 @@ static void adjust_system_rates(void) // We won't be able to do VSync reliably as game FPS > monitor FPS. if (info->fps > g_settings.video.refresh_rate) { - g_settings.video.vsync = false; + g_extern.system.force_nonblock = true; RARCH_LOG("Game FPS > Monitor FPS. Cannot rely on VSync.\n"); -#ifdef RARCH_CONSOLE - video_set_nonblock_state_func(true); -#endif } - g_settings.video.refresh_rate = info->fps; + g_settings.audio.in_rate = info->sample_rate; } - - g_settings.audio.in_rate = info->sample_rate * - (g_settings.video.refresh_rate / info->fps); + else + g_settings.audio.in_rate = info->sample_rate * + (g_settings.video.refresh_rate / info->fps); RARCH_LOG("Set audio input rate to: %.2f Hz.\n", g_settings.audio.in_rate); + +#ifdef RARCH_CONSOLE + video_set_nonblock_state_func(!g_settings.video.vsync || g_extern.system.force_nonblock); +#endif } void init_drivers(void) @@ -596,7 +598,7 @@ void init_video_input(void) video.width = width; video.height = height; video.fullscreen = g_settings.video.fullscreen; - video.vsync = g_settings.video.vsync; + video.vsync = g_settings.video.vsync && !g_extern.system.force_nonblock; video.force_aspect = g_settings.video.force_aspect; video.smooth = g_settings.video.smooth; video.input_scale = scale; diff --git a/general.h b/general.h index d4e359df5b..b76f68659f 100644 --- a/general.h +++ b/general.h @@ -338,6 +338,8 @@ struct global bool shutdown; unsigned performance_level; bool rgb32; + + bool force_nonblock; } system; struct diff --git a/retroarch.c b/retroarch.c index 78f67b615d..f3e3d2b601 100644 --- a/retroarch.c +++ b/retroarch.c @@ -73,7 +73,7 @@ static void set_fast_forward_button(bool new_button_state, bool new_hold_button_ if (update_sync) { // Only apply non-block-state for video if we're using vsync. - if (g_extern.video_active && g_settings.video.vsync) + if (g_extern.video_active && g_settings.video.vsync && !g_extern.system.force_nonblock) video_set_nonblock_state_func(syncing_state); if (g_extern.audio_active) From bbe0f00059d2a60b0e9a31b181186774bd4e5b0b Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 15 Aug 2012 21:00:23 +0200 Subject: [PATCH 182/492] (GX) Should save soft_display_filter to config file now (CONSOLE) throttle mode will not be enabled if force_nonblock is set to true --- console/rarch_console_config.c | 4 ++-- console/rarch_console_settings.c | 6 ++++-- retroarch.c | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/console/rarch_console_config.c b/console/rarch_console_config.c index a6b9ea8ec6..8182cdc642 100644 --- a/console/rarch_console_config.c +++ b/console/rarch_console_config.c @@ -103,8 +103,8 @@ void rarch_config_load(const char * conf_name, const char * libretro_dir_path, c CONFIG_GET_BOOL_CONSOLE(gamma_correction, "gamma_correction"); #ifdef _XBOX1 CONFIG_GET_INT_CONSOLE(flicker_filter, "fliker_filter"); - CONFIG_GET_BOOL_CONSOLE(soft_display_filter_enable, "soft_display_filter_enable"); #endif + CONFIG_GET_BOOL_CONSOLE(soft_display_filter_enable, "soft_display_filter_enable"); CONFIG_GET_STRING_CONSOLE(default_rom_startup_dir, "default_rom_startup_dir"); CONFIG_GET_FLOAT_CONSOLE(menu_font_size, "menu_font_size"); CONFIG_GET_FLOAT_CONSOLE(overscan_amount, "overscan_amount"); @@ -160,8 +160,8 @@ void rarch_config_save(const char * conf_name) #ifdef _XBOX360 config_set_int(conf, "color_format", g_console.color_format); #endif -#ifdef _XBOX1 config_set_bool(conf, "soft_display_filter_enable", g_console.soft_display_filter_enable); +#ifdef _XBOX1 config_set_int(conf, "flicker_filter", g_console.flicker_filter); #endif config_set_bool(conf, "throttle_enable", g_console.throttle_enable); diff --git a/console/rarch_console_settings.c b/console/rarch_console_settings.c index b2e6f8f163..5d77ad8947 100644 --- a/console/rarch_console_settings.c +++ b/console/rarch_console_settings.c @@ -148,7 +148,8 @@ void rarch_settings_change(unsigned setting) g_settings.video.fbo_scale_y += 1.0f; break; case S_THROTTLE: - g_console.throttle_enable = !g_console.throttle_enable; + if(!g_extern.system.force_nonblock) + g_console.throttle_enable = !g_console.throttle_enable; break; case S_TRIPLE_BUFFERING: g_console.triple_buffering_enable = !g_console.triple_buffering_enable; @@ -189,7 +190,8 @@ void rarch_settings_default(unsigned setting) g_console.screen_orientation = ORIENTATION_NORMAL; break; case S_DEF_THROTTLE: - g_console.throttle_enable = true; + if(!g_extern.system.force_nonblock) + g_console.throttle_enable = true; break; case S_DEF_TRIPLE_BUFFERING: g_console.triple_buffering_enable = true; diff --git a/retroarch.c b/retroarch.c index f3e3d2b601..f25b87499e 100644 --- a/retroarch.c +++ b/retroarch.c @@ -72,6 +72,7 @@ static void set_fast_forward_button(bool new_button_state, bool new_hold_button_ if (update_sync) { + RARCH_LOG("Video active = %u, VSync = %u, Force nonblock = %u\n", g_extern.video_active, g_settings.video.vsync, g_extern.system.force_nonblock); // Only apply non-block-state for video if we're using vsync. if (g_extern.video_active && g_settings.video.vsync && !g_extern.system.force_nonblock) video_set_nonblock_state_func(syncing_state); From 979e45ea66a58fe2f97945f81794dea81a33688f Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 15 Aug 2012 21:02:06 +0200 Subject: [PATCH 183/492] Remove redundant log --- retroarch.c | 1 - 1 file changed, 1 deletion(-) diff --git a/retroarch.c b/retroarch.c index f25b87499e..f3e3d2b601 100644 --- a/retroarch.c +++ b/retroarch.c @@ -72,7 +72,6 @@ static void set_fast_forward_button(bool new_button_state, bool new_hold_button_ if (update_sync) { - RARCH_LOG("Video active = %u, VSync = %u, Force nonblock = %u\n", g_extern.video_active, g_settings.video.vsync, g_extern.system.force_nonblock); // Only apply non-block-state for video if we're using vsync. if (g_extern.video_active && g_settings.video.vsync && !g_extern.system.force_nonblock) video_set_nonblock_state_func(syncing_state); From 70fd5350dc6813640b0378f180f656f40758d203 Mon Sep 17 00:00:00 2001 From: Themaister Date: Thu, 16 Aug 2012 09:25:13 +0200 Subject: [PATCH 184/492] Always build in h264 support. --- Makefile.win | 1 - config.features.h | 6 ------ qb/config.libs.sh | 6 +----- qb/config.params.sh | 1 - record/ffemu.c | 17 +++-------------- retroarch.c | 1 - 6 files changed, 4 insertions(+), 28 deletions(-) diff --git a/Makefile.win b/Makefile.win index 68aa7c95ed..cc53111e19 100644 --- a/Makefile.win +++ b/Makefile.win @@ -166,7 +166,6 @@ ifeq ($(HAVE_FFMPEG), 1) DEFINES += -DHAVE_FFMPEG_AVIO_OPEN DEFINES += -DHAVE_FFMPEG_AVFORMAT_WRITE_HEADER DEFINES += -DHAVE_FFMPEG_AVFORMAT_NEW_STREAM - DEFINES += -DHAVE_X264RGB OBJ += record/ffemu.o endif diff --git a/config.features.h b/config.features.h index d05067885d..8d992d8723 100644 --- a/config.features.h +++ b/config.features.h @@ -134,12 +134,6 @@ static const bool _ffmpeg_supp = true; static const bool _ffmpeg_supp = false; #endif -#ifdef HAVE_X264RGB -static const bool _x264rgb_supp = true; -#else -static const bool _x264rgb_supp = false; -#endif - #ifdef HAVE_CONFIGFILE static const bool _configfile_supp = true; #else diff --git a/qb/config.libs.sh b/qb/config.libs.sh index d222f5eb48..d9710d03b7 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -120,10 +120,6 @@ if [ "$HAVE_THREADS" != 'no' ]; then check_lib FFMPEG_AVFORMAT_NEW_STREAM "$AVFORMAT_LIBS" avformat_new_stream check_lib FFMPEG_AVCODEC_ENCODE_VIDEO2 "$AVCODEC_LIBS" avcodec_encode_video2 fi - - if [ "$HAVE_FFMPEG" = 'no' ] && [ "$HAVE_X264RGB" = 'yes' ]; then - echo "x264 RGB recording is enabled, but FFmpeg is not. --enable-x264rgb will not have any effect." - fi else echo "Not building with threading support. Will skip FFmpeg." HAVE_FFMPEG='no' @@ -148,6 +144,6 @@ check_pkgconf PYTHON python3 add_define_make OS "$OS" # Creates config.mk and config.h. -VARS="ALSA OSS OSS_BSD OSS_LIB AL RSOUND ROAR JACK COREAUDIO PULSE SDL OPENGL DYLIB GETOPT_LONG THREADS CG XML SDL_IMAGE LIBPNG DYNAMIC FFMPEG AVCODEC AVFORMAT AVUTIL SWSCALE CONFIGFILE FREETYPE XVIDEO X11 XEXT NETPLAY NETWORK_CMD STDIN_CMD COMMAND SOCKET_LEGACY FBO STRL PYTHON FFMPEG_ALLOC_CONTEXT3 FFMPEG_AVCODEC_OPEN2 FFMPEG_AVIO_OPEN FFMPEG_AVFORMAT_WRITE_HEADER FFMPEG_AVFORMAT_NEW_STREAM FFMPEG_AVCODEC_ENCODE_AUDIO2 FFMPEG_AVCODEC_ENCODE_VIDEO2 X264RGB SINC FIXED_POINT BSV_MOVIE RPI" +VARS="ALSA OSS OSS_BSD OSS_LIB AL RSOUND ROAR JACK COREAUDIO PULSE SDL OPENGL DYLIB GETOPT_LONG THREADS CG XML SDL_IMAGE LIBPNG DYNAMIC FFMPEG AVCODEC AVFORMAT AVUTIL SWSCALE CONFIGFILE FREETYPE XVIDEO X11 XEXT NETPLAY NETWORK_CMD STDIN_CMD COMMAND SOCKET_LEGACY FBO STRL PYTHON FFMPEG_ALLOC_CONTEXT3 FFMPEG_AVCODEC_OPEN2 FFMPEG_AVIO_OPEN FFMPEG_AVFORMAT_WRITE_HEADER FFMPEG_AVFORMAT_NEW_STREAM FFMPEG_AVCODEC_ENCODE_AUDIO2 FFMPEG_AVCODEC_ENCODE_VIDEO2 SINC FIXED_POINT BSV_MOVIE RPI" create_config_make config.mk $VARS create_config_header config.h $VARS diff --git a/qb/config.params.sh b/qb/config.params.sh index 02e524d574..fad2e7bcf7 100644 --- a/qb/config.params.sh +++ b/qb/config.params.sh @@ -2,7 +2,6 @@ HAVE_DYNAMIC=yes # Disable dynamic loading of libretro library HAVE_LIBRETRO= # libretro library used HAVE_THREADS=auto # Threading support HAVE_FFMPEG=auto # Enable FFmpeg recording support -HAVE_X264RGB=no # Enable lossless X264 RGB recording HAVE_DYLIB=auto # Enable dynamic loading support HAVE_NETPLAY=auto # Enable netplay support HAVE_CONFIGFILE=yes # Disable support for config file diff --git a/record/ffemu.c b/record/ffemu.c index 6e812a5dd2..1bf2241c49 100644 --- a/record/ffemu.c +++ b/record/ffemu.c @@ -154,7 +154,6 @@ static bool ffemu_init_audio(struct ff_audio_info *audio, struct ffemu_params *p static bool ffemu_init_video(struct ff_video_info *video, const struct ffemu_params *param) { -#ifdef HAVE_X264RGB AVCodec *codec = NULL; if (g_settings.video.h264_record) { @@ -165,9 +164,7 @@ static bool ffemu_init_video(struct ff_video_info *video, const struct ffemu_par } else codec = avcodec_find_encoder_by_name("ffv1"); -#else - AVCodec *codec = avcodec_find_encoder_by_name("ffv1"); -#endif + if (!codec) return false; @@ -185,11 +182,7 @@ static bool ffemu_init_video(struct ff_video_info *video, const struct ffemu_par video->pix_size = sizeof(uint32_t); } -#ifdef HAVE_X264RGB video->pix_fmt = g_settings.video.h264_record ? PIX_FMT_BGR24 : PIX_FMT_RGB32; -#else - video->pix_fmt = PIX_FMT_RGB32; -#endif #ifdef HAVE_FFMPEG_ALLOC_CONTEXT3 video->codec = avcodec_alloc_context3(codec); @@ -208,7 +201,6 @@ static bool ffemu_init_video(struct ff_video_info *video, const struct ffemu_par AVDictionary *opts = NULL; #endif -#ifdef HAVE_X264RGB if (g_settings.video.h264_record) { video->codec->thread_count = 3; @@ -216,9 +208,6 @@ static bool ffemu_init_video(struct ff_video_info *video, const struct ffemu_par } else video->codec->thread_count = 2; -#else - video->codec->thread_count = 2; -#endif #ifdef HAVE_FFMPEG_AVCODEC_OPEN2 if (avcodec_open2(video->codec, codec, &opts) != 0) @@ -298,10 +287,10 @@ static bool ffemu_init_muxer(ffemu_t *handle) handle->audio.codec->flags |= CODEC_FLAG_GLOBAL_HEADER; handle->muxer.astream = stream; -#ifdef HAVE_X264RGB // Avoids a warning at end about non-monotonically increasing DTS values. It seems to be harmless to disable this. + // Avoids a warning at end about non-monotonically increasing DTS values. + // It seems to be harmless to disable this. if (g_settings.video.h264_record) ctx->oformat->flags |= AVFMT_TS_NONSTRICT; -#endif av_dict_set(&ctx->metadata, "title", "RetroArch video dump", 0); diff --git a/retroarch.c b/retroarch.c index f3e3d2b601..eaa2bbf6c1 100644 --- a/retroarch.c +++ b/retroarch.c @@ -506,7 +506,6 @@ static void print_features(void) _PSUPP(fbo, "FBO", "OpenGL render-to-texture (multi-pass shaders)"); _PSUPP(dynamic, "Dynamic", "Dynamic run-time loading of libretro library"); _PSUPP(ffmpeg, "FFmpeg", "On-the-fly recording of gameplay with libavcodec"); - _PSUPP(x264rgb, "x264 RGB", "x264 lossless RGB recording for FFmpeg"); _PSUPP(configfile, "Config file", "Configuration file support"); _PSUPP(freetype, "FreeType", "TTF font rendering with FreeType"); _PSUPP(netplay, "Netplay", "Peer-to-peer netplay"); From 38a3c72a218e4d169a76fd2c646023b4ff8ea2c2 Mon Sep 17 00:00:00 2001 From: Themaister Date: Thu, 16 Aug 2012 09:31:05 +0200 Subject: [PATCH 185/492] Update to 0.9.7-rc2. --- Makefile.ps3 | 2 +- Makefile.ps3.retroarch | 2 +- Makefile.psl1ght | 2 +- Makefile.wii | 2 +- Makefile.wii.salamander | 2 +- Makefile.win | 6 +++--- Makefile.xenon | 2 +- configure | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Makefile.ps3 b/Makefile.ps3 index ccb518d951..7f085d38db 100644 --- a/Makefile.ps3 +++ b/Makefile.ps3 @@ -1,4 +1,4 @@ -RARCH_VERSION = "0.9.7-rc1" +RARCH_VERSION = "0.9.7-rc2" #which compiler to build with - GCC or SNC #set to GCC for debug builds for use with debugger diff --git a/Makefile.ps3.retroarch b/Makefile.ps3.retroarch index eb42aaa0d3..2870f8e5d4 100644 --- a/Makefile.ps3.retroarch +++ b/Makefile.ps3.retroarch @@ -1,4 +1,4 @@ -RARCH_VERSION = "0.9.7-rc1" +RARCH_VERSION = "0.9.7-rc2" #which compiler to build with - GCC or SNC #set to GCC for debug builds for use with debugger diff --git a/Makefile.psl1ght b/Makefile.psl1ght index d510d71125..cafa1ab001 100644 --- a/Makefile.psl1ght +++ b/Makefile.psl1ght @@ -40,7 +40,7 @@ endif RSXGL_DEFINES = -D__RSX__ -DGL3_PROTOTYPES -SHARED_FLAGS := -DHAVE_FILEBROWSER $(RSXGL_DEFINES) -DHAVE_OSKUTIL -DHAVE_MOUSE -DHAVE_DEFAULT_RETROPAD_INPUT -DRARCH_CONSOLE -DHAVE_CONFIGFILE=1 -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"0.9.7-rc1\" -Dmain=rarch_main -Wno-char-subscripts +SHARED_FLAGS := -DHAVE_FILEBROWSER $(RSXGL_DEFINES) -DHAVE_OSKUTIL -DHAVE_MOUSE -DHAVE_DEFAULT_RETROPAD_INPUT -DRARCH_CONSOLE -DHAVE_CONFIGFILE=1 -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"0.9.7-rc2\" -Dmain=rarch_main -Wno-char-subscripts CFLAGS += -std=gnu99 $(SHARED_FLAGS) CXXFLAGS += $(SHARED_FLAGS) diff --git a/Makefile.wii b/Makefile.wii index c0da196745..270a2a6a54 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -39,7 +39,7 @@ CFLAGS += -DHAVE_FILE_LOGGER CFLAGS += -Iconsole/logger endif -CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_RGUI -DHAVE_THREAD -DRARCH_CONSOLE -DHAVE_LIBRETRO_MANAGEMENT -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"0.9.7-rc1\" -Dmain=rarch_main -Wno-char-subscripts +CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_RGUI -DHAVE_THREAD -DRARCH_CONSOLE -DHAVE_LIBRETRO_MANAGEMENT -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"0.9.7-rc2\" -Dmain=rarch_main -Wno-char-subscripts ifeq ($(DEBUG), 1) CFLAGS += -O0 -g diff --git a/Makefile.wii.salamander b/Makefile.wii.salamander index 660be31137..a50544c9bc 100644 --- a/Makefile.wii.salamander +++ b/Makefile.wii.salamander @@ -39,7 +39,7 @@ CFLAGS += -DHAVE_FILE_LOGGER CFLAGS += -Iconsole/logger endif -CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DIS_SALAMANDER -DRARCH_CONSOLE -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DPACKAGE_VERSION=\"0.9.7-rc1\" -Wno-char-subscripts +CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DIS_SALAMANDER -DRARCH_CONSOLE -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DPACKAGE_VERSION=\"0.9.7-rc2\" -Wno-char-subscripts ifeq ($(DEBUG), 1) CFLAGS += -O0 -g diff --git a/Makefile.win b/Makefile.win index cc53111e19..b381ad2be5 100644 --- a/Makefile.win +++ b/Makefile.win @@ -53,7 +53,7 @@ endif libretro ?= -lretro LIBS = -lm -DEFINES = -I. -DHAVE_CONFIGFILE -DHAVE_SDL -DHAVE_SCREENSHOTS -DHAVE_BSV_MOVIE -DPACKAGE_VERSION=\"0.9.7-rc1\" +DEFINES = -I. -DHAVE_CONFIGFILE -DHAVE_SDL -DHAVE_SCREENSHOTS -DHAVE_BSV_MOVIE -DPACKAGE_VERSION=\"0.9.7-rc2\" LDFLAGS = -L. -static-libgcc ifeq ($(TDM_GCC),) @@ -228,10 +228,10 @@ clean: rm -f tools/*.o dist_x86: all - zip -r retroarch-win32-0.9.7-rc1.zip $(TARGET) $(JTARGET) retroarch.cfg SDL.dll + zip -r retroarch-win32-0.9.7-rc2.zip $(TARGET) $(JTARGET) retroarch.cfg SDL.dll dist_x86_64: all - zip -r retroarch-win64-0.9.7-rc1.zip $(TARGET) $(JTARGET) retroarch.cfg SDL.dll + zip -r retroarch-win64-0.9.7-rc2.zip $(TARGET) $(JTARGET) retroarch.cfg SDL.dll libs_x86: wget https://github.com/downloads/Themaister/RetroArch/RetroArch-win32-libs.zip --no-check-certificate diff --git a/Makefile.xenon b/Makefile.xenon index 9e259a9884..464fbeb958 100644 --- a/Makefile.xenon +++ b/Makefile.xenon @@ -21,7 +21,7 @@ INCDIRS = -I. -I$(DEVKITXENON)/usr/include OBJ = fifo_buffer.o retroarch.o driver.o file.o file_path.o settings.o message.o rewind.o movie.o gfx/gfx_common.o patch.o compat/compat.o screenshot.o audio/hermite.o dynamic.o audio/utils.o conf/config_file.o 360/frontend-xenon/main.o 360/xenon360_audio.o 360/xenon360_input.o 360/xenon360_video.o thread/xenon_sdl_threads.o LIBS = -lretro_xenon360 -lxenon -lm -lc -DEFINES = -std=gnu99 -DHAVE_CONFIGFILE=1 -DPACKAGE_VERSION=\"0.9.7-rc1\" -DRARCH_CONSOLE -DHAVE_GETOPT_LONG=1 -Dmain=rarch_main +DEFINES = -std=gnu99 -DHAVE_CONFIGFILE=1 -DPACKAGE_VERSION=\"0.9.7-rc2\" -DRARCH_CONSOLE -DHAVE_GETOPT_LONG=1 -Dmain=rarch_main DEFINES += -maltivec -mhard-float -m32 -mpowerpc64 -mcpu=cell -mtune=cell -fno-pic -g -Wall -DXENON $(INCDIRS) DEFINES += -u read -u _start -u exc_base diff --git a/configure b/configure index 3e084a275c..120e0f41ba 100755 --- a/configure +++ b/configure @@ -1,7 +1,7 @@ #!/bin/sh PACKAGE_NAME=retroarch -PACKAGE_VERSION=0.9.7-rc1 +PACKAGE_VERSION=0.9.7-rc2 . qb/qb.params.sh From 81989272601ac1c31f22360c18e55cc0d5d60fda Mon Sep 17 00:00:00 2001 From: Themaister Date: Thu, 16 Aug 2012 10:09:44 +0200 Subject: [PATCH 186/492] Fixup build on Win32. --- gfx/gl.c | 6 +++--- gfx/gl_common.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gfx/gl.c b/gfx/gl.c index a85b9b6f01..529d742d6b 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -129,7 +129,7 @@ static bool load_fbo_proc(void) { return true; } #endif #endif -#if (defined(HAVE_XML) || defined(HAVE_CG)) && defined(_WIN32) +#ifdef _WIN32 PFNGLCLIENTACTIVETEXTUREPROC pglClientActiveTexture = NULL; PFNGLACTIVETEXTUREPROC pglActiveTexture = NULL; static inline bool load_gl_proc(void) @@ -1067,8 +1067,8 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); #endif -#if (defined(HAVE_XML) || defined(HAVE_CG)) && defined(_WIN32) - // Win32 GL lib doesn't have some functions needed for XML shaders. +#ifdef _WIN32 + // Win32 GL lib doesn't have some functions needed. // Need to load dynamically :( if (!load_gl_proc()) { diff --git a/gfx/gl_common.h b/gfx/gl_common.h index 43f913186d..15e377dbfc 100644 --- a/gfx/gl_common.h +++ b/gfx/gl_common.h @@ -211,7 +211,7 @@ typedef struct gl } gl_t; // Windows ... <_< -#if (defined(HAVE_XML) || defined(HAVE_CG)) && defined(_WIN32) +#ifdef _WIN32 extern PFNGLCLIENTACTIVETEXTUREPROC pglClientActiveTexture; extern PFNGLACTIVETEXTUREPROC pglActiveTexture; #else From b3d4044e09ca761f2883b85b193687634c1f1548 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 16 Aug 2012 10:26:09 +0200 Subject: [PATCH 187/492] (Xbox 1) Fix Salamander --- msvc/RetroArch-Xbox1-Salamander/RetroArch-Salamander.vcproj | 2 +- xdk/salamander/main.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/msvc/RetroArch-Xbox1-Salamander/RetroArch-Salamander.vcproj b/msvc/RetroArch-Xbox1-Salamander/RetroArch-Salamander.vcproj index f0e1685e13..0cfc33aaf5 100644 --- a/msvc/RetroArch-Xbox1-Salamander/RetroArch-Salamander.vcproj +++ b/msvc/RetroArch-Xbox1-Salamander/RetroArch-Salamander.vcproj @@ -372,7 +372,7 @@ + RelativePath="..\..\xdk\salamander\main.c"> Date: Thu, 16 Aug 2012 10:51:27 +0200 Subject: [PATCH 188/492] Do not log unless g_extern.verbose is set. --- retroarch_logger.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/retroarch_logger.h b/retroarch_logger.h index cbca98e8b0..1b93f81c3b 100644 --- a/retroarch_logger.h +++ b/retroarch_logger.h @@ -29,8 +29,11 @@ } while (0) #else #define RARCH_LOG(...) do { \ - fprintf(stderr, "RetroArch: " __VA_ARGS__); \ - fflush(stderr); \ + if (g_extern.verbose) \ + { \ + fprintf(stderr, "RetroArch: " __VA_ARGS__); \ + fflush(stderr); \ + } \ } while (0) #endif #endif From 9890a0ba9a489832d2cdf353d5e26a24ec234547 Mon Sep 17 00:00:00 2001 From: Toad King Date: Thu, 16 Aug 2012 12:40:52 -0400 Subject: [PATCH 189/492] (GX) aspect ratio selection TODO: custom viewport code --- console/rgui/rgui.c | 14 +++++++++ console/rgui/rgui.h | 1 + gx/gx_video.c | 75 ++++++++++++++++++++++++++++++++++++++++++--- gx/gx_video.h | 3 ++ 4 files changed, 88 insertions(+), 5 deletions(-) diff --git a/console/rgui/rgui.c b/console/rgui/rgui.c index 315f4fe9b4..d7bd41ee39 100644 --- a/console/rgui/rgui.c +++ b/console/rgui/rgui.c @@ -15,6 +15,7 @@ #include "rgui.h" #include "list.h" +#include "../rarch_console_video.h" #include #include #include @@ -335,6 +336,9 @@ static void render_text(rgui_handle_t *rgui) case RGUI_SETTINGS_VIDEO_GAMMA: snprintf(type_str, sizeof(type_str), "%d", g_console.gamma_correction); break; + case RGUI_SETTINGS_VIDEO_ASPECT_RATIO: + snprintf(type_str, sizeof(type_str), "%s", aspectratio_lut[g_console.aspect_ratio_index].name); + break; case RGUI_SETTINGS_VIDEO_ROTATION: { char rotate_msg[64]; @@ -469,6 +473,15 @@ static void rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t } } break; + case RGUI_SETTINGS_VIDEO_ASPECT_RATIO: + if (action == RGUI_ACTION_START) + rarch_settings_default(S_DEF_ASPECT_RATIO); + else if (action == RGUI_ACTION_LEFT) + rarch_settings_change(S_ASPECT_RATIO_DECREMENT); + else if (action == RGUI_ACTION_RIGHT) + rarch_settings_change(S_ASPECT_RATIO_INCREMENT); + video_set_aspect_ratio_func(g_console.aspect_ratio_index); + break; case RGUI_SETTINGS_VIDEO_ROTATION: if (action == RGUI_ACTION_START) { @@ -581,6 +594,7 @@ static void rgui_settings_populate_entries(rgui_handle_t *rgui) RGUI_MENU_ITEM("VI Trap filtering", RGUI_SETTINGS_VIDEO_SOFT_FILTER); #endif RGUI_MENU_ITEM("Gamma", RGUI_SETTINGS_VIDEO_GAMMA); + RGUI_MENU_ITEM("Aspect Ratio", RGUI_SETTINGS_VIDEO_ASPECT_RATIO); RGUI_MENU_ITEM("Rotation", RGUI_SETTINGS_VIDEO_ROTATION); RGUI_MENU_ITEM("Mute Audio", RGUI_SETTINGS_AUDIO_MUTE); RGUI_MENU_ITEM("Audio Control Rate", RGUI_SETTINGS_AUDIO_CONTROL_RATE); diff --git a/console/rgui/rgui.h b/console/rgui/rgui.h index ddf97874a4..476d310b12 100644 --- a/console/rgui/rgui.h +++ b/console/rgui/rgui.h @@ -41,6 +41,7 @@ typedef enum RGUI_SETTINGS_VIDEO_SOFT_FILTER, #endif RGUI_SETTINGS_VIDEO_GAMMA, + RGUI_SETTINGS_VIDEO_ASPECT_RATIO, RGUI_SETTINGS_VIDEO_ROTATION, RGUI_SETTINGS_AUDIO_MUTE, RGUI_SETTINGS_AUDIO_CONTROL_RATE, diff --git a/gx/gx_video.c b/gx/gx_video.c index b874ce22d7..84cb8d385c 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -17,6 +17,7 @@ #include "../driver.h" #include "../general.h" +#include "../console/rarch_console_video.h" #include "gx_video.h" #include #include @@ -45,6 +46,7 @@ struct uint8_t gx_fifo[256 * 1024] ATTRIBUTE_ALIGN(32); uint8_t display_list[1024] ATTRIBUTE_ALIGN(32); +uint16_t gx_width, gx_height; size_t display_list_size; float verts[16] ATTRIBUTE_ALIGN(32) = { @@ -84,6 +86,19 @@ float tex_coords_270[8] ATTRIBUTE_ALIGN(32) = { float *vertex_ptr = tex_coords; +void gx_set_aspect_ratio(void *data, unsigned aspectratio_idx) +{ + gx_video_t *gx = (gx_video_t*)driver.video_data; + + if (g_console.aspect_ratio_index == ASPECT_RATIO_AUTO) + rarch_set_auto_viewport(g_extern.frame_cache.width, g_extern.frame_cache.height); + + g_settings.video.aspect_ratio = aspectratio_lut[g_console.aspect_ratio_index].value; + g_settings.video.force_aspect = false; + gx->keep_aspect = true; + gx->should_resize = true; +} + static void retrace_callback(u32 retrace_count) { (void)retrace_count; @@ -205,6 +220,7 @@ static void *gx_init(const video_info_t *video, g_vsync = video->vsync; + gx->should_resize = true; return gx; } @@ -233,6 +249,8 @@ static void gx_start(void) build_disp_list(); g_vsync = true; + gx_width = mode->fbWidth; + gx_height = mode->efbHeight; } #define ASM_BLITTER @@ -414,6 +432,57 @@ static void update_texture(const uint32_t *src, GX_InvalidateTexAll(); } +static void gx_resize(gx_video_t *gx) +{ + unsigned x = 0, y = 0, width = gx_width, height = gx_height; + +#ifdef HW_RVL + VIDEO_SetTrapFilter(g_console.soft_display_filter_enable); +#endif + GX_SetDispCopyGamma(g_console.gamma_correction); + + if (gx->keep_aspect) + { + float desired_aspect = g_settings.video.aspect_ratio; + float device_aspect = CONF_GetAspectRatio() == CONF_ASPECT_4_3 ? 4.0 / 3.0 : 16.0 / 9.0; + float delta; + +#ifdef RARCH_CONSOLE + if (g_console.aspect_ratio_index == ASPECT_RATIO_CUSTOM) + { + // TODO + /*x = g_console.viewports.custom_vp.x; + y = g_console.viewports.custom_vp.y; + width = g_console.viewports.custom_vp.width; + height = g_console.viewports.custom_vp.height;*/ + } + else +#endif + { + if (fabs(device_aspect - desired_aspect) < 0.0001) + { + // If the aspect ratios of screen and desired aspect ratio are sufficiently equal (floating point stuff), + // assume they are actually equal. + } + else if (device_aspect > desired_aspect) + { + delta = (desired_aspect / device_aspect - 1.0) / 2.0 + 0.5; + x = (unsigned)(width * (0.5 - delta)); + width = (unsigned)(2.0 * width * delta); + } + else + { + delta = (device_aspect / desired_aspect - 1.0) / 2.0 + 0.5; + y = (unsigned)(height * (0.5 - delta)); + height = (unsigned)(2.0 * height * delta); + } + } + } + + GX_SetViewport(x, y, width, height, 0, 1); + gx->should_resize = false; +} + static bool gx_frame(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch, const char *msg) @@ -432,11 +501,7 @@ static bool gx_frame(void *data, const void *frame, if(should_resize) { -#ifdef HW_RVL - VIDEO_SetTrapFilter(g_console.soft_display_filter_enable); -#endif - GX_SetDispCopyGamma(g_console.gamma_correction); - gx->should_resize = false; + gx_resize(gx); } while (g_vsync && !g_draw_done) diff --git a/gx/gx_video.h b/gx/gx_video.h index 118f670ab2..996b12a7d1 100644 --- a/gx/gx_video.h +++ b/gx/gx_video.h @@ -20,9 +20,12 @@ typedef struct gx_video { bool menu_render; bool should_resize; + bool keep_aspect; uint32_t frame_count; uint32_t *menu_data; } gx_video_t; +void gx_set_aspect_ratio(void *data, unsigned aspectratio_idx); + #endif From 878a141b4a54a0751a93a005c27fb8bfff5f9e0b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 16 Aug 2012 19:11:54 +0200 Subject: [PATCH 190/492] (Xbox 1) Increase stack size to 131072 - Genesis Plus GX needs it --- msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj index 3b0346f99d..fdb6d8b4e2 100644 --- a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj +++ b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj @@ -278,7 +278,7 @@ ForceCopy="TRUE"/> + StackSize="262144"/> From 1854388a566f57350f1a275ba56d39f66b919aee Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 16 Aug 2012 19:14:27 +0200 Subject: [PATCH 191/492] (Xbox 1) Reapply stack size changes --- msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj index fdb6d8b4e2..b2cec55e59 100644 --- a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj +++ b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj @@ -56,7 +56,7 @@ ForceCopy="TRUE"/> @@ -110,8 +110,9 @@ ForceCopy="TRUE"/> @@ -225,7 +226,7 @@ ForceCopy="TRUE"/> + StackSize="131072"/> + StackSize="131072"/> From 8f3305a316e7e63e0e0fa547bf0a447bdde5adf2 Mon Sep 17 00:00:00 2001 From: Toad King Date: Thu, 16 Aug 2012 14:58:59 -0400 Subject: [PATCH 192/492] (GX) add custom linker script for increased stack size --- Makefile.wii | 2 +- gx/ld/rvl.ld | 298 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 299 insertions(+), 1 deletion(-) create mode 100644 gx/ld/rvl.ld diff --git a/Makefile.wii b/Makefile.wii index 270a2a6a54..c3f0f9523f 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -22,7 +22,7 @@ LIBDIRS := -L$(DEVKITPRO)/libogc/lib/wii -L. MACHDEP := -DGEKKO -DHW_RVL -mrvl -mcpu=750 -meabi -mhard-float CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE) -LDFLAGS := $(MACHDEP) +LDFLAGS := $(MACHDEP) -T gx/ld/rvl.ld LIBS := -lfat -lretro_wii -lwiiuse -logc -lbte OBJ = console/griffin/griffin.o console/font.bmpobj console/rzlib/rzlib.o diff --git a/gx/ld/rvl.ld b/gx/ld/rvl.ld new file mode 100644 index 0000000000..7a9867c2f4 --- /dev/null +++ b/gx/ld/rvl.ld @@ -0,0 +1,298 @@ +/* + * Linkscript for Wii + */ + +OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc"); +OUTPUT_ARCH(powerpc:common); +EXTERN(_start); +ENTRY(_start); + +PHDRS +{ + stub PT_LOAD FLAGS(5); + text PT_LOAD FLAGS(5); + data PT_LOAD FLAGS(6); + bss1 PT_LOAD; + bss2 PT_LOAD; + +} + +SECTIONS +{ + /* stub is loaded at physical address 0x00003400 (though both 0x80003400 and 0x00003400 are equivalent for IOS) */ + /* This can also be used to load an arbitrary standalone stub at an arbitrary address in memory, for any purpose */ + /* Use -Wl,--section-start,.stub=0xADDRESS to change */ + . = 0x00003400; + + .stub : + { + KEEP(*(.stub)) + } :stub = 0 + + /* default base address */ + /* use -Wl,--section-start,.init=0xADDRESS to change */ + . = 0x80004000; + + /* Program */ + .init : + { + KEEP (*crt0.o(*.init)) + KEEP (*(.init)) + } :text = 0 + .plt : { *(.plt) } + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } + .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } + .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } + .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } + .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } + .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rela.got1 : { *(.rela.got1) } + .rela.got2 : { *(.rela.got2) } + .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } + .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } + .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } + .rela.sbss : { *(.rela.sbss .rela.sbss.* .rel.gnu.linkonce.sb.*) } + .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } + .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } + .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } + .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } + .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + + .text : + { + *(.text) + *(.text.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t.*) + . = ALIGN(32); /* REQUIRED. LD is flaky without it. */ + } = 0 + + .fini : + { + KEEP (*(.fini)) + . = ALIGN(32); /* REQUIRED. LD is flaky without it. */ + } = 0 + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + .rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) } :data + .rodata1 : { *(.rodata1) } + .sdata2 : { *(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*) } + .sbss2 : { *(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + /* Ensure the __preinit_array_start label is properly aligned. We + could instead move the label definition inside the section, but + the linker would then create the section even if it turns out to + be empty, which isn't pretty. */ + . = ALIGN(32 / 8); + PROVIDE (__preinit_array_start = .); + .preinit_array : { *(.preinit_array) } + PROVIDE (__preinit_array_end = .); + PROVIDE (__init_array_start = .); + .init_array : { *(.init_array) } + PROVIDE (__init_array_end = .); + PROVIDE (__fini_array_start = .); + .fini_array : { *(.fini_array) } + PROVIDE (__fini_array_end = .); + .data : + { + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + . = ALIGN(32); /* REQUIRED. LD is flaky without it. */ + } + + .data1 : { *(.data1) } + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .eh_frame : { KEEP (*(.eh_frame)) } + .gcc_except_table : { *(.gcc_except_table) } + .fixup : { *(.fixup) } + .got1 : { *(.got1) } + .got2 : { *(.got2) } + .dynamic : { *(.dynamic) } + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + + KEEP (*crtbegin.o(.ctors)) + + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + + KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + . = ALIGN(32); /* REQUIRED. LD is flaky without it. */ + } + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + . = ALIGN(32); /* REQUIRED. LD is flaky without it. */ + } + + .jcr : { KEEP (*(.jcr)) } + .got : { *(.got.plt) *(.got) } + + + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + + .sdata : + { + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(32); /* REQUIRED. LD is flaky without it. */ + } + + _edata = .; + PROVIDE (edata = .); + + .sbss : + { + __sbss_start = .; + PROVIDE (__sbss_start = .); + PROVIDE (___sbss_start = .); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + PROVIDE (__sbss_end = .); + PROVIDE (___sbss_end = .); + . = ALIGN(32); /* REQUIRED. LD is flaky without it. */ + __sbss_end = .; + } :bss1 + + .bss : + { + __bss_start = .; + PROVIDE (__bss_start = .); + *(.dynbss) + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. */ + + . = ALIGN(32); + + PROVIDE (__bss_end = .); + __bss_end = .; + } :bss2 + + _end = .; + PROVIDE(end = .); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* These must appear regardless of . */ +} + +__isIPL = 0; +__stack_addr = (__bss_start + SIZEOF(.bss) + 0x40000 + 7) & (-8); +__stack_end = (__bss_start + SIZEOF(.bss)); +__intrstack_addr = (__stack_addr + 0x4000); +__intrstack_end = (__stack_addr); +__Arena1Lo = (__intrstack_addr + 31) & (-32); +__Arena1Hi = (0x817FEFF0); +__Arena2Lo = (0x90002000); +__Arena2Hi = (0x933E0000); + +__gxregs = (__Arena1Hi + 31) & (-32); +__ipcbufferLo = (0x933e0000); +__ipcbufferHi = (0x93400000); + +/* for backward compatibility with old crt0 */ +PROVIDE (__stack = (0x817FEFF0)); + +PROVIDE(__isIPL = __isIPL); +PROVIDE(__stack_addr = __stack_addr); +PROVIDE(__stack_end = __stack_end); +PROVIDE(__intrstack_addr = __intrstack_addr); +PROVIDE(__intrstack_end = __intrstack_end); +PROVIDE(__Arena1Lo = __Arena1Lo); +PROVIDE(__Arena1Hi = __Arena1Hi); +PROVIDE(__Arena2Lo = __Arena2Lo); +PROVIDE(__Arena2Hi = __Arena2Hi); +PROVIDE(__ipcbufferLo = __ipcbufferLo); +PROVIDE(__ipcbufferHi = __ipcbufferHi); +PROVIDE(__gxregs = __gxregs); From f0d9cc09c902ffac73ddd4ed89d73d5e189298f3 Mon Sep 17 00:00:00 2001 From: Themaister Date: Thu, 16 Aug 2012 21:20:38 +0200 Subject: [PATCH 193/492] Add --dualanalog/-A flag. --- docs/retroarch.1 | 16 +++++---- general.h | 7 ++-- retroarch.c | 86 ++++++++++++++++++++++++++++-------------------- 3 files changed, 65 insertions(+), 44 deletions(-) diff --git a/docs/retroarch.1 b/docs/retroarch.1 index 13192b6973..d439d65c6e 100644 --- a/docs/retroarch.1 +++ b/docs/retroarch.1 @@ -99,27 +99,31 @@ When using Sufami, save ram paths will be inferred from the Sufami BIOS path, no .TP \fB--mouse PORT, -m PORT\fR -Connects a Super Nintendo Mouse into port number PORT of the emulated SNES. Possible values for PORT are 1 and 2. +Connects a mouse into port number PORT. Possible values for PORT are 1 to 8. .TP \fB--nodevice PORT, -N PORT\fR -Disconnects an input device from port number PORT of the emulated SNES. Possible values for PORT are 1 and 2. This may be needed for some odd games to run properly. +Disconnects an input device from port number PORT. Possible values for PORT are 1 to 8. This may be needed for some odd games to run properly. .TP \fB--scope, -p\fR -Connects a Super Scope into port 2 of the SNES. It is controlled with your mouse. +Connects a Super Scope into port 2 of an emulated SNES. It is controlled with your mouse. .TP \fB--justifier, -j\fR -Connects a Konami Justifier into port 2 of the SNES. It is controller with your mouse. +Connects a Konami Justifier into port 2 of an emulated SNES. It is controlled with your mouse. .TP \fB--justifiers, -J\fR -Connects two Konami Justifier into port 2 of the SNES. Currently, only player 1 is controlled with the mouse. +Connects two Konami Justifier into port 2 of an emulated SNES. Currently, only player 1 is controlled with the mouse. .TP \fB--multitap, -4\fR -Connects a four-way multitap into port 2 of the SNES. This allows for up to 5 players. +Connects a four-way multitap into an emulated SNES. This allows for up to 5 players. + +.TP +\fB--dualanalog PORT, -A PORT\fR +Connects a DualAnalog controller into port PORT. Possible values are 1 to 8. .TP \fB--record PATH, -r PATH\fR diff --git a/general.h b/general.h index b76f68659f..bf15e959f6 100644 --- a/general.h +++ b/general.h @@ -285,12 +285,13 @@ struct global bool video_active; bool force_fullscreen; - bool has_mouse[2]; - bool has_scope[2]; + bool disconnect_device[MAX_PLAYERS]; + bool has_mouse[MAX_PLAYERS]; + bool has_dualanalog[MAX_PLAYERS]; + bool has_scope; bool has_justifier; bool has_justifiers; bool has_multitap; - bool disconnect_device[2]; FILE *rom_file; enum rarch_game_type game_type; diff --git a/retroarch.c b/retroarch.c index eaa2bbf6c1..ce5813b47f 100644 --- a/retroarch.c +++ b/retroarch.c @@ -560,13 +560,15 @@ static void print_help(void) puts("\t-B/--bsxslot: Path to BSX slotted rom. Load BSX BIOS as the regular rom."); puts("\t--sufamiA: Path to A slot of Sufami Turbo. Load Sufami base cart as regular rom."); puts("\t--sufamiB: Path to B slot of Sufami Turbo."); - puts("\t-m/--mouse: Connect a virtual mouse into designated port of the SNES (1 or 2)."); - puts("\t\tThis argument can be specified several times to connect more mice."); - puts("\t-N/--nodevice: Disconnects the controller device connected to the emulated SNES (1 or 2)."); - puts("\t-p/--scope: Connect a virtual SuperScope into port 2 of the SNES."); - puts("\t-j/--justifier: Connect a virtual Konami Justifier into port 2 of the SNES."); - puts("\t-J/--justifiers: Daisy chain two virtual Konami Justifiers into port 2 of the SNES."); - puts("\t-4/--multitap: Connect a multitap to port 2 of the SNES."); + + printf("\t-N/--nodevice: Disconnects controller device connected to port (1 to %d).\n", MAX_PLAYERS); + printf("\t-A/--dualanalog: Connect a DualAnalog controller to port (1 to %d).\n", MAX_PLAYERS); + printf("\t-m/--mouse: Connect a mouse into port of the device (1 to %d).\n", MAX_PLAYERS); + puts("\t-p/--scope: Connect a virtual SuperScope into port 2. (SNES specific)."); + puts("\t-j/--justifier: Connect a virtual Konami Justifier into port 2. (SNES specific)."); + puts("\t-J/--justifiers: Daisy chain two virtual Konami Justifiers into port 2. (SNES specific)."); + puts("\t-4/--multitap: Connect a SNES multitap to port 2. (SNES specific)."); + #ifdef HAVE_BSV_MOVIE puts("\t-P/--bsvplay: Playback a BSV movie file."); puts("\t-R/--bsvrecord: Start recording a BSV movie file from the beginning."); @@ -727,11 +729,12 @@ static void parse_input(int argc, char *argv[]) { "mouse", 1, NULL, 'm' }, { "nodevice", 1, NULL, 'N' }, { "scope", 0, NULL, 'p' }, + { "justifier", 0, NULL, 'j' }, + { "justifiers", 0, NULL, 'J' }, + { "dualanalog", 1, NULL, 'A' }, { "savestate", 1, NULL, 'S' }, { "bsx", 1, NULL, 'b' }, { "bsxslot", 1, NULL, 'B' }, - { "justifier", 0, NULL, 'j' }, - { "justifiers", 0, NULL, 'J' }, { "multitap", 0, NULL, '4' }, { "sufamiA", 1, NULL, 'Y' }, { "sufamiB", 1, NULL, 'Z' }, @@ -791,7 +794,7 @@ static void parse_input(int argc, char *argv[]) #define BSV_MOVIE_ARG #endif - const char *optstring = "hs:fvS:m:p4jJg:b:B:Y:Z:U:DN:X:" BSV_MOVIE_ARG NETPLAY_ARG DYNAMIC_ARG FFMPEG_RECORD_ARG CONFIG_FILE_ARG; + const char *optstring = "hs:fvS:m:p4jJA:g:b:B:Y:Z:U:DN:X:" BSV_MOVIE_ARG NETPLAY_ARG DYNAMIC_ARG FFMPEG_RECORD_ARG CONFIG_FILE_ARG; for (;;) { val = 0; @@ -819,6 +822,17 @@ static void parse_input(int argc, char *argv[]) g_extern.has_justifiers = true; break; + case 'A': + port = strtol(optarg, NULL, 0); + if (port < 1 || port > MAX_PLAYERS) + { + RARCH_ERR("Connect dualanalog to a valid port.\n"); + print_help(); + rarch_fail(1, "parse_input()"); + } + g_extern.has_dualanalog[port - 1] = true; + break; + case 's': strlcpy(g_extern.savefile_name_srm, optarg, sizeof(g_extern.savefile_name_srm)); g_extern.has_set_save_path = true; @@ -864,9 +878,9 @@ static void parse_input(int argc, char *argv[]) case 'm': port = strtol(optarg, NULL, 0); - if (port < 1 || port > 2) + if (port < 1 || port > MAX_PLAYERS) { - RARCH_ERR("Connect mouse to port 1 or 2.\n"); + RARCH_ERR("Connect mouse to a valid port.\n"); print_help(); rarch_fail(1, "parse_input()"); } @@ -875,9 +889,9 @@ static void parse_input(int argc, char *argv[]) case 'N': port = strtol(optarg, NULL, 0); - if (port < 1 || port > 2) + if (port < 1 || port > MAX_PLAYERS) { - RARCH_ERR("Disconnected device from port 1 or 2.\n"); + RARCH_ERR("Disconnect device from a valid port.\n"); print_help(); rarch_fail(1, "parse_input()"); } @@ -885,7 +899,7 @@ static void parse_input(int argc, char *argv[]) break; case 'p': - g_extern.has_scope[1] = true; + g_extern.has_scope = true; break; #ifdef HAVE_CONFIGFILE @@ -1054,9 +1068,27 @@ static void parse_input(int argc, char *argv[]) verify_stdin_paths(); } -// TODO: Add rest of the controllers. static void init_controllers(void) { + for (unsigned i = 0; i < MAX_PLAYERS; i++) + { + if (g_extern.disconnect_device[i]) + { + RARCH_LOG("Disconnecting device from port %u.\n", i + 1); + pretro_set_controller_port_device(i, RETRO_DEVICE_NONE); + } + else if (g_extern.has_dualanalog[i]) + { + RARCH_LOG("Connecting dualanalog to port %u.\n", i + 1); + pretro_set_controller_port_device(i, RETRO_DEVICE_ANALOG); + } + else if (g_extern.has_mouse[i]) + { + RARCH_LOG("Connecting mouse to port %u.\n", i + 1); + pretro_set_controller_port_device(i, RETRO_DEVICE_MOUSE); + } + } + if (g_extern.has_justifier) { RARCH_LOG("Connecting Justifier to port 2.\n"); @@ -1072,26 +1104,10 @@ static void init_controllers(void) RARCH_LOG("Connecting Multitap to port 2.\n"); pretro_set_controller_port_device(1, RETRO_DEVICE_JOYPAD_MULTITAP); } - else + else if (g_extern.has_scope) { - for (unsigned i = 0; i < 2; i++) - { - if (g_extern.disconnect_device[i]) - { - RARCH_LOG("Disconnecting device from port %u.\n", i + 1); - pretro_set_controller_port_device(i, RETRO_DEVICE_NONE); - } - else if (g_extern.has_mouse[i]) - { - RARCH_LOG("Connecting mouse to port %u.\n", i + 1); - pretro_set_controller_port_device(i, RETRO_DEVICE_MOUSE); - } - else if (g_extern.has_scope[i]) - { - RARCH_LOG("Connecting scope to port %u.\n", i + 1); - pretro_set_controller_port_device(i, RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE); - } - } + RARCH_LOG("Connecting scope to port 2.\n"); + pretro_set_controller_port_device(1, RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE); } } From 6a08c92ada9214ecb6a010e19b1bc9233a3fdc87 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 17 Aug 2012 17:43:23 +0200 Subject: [PATCH 194/492] (Xbox 1) Cut down on some static variables --- audio/dsound.c | 4 ++-- console/rmenu/rmenu.c | 8 ++++---- console/rzlib/rzlib.c | 26 +++++++++++++------------- xdk/xdk_xinput_input.c | 2 +- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/audio/dsound.c b/audio/dsound.c index 370e6d8f88..77bde9a507 100644 --- a/audio/dsound.c +++ b/audio/dsound.c @@ -22,7 +22,7 @@ // succeed #define DSERR_PRIOLEVELNEEDED MAKE_DSHRESULT(70) // Send the audio signal (stereo, without attenuation) to all existing speakers -static DSMIXBINVOLUMEPAIR dsmbvp[8] = { +DSMIXBINVOLUMEPAIR dsmbvp[8] = { { DSMIXBIN_FRONT_LEFT, DSBVOLUME_MAX }, { DSMIXBIN_FRONT_RIGHT, DSBVOLUME_MAX }, { DSMIXBIN_FRONT_CENTER, DSBVOLUME_MAX }, @@ -33,7 +33,7 @@ static DSMIXBINVOLUMEPAIR dsmbvp[8] = { { DSMIXBIN_LOW_FREQUENCY, DSBVOLUME_MAX }, }; -static DSMIXBINS dsmb; +DSMIXBINS dsmb; #endif #include "../driver.h" diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index 62d42e1c12..1d3d775310 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -92,7 +92,7 @@ static bool set_libretro_core_as_launch; filebrowser_t browser; filebrowser_t tmpBrowser; unsigned set_shader = 0; -static unsigned currently_selected_controller_menu = 0; +unsigned currently_selected_controller_menu = 0; char m_title[256]; static uint64_t old_state = 0; @@ -2077,7 +2077,7 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) { char comment[256], overscan_msg[64]; char strw_buffer[256]; - static unsigned menuitem_colors[MENU_ITEM_LAST]; + unsigned menuitem_colors[MENU_ITEM_LAST]; DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; float x_position = POSITION_X; @@ -2374,7 +2374,7 @@ void menu_loop(void) input_ptr.poll(NULL); - static const struct retro_keybind *binds[MAX_PLAYERS] = { + const struct retro_keybind *binds[MAX_PLAYERS] = { g_settings.input.binds[0], g_settings.input.binds[1], g_settings.input.binds[2], @@ -2385,7 +2385,7 @@ void menu_loop(void) g_settings.input.binds[7], }; - static const struct retro_keybind _analog_binds[] = { + const struct retro_keybind _analog_binds[] = { { 0, 0, (enum retro_key)0, (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_LEFT), 0 }, { 0, 0, (enum retro_key)0, (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_RIGHT), 0 }, { 0, 0, (enum retro_key)0, (1 << RETRO_DEVICE_ID_JOYPAD_ANALOG_LEFT_DPAD_UP), 0 }, diff --git a/console/rzlib/rzlib.c b/console/rzlib/rzlib.c index f3e88eec82..d7b09e1f68 100644 --- a/console/rzlib/rzlib.c +++ b/console/rzlib/rzlib.c @@ -59,8 +59,7 @@ struct internal_state inflate_blocks_statef *blocks; /* current inflate_blocks state */ }; -static const unsigned int border[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - +const unsigned int border[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ START, /* x: set up for LEN */ @@ -88,18 +87,18 @@ static int huft_build ( unsigned int * ); /* space for values */ /* Tables for deflate from PKZIP's appnote.txt. */ -static const unsigned int cplens[31] = { /* Copy lengths for literal codes 257..285 */ +const unsigned int cplens[31] = { /* Copy lengths for literal codes 257..285 */ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; /* see note #13 above about 258 */ -static const unsigned int cplext[31] = { /* Extra bits for literal codes 257..285 */ +const unsigned int cplext[31] = { /* Extra bits for literal codes 257..285 */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ -static const unsigned int cpdist[30] = { /* Copy offsets for distance codes 0..29 */ +const unsigned int cpdist[30] = { /* Copy offsets for distance codes 0..29 */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; -static const unsigned int cpdext[30] = { /* Extra bits for distance codes */ +const unsigned int cpdext[30] = { /* Extra bits for distance codes */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; @@ -736,9 +735,10 @@ int inflate_trees_dynamic(unsigned int nl, unsigned int nd, unsigned int *c, uns return Z_OK; } -static unsigned int fixed_bl = 9; -static unsigned int fixed_bd = 5; -static inflate_huft fixed_tl[] = { +unsigned int fixed_bl = 9; +unsigned int fixed_bd = 5; + +inflate_huft fixed_tl[] = { {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, @@ -869,7 +869,7 @@ static inflate_huft fixed_tl[] = { {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} }; -static inflate_huft fixed_td[] = { +inflate_huft fixed_td[] = { {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, @@ -1284,7 +1284,7 @@ void zcfree (voidpf opaque, voidpf ptr) * For conditions of distribution and use, see copyright notice in zlib.h */ -static const unsigned long crc_table[256] = { +const unsigned long crc_table[256] = { 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, @@ -1466,7 +1466,7 @@ int inflateInit2_(z_streamp z, int w, const char * version, int stream_size) } -int inflateInit_(z_streamp z, const char * version, int stream_size) +int inflateInit_(z_streamp z, const char * version, int stream_size) { return inflateInit2_(z, DEF_WBITS, version, stream_size); } @@ -1616,7 +1616,7 @@ int inflate(z_streamp z, int f) # define Z_PRINTF_BUFSIZE 4096 #endif -static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ +int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ /* gzip flag byte */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ diff --git a/xdk/xdk_xinput_input.c b/xdk/xdk_xinput_input.c index 2499bab532..5e6b51e9b2 100644 --- a/xdk/xdk_xinput_input.c +++ b/xdk/xdk_xinput_input.c @@ -29,7 +29,7 @@ #include "xdk_xinput_input.h" static uint64_t state[MAX_PADS]; -static unsigned pads_connected; +unsigned pads_connected; #ifdef _XBOX1 HANDLE gamepads[MAX_PADS]; From 71c8dfb8919202f000d2f827203e0fa7f1295fcb Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 17 Aug 2012 18:02:09 +0200 Subject: [PATCH 195/492] (Xbox 1) Free texture BG before going into game and reload texture when going back to menu - frees up 3MB RAM --- console/rmenu/rmenu.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index 1d3d775310..914e47f731 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -2319,19 +2319,6 @@ void menu_init (void) // Quick hack to properly center the romlist in 720p, // it might need more work though (font size and rom selector size -> needs more memory) // Init rom list coords - // Load background image - if(width == 640) - { - texture_image_load("D:\\Media\\main-menu_480p.png", &m_menuMainBG); - m_menuMainRomListPos_x = 60; - m_menuMainRomListPos_y = 80; - } - else if(width == 1280) - { - texture_image_load("D:\\Media\\main-menu_720p.png", &m_menuMainBG); - m_menuMainRomListPos_x = 360; - m_menuMainRomListPos_y = 130; - } // Load rom selector panel texture_image_load("D:\\Media\\menuMainRomSelectPanel.png", &m_menuMainRomSelectPanel); @@ -2349,7 +2336,6 @@ void menu_free (void) filebrowser_free(&tmpBrowser); #ifdef _XBOX1 - texture_image_free(&m_menuMainBG); texture_image_free(&m_menuMainRomSelectPanel); #endif } @@ -2364,6 +2350,24 @@ void menu_loop(void) if(g_console.ingame_menu_enable) menu_stack_push(ingame_menu_settings, INGAME_MENU); +#ifdef _XBOX1 + int width = device_ptr->d3dpp.BackBufferWidth; + + // Load background image + if(width == 640) + { + texture_image_load("D:\\Media\\main-menu_480p.png", &m_menuMainBG); + m_menuMainRomListPos_x = 60; + m_menuMainRomListPos_y = 80; + } + else if(width == 1280) + { + texture_image_load("D:\\Media\\main-menu_720p.png", &m_menuMainBG); + m_menuMainRomListPos_x = 360; + m_menuMainRomListPos_y = 130; + } +#endif + do { //first button input frame @@ -2611,6 +2615,10 @@ void menu_loop(void) device_ptr->menu_render = false; #endif +#ifdef _XBOX1 + texture_image_free(&m_menuMainBG); +#endif + if(g_console.ingame_menu_enable) menu_stack_decrement(); From d709cb04b47483043d21d3f11c9d3d4a06bdd943 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 17 Aug 2012 18:08:15 +0200 Subject: [PATCH 196/492] (Xbox 1) Free up ROM select panel too - shaves off 0.34MB memory usage --- console/rmenu/rmenu.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index 914e47f731..1210def59b 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -2311,33 +2311,12 @@ void menu_init (void) menu_stack_push(rmenu_items, FILE_BROWSER_MENU); filebrowser_set_root_and_ext(&browser, rarch_console_get_rom_ext(), default_paths.filebrowser_startup_dir); filebrowser_set_root(&tmpBrowser, default_paths.filesystem_root_dir); - -#ifdef _XBOX1 - // Backbuffer width - int width = device_ptr->d3dpp.BackBufferWidth; - - // Quick hack to properly center the romlist in 720p, - // it might need more work though (font size and rom selector size -> needs more memory) - // Init rom list coords - - // Load rom selector panel - texture_image_load("D:\\Media\\menuMainRomSelectPanel.png", &m_menuMainRomSelectPanel); - - //Display some text - //Center the text (hardcoded) - xpos = width == 640 ? 65 : 400; - ypos = width == 640 ? 430 : 670; -#endif } void menu_free (void) { filebrowser_free(&browser); filebrowser_free(&tmpBrowser); - -#ifdef _XBOX1 - texture_image_free(&m_menuMainRomSelectPanel); -#endif } void menu_loop(void) @@ -2366,6 +2345,14 @@ void menu_loop(void) m_menuMainRomListPos_x = 360; m_menuMainRomListPos_y = 130; } + + // Load rom selector panel + texture_image_load("D:\\Media\\menuMainRomSelectPanel.png", &m_menuMainRomSelectPanel); + + //Display some text + //Center the text (hardcoded) + xpos = width == 640 ? 65 : 400; + ypos = width == 640 ? 430 : 670; #endif do @@ -2617,6 +2604,7 @@ void menu_loop(void) #ifdef _XBOX1 texture_image_free(&m_menuMainBG); + texture_image_free(&m_menuMainRomSelectPanel); #endif if(g_console.ingame_menu_enable) From 07c6ff566696293219482447ce4798f26152aff1 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 17 Aug 2012 18:22:28 +0200 Subject: [PATCH 197/492] (RMenu) filebrowser_free called at end of menu_loop - filebrowser_init called at start of menu_loop --- console/rmenu/rmenu.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index 1210def59b..f11d791032 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -2307,18 +2307,25 @@ void menu_init (void) retro_get_system_info(&info); const char *id = info.library_name ? info.library_name : "Unknown"; snprintf(m_title, sizeof(m_title), "Libretro core: %s %s", id, info.library_version); +} +static void filebrowser_init(void) +{ menu_stack_push(rmenu_items, FILE_BROWSER_MENU); filebrowser_set_root_and_ext(&browser, rarch_console_get_rom_ext(), default_paths.filebrowser_startup_dir); filebrowser_set_root(&tmpBrowser, default_paths.filesystem_root_dir); } -void menu_free (void) +static void filebrowser_free(void) { filebrowser_free(&browser); filebrowser_free(&tmpBrowser); } +void menu_free (void) +{ +} + void menu_loop(void) { DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; @@ -2326,6 +2333,8 @@ void menu_loop(void) g_console.menu_enable = true; device_ptr->block_swap = true; + filebrowser_init(); + if(g_console.ingame_menu_enable) menu_stack_push(ingame_menu_settings, INGAME_MENU); @@ -2607,6 +2616,8 @@ void menu_loop(void) texture_image_free(&m_menuMainRomSelectPanel); #endif + filebrowser_free(); + if(g_console.ingame_menu_enable) menu_stack_decrement(); From a7fe9aa50a2c1208336e865f27d43b73e0b60499 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 17 Aug 2012 19:11:43 +0200 Subject: [PATCH 198/492] (Xbox 1) Make some variables non-static --- xbox1/xdk_d3d8.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xbox1/xdk_d3d8.cpp b/xbox1/xdk_d3d8.cpp index da8ae2b10a..0835c5fa6d 100644 --- a/xbox1/xdk_d3d8.cpp +++ b/xbox1/xdk_d3d8.cpp @@ -299,7 +299,7 @@ static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **inpu d3d->d3d_render_device->CreateVertexBuffer(4 * sizeof(DrawVerticeFormats), D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &d3d->vertex_buf); - static const DrawVerticeFormats init_verts[] = { + const DrawVerticeFormats init_verts[] = { { -1.0f, -1.0f, 1.0f, 0.0f, 1.0f }, { 1.0f, -1.0f, 1.0f, 1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f, 0.0f, 0.0f }, @@ -444,7 +444,7 @@ static bool xdk_d3d_frame(void *data, const void *frame, if(fps_enable) { - static MEMORYSTATUS stat; + MEMORYSTATUS stat; GlobalMemoryStatus(&stat); //Output memory usage From 2790555f1c955ddfc1651e46e43cc36712d18caa Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Fri, 17 Aug 2012 21:43:12 +0200 Subject: [PATCH 199/492] (PS3/Rmenu) Build fix --- console/rmenu/rmenu.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index f11d791032..75fbf7c97f 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -2307,16 +2307,18 @@ void menu_init (void) retro_get_system_info(&info); const char *id = info.library_name ? info.library_name : "Unknown"; snprintf(m_title, sizeof(m_title), "Libretro core: %s %s", id, info.library_version); + + rmenu_filebrowser_init(); } -static void filebrowser_init(void) +static void rmenu_filebrowser_init(void) { menu_stack_push(rmenu_items, FILE_BROWSER_MENU); filebrowser_set_root_and_ext(&browser, rarch_console_get_rom_ext(), default_paths.filebrowser_startup_dir); filebrowser_set_root(&tmpBrowser, default_paths.filesystem_root_dir); } -static void filebrowser_free(void) +static void rmenu_filebrowser_free(void) { filebrowser_free(&browser); filebrowser_free(&tmpBrowser); @@ -2324,6 +2326,7 @@ static void filebrowser_free(void) void menu_free (void) { + rmenu_filebrowser_free(); } void menu_loop(void) @@ -2333,7 +2336,6 @@ void menu_loop(void) g_console.menu_enable = true; device_ptr->block_swap = true; - filebrowser_init(); if(g_console.ingame_menu_enable) menu_stack_push(ingame_menu_settings, INGAME_MENU); @@ -2616,7 +2618,6 @@ void menu_loop(void) texture_image_free(&m_menuMainRomSelectPanel); #endif - filebrowser_free(); if(g_console.ingame_menu_enable) menu_stack_decrement(); From 2234073c2f76d2e59481091039a24b4261bafbb3 Mon Sep 17 00:00:00 2001 From: Themaister Date: Fri, 17 Aug 2012 23:20:08 +0200 Subject: [PATCH 200/492] Readding static to globals in dsound. --- audio/dsound.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/audio/dsound.c b/audio/dsound.c index 77bde9a507..370e6d8f88 100644 --- a/audio/dsound.c +++ b/audio/dsound.c @@ -22,7 +22,7 @@ // succeed #define DSERR_PRIOLEVELNEEDED MAKE_DSHRESULT(70) // Send the audio signal (stereo, without attenuation) to all existing speakers -DSMIXBINVOLUMEPAIR dsmbvp[8] = { +static DSMIXBINVOLUMEPAIR dsmbvp[8] = { { DSMIXBIN_FRONT_LEFT, DSBVOLUME_MAX }, { DSMIXBIN_FRONT_RIGHT, DSBVOLUME_MAX }, { DSMIXBIN_FRONT_CENTER, DSBVOLUME_MAX }, @@ -33,7 +33,7 @@ DSMIXBINVOLUMEPAIR dsmbvp[8] = { { DSMIXBIN_LOW_FREQUENCY, DSBVOLUME_MAX }, }; -DSMIXBINS dsmb; +static DSMIXBINS dsmb; #endif #include "../driver.h" From fdbea950f1054d2ab5617373f8e21253589795bb Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sat, 18 Aug 2012 01:13:00 +0200 Subject: [PATCH 201/492] (Filebrowser) Do dir_list_free in parse_directory --- console/fileio/file_browser.c | 3 +++ console/rmenu/rmenu.c | 26 +++++++++++++------------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/console/fileio/file_browser.c b/console/fileio/file_browser.c index 30e43d5bc8..33f6e206d9 100644 --- a/console/fileio/file_browser.c +++ b/console/fileio/file_browser.c @@ -26,6 +26,9 @@ const char * path, const char * extensions) strlcpy(filebrowser->dir[stack_size], path, sizeof(filebrowser->dir[stack_size])); + if(filebrowser->current_dir.list != NULL) + dir_list_free(filebrowser->current_dir.list); + filebrowser->current_dir.list = list; filebrowser->current_dir.ptr = 0; diff --git a/console/rmenu/rmenu.c b/console/rmenu/rmenu.c index 75fbf7c97f..a380f73033 100644 --- a/console/rmenu/rmenu.c +++ b/console/rmenu/rmenu.c @@ -2297,6 +2297,19 @@ static void ingame_menu(item *items, menu *current_menu, uint64_t input) #endif } +static void rmenu_filebrowser_init(void) +{ + menu_stack_push(rmenu_items, FILE_BROWSER_MENU); + filebrowser_set_root_and_ext(&browser, rarch_console_get_rom_ext(), default_paths.filebrowser_startup_dir); + filebrowser_set_root(&tmpBrowser, default_paths.filesystem_root_dir); +} + +static void rmenu_filebrowser_free(void) +{ + filebrowser_free(&browser); + filebrowser_free(&tmpBrowser); +} + void menu_init (void) { DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data; @@ -2311,19 +2324,6 @@ void menu_init (void) rmenu_filebrowser_init(); } -static void rmenu_filebrowser_init(void) -{ - menu_stack_push(rmenu_items, FILE_BROWSER_MENU); - filebrowser_set_root_and_ext(&browser, rarch_console_get_rom_ext(), default_paths.filebrowser_startup_dir); - filebrowser_set_root(&tmpBrowser, default_paths.filesystem_root_dir); -} - -static void rmenu_filebrowser_free(void) -{ - filebrowser_free(&browser); - filebrowser_free(&tmpBrowser); -} - void menu_free (void) { rmenu_filebrowser_free(); From b8399105513115de001f07d7f8350bef35bce75a Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 18 Aug 2012 12:25:37 +0200 Subject: [PATCH 202/492] (Xbox 1) Set MAX_PATH to theoretical max - 260 - frees up around 20Kb --- general.h | 2 +- msvc/msvc_compat.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/general.h b/general.h index bf15e959f6..763ed3b165 100644 --- a/general.h +++ b/general.h @@ -41,7 +41,7 @@ #include